Browse Source

add capability to update UIML View elements after dom xml changes without recreating all viewed elements

Kolja Strohm 8 months ago
parent
commit
771148e442
8 changed files with 351 additions and 90 deletions
  1. 13 0
      Array.h
  2. 49 60
      Fenster.cpp
  3. 3 1
      Fenster.h
  4. 4 4
      UIDialog.cpp
  5. 235 25
      UIMLView.cpp
  6. 40 0
      UIMLView.h
  7. 5 0
      Zeichnung.cpp
  8. 2 0
      Zeichnung.h

+ 13 - 0
Array.h

@@ -832,6 +832,19 @@ namespace Framework
             return i >= 0 && i < count;
         }
 
+        // returns the index of the first element that matches zT or -1 if not found
+        int indexOf(TYP* zT) const
+        {
+            int i = 0;
+            for (TYP* t : *this)
+            {
+				if (t == zT)
+					return i;
+				++i;
+			}
+			return -1;
+        }
+
         RCArray& operator=(const RCArray& arr)
         {
             leeren();

+ 49 - 60
Fenster.cpp

@@ -1061,7 +1061,7 @@ Fenster::Fenster()
       closingMeParam(0),
       rahmen(0),
       titel(0),
-      members(0),
+      members(new RCArray<Zeichnung>()),
       bgBodyColor(0xFF000000),
       bgBodyPicture(0),
       bodyBuffer(0),
@@ -1091,7 +1091,7 @@ Fenster::~Fenster()
 {
     if (rahmen) rahmen->release();
     if (titel) titel->release();
-    if (members) members->release();
+    members->release();
     if (bodyBuffer) bodyBuffer->release();
     if (bgBodyPicture) bgBodyPicture->release();
     if (bgClosingBild) bgClosingBild->release();
@@ -1123,7 +1123,7 @@ void Fenster::doMausEreignis(MausEreignis& me, bool userRet)
         me.my -= rbr + th;
         if (hatStyle(Style::VScroll) && vScroll) me.my += vScroll->getScroll();
         if (hatStyle(Style::HScroll) && hScroll) me.mx += hScroll->getScroll();
-        if (me.id != ME_Betritt && me.id != ME_Leaves && members)
+        if (me.id != ME_Betritt && me.id != ME_Leaves)
         {
             for (int i = members->getEintragAnzahl() - 1; i >= 0; i--)
                 members->z(i)->doPublicMausEreignis(me);
@@ -1373,33 +1373,29 @@ void Fenster::doMausEreignis(MausEreignis& me, bool userRet)
                 moving |= 0x20;
         }
     }
-    if (members)
+    if (vSc)
     {
-        if (vSc)
-        {
-            vScroll->doMausMessage(
-                gr.x - rbr - 15, rbr + th, 15, gr.y - rbr * 2 - th, me);
-            if (hSc)
-                hScroll->doMausMessage(
-                    rbr, gr.y - rbr - 15, gr.x - rbr * 2 - 15, 15, me);
-        }
-        else if (hSc)
+        vScroll->doMausMessage(
+            gr.x - rbr - 15, rbr + th, 15, gr.y - rbr * 2 - th, me);
+        if (hSc)
             hScroll->doMausMessage(
-                rbr, gr.y - rbr - 15, gr.x - rbr * 2, 15, me);
-        me.mx -= rbr;
-        me.my -= rbr + th;
-        if (hatStyle(Style::VScroll) && vScroll) me.my += vScroll->getScroll();
-        if (hatStyle(Style::HScroll) && hScroll) me.mx += hScroll->getScroll();
-        if (me.id != ME_Betritt && me.id != ME_Leaves)
-        {
-            for (int i = members->getEintragAnzahl() - 1; i >= 0; i--)
-                members->z(i)->doPublicMausEreignis(me);
-        }
-        me.mx += rbr;
-        me.my += rbr + th;
-        if (hatStyle(Style::VScroll) && vScroll) me.my -= vScroll->getScroll();
-        if (hatStyle(Style::HScroll) && hScroll) me.mx -= hScroll->getScroll();
+                rbr, gr.y - rbr - 15, gr.x - rbr * 2 - 15, 15, me);
     }
+    else if (hSc)
+        hScroll->doMausMessage(rbr, gr.y - rbr - 15, gr.x - rbr * 2, 15, me);
+    me.mx -= rbr;
+    me.my -= rbr + th;
+    if (hatStyle(Style::VScroll) && vScroll) me.my += vScroll->getScroll();
+    if (hatStyle(Style::HScroll) && hScroll) me.mx += hScroll->getScroll();
+    if (me.id != ME_Betritt && me.id != ME_Leaves)
+    {
+        for (int i = members->getEintragAnzahl() - 1; i >= 0; i--)
+            members->z(i)->doPublicMausEreignis(me);
+    }
+    me.mx += rbr;
+    me.my += rbr + th;
+    if (hatStyle(Style::VScroll) && vScroll) me.my -= vScroll->getScroll();
+    if (hatStyle(Style::HScroll) && hScroll) me.mx -= hScroll->getScroll();
     if (hatStyleNicht(Style::METransparenz)) me.verarbeitet = 1;
     if (hatStyleNicht(Style::Erlaubt)) me.verarbeitet = mvtmp;
 }
@@ -1785,14 +1781,19 @@ void Fenster::setVSBScroll(int scroll)
 // -- Members --
 void Fenster::addMember(Zeichnung* obj) // fügt einen Member hinzu
 {
-    if (!members) members = new RCArray<Zeichnung>();
     members->add(obj);
     rend = 1;
 }
 
+void Framework::Fenster::setMemberIndex(Zeichnung* zMember, int index)
+{
+    if (index < 0 || index >= members->getEintragAnzahl()) return;
+    int currentIndex = members->indexOf(zMember);
+    members->setPosition(currentIndex, index);
+}
+
 void Fenster::removeMember(Zeichnung* zObj) // entfernt einen Member
 {
-    if (!members) return;
     for (int i = 0; i < members->getEintragAnzahl(); i++)
     {
         if (members->z(i) == zObj)
@@ -1805,7 +1806,6 @@ void Fenster::removeMember(Zeichnung* zObj) // entfernt einen Member
 
 void Fenster::removeAll()
 {
-    if (!members) return;
     members->leeren();
     rend = 1;
 }
@@ -1813,12 +1813,12 @@ void Fenster::removeAll()
 // -- Messages --
 bool Fenster::tick(double tickval) // tick
 {
-    if (members && hatStyle(Style::Sichtbar))
+    if (hatStyle(Style::Sichtbar))
     {
         for (Zeichnung* i : *members)
             rend |= i->tick(tickval);
     }
-    else if (members)
+    else
     {
         for (Zeichnung* i : *members)
             i->tick(tickval);
@@ -1835,21 +1835,15 @@ void Fenster::doTastaturEreignis(TastaturEreignis& te)
     {
         if (te.verarbeitet)
         {
-            if (members)
-            {
-                for (int i = members->getEintragAnzahl() - 1; i >= 0; i--)
-                    members->z(i)->doTastaturEreignis(te);
-            }
+            for (int i = members->getEintragAnzahl() - 1; i >= 0; i--)
+                members->z(i)->doTastaturEreignis(te);
         }
         else
         {
             if (tak && tak(takParam, this, te))
             {
-                if (members)
-                {
-                    for (int i = members->getEintragAnzahl() - 1; i >= 0; i--)
-                        members->z(i)->doTastaturEreignis(te);
-                }
+                for (int i = members->getEintragAnzahl() - 1; i >= 0; i--)
+                    members->z(i)->doTastaturEreignis(te);
             }
         }
     }
@@ -1957,8 +1951,7 @@ void Fenster::render(Bild& zRObj) // zeichent nach zRObj
                     rbr, gr.y - rbr - 15, gr.x - rbr * 2 - 15, 15, zRObj);
         }
         else if (hSc)
-            hScroll->render(
-                rbr, gr.y - rbr - 15, gr.x - rbr * 2, 15, zRObj);
+            hScroll->render(rbr, gr.y - rbr - 15, gr.x - rbr * 2, 15, zRObj);
         int x = rbr;
         int y = rbr + th;
         int br = gr.x - rbr * 2;
@@ -1990,20 +1983,17 @@ void Fenster::render(Bild& zRObj) // zeichent nach zRObj
             bodyBuffer->setSize(br, hi);
             bodyBuffer->render(zRObj);
         }
-        if (members)
+        if (!vSc && !hSc)
         {
-            if (!vSc && !hSc)
-            {
-                for (Zeichnung* i : *members)
-                    i->render(zRObj);
-            }
-            else
-            {
-                zRObj.addScrollOffset(hSc ? hScroll->getScroll() : 0,
-                    vSc ? vScroll->getScroll() : 0);
-                for (Zeichnung* i : *members)
-                    i->render(zRObj);
-            }
+            for (Zeichnung* i : *members)
+                i->render(zRObj);
+        }
+        else
+        {
+            zRObj.addScrollOffset(hSc ? hScroll->getScroll() : 0,
+                vSc ? vScroll->getScroll() : 0);
+            for (Zeichnung* i : *members)
+                i->render(zRObj);
         }
         zRObj.releaseDrawOptions();
         zRObj.releaseDrawOptions();
@@ -2331,10 +2321,9 @@ HScrollBar* Fenster::zHScrollBar() const
 }
 
 // -- Members --
-Iterator<Zeichnung*> Fenster::getMembers() const // gibt die Members zurück
+const RCArray<Zeichnung>& Fenster::getMembers() const // gibt die Members zurück
 {
-    if (!members) return Iterator<Zeichnung*>(0, 0);
-    return members->begin();
+    return *members;
 }
 
 // -- Kopie --

+ 3 - 1
Fenster.h

@@ -595,6 +595,8 @@ namespace Framework
         //! Fügt dem Fenster eine Zeichnung hinzu
         //! \param obj Die Zeichnung
         DLLEXPORT virtual void addMember(Zeichnung* obj);
+        // sets the position of a member to index. This changes the order of rendering and the order input events are processed
+        DLLEXPORT void setMemberIndex(Zeichnung* zMember, int index);
         //! Entfernt eine Zeichnung aus dem Fenster
         //! \param zObj Die Zeichnung (ohne erhöhten reference Counter)
         DLLEXPORT virtual void removeMember(Zeichnung* zObj);
@@ -733,7 +735,7 @@ namespace Framework
         //! Counter zurück
         DLLEXPORT HScrollBar* zHScrollBar() const;
         //! Gibt eine Liste mit Zeichnungen zurück, die im Fenster sind
-        DLLEXPORT Iterator<Zeichnung*> getMembers() const;
+        DLLEXPORT const RCArray<Zeichnung> &getMembers() const;
         //! Erzeugt eine Kopie des Fensters, die ohne Auswirkungen auf das
         //! Original verändert werden kann
         DLLEXPORT Zeichnung* dublizieren() const override;

+ 4 - 4
UIDialog.cpp

@@ -43,12 +43,12 @@ UIDialog::~UIDialog() {}
 void UIDialog::adjustSize()
 {
     Punkt max = Punkt(0, 0);
-    for (auto m = getMembers(); m; m++)
+    for (Zeichnung *z : getMembers())
     {
-        if (m->hatStyle(Zeichnung::Style::Sichtbar))
+        if (z->hatStyle(Zeichnung::Style::Sichtbar))
         {
-            max.x = MAX(max.x, m->getX() + m->getBreite() + 5);
-            max.y = MAX(max.y, m->getY() + m->getHeight() + 5);
+            max.x = MAX(max.x, z->getX() + z->getBreite() + 5);
+            max.y = MAX(max.y, z->getY() + z->getHeight() + 5);
         }
     }
     setSize(

+ 235 - 25
UIMLView.cpp

@@ -232,6 +232,15 @@ Zeichnung* UIMLTextField::parseElement(
 {
     TextFeld* t = generalFactory.getFactory().createTextFeld(
         generalFactory.getFactory().initParam);
+    updateElement(element, *t, generalFactory);
+    return t;
+}
+
+bool Framework::UIMLTextField::updateElement(
+    XML::Element& element, Zeichnung& z, UIMLContainer& generalFactory)
+{
+    TextFeld* t = dynamic_cast<TextFeld*>(&z);
+    if (!t) return false;
     if (element.hasAttribute("style"))
     {
         Text style = element.getAttributeValue("style");
@@ -243,9 +252,13 @@ Zeichnung* UIMLTextField::parseElement(
     }
     else
     {
-        t->addStyle(TextFeld::Style::TextFeld);
+        TextFeld* tmp = generalFactory.getFactory().createTextFeld(
+            generalFactory.getFactory().initParam);
+        tmp->addStyle(TextFeld::Style::TextFeld);
+        t->setStyle(tmp->getStyles());
+        tmp->release();
     }
-    return t;
+    return true;
 }
 
 void UIMLTextField::layout(XML::Element& element,
@@ -302,6 +315,15 @@ Zeichnung* UIMLButton::parseElement(
 {
     Knopf* k = generalFactory.getFactory().createKnopf(
         generalFactory.getFactory().initParam);
+    updateElement(element, *k, generalFactory);
+    return k;
+}
+
+bool Framework::UIMLButton::updateElement(
+    XML::Element& element, Zeichnung& z, UIMLContainer& generalFactory)
+{
+    Knopf* k = dynamic_cast<Knopf*>(&z);
+    if (!k) return false;
     if (element.hasAttribute("style"))
     {
         Text style = element.getAttributeValue("style");
@@ -311,7 +333,14 @@ Zeichnung* UIMLButton::parseElement(
         }
         k->setStyle((int)style);
     }
-    return k;
+    else
+    {
+        Knopf* tmp = generalFactory.getFactory().createKnopf(
+            generalFactory.getFactory().initParam);
+        k->setStyle(tmp->getStyles());
+        tmp->release();
+    }
+    return true;
 }
 
 void UIMLButton::layout(XML::Element& element,
@@ -342,6 +371,15 @@ Zeichnung* UIMLCheck::parseElement(
 {
     KontrollKnopf* k = generalFactory.getFactory().createKontrollKnopf(
         generalFactory.getFactory().initParam);
+    updateElement(element, *k, generalFactory);
+    return k;
+}
+
+bool Framework::UIMLCheck::updateElement(
+    XML::Element& element, Zeichnung& z, UIMLContainer& generalFactory)
+{
+    KontrollKnopf* k = dynamic_cast<KontrollKnopf*>(&z);
+    if (!k) return false;
     if (element.hasAttribute("style"))
     {
         Text style = element.getAttributeValue("style");
@@ -351,7 +389,14 @@ Zeichnung* UIMLCheck::parseElement(
         }
         k->setStyle((int)style);
     }
-    return k;
+    else
+    {
+        KontrollKnopf* tmp = generalFactory.getFactory().createKontrollKnopf(
+            generalFactory.getFactory().initParam);
+        k->setStyle(tmp->getStyles());
+        tmp->release();
+    }
+    return true;
 }
 
 void UIMLCheck::layout(XML::Element& element,
@@ -385,6 +430,15 @@ Zeichnung* UIMLText::parseElement(
 {
     TextFeld* t = generalFactory.getFactory().createTextFeld(
         generalFactory.getFactory().initParam);
+    updateElement(element, *t, generalFactory);
+    return t;
+}
+
+bool Framework::UIMLText::updateElement(
+    XML::Element& element, Zeichnung& z, UIMLContainer& generalFactory)
+{
+    TextFeld* t = dynamic_cast<TextFeld*>(&z);
+    if (!t) return false;
     if (element.hasAttribute("style"))
     {
         Text style = element.getAttributeValue("style");
@@ -396,9 +450,13 @@ Zeichnung* UIMLText::parseElement(
     }
     else
     {
-        t->addStyle(TextFeld::Style::Text);
+        TextFeld* tmp = generalFactory.getFactory().createTextFeld(
+            generalFactory.getFactory().initParam);
+        tmp->addStyle(TextFeld::Style::Text);
+        t->setStyle(tmp->getStyles());
+        tmp->release();
     }
-    return t;
+    return true;
 }
 
 void UIMLText::layout(XML::Element& element,
@@ -455,6 +513,15 @@ Zeichnung* UIMLTextArea::parseElement(
 {
     TextFeld* t = generalFactory.getFactory().createTextFeld(
         generalFactory.getFactory().initParam);
+    updateElement(element, *t, generalFactory);
+    return t;
+}
+
+bool Framework::UIMLTextArea::updateElement(
+    XML::Element& element, Zeichnung& z, UIMLContainer& generalFactory)
+{
+    TextFeld* t = dynamic_cast<TextFeld*>(&z);
+    if (!t) return false;
     if (element.hasAttribute("style"))
     {
         Text style = element.getAttributeValue("style");
@@ -466,9 +533,13 @@ Zeichnung* UIMLTextArea::parseElement(
     }
     else
     {
-        t->addStyle(TextFeld::Style::TextGebiet);
+        TextFeld* tmp = generalFactory.getFactory().createTextFeld(
+            generalFactory.getFactory().initParam);
+        tmp->addStyle(TextFeld::Style::TextGebiet);
+        t->setStyle(tmp->getStyles());
+        tmp->release();
     }
-    return t;
+    return true;
 }
 
 void UIMLTextArea::layout(XML::Element& element,
@@ -528,7 +599,18 @@ Zeichnung* UIMLTable::parseElement(
 {
     ObjTabelle* t = generalFactory.getFactory().createObjTabelle(
         generalFactory.getFactory().initParam);
+    updateElement(element, *t, generalFactory);
+    return t;
+}
+
+DLLEXPORT bool Framework::UIMLTable::updateElement(
+    XML::Element& element, Zeichnung& z, UIMLContainer& generalFactory)
+{
+    ObjTabelle* t = dynamic_cast<ObjTabelle*>(&z);
+    if (!t) return false;
     int index = 0;
+    int linePos = 0;
+    int numCols = 0;
     for (auto i = element.getChilds(); i; i++)
     {
         Text id;
@@ -541,18 +623,51 @@ Zeichnung* UIMLTable::parseElement(
         }
         if (i->getName().istGleich("tr"))
         {
-            t->addZeile(id);
-            Text line = id;
+            if (t->getZeilenNummer(id) == -1) t->addZeile(id);
+            t->setZeilePosition(id, linePos);
             int c = 1;
             for (auto j = i->getChilds(); j; j++)
             {
-                Zeichnung* z
-                    = generalFactory.parseElement(*i.val(), generalFactory);
                 if (t->getSpaltenAnzahl() < c) t->addSpalte(Text(c - 1));
-                if (z) t->setZeichnungZ(Text(c - 1), line, z);
+                if (numCols < c) numCols = c;
+                Zeichnung* z = t->zZeichnung(Text(c - 1), id);
+                if (!z
+                    || !generalFactory.updateElement(
+                        element, *z, generalFactory))
+                {
+                    if (z) generalFactory.removeZeichnung(*z);
+                    z = generalFactory.parseElement(*i.val(), generalFactory);
+                    if (z) t->setZeichnungZ(Text(c - 1), id, z);
+                }
                 c++;
             }
         }
+        linePos++;
+    }
+    for (int i = 0; i < t->getZeilenAnzahl(); i++)
+    { // remove all lines that are not in the xml
+        if (!element.selectChildsByName("tr")
+                 .whereAttributeEquals("id", *t->zZeilenName(i))
+                 .exists())
+        {
+            for (int j = 0; j < t->getSpaltenAnzahl(); j++)
+            {
+                Zeichnung* z = t->zZeichnung(j, i);
+                if (z) generalFactory.removeZeichnung(*z);
+            }
+            t->removeZeile(i);
+            i--;
+        }
+    }
+    for (int i = numCols; i < t->getSpaltenAnzahl(); i++)
+    { // remove all columns that are not in the xml
+        for (int j = 0; j < t->getZeilenAnzahl(); j++)
+        {
+            Zeichnung* z = t->zZeichnung(i, j);
+            if (z) generalFactory.removeZeichnung(*z);
+        }
+        t->removeSpalte(i);
+        i--;
     }
     if (element.hasAttribute("style"))
     {
@@ -563,7 +678,14 @@ Zeichnung* UIMLTable::parseElement(
         }
         t->setStyle((int)style);
     }
-    return t;
+    else
+    {
+        ObjTabelle* tmp = generalFactory.getFactory().createObjTabelle(
+            generalFactory.getFactory().initParam);
+        t->setStyle(tmp->getStyles());
+        tmp->release();
+    }
+    return true;
 }
 
 void UIMLTable::layout(XML::Element& element,
@@ -613,6 +735,40 @@ Zeichnung* UIMLFrame::parseElement(
 {
     Fenster* f = generalFactory.getFactory().createFenster(
         generalFactory.getFactory().initParam);
+    updateElement(element, *f, generalFactory);
+    return f;
+}
+
+bool Framework::UIMLFrame::updateElement(
+    XML::Element& element, Zeichnung& z, UIMLContainer& generalFactory)
+{
+    Fenster* f = dynamic_cast<Fenster*>(&z);
+    if (!f) return false;
+    for (auto member = f->getMembers().begin(); member; member++)
+    { // remove all members that are not in the xml
+        if (!element
+                 .selectChildsByAttribute(
+                     "id", generalFactory.getZeichnungId(*member.val()))
+                 .exists())
+        {
+            member.remove();
+            f->setRender();
+        }
+    }
+    int index = 0;
+    for (auto i = element.getChilds(); i; i++)
+    {
+        Text id = element.getAttributeValue("id");
+        Zeichnung* z = generalFactory.zZeichnungById(id);
+        if (!id.getLength() || !z || f->getMembers().indexOf(z) < 0
+            || !generalFactory.updateElement(*i.val(), *z, generalFactory))
+        {
+            if (z) generalFactory.removeZeichnung(*z);
+            z = generalFactory.parseElement(*i.val(), generalFactory);
+            if (z) f->addMember(z);
+        }
+        if (z) f->setMemberIndex(z, index++);
+    }
     if (element.hasAttribute("style"))
     {
         Text style = element.getAttributeValue("style");
@@ -622,12 +778,14 @@ Zeichnung* UIMLFrame::parseElement(
         }
         f->setStyle((int)style);
     }
-    for (auto i = element.getChilds(); i; i++)
+    else
     {
-        Zeichnung* z = generalFactory.parseElement(*i.val(), generalFactory);
-        if (z) f->addMember(z);
+        Fenster* tmp = generalFactory.getFactory().createFenster(
+            generalFactory.getFactory().initParam);
+        f->setStyle(tmp->getStyles());
+        tmp->release();
     }
-    return f;
+    return true;
 }
 
 void UIMLFrame::layout(XML::Element& element,
@@ -762,12 +920,14 @@ bool UIMLView::isKnownElement(XML::Element* zElement)
 //  uiml: Ein xml element gemät des ksg uiml standarts
 void UIMLView::setUIML(XML::Element* uiml)
 {
-    if (dom) dom->release();
-    dom = uiml;
-    members->leeren();
-    nextId = 0;
     if (dom)
-    {
+    { // update dom and members
+        dom = uiml;
+        update();
+    }
+    else
+    { // initialize dom and members
+        dom = uiml;
         for (auto i = dom->getChilds(); i; i++)
         {
             Zeichnung* z = parseElement(*i.val(), *this);
@@ -797,6 +957,21 @@ Zeichnung* UIMLView::getZeichnungById(const char* id)
     return members->get(id, textLength(id));
 }
 
+void Framework::UIMLView::update()
+{
+    for (auto i = dom->getChilds(); i; i++)
+    {
+        Text id = i->getAttributeValue("id");
+        Zeichnung* z = zZeichnungById(id);
+        if (!id.getLength() || !z || !updateElement(*i.val(), *z, *this))
+        {
+            if (z) removeZeichnung(*z);
+            z = parseElement(*i.val(), *this);
+            if (z) z->release();
+        }
+    }
+}
+
 // aktualisiert größe und position aller Zeichnungen gemäß den spezifikationen
 // in UIML
 void UIMLView::layout()
@@ -1042,14 +1217,31 @@ Zeichnung* UIMLView::parseElement(
             }
         }
         if (z)
+        {
             members->set(
                 id, id.getLength(), dynamic_cast<Zeichnung*>(z->getThis()));
+            idList.add(new Text(id));
+            memberList.add(z);
+        }
     }
     else
         z->getThis();
     return z;
 }
 
+bool Framework::UIMLView::updateElement(
+    XML::Element& element, Zeichnung& z, UIMLContainer& generalFactory)
+{
+    for (UIMLElement* e : knownElements)
+    {
+        if (e->isApplicableFor(element))
+        {
+            return e->updateElement(element, z, *this);
+        }
+    }
+    return false;
+}
+
 void UIMLView::layout(XML::Element& element,
     Zeichnung& z,
     int pWidth,
@@ -1066,8 +1258,26 @@ void UIMLView::layout(XML::Element& element,
     }
 }
 
-DLLEXPORT bool Framework::UIMLView::registerZeichnung(
-    const char* id, Zeichnung* z)
+Text Framework::UIMLView::getZeichnungId(Zeichnung& z)
+{
+    int index = memberList.getWertIndex(&z);
+    if (index >= 0) return *idList.z(index);
+    return "";
+}
+
+void Framework::UIMLView::removeZeichnung(Zeichnung& z)
+{
+    int index = memberList.getWertIndex(&z);
+    if (index >= 0)
+    {
+        Text id = *idList.z(index);
+		idList.remove(index);
+		memberList.remove(index);
+        members->remove(id, id.getLength());
+	}
+}
+
+bool Framework::UIMLView::registerZeichnung(const char* id, Zeichnung* z)
 {
     Zeichnung* existing = members->z(id, textLength(id));
     if (existing)

+ 40 - 0
UIMLView.h

@@ -30,6 +30,12 @@ namespace Framework
         virtual Zeichnung* parseElement(
             XML::Element& element, UIMLContainer& generalFactory)
             = 0;
+        //! aktualisiert eine Zeichnung mit den Daten eines xml Elements. Gibt
+        //! false zurück, wenn die Zeichnung nicht aktualisiert werden konnte
+        //! und neu erstellt werden muss
+        virtual bool updateElement(
+            XML::Element& element, Zeichnung& z, UIMLContainer& generalFactory)
+            = 0;
         //! wendet die layout parameter zu einer Zeichnung an
         DLLEXPORT virtual void layout(XML::Element& element,
             Zeichnung& z,
@@ -45,6 +51,8 @@ namespace Framework
         DLLEXPORT virtual ~UIMLContainer();
         virtual Zeichnung* zZeichnungById(const char* id) = 0;
         virtual Zeichnung* getZeichnungById(const char* id) = 0;
+        virtual Text getZeichnungId(Zeichnung& z) = 0;
+        virtual void removeZeichnung(Zeichnung& z) = 0;
         virtual bool registerZeichnung(const char* id, Zeichnung* z) = 0;
         virtual const UIInit& getFactory() = 0;
     };
@@ -56,6 +64,9 @@ namespace Framework
         DLLEXPORT bool isApplicableFor(XML::Element& element) override;
         DLLEXPORT Zeichnung* parseElement(
             XML::Element& element, UIMLContainer& generalFactory) override;
+        DLLEXPORT bool updateElement(XML::Element& element,
+            Zeichnung& z,
+            UIMLContainer& generalFactory) override;
         DLLEXPORT void layout(XML::Element& element,
             Zeichnung& z,
             int pWidth,
@@ -70,6 +81,9 @@ namespace Framework
         DLLEXPORT bool isApplicableFor(XML::Element& element) override;
         DLLEXPORT Zeichnung* parseElement(
             XML::Element& element, UIMLContainer& generalFactory) override;
+        DLLEXPORT bool updateElement(XML::Element& element,
+            Zeichnung& z,
+            UIMLContainer& generalFactory) override;
         DLLEXPORT void layout(XML::Element& element,
             Zeichnung& z,
             int pWidth,
@@ -84,6 +98,9 @@ namespace Framework
         DLLEXPORT bool isApplicableFor(XML::Element& element) override;
         DLLEXPORT Zeichnung* parseElement(
             XML::Element& element, UIMLContainer& generalFactory) override;
+        DLLEXPORT bool updateElement(XML::Element& element,
+            Zeichnung& z,
+            UIMLContainer& generalFactory) override;
         DLLEXPORT void layout(XML::Element& element,
             Zeichnung& z,
             int pWidth,
@@ -98,6 +115,9 @@ namespace Framework
         DLLEXPORT bool isApplicableFor(XML::Element& element) override;
         DLLEXPORT Zeichnung* parseElement(
             XML::Element& element, UIMLContainer& generalFactory) override;
+        DLLEXPORT bool updateElement(XML::Element& element,
+            Zeichnung& z,
+            UIMLContainer& generalFactory) override;
         DLLEXPORT void layout(XML::Element& element,
             Zeichnung& z,
             int pWidth,
@@ -112,6 +132,9 @@ namespace Framework
         DLLEXPORT bool isApplicableFor(XML::Element& element) override;
         DLLEXPORT Zeichnung* parseElement(
             XML::Element& element, UIMLContainer& generalFactory) override;
+        DLLEXPORT bool updateElement(XML::Element& element,
+            Zeichnung& z,
+            UIMLContainer& generalFactory) override;
         DLLEXPORT void layout(XML::Element& element,
             Zeichnung& z,
             int pWidth,
@@ -126,6 +149,9 @@ namespace Framework
         DLLEXPORT bool isApplicableFor(XML::Element& element) override;
         DLLEXPORT Zeichnung* parseElement(
             XML::Element& element, UIMLContainer& generalFactory) override;
+        DLLEXPORT bool updateElement(XML::Element& element,
+            Zeichnung& z,
+            UIMLContainer& generalFactory) override;
         DLLEXPORT void layout(XML::Element& element,
             Zeichnung& z,
             int pWidth,
@@ -140,6 +166,9 @@ namespace Framework
         DLLEXPORT bool isApplicableFor(XML::Element& element) override;
         DLLEXPORT Zeichnung* parseElement(
             XML::Element& element, UIMLContainer& generalFactory) override;
+        DLLEXPORT bool updateElement(XML::Element& element,
+            Zeichnung& z,
+            UIMLContainer& generalFactory) override;
         DLLEXPORT void layout(XML::Element& element,
             Zeichnung& z,
             int pWidth,
@@ -217,6 +246,8 @@ namespace Framework
         RCArray<UIMLElement> knownElements;
         UIInit init;
         RCTrie<Zeichnung>* members;
+        Array<Zeichnung*> memberList;
+        RCArray<Text> idList;
         XML::Element* dom;
         int nextId;
 
@@ -255,6 +286,10 @@ namespace Framework
         //! setzt den inhalt der view
         //! \param uiml Ein xml text gemät des KSG UIML standarts
         DLLEXPORT void setUIML(Text uiml);
+        //! aktualisiert alles zeichnungen gemäß den spezifikationen in UIML.
+        //! Zeichnungen von entfernten elementen werden entfernt und neue
+        //! Zeichnungen für neue Elemente werden erstellt
+        DLLEXPORT void update();
         //! aktualisiert größe und position aller Zeichnungen gemäß den
         //! spezifikationen in UIML
         DLLEXPORT void layout();
@@ -297,11 +332,16 @@ namespace Framework
         DLLEXPORT bool isApplicableFor(XML::Element& element) override;
         DLLEXPORT Zeichnung* parseElement(
             XML::Element& element, UIMLContainer& generalFactory) override;
+        DLLEXPORT bool updateElement(XML::Element& element,
+            Zeichnung& z,
+            UIMLContainer& generalFactory) override;
         DLLEXPORT void layout(XML::Element& element,
             Zeichnung& z,
             int pWidth,
             int pHeight,
             UIMLContainer& generalLayouter) override;
+        DLLEXPORT Text getZeichnungId(Zeichnung& z) override;
+        DLLEXPORT void removeZeichnung(Zeichnung& z) override;
         DLLEXPORT bool registerZeichnung(const char* id, Zeichnung* z) override;
         DLLEXPORT const UIInit& getFactory() override;
         //! calculates the needed size for all content elements to be visible

+ 5 - 0
Zeichnung.cpp

@@ -456,6 +456,11 @@ bool Zeichnung::hatStyleNicht(
     return (this->style | style) != this->style;
 }
 
+__int64 Framework::Zeichnung::getStyles() const
+{
+    return style;
+}
+
 Zeichnung* Zeichnung::dublizieren() const // Erzeugt eine Kopie des Zeichnungs
 {
     Zeichnung* obj = new Zeichnung();

+ 2 - 0
Zeichnung.h

@@ -263,6 +263,8 @@ namespace Framework
         //! \param style Die Styles, die geprüft werden sollen
         //! \return 1, falls alle Styles in style nicht gesetzt wurden
         DLLEXPORT bool hatStyleNicht(__int64 style) const;
+        // returns all currently active styles
+        DLLEXPORT __int64 getStyles() const;
         //! Kopiert die Komplette Zeichnung, so dass sie ohne Effekt auf das
         //! Original verändert werden kann
         DLLEXPORT virtual Zeichnung* dublizieren() const;