kformula/flake

FormulaCommand.cpp

Go to the documentation of this file.
00001 /* This file is part of the KDE project
00002    Copyright (C) 2001 Andrea Rizzi <rizzi@kde.org>
00003                       Ulrich Kuettler <ulrich.kuettler@mailbox.tu-dresden.de>
00004                  2006 Martin Pfeiffer <hubipete@gmx.net>
00005                  2009 Jeremias Epperlein <jeeree@web.de>
00006 
00007    This library is free software; you can redistribute it and/or
00008    modify it under the terms of the GNU Library General Public
00009    License as published by the Free Software Foundation; either
00010    version 2 of the License, or (at your option) any later version.
00011 
00012    This library is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015    Library General Public License for more details.
00016 
00017    You should have received a copy of the GNU Library General Public License
00018    along with this library; see the file COPYING.LIB.  If not, write to
00019    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00020    Boston, MA 02110-1301, USA.
00021 */
00022 
00023 #include "FormulaCommand.h"
00024 #include "FormulaCursor.h"
00025 #include <klocale.h> 
00026 #include "TokenElement.h"
00027 #include "BasicElement.h"
00028 #include "TableElement.h"
00029 #include "TableRowElement.h"
00030 #include "TableEntryElement.h"
00031 #include <kdebug.h>
00032 
00033 FormulaCommand::FormulaCommand(QUndoCommand* parent)
00034               : QUndoCommand(parent)
00035 {
00036     m_done=false;
00037 }
00038 
00039 void FormulaCommand::changeCursor ( FormulaCursor& cursor, bool undo ) const
00040 {
00041     if (undo) {
00042         cursor.moveTo(m_undoCursorPosition);
00043     } else {
00044         cursor.moveTo(m_redoCursorPosition);
00045     }
00046     if (!cursor.isAccepted()) {
00047         cursor.move(MoveRight);
00048     }
00049 }
00050 
00051 void FormulaCommand::setUndoCursorPosition ( const FormulaCursor& position )
00052 {
00053     m_undoCursorPosition=position;
00054 }
00055 
00056 void FormulaCommand::setRedoCursorPosition ( const FormulaCursor& position )
00057 {
00058     m_redoCursorPosition=position;
00059 }
00060 
00061 FormulaCommandReplaceText::FormulaCommandReplaceText( TokenElement* owner, int position, int length, const QString& added , QUndoCommand* parent)
00062                   : FormulaCommand(parent)
00063 {
00064     m_ownerElement = owner;
00065     m_position = position;
00066     m_added = added;
00067     m_length = length;
00068     m_removedGlyphs=m_ownerElement->glyphList(position,length);
00069     m_removed=m_ownerElement->text().mid(position,length);
00070     setText( i18n( "Add text to formula" ) );
00071     setUndoCursorPosition(FormulaCursor(m_ownerElement, m_position+m_removed.length()));
00072     setRedoCursorPosition(FormulaCursor(m_ownerElement, m_position+m_added.length()));
00073 }
00074 
00075 FormulaCommandReplaceText::~FormulaCommandReplaceText()
00076 {
00077 }
00078 
00079 void FormulaCommandReplaceText::redo()
00080 {
00081     m_done=true;
00082     if (m_length>0) {
00083         m_glyphpos=m_ownerElement->removeText(m_position,m_length);
00084     }
00085     m_ownerElement->insertText(m_position, m_added);
00086 }
00087 
00088 void FormulaCommandReplaceText::undo()
00089 {
00090     m_done=false;
00091     m_ownerElement->removeText(m_position,m_added.length());
00092     m_ownerElement->insertText(m_position, m_removed);
00093     m_ownerElement->insertGlyphs(m_glyphpos,m_removedGlyphs);
00094 }
00095 
00096 FormulaCommandReplaceElements::FormulaCommandReplaceElements ( RowElement* owner, int position, int length, QList< BasicElement* > elements, bool wrap,QUndoCommand* parent )
00097                             : FormulaCommand(parent)
00098 {
00099     m_ownerElement=owner;
00100     m_position=position;
00101     m_added=elements;
00102     m_length=length;
00103     m_wrap=wrap;
00104     m_removed=m_ownerElement->childElements().mid(m_position,m_length);
00105     m_placeholderPosition=0;
00106     
00107     //we have to remember to which descendant of m_added the elements got moved
00108     BasicElement* placeholder=0;
00109     foreach (BasicElement* tmp, m_added) {
00110         if ( (placeholder=tmp->emptyDescendant()) ) {
00111             break;
00112         }
00113     }
00114     if (placeholder) { //we are actually wrapping stuff
00115         //empty descandant only returns a element hows parent is an inferred mrow
00116         m_placeholderParent=static_cast<RowElement*>(placeholder->parentElement());
00117         m_placeholderPosition=m_placeholderParent->positionOfChild(placeholder);
00118         m_placeholderParent->removeChild(placeholder);
00119         delete placeholder;
00120         if (m_wrap) {
00121             setRedoCursorPosition(FormulaCursor(m_placeholderParent,m_placeholderPosition+m_removed.count()));
00122         } else {
00123             setRedoCursorPosition(FormulaCursor(m_placeholderParent,m_placeholderPosition));
00124         }
00125     } else {
00126         m_placeholderParent=0;
00127         setRedoCursorPosition(FormulaCursor(m_ownerElement,m_position+m_added.length()));
00128     }
00129     setUndoCursorPosition(FormulaCursor(m_ownerElement,m_position+m_removed.length()));
00130 }
00131 
00132 FormulaCommandReplaceElements::~FormulaCommandReplaceElements()
00133 {
00134     if (m_done) {
00135         if (!(m_wrap && m_placeholderParent)) {
00136             foreach (BasicElement* tmp, m_removed) {
00137                 delete tmp;
00138             }
00139         }
00140     } else {
00141         foreach (BasicElement* tmp, m_added) {
00142             delete tmp;
00143         }
00144     }
00145 }
00146 
00147 void FormulaCommandReplaceElements::redo()
00148 {
00149     m_done=true;
00150     for (int i=0; i<m_length; ++i) {
00151         m_ownerElement->removeChild(m_removed[i]);
00152     }
00153     if (m_wrap &&  m_placeholderParent!=0) {
00154         int counter=0;
00155         foreach (BasicElement *tmp, m_removed) {
00156             m_placeholderParent->insertChild(m_placeholderPosition+counter,tmp);
00157             counter++;
00158         }
00159     }
00160     for (int i=0; i<m_added.length(); ++i) {
00161         m_ownerElement->insertChild(m_position+i,m_added[i]);
00162     }
00163 }
00164 
00165 void FormulaCommandReplaceElements::undo()
00166 {
00167     m_done=false;
00168     for (int i=0; i<m_added.length(); ++i) {
00169         m_ownerElement->removeChild(m_added[i]);
00170     }
00171     if (m_wrap &&  m_placeholderParent!=0) {
00172         foreach (BasicElement *tmp, m_removed) {
00173             m_placeholderParent->removeChild(tmp);
00174         }
00175     }
00176     for (int i=0; i<m_length; ++i) {
00177         m_ownerElement->insertChild(m_position+i,m_removed[i]);
00178     }
00179 }
00180 
00181 FormulaCommandLoad::FormulaCommandLoad ( FormulaData* data, FormulaElement* newelement, QUndoCommand* parent )
00182                    : FormulaCommand ( parent)
00183 {
00184     m_data=data;
00185     m_newel=newelement;
00186     m_oldel=data->formulaElement();
00187     setUndoCursorPosition(FormulaCursor(m_oldel,0));
00188     setRedoCursorPosition(FormulaCursor(m_newel,0));
00189 }
00190 
00191 FormulaCommandLoad::~FormulaCommandLoad()
00192 {
00193     if (m_done) {
00194     } else {
00195     }
00196 }
00197 
00198 void FormulaCommandLoad::redo()
00199 {
00200     m_done=true;
00201     m_data->setFormulaElement(m_newel);
00202 }
00203 
00204 void FormulaCommandLoad::undo()
00205 {
00206     m_done=false;
00207     m_data->setFormulaElement(m_oldel);
00208 }
00209 
00210 FormulaCommandReplaceRow::FormulaCommandReplaceRow ( FormulaData* data, FormulaCursor oldposition, TableElement* table, int number, int oldlength, int newlength)
00211 {
00212     m_data=data;
00213     m_table=table;
00214     m_number=number;
00215     m_empty=0;
00216     int columnnumber=m_table->childElements()[0]->childElements().count();
00217     TableRowElement* tmpRow;
00218     for (int i=0; i<newlength;i++) {
00219         tmpRow = new TableRowElement();
00220         for (int j=0; j<columnnumber; j++) {
00221             tmpRow->insertChild(i,new TableEntryElement());
00222         }
00223         m_newRows<<tmpRow;
00224     }
00225     m_oldRows=table->childElements().mid(number, oldlength);
00226     setText( i18n( "Change rows" ) );
00227     if (newlength==0 && oldlength>=table->childElements().count()) {
00228         m_empty=new TableRowElement();
00229         m_empty->insertChild(0, new TableEntryElement());
00230     }
00231     setUndoCursorPosition(oldposition);
00232 
00233     if (newlength>0) {
00234         setRedoCursorPosition(FormulaCursor(m_newRows[0]->childElements()[0],0));
00235     } else {
00236         if (m_empty) {
00237             setRedoCursorPosition(FormulaCursor(m_empty->childElements()[0],0));
00238         } else {
00239             int rowcount=m_table->childElements().count();
00240             if (number+oldlength < rowcount) {
00241                 //we can place the cursor after the removed elements
00242                 setRedoCursorPosition(FormulaCursor(table->childElements()[number+oldlength]->childElements()[0],0));
00243             } else {
00244                 //we have to place the cursor before the removed rows
00245                 setRedoCursorPosition(FormulaCursor(table->childElements()[number==0 ? 0: number-1]->childElements()[0],0));
00246             }
00247         }
00248     }
00249 }
00250 
00251 FormulaCommandReplaceRow::~FormulaCommandReplaceRow()
00252 {
00253     if (m_done) {
00254         qDeleteAll(m_oldRows);
00255     } else {
00256         if (m_empty) {
00257             delete m_empty;
00258         } else {
00259             qDeleteAll(m_newRows);
00260         }
00261     }
00262 }
00263 
00264 void FormulaCommandReplaceRow::redo()
00265 {
00266     for (int i=0; i<m_oldRows.count(); i++) {
00267         m_table->removeChild(m_oldRows[i]);
00268     }
00269     if (m_empty) {
00270         m_table->insertChild(0,m_empty);
00271     } else {
00272         for (int i=0; i<m_newRows.count(); i++) {
00273             m_table->insertChild(i+m_number,m_newRows[i]);
00274         }
00275     }
00276 }
00277 
00278 void FormulaCommandReplaceRow::undo()
00279 {
00280     if (m_empty) {
00281         m_table->removeChild(m_empty);
00282     } else {
00283         for (int i=0; i<m_newRows.count(); i++) {
00284             m_table->removeChild(m_newRows[i]);
00285         }
00286     }
00287     for (int i=0; i<m_oldRows.count(); i++) {
00288         m_table->insertChild(i+m_number,m_oldRows[i]);
00289     }
00290 }
00291 
00292 
00293 FormulaCommandReplaceColumn::FormulaCommandReplaceColumn ( FormulaData* data, FormulaCursor oldcursor, TableElement* table, int position, int oldlength, int newlength)
00294 {
00295     m_data=data;
00296     m_table=table;
00297     m_position=position;
00298     m_empty=0;
00299     int rownumber=m_table->childElements().count();
00300     QList<BasicElement*> tmp;
00301 
00302     if (newlength==0 && oldlength>=table->childElements().count()) {
00303         //we remove the whole table
00304         m_empty=new TableRowElement();
00305         m_empty->insertChild(0, new TableEntryElement());
00306         m_oldRows=table->childElements();
00307     } else {
00308         for (int i=0; i<newlength;i++) {
00309             for (int j=0; j<rownumber;j++) {
00310                 tmp<<new TableEntryElement();
00311             }
00312             m_newColumns<<tmp;
00313             tmp.clear();
00314         }
00315         for (int i=0; i<oldlength;i++) {
00316             for (int j=0; j<rownumber;j++) {
00317                 tmp<<table->childElements()[j]->childElements()[m_position+i];
00318             }
00319             m_oldColumns<<tmp;
00320             tmp.clear();
00321         }
00322     }
00323     setUndoCursorPosition(oldcursor);
00324 
00325     if (newlength>0) {
00326         setRedoCursorPosition(FormulaCursor(m_newColumns[0][0],0));
00327     } else {
00328         if (m_empty) {
00329             setRedoCursorPosition(FormulaCursor(m_empty->childElements()[0],0));
00330         } else {
00331             int columncount=m_table->childElements()[0]->childElements().count();
00332             if (position+oldlength < columncount) {
00333                 //we can place the cursor after the removed elements
00334                 setRedoCursorPosition(FormulaCursor(table->childElements()[0]->childElements()[position+oldlength],0));
00335             } else {
00336                 //we have to place the cursor before the removed rows
00337                 setRedoCursorPosition(FormulaCursor(table->childElements()[0]->childElements()[position==0 ? 0: position-1],0));
00338             }
00339         }
00340     }
00341 }
00342 
00343 FormulaCommandReplaceColumn::~FormulaCommandReplaceColumn()
00344 {
00345     if (m_done) {
00346         if (m_empty) {
00347             qDeleteAll(m_oldRows);
00348         } else {
00349             foreach (QList<BasicElement*> column, m_oldColumns) {
00350                 foreach( BasicElement* element, column) {
00351                     delete element;
00352                 }
00353             }
00354         }
00355     } else {
00356         if (m_empty) {
00357             delete m_empty;
00358         } else {
00359             foreach (QList<BasicElement*> column, m_newColumns) {
00360                 foreach( BasicElement* element, column) {
00361                     delete element;
00362                 }
00363             }
00364         }
00365     }
00366 }
00367 
00368 void FormulaCommandReplaceColumn::redo()
00369 {
00370     if (m_empty) {
00371         for (int i=0; i<m_oldRows.count();i++) {
00372             m_table->removeChild(m_oldRows[i]);
00373         }
00374         m_table->insertChild(0,m_empty);
00375     } else {
00376         for (int i=0; i<m_table->childElements().count(); i++) {
00377             TableRowElement* row=static_cast<TableRowElement*>(m_table->childElements()[i]);
00378             for (int j=0; j<m_oldColumns.count(); j++) {
00379                 row->removeChild(m_oldColumns[j][i]);
00380             }
00381             for (int j=0; j<m_newColumns.count(); j++) {
00382                 row->insertChild(m_position+j,m_newColumns[j][i]);
00383             }
00384         }
00385     }
00386 }
00387 
00388 void FormulaCommandReplaceColumn::undo()
00389 {
00390     if (m_empty) {
00391         m_table->removeChild(m_empty);
00392         for (int i=0; i<m_oldRows.count(); ++i) {
00393             m_table->insertChild(i,m_oldRows[i]);
00394         }
00395     } else {
00396         for (int i=0; i<m_table->childElements().count(); i++) {
00397             TableRowElement* row=static_cast<TableRowElement*>(m_table->childElements()[i]);
00398             for (int j=0; j<m_newColumns.count(); j++) {
00399                 row->removeChild(m_newColumns[j][i]);
00400             }
00401             for (int j=0; j<m_oldColumns.count(); j++) {
00402                 row->insertChild(m_position+j,m_oldColumns[j][i]);
00403             }
00404         }
00405     }
00406 }
00407 
00408 
00409 // FormulaCommandAttribute::FormulaCommandAttribute( FormulaCursor* cursor,
00410 //                                                   QHash<QString,QString> attributes )
00411 //                        : QUndoCommand()
00412 // {
00413 //     m_ownerElement = cursor.ownerElement();
00414 //     m_attributes = attributes;
00415 //     m_oldAttributes = m_ownerElement->attributes();
00416 //     QHashIterator<QString, QString> i( m_oldAttributes );
00417 //     while( i.hasNext() )
00418 //     {
00419 //         i.next();
00420 //  if( !m_attributes.contains( i.key() ) )
00421 //             m_attributes.insert( i.key(), i.value() );
00422 //     }
00423 // 
00424 //     setText( i18n( "Attribute Changed" ) );
00425 // }
00426 // 
00427 // void FormulaCommandAttribute::redo()
00428 // {
00429 //     m_ownerElement->setAttributes( m_attributes );
00430 // }
00431 // 
00432 // void FormulaCommandAttribute::undo()
00433 // {
00434 //     m_ownerElement->setAttributes( m_oldAttributes );
00435 // }