kformula/flake

FormulaEditor.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 "FormulaEditor.h"
00024 #include "BasicElement.h"
00025 #include "RowElement.h"
00026 #include "FixedElement.h"
00027 #include "NumberElement.h"
00028 #include "TableElement.h"
00029 #include "TableEntryElement.h"
00030 #include "TableRowElement.h"
00031 #include "ElementFactory.h"
00032 #include "OperatorElement.h"
00033 #include "IdentifierElement.h"
00034 #include "ElementFactory.h"
00035 #include "FormulaCommand.h"
00036 #include <QPainter>
00037 #include <QPen>
00038 #include <algorithm>
00039 #include <QObject>
00040 
00041 #include <kdebug.h>
00042 #include <klocale.h>
00043 #include <QUndoCommand>
00044 #include <KoOdfLoadingContext.h>
00045 #include <KoOdfStylesReader.h>
00046 
00047 FormulaEditor::FormulaEditor( FormulaCursor cursor, FormulaData* data )
00048 {
00049     m_cursor=cursor;
00050     m_data=data;
00051 }
00052 
00053 FormulaEditor::FormulaEditor ( FormulaData* data )
00054 {
00055     m_cursor=FormulaCursor(data->formulaElement(),0);
00056     m_data=data;
00057 }
00058 
00059 
00060 
00061 void FormulaEditor::paint( QPainter& painter ) const
00062 {
00063     m_cursor.paint(painter);
00064 }
00065 
00066 FormulaCommand* FormulaEditor::insertText( const QString& text )
00067 {
00068     FormulaCommand *undo = 0;
00069     m_inputBuffer = text;
00070     if (m_cursor.insideToken()) {
00071         TokenElement* token=static_cast<TokenElement*>(m_cursor.currentElement());
00072         if (m_cursor.hasSelection()) {
00073             undo=new FormulaCommandReplaceText(token,m_cursor.selection().first,m_cursor.selection().second-m_cursor.selection().first,text);
00074         } else {
00075             undo=new FormulaCommandReplaceText(token,m_cursor.position(),0,text);
00076         }
00077     } else {
00078         TokenElement* token = static_cast<TokenElement*>
00079             (ElementFactory::createElement(tokenType(text[0]),0));
00080         token->insertText(0,text);
00081         undo=insertElement(token);
00082         if (undo) {
00083             undo->setRedoCursorPosition(FormulaCursor(token,text.length()));
00084         }
00085     }
00086     if (undo) {
00087         undo->setText(i18n("Add text"));
00088     }
00089     return undo;
00090 }
00091 
00092 FormulaCommand* FormulaEditor::insertMathML( const QString& data )
00093 {
00094     // setup a DOM structure and start the actual loading process
00095     KoXmlDocument tmpDocument;
00096     tmpDocument.setContent( QString(data), false, 0, 0, 0 );
00097     BasicElement* element=ElementFactory::createElement(tmpDocument.documentElement().tagName(),0);
00098     element->readMathML( tmpDocument.documentElement() );     // and load the new formula
00099     FormulaCommand* command=insertElement( element );
00100     kDebug()<<"Inserting "<< tmpDocument.documentElement().tagName();
00101     if (command==0) {
00102         delete element;
00103     }
00104     return command;
00105 }
00106 
00107 FormulaCommand* FormulaEditor::changeTable ( bool insert, bool rows )
00108 {
00109     FormulaCommand* undo;
00110     TableEntryElement* entry=m_cursor.currentElement()->parentTableEntry();
00111     if (entry) {
00112         TableElement* table=static_cast<TableElement*>(entry->parentElement()->parentElement());
00113         int rowNumber=table->childElements().indexOf(entry->parentElement());
00114         int columnNumber=entry->parentElement()->childElements().indexOf(entry);
00115         if (rows) {
00116             //Changing rows
00117             if (insert) {
00118                 undo=new FormulaCommandReplaceRow(formulaData(),cursor(),table,rowNumber,0,1);
00119                 if (undo) {
00120                     undo->setText(i18n("Insert row"));
00121                 }
00122             } else {
00123                 undo=new FormulaCommandReplaceRow(formulaData(),cursor(),table,rowNumber,1,0);
00124                 if (undo) {
00125                     undo->setText(i18n("Remove row"));
00126                 }
00127             }
00128         } else {
00129             //Changing columns
00130             if (insert) {
00131                 undo=new FormulaCommandReplaceColumn(formulaData(),cursor(),table,columnNumber,0,1);
00132                 if (undo) {
00133                     undo->setText(i18n("Insert column"));
00134                 }
00135             } else {
00136                 undo=new FormulaCommandReplaceColumn(formulaData(),cursor(),table,columnNumber,1,0);
00137                 if (undo) {
00138                     undo->setText(i18n("Remove column"));
00139                 }
00140             }
00141         }
00142     } else {
00143         return 0;
00144     }
00145     return undo;
00146 }
00147 
00148 FormulaCommand* FormulaEditor::insertElement( BasicElement* element )
00149 {
00150     FormulaCommand *undo = 0;
00151     if (m_cursor.insideInferredRow()) {
00152         RowElement* tmprow=static_cast<RowElement*>(m_cursor.currentElement());
00153         QList<BasicElement*> list;
00154         list<<element;
00155         if (m_cursor.hasSelection()) {
00156             undo=new FormulaCommandReplaceElements(tmprow,m_cursor.selection().first,m_cursor.selection().second-m_cursor.selection().first,list,true);
00157         } else {
00158             undo=new FormulaCommandReplaceElements(tmprow,m_cursor.position(),0,list,false);
00159         }
00160     } else if (m_cursor.insideToken() && element->elementType()==Glyph) {
00161         //TODO: implement the insertion of glyphs
00162     }
00163     if (undo) {
00164         undo->setText(i18n("Insert formula elements."));
00165         undo->setUndoCursorPosition(cursor());
00166     }
00167     return undo;
00168 }
00169 
00170 FormulaCommand* FormulaEditor::remove( bool elementBeforePosition )
00171 {
00172     FormulaCommand *undo=0;
00173     if (m_cursor.insideInferredRow()) {
00174         RowElement* tmprow=static_cast<RowElement*>(m_cursor.currentElement());
00175         if (m_cursor.isSelecting()) {
00176             undo=new FormulaCommandReplaceElements(tmprow,m_cursor.selection().first,m_cursor.selection().second-m_cursor.selection().first,QList<BasicElement*>());
00177         } else {
00178             if (elementBeforePosition && !m_cursor.isHome()) {
00179                 undo=new FormulaCommandReplaceElements(tmprow,m_cursor.position()-1,1,QList<BasicElement*>());
00180             } else if (!elementBeforePosition && !m_cursor.isEnd()) {
00181                 undo=new FormulaCommandReplaceElements(tmprow,m_cursor.position(),1,QList<BasicElement*>());
00182             }
00183         }
00184     } else if (m_cursor.insideToken()) {
00185         TokenElement* tmptoken=static_cast<TokenElement*>(m_cursor.currentElement());
00186         if (m_cursor.hasSelection()) {
00187             undo=new FormulaCommandReplaceText(tmptoken,m_cursor.selection().first,m_cursor.selection().second-m_cursor.selection().first,"");
00188         } else {
00189             if (elementBeforePosition && !m_cursor.isHome()) {
00190                 undo=new FormulaCommandReplaceText(tmptoken,m_cursor.position()-1,1,"");
00191             } else if (!elementBeforePosition && !m_cursor.isEnd()) {
00192                 undo=new FormulaCommandReplaceText(tmptoken,m_cursor.position(),1,"");
00193             }
00194         }
00195     }
00196     if (undo) {
00197         undo->setText(i18n("Remove formula elements"));
00198         undo->setUndoCursorPosition(cursor());
00199     }
00200     return undo;
00201 }
00202 
00203 void FormulaEditor::setData ( FormulaData* data )
00204 {
00205     m_data=data;
00206 }
00207 
00208 
00209 FormulaData* FormulaEditor::formulaData() const
00210 {
00211     return m_data;
00212 }
00213 
00214 QString FormulaEditor::inputBuffer() const
00215 {
00216     return m_inputBuffer;
00217 }
00218 
00219 QString FormulaEditor::tokenType ( const QChar& character ) const
00220 {
00221     QChar::Category chat=character.category();
00222     if (character.isNumber()) {
00223         return "mn";
00224     }
00225     else if (chat==QChar::Punctuation_Connector ||
00226              chat==QChar::Punctuation_Dash ||
00227              chat==QChar::Punctuation_Open ||
00228              chat==QChar::Punctuation_Close ||
00229              chat==QChar::Punctuation_InitialQuote ||
00230              chat==QChar::Punctuation_FinalQuote ||
00231              chat==QChar::Symbol_Math) {
00232         return "mo";
00233     }
00234     else if (character.isLetter()) {
00235         return "mi";
00236     }
00237     return "mi";
00238 }
00239 
00240 
00241 FormulaCursor& FormulaEditor::cursor() 
00242 {
00243     return m_cursor;
00244 }
00245 
00246 void FormulaEditor::setCursor ( FormulaCursor& cursor )
00247 {
00248     m_cursor=cursor;
00249 }
00250