[Kst] extragear/graphics/kst/src/libkstapp

Eli Fidler eli at staikos.net
Fri Mar 16 17:56:02 CET 2007


SVN commit 643231 by fidler:

Label patch to fix labels when object names are changed.
re: bug 142622

reviewed by George

This still doesn't handle dependent objects (label: [V/Mean], change V
to V2, label won't update).


 M  +10 -4     kstplotlabel.cpp  
 M  +7 -1      kstplotlabel.h  
 M  +8 -2      kstviewlabel.cpp  
 M  +5 -0      kstviewlabel.h  
 M  +12 -6     kstviewlegend.cpp  
 M  +4 -1      kstviewlegend.h  
 M  +136 -13   labelrenderer.cpp  
 M  +9 -1      labelrenderer.h  


--- trunk/extragear/graphics/kst/src/libkstapp/kstplotlabel.cpp #643230:643231
@@ -71,13 +71,18 @@
 
 void KstPlotLabel::reparse() {
   delete _parsed;
-   _parsed = Label::parse(_txt, _interpret, false);
+  _parsed = Label::parse(_txt, _interpret, false);
+  collectObjects(_parsed, _vectorsUsed, _scalarsUsed, _stringsUsed);
+  _txt = labelText(_txt, _parsed, _vectorsUsed, _scalarsUsed, _stringsUsed);
 }
 
 
 void KstPlotLabel::setText(const QString& text) {
   if (_txt != text) {
     _txt = text;
+    _scalarsUsed.clear();
+    _stringsUsed.clear();
+    _vectorsUsed.clear();
     reparse();
     computeTextSize();
     //setDirty(true);
@@ -160,7 +165,7 @@
   rc.pen = p.pen();
 
   if (lp && lp->chunk) {
-    renderLabel(rc, lp->chunk);
+    renderLabel(rc, lp->chunk, _vectorsUsed, _scalarsUsed, _stringsUsed);
   }
 }
 
@@ -169,7 +174,7 @@
   if (_parsed && _parsed->chunk) {
     RenderContext rc(_fontName, _absFontSize, 0L);
     rc.setSubstituteScalars(_replace);
-    renderLabel(rc, _parsed->chunk);
+    renderLabel(rc, _parsed->chunk, _vectorsUsed, _scalarsUsed, _stringsUsed);
     _textWidth = rc.x;
     _ascent = rc.ascent;
     _textHeight = 1 + rc.ascent + rc.descent;
@@ -246,7 +251,8 @@
 }
 
 
-void KstPlotLabel::save(QTextStream &ts, const QString& indent, bool save_pos) const {
+void KstPlotLabel::save(QTextStream &ts, const QString& indent, bool save_pos) {
+  reparse();
   QString l2 = indent + "  ";
   ts << indent << "<text>" << QStyleSheet::escape(_txt) << "</text>" << endl;
   if (_interpret) {
--- trunk/extragear/graphics/kst/src/libkstapp/kstplotlabel.h #643230:643231
@@ -20,6 +20,8 @@
 
 #include "labelparser.h"
 
+#include "kstvector.h"
+
 class KstPlotLabel {
   public:
     explicit KstPlotLabel(float rotation = 0.0);
@@ -58,7 +60,7 @@
     QSize size() const;
 
     void load(const QDomElement& e);
-    void save(QTextStream& ts, const QString& indent = QString::null, bool save_pos = false) const;
+    void save(QTextStream& ts, const QString& indent = QString::null, bool save_pos = false);
 
     KstPlotLabel& operator=(const KstPlotLabel&);
 
@@ -82,6 +84,10 @@
     KstLJustifyType _justify;
     Label::Parsed *_parsed;
     int _lineSpacing;
+
+    KstScalarMap _scalarsUsed;
+    KstStringMap _stringsUsed;
+    KstVectorMap _vectorsUsed;
 };
 
 #endif
--- trunk/extragear/graphics/kst/src/libkstapp/kstviewlabel.cpp #643230:643231
@@ -153,6 +153,8 @@
 void KstViewLabel::reparse() {
   delete _parsed;
   _parsed = Label::parse(_txt, _interpret);
+  collectObjects(_parsed, _vectorsUsed, _scalarsUsed, _stringsUsed);
+  _txt = labelText(_txt, _parsed, _vectorsUsed, _scalarsUsed, _stringsUsed);
   setDirty();
 }
 
@@ -160,6 +162,9 @@
 void KstViewLabel::setText(const QString& text) {
   if (_txt != text) {
     _txt = text;
+    _scalarsUsed.clear();
+    _stringsUsed.clear();
+    _vectorsUsed.clear();
     reparse(); // calls setDirty()
   }
 }
@@ -220,6 +225,7 @@
 
 
 void KstViewLabel::save(QTextStream &ts, const QString& indent) {
+  reparse();
   ts << indent << "<" << type() << ">" << endl;
   KstBorderedViewObject::save(ts, indent + "  ");
   ts << indent << "</" << type() << ">" << endl;
@@ -299,7 +305,7 @@
   t.start();
 #endif
   if (lp && lp->chunk) {
-    renderLabel(rc, lp->chunk);
+    renderLabel(rc, lp->chunk, _vectorsUsed, _scalarsUsed, _stringsUsed);
     _cache.valid = true;
   }
 #ifdef BENCHMARK
@@ -322,7 +328,7 @@
     QTime t;
     t.start();
 #endif
-    renderLabel(rc, lp->chunk);
+    renderLabel(rc, lp->chunk, _vectorsUsed, _scalarsUsed, _stringsUsed);
 #ifdef BENCHMARK
     kstdDebug() << "compute (false render) took: " << t.elapsed() << endl;
 #endif
--- trunk/extragear/graphics/kst/src/libkstapp/kstviewlabel.h #643230:643231
@@ -23,6 +23,7 @@
 #include "kstbackbuffer.h"
 #include "kstborderedviewobject.h"
 #include "kstscalar.h"
+#include "kstvector.h"
 #include "labelparser.h"
 
 #include <qguardedptr.h>
@@ -139,6 +140,10 @@
       void update();
     };
     DataCache _cache;
+
+    KstScalarMap _scalarsUsed;
+    KstStringMap _stringsUsed;
+    KstVectorMap _vectorsUsed;
 };
 
 typedef KstSharedPtr<KstViewLabel> KstViewLabelPtr;
--- trunk/extragear/graphics/kst/src/libkstapp/kstviewlegend.cpp #643230:643231
@@ -204,6 +204,7 @@
 
 
 void KstViewLegend::save(QTextStream &ts, const QString& indent) {
+  reparseTitle();
   ts << indent << "<" << type() << ">" << endl;
   KstBorderedViewObject::save(ts, indent + "  ");
   
@@ -244,7 +245,7 @@
       rc.x = 0;
       rc.y = _ascent;
       rc.xStart = rc.x;
-      renderLabel(rc, _parsedTitle->chunk);
+      renderLabel(rc, _parsedTitle->chunk, _vectorsUsed, _scalarsUsed, _stringsUsed);
       i = 1;
       p.restore();
     }
@@ -259,7 +260,7 @@
         rc.x = 0;
         rc.y = _ascent;
         rc.xStart = rc.x;
-        renderLabel(rc, (*it)->parsedLegendTag()->chunk);
+        renderLabel(rc, (*it)->parsedLegendTag()->chunk, _vectorsUsed, _scalarsUsed, _stringsUsed);
       }
       p.restore();
       ++i;
@@ -271,7 +272,7 @@
       rc.x = 0;
       rc.y = _ascent;
       rc.xStart = rc.x;
-      renderLabel(rc, _parsedTitle->chunk);
+      renderLabel(rc, _parsedTitle->chunk, _vectorsUsed, _scalarsUsed, _stringsUsed);
       p.translate(_titleWidth + _ascent,0);
     }
 
@@ -284,7 +285,7 @@
         rc.x = 0;
         rc.y = _ascent;
         rc.xStart = rc.x;
-        renderLabel(rc, (*it)->parsedLegendTag()->chunk);
+        renderLabel(rc, (*it)->parsedLegendTag()->chunk, _vectorsUsed, _scalarsUsed, _stringsUsed);
         p.translate((*it)->legendLabelSize().width() + _ascent,0);
       }
     }
@@ -303,7 +304,7 @@
   for (KstBaseCurveList::Iterator it = _curves.begin(); it != _curves.end(); it++) {
     if ((*it)->parsedLegendTag()) {
       RenderContext rc(_fontName, _absFontSize, 0L);
-      renderLabel(rc, (*it)->parsedLegendTag()->chunk);
+      renderLabel(rc, (*it)->parsedLegendTag()->chunk, _vectorsUsed, _scalarsUsed, _stringsUsed);
       if (_vertical) {
         if (rc.xMax > _textWidth) {
           _textWidth = rc.xMax;
@@ -341,7 +342,7 @@
     if (!_parsedTitle) {
       reparseTitle();
     }
-    renderLabel(rc, _parsedTitle->chunk);
+    renderLabel(rc, _parsedTitle->chunk, _vectorsUsed, _scalarsUsed, _stringsUsed);
     _titleWidth = rc.xMax;
     _titleHeight = rc.fontHeight();
   } else {
@@ -574,6 +575,8 @@
 void KstViewLegend::reparseTitle() {
   delete _parsedTitle;
   _parsedTitle = Label::parse(_title, true, false);
+  collectObjects(_parsedTitle, _vectorsUsed, _scalarsUsed, _stringsUsed);
+  _title = labelText(_title, _parsedTitle, _vectorsUsed, _scalarsUsed, _stringsUsed);
   setDirty();
 }
 
@@ -751,6 +754,9 @@
 void KstViewLegend::setTitle(const QString& title_in) {
   if (_title != title_in) {
     _title = title_in;
+    _scalarsUsed.clear();
+    _stringsUsed.clear();
+    _vectorsUsed.clear();
     reparseTitle(); // calls setDirty()
   }
 }
--- trunk/extragear/graphics/kst/src/libkstapp/kstviewlegend.h #643230:643231
@@ -117,7 +117,10 @@
 
     double _rotation;
     QString _fontName;
-    KstScalarList _scalarsUsed;
+//    KstScalarList _scalarsUsed;
+    KstScalarMap _scalarsUsed;
+    KstStringMap _stringsUsed;
+    KstVectorMap _vectorsUsed;
 
     bool _replace : 1;
     bool _vertical : 1;
--- trunk/extragear/graphics/kst/src/libkstapp/labelrenderer.cpp #643230:643231
@@ -29,7 +29,112 @@
 
 #include <iostream>
 
-void renderLabel(RenderContext& rc, Label::Chunk *fi) {
+bool collectObjects(Label::Parsed *lp, KstVectorMap& vm, KstScalarMap& scm, KstStringMap& stm) {
+  if (!lp) {
+    return false;
+  }
+
+  for (Label::Chunk *fi = lp->chunk; fi; fi = fi->next) {
+    if (fi->scalar) {
+      KST::scalarList.lock().readLock();
+      KstScalarPtr scp = KST::scalarList.retrieveObject(KstObjectTag::fromString(fi->text));
+      KST::scalarList.lock().unlock();
+      if (scp) {
+        scm.insert(fi->text, scp);
+        continue;
+      }
+
+      KST::stringList.lock().readLock();
+      KstStringPtr stp = KST::stringList.retrieveObject(KstObjectTag::fromString(fi->text));
+      KST::stringList.lock().unlock();
+      if (stp) {
+        stm.insert(fi->text, stp);
+        continue;
+      }
+    } else if (fi->vector) {
+      KST::vectorList.lock().readLock();
+      KstVectorPtr vp = KST::vectorList.retrieveObject(KstObjectTag::fromString(fi->text));
+      KST::vectorList.lock().unlock();
+      if (vp) {
+        vm.insert(fi->text, vp);
+        continue;
+      }
+    } else {
+      // not an object reference
+      continue;
+    }
+    
+//    kstdWarning() << "Label references unknown object [" << fi->text << "]." << endl;
+    return false;
+  }
+
+  return true;
+}
+
+
+// This is a hack to give us back the label text using the current object names
+QString labelText(QString txt, Label::Parsed *lp, KstVectorMap& vm, KstScalarMap& scm, KstStringMap& stm) {
+  QString label = txt;
+
+  if (!lp) {
+    return label;
+  }
+
+  for (Label::Chunk *fi = lp->chunk; fi; fi = fi->next) {
+    if (fi->scalar) {
+      KstScalarPtr scp;
+      if (scm.contains(fi->text)) {
+        scp = scm[fi->text];
+      } else {
+        KST::scalarList.lock().readLock();
+        scp = KST::scalarList.retrieveObject(KstObjectTag::fromString(fi->text));
+        KST::scalarList.lock().unlock();
+      }
+      if (scp && scp->tag().displayString() != fi->text) {
+        label.replace(QString("[%1]").arg(fi->text), QString("[%1]").arg(scp->tag().displayString()));
+        scm.insert(scp->tag().displayString(), scp);
+        continue;
+      }
+
+      KstStringPtr stp;
+      if (stm.contains(fi->text)) {
+        stp = stm[fi->text];
+      } else {
+        KST::stringList.lock().readLock();
+        stp = KST::stringList.retrieveObject(KstObjectTag::fromString(fi->text));
+        KST::stringList.lock().unlock();
+      }
+      if (stp && stp->tag().displayString() != fi->text) {
+        label.replace(QString("[%1]").arg(fi->text), QString("[%1]").arg(stp->tag().displayString()));
+        stm.insert(stp->tag().displayString(), stp);
+        continue;
+      }
+    } else if (fi->vector) {
+      KstVectorPtr vp;
+      if (vm.contains(fi->text)) {
+        vp = vm[fi->text];
+      } else {
+        KST::vectorList.lock().readLock();
+        vp = KST::vectorList.retrieveObject(KstObjectTag::fromString(fi->text));
+        KST::vectorList.lock().unlock();
+      }
+      if (vp && vp->tag().displayString() != fi->text) {
+        label.replace(QString("[%1[").arg(fi->text), QString("[%1[").arg(vp->tag().displayString()));
+        vm.insert(vp->tag().displayString(), vp);
+        continue;
+      }
+    }
+  }
+
+  if (label != txt) {
+    kstdDebug() << "Updated label \"" << txt << "\" to \"" << label << "\"" << endl;
+  }
+
+  return label;
+}
+
+
+void renderLabel(RenderContext& rc, Label::Chunk *fi, const KstVectorMap& vm, const KstScalarMap& scm, const KstStringMap& stm) {
   // FIXME: RTL support
   int oldSize = rc.size;
   int oldY = rc.y;
@@ -88,9 +193,15 @@
           rc._cache->append(DataRef(DataRef::DRExpression, fi->text, QString::null, 0.0, QVariant(eqResult)));
         }
       } else {
-        KST::scalarList.lock().readLock();
-        KstScalarPtr scp = KST::scalarList.retrieveObject(KstObjectTag::fromString(fi->text));
-        KST::scalarList.lock().unlock();
+        KstScalarPtr scp;
+        if (scm.contains(fi->text)) {
+          scp = scm[fi->text];
+        }
+        if (!scp) {
+          KST::scalarList.lock().readLock();
+          scp = KST::scalarList.retrieveObject(KstObjectTag::fromString(fi->text));
+          KST::scalarList.lock().unlock();
+        }
         if (scp) {
           scp->readLock();
           txt = QString::number(scp->value(), 'g', rc.precision);
@@ -99,9 +210,15 @@
           }
           scp->unlock();
         } else {
-          KST::stringList.lock().readLock();
-          KstStringPtr stp = KST::stringList.retrieveObject(KstObjectTag::fromString(fi->text));
-          KST::stringList.lock().unlock();
+          KstStringPtr stp;
+          if (stm.contains(fi->text)) {
+            stp = stm[fi->text];
+          }
+          if (!stp) {
+            KST::stringList.lock().readLock();
+            stp = KST::stringList.retrieveObject(KstObjectTag::fromString(fi->text));
+            KST::stringList.lock().unlock();
+          }
           if (stp) {
             stp->readLock();
             txt = stp->value();
@@ -155,9 +272,15 @@
       rc.x += rc.fontWidth(txt);
     } else if (fi->vector) {
       QString txt;
-      KST::vectorList.lock().readLock();
-      KstVectorPtr vp = *KST::vectorList.findTag(fi->text);
-      KST::vectorList.lock().unlock();
+      KstVectorPtr vp;
+      if (vm.contains(fi->text)) {
+        vp = vm[fi->text];
+      }
+      if (!vp) {
+        KST::vectorList.lock().readLock();
+        vp = *KST::vectorList.findTag(fi->text);
+        KST::vectorList.lock().unlock();
+      }
       if (vp) {
         if (!fi->expression.isEmpty()) {
           // Parse and evaluate as an equation
@@ -214,19 +337,19 @@
 
     int xNext = rc.x;
     if (fi->group) {
-      renderLabel(rc, fi->group);
+      renderLabel(rc, fi->group, vm, scm, stm);
       xNext = rc.x;
     }
 
     if (fi->up) {
       int xPrev = rc.x;
-      renderLabel(rc, fi->up);
+      renderLabel(rc, fi->up, vm, scm, stm);
       xNext = kMax(xNext, rc.x);
       rc.x = xPrev;
     }
 
     if (fi->down) {
-      renderLabel(rc, fi->down);
+      renderLabel(rc, fi->down, vm, scm, stm);
       xNext = kMax(xNext, rc.x);
     }
 
--- trunk/extragear/graphics/kst/src/libkstapp/labelrenderer.h #643230:643231
@@ -28,6 +28,10 @@
 #include "dataref.h"
 #include "kst_export.h"
 
+#include "kstscalar.h"
+#include "kststring.h"
+#include "kstvector.h"
+
 // inline for speed.
 struct RenderContext {
   RenderContext(const QString& fontName, int fontSize, QPainter *p)
@@ -135,10 +139,14 @@
 
 namespace Label {
   class Chunk;
+  class Parsed;
 }
 
-KST_EXPORT void renderLabel(RenderContext& rc, Label::Chunk *fi);
+KST_EXPORT bool collectObjects(Label::Parsed *lp, KstVectorMap& vm, KstScalarMap& scm, KstStringMap& stm);
 
+KST_EXPORT QString labelText(QString txt, Label::Parsed *lp, KstVectorMap& vm, KstScalarMap& scm, KstStringMap& stm);
 
+KST_EXPORT void renderLabel(RenderContext& rc, Label::Chunk *fi, const KstVectorMap& vm, const KstScalarMap& scm, const KstStringMap& stm);
+
 #endif
 // vim: ts=2 sw=2 et


More information about the Kst mailing list