insert and remove actions for odf edit
authorKonrad Rosenbaum <konrad@silmor.de>
Wed, 7 Mar 2012 08:51:21 +0000 (09:51 +0100)
committerKonrad Rosenbaum <konrad@silmor.de>
Wed, 7 Mar 2012 08:51:21 +0000 (09:51 +0100)
src/misc/dommodel.cpp
src/misc/dommodel.h
src/templates/odfedit.cpp
src/templates/odfedit.h

index 9404a64..1635789 100644 (file)
@@ -230,6 +230,36 @@ void MDomItemModel::setNode(const QModelIndex& index, const QDomNode& node)
        dataChanged(index,index);
 }
 
+void MDomItemModel::insertNode(const QDomNode& newnode, const QModelIndex& parent, int row)
+{
+       //check parent validity
+       if(!parent.isValid())return;
+       int pid=parent.internalId();
+       if(!d->domCache.contains(pid))return;
+       //only add to tags (TODO: there are a few other node types that can have children)
+       if(!d->domCache[pid].node.isElement())return;
+       //get the parent and a clone of the new node
+       QDomNode nn=newnode.cloneNode();
+       QDomElement pn=d->domCache[pid].node.toElement();
+       const int rcnt=rowCount(parent);
+       //handle appending
+       if(row<0 || row>=rcnt){
+               beginInsertRows(parent,rcnt,rcnt);
+               pn.appendChild(nn);
+               d->domCache[pid].children.append(d->buildCache(nn,pid));
+               endInsertRows();
+               return;
+       }
+       //handle inserting
+       //get current occupant of this row
+       QDomNode sibl=node(index(row,0,parent));
+       beginInsertRows(parent,row,row);
+       //insert
+       pn.insertBefore(nn,sibl);
+       d->domCache[pid].children.insert(row,d->buildCache(nn,pid));
+       endInsertRows();
+}
+
 int MDomItemModel::columnCount(const QModelIndex&) const
 {
        return 1;
@@ -422,15 +452,16 @@ void MDomItemModel::removeNode(const QModelIndex& index)
        else endResetModel();
 }
 
-void MDomItemModel::Private::removeNode(int nid,bool rec)
+void MDomItemModel::Private::removeNode(int nid,bool inrecurs)
 {
        //sanity check
        if(!domCache.contains(nid))return;
        //remove main node from model
-       if(!rec){
+       if(!inrecurs){
                int pid=domCache[nid].parent;
                if(domCache.contains(pid)){
                        domCache[pid].node.removeChild(domCache[nid].node);
+                       domCache[pid].children.removeAll(nid);
                }
        }
        //remove children
index 744cbad..a770e5f 100644 (file)
@@ -107,6 +107,8 @@ class MDomItemModel:public QAbstractItemModel
                
                ///replaces the node at the index, you cannot replace the entire document with this function - use setDomDocument for this
                virtual void setNode(const QModelIndex&index,const QDomNode&);
+               ///insert a node into the parent at given position (if no position is given: append)
+               virtual void insertNode(const QDomNode&newnode,const QModelIndex&parent,int row=-1);
                ///removes the nodes at the given position and their child nodes
                virtual bool removeRows(int row, int count, const QModelIndex&parent=QModelIndex());
                ///removes the node at the given position and its child nodes
index ad4e56c..e366ed8 100644 (file)
@@ -138,13 +138,13 @@ MOdfEditor::MOdfEditor(QWidget* parent, Qt::WindowFlags f): QMainWindow(parent,
        m->addAction(tr("&Close"),this,SLOT(close()));
        
        QMenu*medit=m=mb->addMenu(tr("&Edit"));
-       d->maAddIntoCalc=m->addAction(tr("Insert &Calculation into current"));
-       d->maInsBehindCalc=m->addAction(tr("Insert Calculation behind current"));
+       d->maAddIntoCalc=m->addAction(tr("Insert &Calculation into current"),this,SLOT(insCalcIntoCurrent()));
+       d->maInsBehindCalc=m->addAction(tr("Insert Calculation behind current"),this,SLOT(insCalcBehindCurrent()));
        d->maWrapInCond=m->addAction(tr("&Wrap in Condition"));
        d->maWrapInLoop=m->addAction(tr("Wrap in &Loop"));
-       d->maInsBehindElse=m->addAction(tr("Insert &Else behind current"));
-       d->maAddIntoComment=m->addAction(tr("Insert Comment into current"));
-       d->maInsBehindComment=m->addAction(tr("Insert Comment behind current"));
+       d->maInsBehindElse=m->addAction(tr("Insert &Else behind current"),this,SLOT(insElse()));
+       d->maAddIntoComment=m->addAction(tr("Insert Comment into current"),this,SLOT(insCommentIntoCurrent()));
+       d->maInsBehindComment=m->addAction(tr("Insert Comment behind current"),this,SLOT(insCommentBehindCurrent()));
        m->addSeparator();
        d->maUnwrap=m->addAction(tr("Unwrap Loop/Condition"));
        d->maDelItem=m->addAction(tr("&Remove Item"),this,SLOT(delItem()));
@@ -488,13 +488,12 @@ void MOdfEditor::selectionChange()
                        emit switchStack(d->st_loop);
                        d->mLoopVar->setText(el.attribute("variable"));
                        d->setActions(QList<QAction*>()<<d->maInsBehindCalc<<d->maInsBehindComment<<d->maAddIntoCalc<<d->maAddIntoComment<<d->maWrapInCond<<d->maWrapInLoop<<d->maUnwrap<<d->maDelItem<<(allowElse?d->maInsBehindElse:nullptr));
-                       #warning implement correct actions for special tags
                        return;
                }
                if(nn[1]=="calculate"){
                        emit switchStack(d->st_calc);
                        d->mCalcExpr->setText(el.attribute("exec"));
-                       d->setActions(QList<QAction*>()<<d->maInsBehindCalc<<d->maInsBehindComment<<d->maAddIntoCalc<<d->maAddIntoComment<<d->maWrapInCond<<d->maWrapInLoop<<d->maDelItem<<(allowElse?d->maInsBehindElse:nullptr));
+                       d->setActions(QList<QAction*>()<<d->maInsBehindCalc<<d->maInsBehindComment<<d->maAddIntoComment<<d->maWrapInCond<<d->maWrapInLoop<<d->maDelItem<<(allowElse?d->maInsBehindElse:nullptr));
                        return;
                }
                if(nn[1]=="if"){
@@ -505,8 +504,11 @@ void MOdfEditor::selectionChange()
                }
                if(nn[1]=="template" || nn[1]=="else"){
                        emit switchStack(d->st_special);
-                       d->setActions(QList<QAction*>());
                        d->mSpecial->setText(tr("<b>Tag Type:</b> %1").arg(htmlize(nn[1])));
+                       if(nn[1]=="else"){
+                               d->setActions(QList<QAction*>()<<d->maDelItem<<d->maInsBehindCalc<<d->maInsBehindComment);
+                       }else
+                               d->setActions(QList<QAction*>());
                        return;
                }
                //else: fall through to normal tags
@@ -614,3 +616,78 @@ void MOdfEditor::Private::setActions(const QList< QAction* >& act)
        maUnwrap->setEnabled(act.contains(maUnwrap));
        maDelItem->setEnabled(act.contains(maDelItem));
 }
+
+void MOdfEditor::insCalcBehindCurrent()
+{
+       //get current
+       QModelIndex idx=d->mDomTree->currentIndex();
+       if(!idx.isValid())return;
+       QDomNode cnode=d->mDomModel->node(idx);
+       if(cnode.isNull())return;
+       //insert calculation
+       QDomNode nn=cnode.ownerDocument().createElement(OdfTemplatePrefix+":calculate");
+       d->mDomModel->insertNode(nn,idx.parent(),idx.row()+1);
+}
+
+void MOdfEditor::insCalcIntoCurrent()
+{
+       //get current
+       QModelIndex idx=d->mDomTree->currentIndex();
+       if(!idx.isValid())return;
+       QDomNode cnode=d->mDomModel->node(idx);
+       if(cnode.isNull())return;
+       //insert calculation
+       QDomNode nn=cnode.ownerDocument().createElement(OdfTemplatePrefix+":calculate");
+       d->mDomModel->insertNode(nn,idx,0);
+}
+
+void MOdfEditor::insElse()
+{
+       //get current
+       QModelIndex idx=d->mDomTree->currentIndex();
+       if(!idx.isValid())return;
+       QDomNode cnode=d->mDomModel->node(idx);
+       if(cnode.isNull())return;
+       //check parent
+       QDomElement pnode=d->mDomModel->node(idx.parent()).toElement();
+       if(pnode.isNull() || pnode.tagName()!= (OdfTemplatePrefix+":if")){
+               qDebug()<<"oops. trying to insert an else into a parent that is not an if";
+               return;
+       }
+       //insert else tag
+       QDomNode nn=cnode.ownerDocument().createElement(OdfTemplatePrefix+":else");
+       d->mDomModel->insertNode(nn,idx.parent(),idx.row()+1);
+}
+
+void MOdfEditor::delItem()
+{
+       //get current
+       QModelIndex idx=d->mDomTree->currentIndex();
+       if(!idx.isValid())return;
+       //delete
+       d->mDomModel->removeNode(idx);
+}
+
+void MOdfEditor::insCommentBehindCurrent()
+{
+       //get current
+       QModelIndex idx=d->mDomTree->currentIndex();
+       if(!idx.isValid())return;
+       QDomNode cnode=d->mDomModel->node(idx);
+       if(cnode.isNull())return;
+       //insert comment
+       QDomNode nn=cnode.ownerDocument().createComment(tr("new comment"));
+       d->mDomModel->insertNode(nn,idx.parent(),idx.row()+1);
+}
+
+void MOdfEditor::insCommentIntoCurrent()
+{
+       //get current
+       QModelIndex idx=d->mDomTree->currentIndex();
+       if(!idx.isValid())return;
+       QDomNode cnode=d->mDomModel->node(idx);
+       if(cnode.isNull())return;
+       //insert comment
+       QDomNode nn=cnode.ownerDocument().createComment(tr("new comment"));
+       d->mDomModel->insertNode(nn,idx,0);
+}
index 5989439..55274a1 100644 (file)
@@ -58,6 +58,18 @@ class MOdfEditor:public QMainWindow
                void selectionChange();
                ///helper: remember that an editor element changed
                void setChanged(bool ch=true);
+               ///helper: insert calc into current
+               void insCalcIntoCurrent();
+               ///helper: insert calc after current
+               void insCalcBehindCurrent();
+               ///helper: insert calc into current
+               void insCommentIntoCurrent();
+               ///helper: insert calc after current
+               void insCommentBehindCurrent();
+               ///helper: insert else after current
+               void insElse();
+               ///helper: delete an item
+               void delItem();
        signals:
                ///used to switch to the correct editor widget
                void switchStack(int);