File indexing completed on 2024-05-12 16:34:01
0001 /* This file is part of the KDE project 0002 Copyright (C) 2001 Andrea Rizzi <rizzi@kde.org> 0003 Ulrich Kuettler <ulrich.kuettler@mailbox.tu-dresden.de> 0004 2006 Martin Pfeiffer <hubipete@gmx.net> 0005 2009 Jeremias Epperlein <jeeree@web.de> 0006 0007 This library is free software; you can redistribute it and/or 0008 modify it under the terms of the GNU Library General Public 0009 License as published by the Free Software Foundation; either 0010 version 2 of the License, or (at your option) any later version. 0011 0012 This library is distributed in the hope that it will be useful, 0013 but WITHOUT ANY WARRANTY; without even the implied warranty of 0014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0015 Library General Public License for more details. 0016 0017 You should have received a copy of the GNU Library General Public License 0018 along with this library; see the file COPYING.LIB. If not, write to 0019 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0020 Boston, MA 02110-1301, USA. 0021 */ 0022 0023 #include "FormulaCommand.h" 0024 0025 #include "FormulaCursor.h" 0026 #include "TokenElement.h" 0027 #include "BasicElement.h" 0028 #include "TableElement.h" 0029 #include "TableRowElement.h" 0030 #include "TableDataElement.h" 0031 #include "FormulaDebug.h" 0032 0033 #include <klocalizedstring.h> 0034 0035 FormulaCommand::FormulaCommand(KUndo2Command* parent) 0036 : KUndo2Command(parent) 0037 { 0038 m_done=false; 0039 } 0040 0041 void FormulaCommand::changeCursor ( FormulaCursor& cursor, bool undo ) const 0042 { 0043 if (undo) { 0044 cursor.moveTo(m_undoCursorPosition); 0045 } else { 0046 cursor.moveTo(m_redoCursorPosition); 0047 } 0048 if (!cursor.isAccepted()) { 0049 cursor.move(MoveRight); 0050 } 0051 } 0052 0053 void FormulaCommand::setUndoCursorPosition ( const FormulaCursor& position ) 0054 { 0055 m_undoCursorPosition=position; 0056 } 0057 0058 void FormulaCommand::setRedoCursorPosition ( const FormulaCursor& position ) 0059 { 0060 m_redoCursorPosition=position; 0061 } 0062 0063 FormulaCommandReplaceText::FormulaCommandReplaceText( TokenElement* owner, int position, int length, const QString& added , KUndo2Command* parent) 0064 : FormulaCommand(parent) 0065 { 0066 m_ownerElement = owner; 0067 m_position = position; 0068 m_added = added; 0069 m_length = length; 0070 m_removedGlyphs=m_ownerElement->glyphList(position,length); 0071 m_removed=m_ownerElement->text().mid(position,length); 0072 setText( kundo2_i18n( "Add text to formula" ) ); 0073 setUndoCursorPosition(FormulaCursor(m_ownerElement, m_position+m_removed.length())); 0074 setRedoCursorPosition(FormulaCursor(m_ownerElement, m_position+m_added.length())); 0075 } 0076 0077 FormulaCommandReplaceText::~FormulaCommandReplaceText() 0078 { 0079 } 0080 0081 void FormulaCommandReplaceText::redo() 0082 { 0083 m_done=true; 0084 if (m_length>0) { 0085 m_glyphpos=m_ownerElement->removeText(m_position,m_length); 0086 } 0087 m_ownerElement->insertText(m_position, m_added); 0088 } 0089 0090 void FormulaCommandReplaceText::undo() 0091 { 0092 m_done=false; 0093 m_ownerElement->removeText(m_position,m_added.length()); 0094 m_ownerElement->insertText(m_position, m_removed); 0095 m_ownerElement->insertGlyphs(m_glyphpos,m_removedGlyphs); 0096 } 0097 0098 FormulaCommandReplaceElements::FormulaCommandReplaceElements ( RowElement* owner, int position, int length, QList< BasicElement* > elements, bool wrap,KUndo2Command* parent ) 0099 : FormulaCommand(parent) 0100 { 0101 m_ownerElement=owner; 0102 m_position=position; 0103 m_added=elements; 0104 m_length=length; 0105 m_wrap=wrap; 0106 m_removed=m_ownerElement->childElements().mid(m_position,m_length); 0107 m_placeholderPosition=0; 0108 0109 //we have to remember to which descendant of m_added the elements got moved 0110 BasicElement* placeholder=0; 0111 foreach (BasicElement* tmp, m_added) { 0112 if ( (placeholder=tmp->emptyDescendant()) ) { 0113 break; 0114 } 0115 } 0116 if (placeholder) { //we are actually wrapping stuff 0117 //empty descandant only returns a element hows parent is an inferred mrow 0118 m_placeholderParent=static_cast<RowElement*>(placeholder->parentElement()); 0119 m_placeholderPosition=m_placeholderParent->positionOfChild(placeholder); 0120 m_placeholderParent->removeChild(placeholder); 0121 delete placeholder; 0122 if (m_wrap) { 0123 setRedoCursorPosition(FormulaCursor(m_placeholderParent,m_placeholderPosition+m_removed.count())); 0124 } else { 0125 setRedoCursorPosition(FormulaCursor(m_placeholderParent,m_placeholderPosition)); 0126 } 0127 } else { 0128 m_placeholderParent=0; 0129 setRedoCursorPosition(FormulaCursor(m_ownerElement,m_position+m_added.length())); 0130 } 0131 setUndoCursorPosition(FormulaCursor(m_ownerElement,m_position+m_removed.length())); 0132 } 0133 0134 FormulaCommandReplaceElements::~FormulaCommandReplaceElements() 0135 { 0136 if (m_done) { 0137 if (!(m_wrap && m_placeholderParent)) { 0138 foreach (BasicElement* tmp, m_removed) { 0139 delete tmp; 0140 } 0141 } 0142 } else { 0143 foreach (BasicElement* tmp, m_added) { 0144 delete tmp; 0145 } 0146 } 0147 } 0148 0149 void FormulaCommandReplaceElements::redo() 0150 { 0151 m_done=true; 0152 for (int i=0; i<m_length; ++i) { 0153 m_ownerElement->removeChild(m_removed[i]); 0154 } 0155 if (m_wrap && m_placeholderParent!=0) { 0156 int counter=0; 0157 foreach (BasicElement *tmp, m_removed) { 0158 m_placeholderParent->insertChild(m_placeholderPosition+counter,tmp); 0159 counter++; 0160 } 0161 } 0162 for (int i=0; i<m_added.length(); ++i) { 0163 m_ownerElement->insertChild(m_position+i,m_added[i]); 0164 } 0165 } 0166 0167 void FormulaCommandReplaceElements::undo() 0168 { 0169 m_done=false; 0170 for (int i=0; i<m_added.length(); ++i) { 0171 m_ownerElement->removeChild(m_added[i]); 0172 } 0173 if (m_wrap && m_placeholderParent!=0) { 0174 foreach (BasicElement *tmp, m_removed) { 0175 m_placeholderParent->removeChild(tmp); 0176 } 0177 } 0178 for (int i=0; i<m_length; ++i) { 0179 m_ownerElement->insertChild(m_position+i,m_removed[i]); 0180 } 0181 } 0182 0183 FormulaCommandLoad::FormulaCommandLoad ( FormulaData* data, FormulaElement* newelement, KUndo2Command* parent ) 0184 : FormulaCommand ( parent) 0185 { 0186 m_data=data; 0187 m_newel=newelement; 0188 m_oldel=data->formulaElement(); 0189 setUndoCursorPosition(FormulaCursor(m_oldel,0)); 0190 setRedoCursorPosition(FormulaCursor(m_newel,0)); 0191 } 0192 0193 FormulaCommandLoad::~FormulaCommandLoad() 0194 { 0195 if (m_done) { 0196 } else { 0197 } 0198 } 0199 0200 void FormulaCommandLoad::redo() 0201 { 0202 m_done=true; 0203 m_data->setFormulaElement(m_newel); 0204 } 0205 0206 void FormulaCommandLoad::undo() 0207 { 0208 m_done=false; 0209 m_data->setFormulaElement(m_oldel); 0210 } 0211 0212 FormulaCommandReplaceRow::FormulaCommandReplaceRow ( FormulaData* data, FormulaCursor oldposition, TableElement* table, int number, int oldlength, int newlength) 0213 { 0214 m_data=data; 0215 m_table=table; 0216 m_number=number; 0217 m_empty=0; 0218 int columnnumber=m_table->childElements()[0]->childElements().count(); 0219 TableRowElement* tmpRow; 0220 for (int i=0; i<newlength;i++) { 0221 tmpRow = new TableRowElement(); 0222 for (int j=0; j<columnnumber; j++) { 0223 tmpRow->insertChild(i,new TableDataElement()); 0224 } 0225 m_newRows<<tmpRow; 0226 } 0227 m_oldRows=table->childElements().mid(number, oldlength); 0228 setText( kundo2_i18n( "Change rows" ) ); 0229 if (newlength==0 && oldlength>=table->childElements().count()) { 0230 m_empty=new TableRowElement(); 0231 m_empty->insertChild(0, new TableDataElement()); 0232 } 0233 setUndoCursorPosition(oldposition); 0234 0235 if (newlength>0) { 0236 setRedoCursorPosition(FormulaCursor(m_newRows[0]->childElements()[0],0)); 0237 } else { 0238 if (m_empty) { 0239 setRedoCursorPosition(FormulaCursor(m_empty->childElements()[0],0)); 0240 } else { 0241 int rowcount=m_table->childElements().count(); 0242 if (number+oldlength < rowcount) { 0243 //we can place the cursor after the removed elements 0244 setRedoCursorPosition(FormulaCursor(table->childElements()[number+oldlength]->childElements()[0],0)); 0245 } else { 0246 //we have to place the cursor before the removed rows 0247 setRedoCursorPosition(FormulaCursor(table->childElements()[number==0 ? 0: number-1]->childElements()[0],0)); 0248 } 0249 } 0250 } 0251 } 0252 0253 FormulaCommandReplaceRow::~FormulaCommandReplaceRow() 0254 { 0255 if (m_done) { 0256 qDeleteAll(m_oldRows); 0257 } else { 0258 if (m_empty) { 0259 delete m_empty; 0260 } else { 0261 qDeleteAll(m_newRows); 0262 } 0263 } 0264 } 0265 0266 void FormulaCommandReplaceRow::redo() 0267 { 0268 for (int i=0; i<m_oldRows.count(); i++) { 0269 m_table->removeChild(m_oldRows[i]); 0270 } 0271 if (m_empty) { 0272 m_table->insertChild(0,m_empty); 0273 } else { 0274 for (int i=0; i<m_newRows.count(); i++) { 0275 m_table->insertChild(i+m_number,m_newRows[i]); 0276 } 0277 } 0278 } 0279 0280 void FormulaCommandReplaceRow::undo() 0281 { 0282 if (m_empty) { 0283 m_table->removeChild(m_empty); 0284 } else { 0285 for (int i=0; i<m_newRows.count(); i++) { 0286 m_table->removeChild(m_newRows[i]); 0287 } 0288 } 0289 for (int i=0; i<m_oldRows.count(); i++) { 0290 m_table->insertChild(i+m_number,m_oldRows[i]); 0291 } 0292 } 0293 0294 0295 FormulaCommandReplaceColumn::FormulaCommandReplaceColumn ( FormulaData* data, FormulaCursor oldcursor, TableElement* table, int position, int oldlength, int newlength) 0296 { 0297 m_data=data; 0298 m_table=table; 0299 m_position=position; 0300 m_empty=0; 0301 int rownumber=m_table->childElements().count(); 0302 QList<BasicElement*> tmp; 0303 0304 if (newlength==0 && oldlength>=table->childElements().count()) { 0305 //we remove the whole table 0306 m_empty=new TableRowElement(); 0307 m_empty->insertChild(0, new TableDataElement()); 0308 m_oldRows=table->childElements(); 0309 } else { 0310 for (int i=0; i<newlength;i++) { 0311 for (int j=0; j<rownumber;j++) { 0312 tmp<<new TableDataElement(); 0313 } 0314 m_newColumns<<tmp; 0315 tmp.clear(); 0316 } 0317 for (int i=0; i<oldlength;i++) { 0318 for (int j=0; j<rownumber;j++) { 0319 tmp<<table->childElements()[j]->childElements()[m_position+i]; 0320 } 0321 m_oldColumns<<tmp; 0322 tmp.clear(); 0323 } 0324 } 0325 setUndoCursorPosition(oldcursor); 0326 0327 if (newlength>0) { 0328 setRedoCursorPosition(FormulaCursor(m_newColumns[0][0],0)); 0329 } else { 0330 if (m_empty) { 0331 setRedoCursorPosition(FormulaCursor(m_empty->childElements()[0],0)); 0332 } else { 0333 int columncount=m_table->childElements()[0]->childElements().count(); 0334 if (position+oldlength < columncount) { 0335 //we can place the cursor after the removed elements 0336 setRedoCursorPosition(FormulaCursor(table->childElements()[0]->childElements()[position+oldlength],0)); 0337 } else { 0338 //we have to place the cursor before the removed rows 0339 setRedoCursorPosition(FormulaCursor(table->childElements()[0]->childElements()[position==0 ? 0: position-1],0)); 0340 } 0341 } 0342 } 0343 } 0344 0345 FormulaCommandReplaceColumn::~FormulaCommandReplaceColumn() 0346 { 0347 if (m_done) { 0348 if (m_empty) { 0349 qDeleteAll(m_oldRows); 0350 } else { 0351 foreach (QList<BasicElement*> column, m_oldColumns) { 0352 foreach( BasicElement* element, column) { 0353 delete element; 0354 } 0355 } 0356 } 0357 } else { 0358 if (m_empty) { 0359 delete m_empty; 0360 } else { 0361 foreach (QList<BasicElement*> column, m_newColumns) { 0362 foreach( BasicElement* element, column) { 0363 delete element; 0364 } 0365 } 0366 } 0367 } 0368 } 0369 0370 void FormulaCommandReplaceColumn::redo() 0371 { 0372 if (m_empty) { 0373 for (int i=0; i<m_oldRows.count();i++) { 0374 m_table->removeChild(m_oldRows[i]); 0375 } 0376 m_table->insertChild(0,m_empty); 0377 } else { 0378 for (int i=0; i<m_table->childElements().count(); i++) { 0379 TableRowElement* row=static_cast<TableRowElement*>(m_table->childElements()[i]); 0380 for (int j=0; j<m_oldColumns.count(); j++) { 0381 row->removeChild(m_oldColumns[j][i]); 0382 } 0383 for (int j=0; j<m_newColumns.count(); j++) { 0384 row->insertChild(m_position+j,m_newColumns[j][i]); 0385 } 0386 } 0387 } 0388 } 0389 0390 void FormulaCommandReplaceColumn::undo() 0391 { 0392 if (m_empty) { 0393 m_table->removeChild(m_empty); 0394 for (int i=0; i<m_oldRows.count(); ++i) { 0395 m_table->insertChild(i,m_oldRows[i]); 0396 } 0397 } else { 0398 for (int i=0; i<m_table->childElements().count(); i++) { 0399 TableRowElement* row=static_cast<TableRowElement*>(m_table->childElements()[i]); 0400 for (int j=0; j<m_newColumns.count(); j++) { 0401 row->removeChild(m_newColumns[j][i]); 0402 } 0403 for (int j=0; j<m_oldColumns.count(); j++) { 0404 row->insertChild(m_position+j,m_oldColumns[j][i]); 0405 } 0406 } 0407 } 0408 } 0409 0410 0411 // FormulaCommandAttribute::FormulaCommandAttribute( FormulaCursor* cursor, 0412 // QHash<QString,QString> attributes ) 0413 // : KUndo2Command() 0414 // { 0415 // m_ownerElement = cursor.ownerElement(); 0416 // m_attributes = attributes; 0417 // m_oldAttributes = m_ownerElement->attributes(); 0418 // QHashIterator<QString, QString> i( m_oldAttributes ); 0419 // while( i.hasNext() ) 0420 // { 0421 // i.next(); 0422 // if( !m_attributes.contains( i.key() ) ) 0423 // m_attributes.insert( i.key(), i.value() ); 0424 // } 0425 // 0426 // setText( kundo2_i18n( "Attribute Changed" ) ); 0427 // } 0428 // 0429 // void FormulaCommandAttribute::redo() 0430 // { 0431 // m_ownerElement->setAttributes( m_attributes ); 0432 // } 0433 // 0434 // void FormulaCommandAttribute::undo() 0435 // { 0436 // m_ownerElement->setAttributes( m_oldAttributes ); 0437 // }