From 8b78a8791bc539bcffe7159f9d9714d577cb3d7d Mon Sep 17 00:00:00 2001 From: Michele Calgaro Date: Sun, 23 May 2021 20:48:35 +0900 Subject: Renaming of files in preparation for code style tools. Signed-off-by: Michele Calgaro --- lib/kformula/Makefile.am | 34 +- lib/kformula/MatrixDialog.cc | 77 - lib/kformula/MatrixDialog.cpp | 77 + lib/kformula/actionelement.cc | 77 - lib/kformula/actionelement.cpp | 77 + lib/kformula/basicelement.cc | 400 --- lib/kformula/basicelement.cpp | 400 +++ lib/kformula/bracketelement.cc | 1005 ------- lib/kformula/bracketelement.cpp | 1005 +++++++ lib/kformula/contextstyle.cc | 765 ----- lib/kformula/contextstyle.cpp | 765 +++++ lib/kformula/creationstrategy.cc | 144 - lib/kformula/creationstrategy.cpp | 144 + lib/kformula/elementtype.cc | 765 ----- lib/kformula/elementtype.cpp | 765 +++++ lib/kformula/encloseelement.cc | 44 - lib/kformula/encloseelement.cpp | 44 + lib/kformula/entities.cc | 2037 ------------- lib/kformula/entities.cpp | 2037 +++++++++++++ lib/kformula/errorelement.cc | 51 - lib/kformula/errorelement.cpp | 51 + lib/kformula/fontstyle.cc | 891 ------ lib/kformula/fontstyle.cpp | 891 ++++++ lib/kformula/formulacursor.cc | 746 ----- lib/kformula/formulacursor.cpp | 746 +++++ lib/kformula/formulaelement.cc | 336 --- lib/kformula/formulaelement.cpp | 336 +++ lib/kformula/fractionelement.cc | 657 ----- lib/kformula/fractionelement.cpp | 657 +++++ lib/kformula/glyphelement.cc | 159 -- lib/kformula/glyphelement.cpp | 159 ++ lib/kformula/identifierelement.cc | 206 -- lib/kformula/identifierelement.cpp | 206 ++ lib/kformula/indexelement.cc | 1763 ------------ lib/kformula/indexelement.cpp | 1763 ++++++++++++ lib/kformula/kformulacommand.cc | 625 ---- lib/kformula/kformulacommand.cpp | 625 ++++ lib/kformula/kformulacompatibility.cc | 402 --- lib/kformula/kformulacompatibility.cpp | 402 +++ lib/kformula/kformulaconfigpage.cc | 543 ---- lib/kformula/kformulaconfigpage.cpp | 543 ++++ lib/kformula/kformulacontainer.cc | 643 ----- lib/kformula/kformulacontainer.cpp | 643 +++++ lib/kformula/kformuladocument.cc | 1299 --------- lib/kformula/kformuladocument.cpp | 1299 +++++++++ lib/kformula/kformulainputfilter.cc | 24 - lib/kformula/kformulainputfilter.cpp | 24 + lib/kformula/kformulamathmlread.cc | 1794 ------------ lib/kformula/kformulamathmlread.cpp | 1794 ++++++++++++ lib/kformula/kformulamimesource.cc | 154 - lib/kformula/kformulamimesource.cpp | 154 + lib/kformula/kformulaview.cc | 413 --- lib/kformula/kformulaview.cpp | 413 +++ lib/kformula/kformulawidget.cc | 171 -- lib/kformula/kformulawidget.cpp | 171 ++ lib/kformula/main.cc | 298 -- lib/kformula/main.cpp | 298 ++ lib/kformula/matrixelement.cc | 2692 ------------------ lib/kformula/matrixelement.cpp | 2692 ++++++++++++++++++ lib/kformula/numberelement.cc | 153 - lib/kformula/numberelement.cpp | 153 + lib/kformula/oasiscreationstrategy.cc | 210 -- lib/kformula/oasiscreationstrategy.cpp | 210 ++ lib/kformula/operatordictionary.cc | 4266 ---------------------------- lib/kformula/operatordictionary.cpp | 4266 ++++++++++++++++++++++++++++ lib/kformula/operatorelement.cc | 547 ---- lib/kformula/operatorelement.cpp | 547 ++++ lib/kformula/paddedelement.cc | 296 -- lib/kformula/paddedelement.cpp | 296 ++ lib/kformula/phantomelement.cc | 39 - lib/kformula/phantomelement.cpp | 39 + lib/kformula/prototype/gensymbolfontmap.py | 8 +- lib/kformula/rootelement.cc | 680 ----- lib/kformula/rootelement.cpp | 680 +++++ lib/kformula/scripts/bynames.py | 2 +- lib/kformula/scripts/oper-dict.py | 2 +- lib/kformula/sequenceelement.cc | 1934 ------------- lib/kformula/sequenceelement.cpp | 1934 +++++++++++++ lib/kformula/sequenceparser.cc | 241 -- lib/kformula/sequenceparser.cpp | 241 ++ lib/kformula/spaceelement.cc | 431 --- lib/kformula/spaceelement.cpp | 431 +++ lib/kformula/stringelement.cc | 88 - lib/kformula/stringelement.cpp | 88 + lib/kformula/styleelement.cc | 390 --- lib/kformula/styleelement.cpp | 390 +++ lib/kformula/symbolaction.cc | 174 -- lib/kformula/symbolaction.cpp | 174 ++ lib/kformula/symbolelement.cc | 906 ------ lib/kformula/symbolelement.cpp | 906 ++++++ lib/kformula/symbolfontmapping.cc | 171 -- lib/kformula/symbolfontmapping.cpp | 171 ++ lib/kformula/symboltable.cc | 152 - lib/kformula/symboltable.cpp | 152 + lib/kformula/textelement.cc | 567 ---- lib/kformula/textelement.cpp | 567 ++++ lib/kformula/tokenelement.cc | 124 - lib/kformula/tokenelement.cpp | 124 + lib/kformula/tokenstyleelement.cc | 624 ---- lib/kformula/tokenstyleelement.cpp | 624 ++++ lib/kformula/unicodetable.cc | 546 ---- lib/kformula/unicodetable.cpp | 546 ++++ 102 files changed, 31743 insertions(+), 31743 deletions(-) delete mode 100644 lib/kformula/MatrixDialog.cc create mode 100644 lib/kformula/MatrixDialog.cpp delete mode 100644 lib/kformula/actionelement.cc create mode 100644 lib/kformula/actionelement.cpp delete mode 100644 lib/kformula/basicelement.cc create mode 100644 lib/kformula/basicelement.cpp delete mode 100644 lib/kformula/bracketelement.cc create mode 100644 lib/kformula/bracketelement.cpp delete mode 100644 lib/kformula/contextstyle.cc create mode 100644 lib/kformula/contextstyle.cpp delete mode 100644 lib/kformula/creationstrategy.cc create mode 100644 lib/kformula/creationstrategy.cpp delete mode 100644 lib/kformula/elementtype.cc create mode 100644 lib/kformula/elementtype.cpp delete mode 100644 lib/kformula/encloseelement.cc create mode 100644 lib/kformula/encloseelement.cpp delete mode 100644 lib/kformula/entities.cc create mode 100644 lib/kformula/entities.cpp delete mode 100644 lib/kformula/errorelement.cc create mode 100644 lib/kformula/errorelement.cpp delete mode 100644 lib/kformula/fontstyle.cc create mode 100644 lib/kformula/fontstyle.cpp delete mode 100644 lib/kformula/formulacursor.cc create mode 100644 lib/kformula/formulacursor.cpp delete mode 100644 lib/kformula/formulaelement.cc create mode 100644 lib/kformula/formulaelement.cpp delete mode 100644 lib/kformula/fractionelement.cc create mode 100644 lib/kformula/fractionelement.cpp delete mode 100644 lib/kformula/glyphelement.cc create mode 100644 lib/kformula/glyphelement.cpp delete mode 100644 lib/kformula/identifierelement.cc create mode 100644 lib/kformula/identifierelement.cpp delete mode 100644 lib/kformula/indexelement.cc create mode 100644 lib/kformula/indexelement.cpp delete mode 100644 lib/kformula/kformulacommand.cc create mode 100644 lib/kformula/kformulacommand.cpp delete mode 100644 lib/kformula/kformulacompatibility.cc create mode 100644 lib/kformula/kformulacompatibility.cpp delete mode 100644 lib/kformula/kformulaconfigpage.cc create mode 100644 lib/kformula/kformulaconfigpage.cpp delete mode 100644 lib/kformula/kformulacontainer.cc create mode 100644 lib/kformula/kformulacontainer.cpp delete mode 100644 lib/kformula/kformuladocument.cc create mode 100644 lib/kformula/kformuladocument.cpp delete mode 100644 lib/kformula/kformulainputfilter.cc create mode 100644 lib/kformula/kformulainputfilter.cpp delete mode 100644 lib/kformula/kformulamathmlread.cc create mode 100644 lib/kformula/kformulamathmlread.cpp delete mode 100644 lib/kformula/kformulamimesource.cc create mode 100644 lib/kformula/kformulamimesource.cpp delete mode 100644 lib/kformula/kformulaview.cc create mode 100644 lib/kformula/kformulaview.cpp delete mode 100644 lib/kformula/kformulawidget.cc create mode 100644 lib/kformula/kformulawidget.cpp delete mode 100644 lib/kformula/main.cc create mode 100644 lib/kformula/main.cpp delete mode 100644 lib/kformula/matrixelement.cc create mode 100644 lib/kformula/matrixelement.cpp delete mode 100644 lib/kformula/numberelement.cc create mode 100644 lib/kformula/numberelement.cpp delete mode 100644 lib/kformula/oasiscreationstrategy.cc create mode 100644 lib/kformula/oasiscreationstrategy.cpp delete mode 100644 lib/kformula/operatordictionary.cc create mode 100644 lib/kformula/operatordictionary.cpp delete mode 100644 lib/kformula/operatorelement.cc create mode 100644 lib/kformula/operatorelement.cpp delete mode 100644 lib/kformula/paddedelement.cc create mode 100644 lib/kformula/paddedelement.cpp delete mode 100644 lib/kformula/phantomelement.cc create mode 100644 lib/kformula/phantomelement.cpp delete mode 100644 lib/kformula/rootelement.cc create mode 100644 lib/kformula/rootelement.cpp delete mode 100644 lib/kformula/sequenceelement.cc create mode 100644 lib/kformula/sequenceelement.cpp delete mode 100644 lib/kformula/sequenceparser.cc create mode 100644 lib/kformula/sequenceparser.cpp delete mode 100644 lib/kformula/spaceelement.cc create mode 100644 lib/kformula/spaceelement.cpp delete mode 100644 lib/kformula/stringelement.cc create mode 100644 lib/kformula/stringelement.cpp delete mode 100644 lib/kformula/styleelement.cc create mode 100644 lib/kformula/styleelement.cpp delete mode 100644 lib/kformula/symbolaction.cc create mode 100644 lib/kformula/symbolaction.cpp delete mode 100644 lib/kformula/symbolelement.cc create mode 100644 lib/kformula/symbolelement.cpp delete mode 100644 lib/kformula/symbolfontmapping.cc create mode 100644 lib/kformula/symbolfontmapping.cpp delete mode 100644 lib/kformula/symboltable.cc create mode 100644 lib/kformula/symboltable.cpp delete mode 100644 lib/kformula/textelement.cc create mode 100644 lib/kformula/textelement.cpp delete mode 100644 lib/kformula/tokenelement.cc create mode 100644 lib/kformula/tokenelement.cpp delete mode 100644 lib/kformula/tokenstyleelement.cc create mode 100644 lib/kformula/tokenstyleelement.cpp delete mode 100644 lib/kformula/unicodetable.cc create mode 100644 lib/kformula/unicodetable.cpp (limited to 'lib/kformula') diff --git a/lib/kformula/Makefile.am b/lib/kformula/Makefile.am index 4ad27bcc..e666bf48 100644 --- a/lib/kformula/Makefile.am +++ b/lib/kformula/Makefile.am @@ -7,20 +7,20 @@ SUBDIRS = pics fonts dtd # We have to name it kformulalib, not just kformula, since that's the name of the tdeinit module for kformula. lib_LTLIBRARIES = libkformulalib.la -libkformulalib_la_SOURCES = basicelement.cc contextstyle.cc formulacursor.cc \ - formulaelement.cc indexelement.cc kformulacontainer.cc \ - sequenceelement.cc textelement.cc bracketelement.cc \ - matrixelement.cc fractionelement.cc rootelement.cc symbolelement.cc \ - kformulacommand.cc kformulamimesource.cc \ - MatrixDialog.cc sequenceparser.cc elementtype.cc kformuladocument.cc \ - symboltable.cc kformulainputfilter.cc kformulaview.cc \ - spaceelement.cc kformulaconfigpage.cc \ - symbolaction.cc fontstyle.cc creationstrategy.cc \ - oasiscreationstrategy.cc tokenstyleelement.cc tokenelement.cc \ - identifierelement.cc operatorelement.cc glyphelement.cc styleelement.cc \ - stringelement.cc paddedelement.cc errorelement.cc phantomelement.cc \ - actionelement.cc encloseelement.cc entities.cc operatordictionary.cc \ - numberelement.cc +libkformulalib_la_SOURCES = basicelement.cpp contextstyle.cpp formulacursor.cpp \ + formulaelement.cpp indexelement.cpp kformulacontainer.cpp \ + sequenceelement.cpp textelement.cpp bracketelement.cpp \ + matrixelement.cpp fractionelement.cpp rootelement.cpp symbolelement.cpp \ + kformulacommand.cpp kformulamimesource.cpp \ + MatrixDialog.cpp sequenceparser.cpp elementtype.cpp kformuladocument.cpp \ + symboltable.cpp kformulainputfilter.cpp kformulaview.cpp \ + spaceelement.cpp kformulaconfigpage.cpp \ + symbolaction.cpp fontstyle.cpp creationstrategy.cpp \ + oasiscreationstrategy.cpp tokenstyleelement.cpp tokenelement.cpp \ + identifierelement.cpp operatorelement.cpp glyphelement.cpp styleelement.cpp \ + stringelement.cpp paddedelement.cpp errorelement.cpp phantomelement.cpp \ + actionelement.cpp encloseelement.cpp entities.cpp operatordictionary.cpp \ + numberelement.cpp #include_HEADERS = kformulacontainer.h kformuladocument.h kformulaview.h \ # kformuladefs.h kformulaconfigpage.h @@ -32,8 +32,8 @@ libkformulalib_la_METASOURCES = AUTO check_PROGRAMS = kformulatest -kformulatest_SOURCES = main.cc kformulawidget.cc +kformulatest_SOURCES = main.cpp kformulawidget.cpp kformulatest_LDADD = libkformulalib.la -#symbolnames.cc: -# awk -F, '$$1 !~ "#" {if (split($$3,a," ")>0) print "i18n(\"" a[1] "\");"}' config/unicode.tbl > symbolnames.cc +#symbolnames.cpp: +# awk -F, '$$1 !~ "#" {if (split($$3,a," ")>0) print "i18n(\"" a[1] "\");"}' config/unicode.tbl > symbolnames.cpp diff --git a/lib/kformula/MatrixDialog.cc b/lib/kformula/MatrixDialog.cc deleted file mode 100644 index feac37ce..00000000 --- a/lib/kformula/MatrixDialog.cc +++ /dev/null @@ -1,77 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 1999 Ilya Baran (ibaran@mit.edu) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - -#include "MatrixDialog.h" -#include -#include -#include -#include -#include -#include - -KFORMULA_NAMESPACE_BEGIN - -const int DEFAULT_SIZE = 3; -const int MAX_SIZE = 200; - -MatrixDialog::MatrixDialog( TQWidget *parent, int _width, int _height ) - : KDialogBase(parent, "Matrix Dialog", true,i18n("Add Matrix"),Ok|Cancel) -{ - w = _width; - h = _height; - - TQLabel *rows, *columns; - TQWidget *page = new TQWidget( this ); - setMainWidget(page); - TQGridLayout *grid = new TQGridLayout(page, 4, 2, 10); - - rows = new TQLabel(i18n("Rows:"), page); - columns = new TQLabel(i18n("Columns:"), page); - - grid->addWidget(rows, 0, 0); - grid->addWidget(columns, 0, 1); - - TQSpinBox *width, *height; - - height = new TQSpinBox(1, MAX_SIZE, 1, page); - grid->addWidget(height, 1, 0); - height->setValue(h); - connect(height, TQT_SIGNAL(valueChanged(int)), TQT_SLOT(setHeight(int))); - - width = new TQSpinBox(1, MAX_SIZE, 1, page); - grid->addWidget(width, 1, 1); - width->setValue(w); - connect(width, TQT_SIGNAL(valueChanged(int)), TQT_SLOT(setWidth(int))); - height->setFocus(); -} - -void MatrixDialog::setHeight(int value) -{ - h = value; -} - -void MatrixDialog::setWidth(int value) -{ - w = value; -} - -KFORMULA_NAMESPACE_END - -using namespace KFormula; -#include "MatrixDialog.moc" diff --git a/lib/kformula/MatrixDialog.cpp b/lib/kformula/MatrixDialog.cpp new file mode 100644 index 00000000..feac37ce --- /dev/null +++ b/lib/kformula/MatrixDialog.cpp @@ -0,0 +1,77 @@ +/* This file is part of the KDE libraries + Copyright (C) 1999 Ilya Baran (ibaran@mit.edu) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "MatrixDialog.h" +#include +#include +#include +#include +#include +#include + +KFORMULA_NAMESPACE_BEGIN + +const int DEFAULT_SIZE = 3; +const int MAX_SIZE = 200; + +MatrixDialog::MatrixDialog( TQWidget *parent, int _width, int _height ) + : KDialogBase(parent, "Matrix Dialog", true,i18n("Add Matrix"),Ok|Cancel) +{ + w = _width; + h = _height; + + TQLabel *rows, *columns; + TQWidget *page = new TQWidget( this ); + setMainWidget(page); + TQGridLayout *grid = new TQGridLayout(page, 4, 2, 10); + + rows = new TQLabel(i18n("Rows:"), page); + columns = new TQLabel(i18n("Columns:"), page); + + grid->addWidget(rows, 0, 0); + grid->addWidget(columns, 0, 1); + + TQSpinBox *width, *height; + + height = new TQSpinBox(1, MAX_SIZE, 1, page); + grid->addWidget(height, 1, 0); + height->setValue(h); + connect(height, TQT_SIGNAL(valueChanged(int)), TQT_SLOT(setHeight(int))); + + width = new TQSpinBox(1, MAX_SIZE, 1, page); + grid->addWidget(width, 1, 1); + width->setValue(w); + connect(width, TQT_SIGNAL(valueChanged(int)), TQT_SLOT(setWidth(int))); + height->setFocus(); +} + +void MatrixDialog::setHeight(int value) +{ + h = value; +} + +void MatrixDialog::setWidth(int value) +{ + w = value; +} + +KFORMULA_NAMESPACE_END + +using namespace KFormula; +#include "MatrixDialog.moc" diff --git a/lib/kformula/actionelement.cc b/lib/kformula/actionelement.cc deleted file mode 100644 index e1dce937..00000000 --- a/lib/kformula/actionelement.cc +++ /dev/null @@ -1,77 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2006 Alfredo Beaumont Sainz - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - -#include "creationstrategy.h" -#include "actionelement.h" - -KFORMULA_NAMESPACE_BEGIN - -ActionElement::ActionElement( BasicElement* parent ) : SequenceElement( parent ), - m_selection( 0 ) -{ -} - -bool ActionElement::readAttributesFromMathMLDom(const TQDomElement& element) -{ - if ( ! BasicElement::readAttributesFromMathMLDom( element ) ) { - return false; - } - - m_actionType = element.attribute( "actiontype" ); - TQString selectionStr = element.attribute( "selection" ); - if ( ! selectionStr.isNull() ) { - bool ok; - m_selection = selectionStr.toUInt( &ok ); - if ( ! ok ) m_selection = 0; - } - - return true; -} - -int ActionElement::buildChildrenFromMathMLDom(TQPtrList& list, TQDomNode n) -{ - if ( ! n.isElement() ) - return -1; - TQDomElement e = n.toElement(); - TQString tag = e.tagName().lower(); - BasicElement* child = getCreationStrategy()->createElement( tag, e ); - if ( child == 0 ) - return -1; - child->setParent( this ); - if ( child->buildFromMathMLDom( e ) == -1 ) { - delete child; - return -1; - } - list.append( child ); - parse(); - return 1; -} - -void ActionElement::writeMathMLAttributes( TQDomElement& element ) const -{ - if ( ! m_actionType.isNull() ) { - element.setAttribute( "actiontype", m_actionType ); - } - if ( m_selection ) { - element.setAttribute( "selection", TQString( "%1" ).arg( m_selection ) ); - } -} - - -KFORMULA_NAMESPACE_END diff --git a/lib/kformula/actionelement.cpp b/lib/kformula/actionelement.cpp new file mode 100644 index 00000000..e1dce937 --- /dev/null +++ b/lib/kformula/actionelement.cpp @@ -0,0 +1,77 @@ +/* This file is part of the KDE project + Copyright (C) 2006 Alfredo Beaumont Sainz + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "creationstrategy.h" +#include "actionelement.h" + +KFORMULA_NAMESPACE_BEGIN + +ActionElement::ActionElement( BasicElement* parent ) : SequenceElement( parent ), + m_selection( 0 ) +{ +} + +bool ActionElement::readAttributesFromMathMLDom(const TQDomElement& element) +{ + if ( ! BasicElement::readAttributesFromMathMLDom( element ) ) { + return false; + } + + m_actionType = element.attribute( "actiontype" ); + TQString selectionStr = element.attribute( "selection" ); + if ( ! selectionStr.isNull() ) { + bool ok; + m_selection = selectionStr.toUInt( &ok ); + if ( ! ok ) m_selection = 0; + } + + return true; +} + +int ActionElement::buildChildrenFromMathMLDom(TQPtrList& list, TQDomNode n) +{ + if ( ! n.isElement() ) + return -1; + TQDomElement e = n.toElement(); + TQString tag = e.tagName().lower(); + BasicElement* child = getCreationStrategy()->createElement( tag, e ); + if ( child == 0 ) + return -1; + child->setParent( this ); + if ( child->buildFromMathMLDom( e ) == -1 ) { + delete child; + return -1; + } + list.append( child ); + parse(); + return 1; +} + +void ActionElement::writeMathMLAttributes( TQDomElement& element ) const +{ + if ( ! m_actionType.isNull() ) { + element.setAttribute( "actiontype", m_actionType ); + } + if ( m_selection ) { + element.setAttribute( "selection", TQString( "%1" ).arg( m_selection ) ); + } +} + + +KFORMULA_NAMESPACE_END diff --git a/lib/kformula/basicelement.cc b/lib/kformula/basicelement.cc deleted file mode 100644 index 096814aa..00000000 --- a/lib/kformula/basicelement.cc +++ /dev/null @@ -1,400 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2001 Andrea Rizzi - Ulrich Kuettler - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - -#include -#include - -#include "contextstyle.h" -#include "basicelement.h" -#include "formulacursor.h" -#include "formulaelement.h" -#include "sequenceelement.h" - -KFORMULA_NAMESPACE_BEGIN -using namespace std; - - -int BasicElement::evilDestructionCount = 0; - -BasicElement::BasicElement( BasicElement* p ) - : parent( p ), m_baseline( 0 ), elementType( 0 ) -{ - setX( 0 ); - setY( 0 ); - setWidth( 0 ); - setHeight( 0 ); - evilDestructionCount++; -} - -BasicElement::~BasicElement() -{ - evilDestructionCount--; -} - -BasicElement::BasicElement( const BasicElement& other ) - : parent( 0 ), - m_baseline( other.m_baseline ), - elementType( other.elementType ) -{ - setX( other.getX() ); - setY( other.getY() ); - setWidth( other.getWidth() ); - setHeight( other.getHeight() ); - evilDestructionCount++; -} - - -bool BasicElement::readOnly( const BasicElement* /*child*/ ) const -{ - return parent->readOnly( this ); -} - - -FormulaElement* BasicElement::formula() -{ - //if ( parent != 0 ) { - return parent->formula(); - //} - //return 0; -} - - -/** - * Returns the element the point is in. - */ -BasicElement* BasicElement::goToPos( FormulaCursor*, bool&, - const LuPixelPoint& point, const LuPixelPoint& parentOrigin ) -{ - luPixel x = point.x() - (parentOrigin.x() + getX()); - if ((x >= 0) && (x < getWidth())) { - luPixel y = point.y() - (parentOrigin.y() + getY()); - if ((y >= 0) && (y < getHeight())) { - return this; - } - } - return 0; -} - -/** - * Returns our position inside the widget. - */ -LuPixelPoint BasicElement::widgetPos() -{ - luPixel x = 0; - luPixel y = 0; - for (BasicElement* element = this; element != 0; element = element->parent) { - x += element->getX(); - y += element->getY(); - } - return LuPixelPoint(x, y); -} - - -/** - * Sets the cursor inside this element to its start position. - * For most elements that is the main child. - */ -void BasicElement::goInside(FormulaCursor* cursor) -{ - BasicElement* mainChild = getMainChild(); - if (mainChild != 0) { - mainChild->goInside(cursor); - } -} - - -void BasicElement::entered( SequenceElement* /*child*/ ) -{ - formula()->tell( "" ); -} - - -/** - * Enters this element while moving to the left starting inside - * the element `from'. Searches for a cursor position inside - * this element or to the left of it. - */ -void BasicElement::moveLeft(FormulaCursor* cursor, BasicElement*) -{ - getParent()->moveLeft(cursor, this); -} - - -/** - * Enters this element while moving to the right starting inside - * the element `from'. Searches for a cursor position inside - * this element or to the right of it. - */ -void BasicElement::moveRight(FormulaCursor* cursor, BasicElement*) -{ - getParent()->moveRight(cursor, this); -} - - -/** - * Moves the cursor to a normal place where new elements - * might be inserted. - */ -void BasicElement::normalize(FormulaCursor* cursor, Direction direction) -{ - BasicElement* element = getMainChild(); - if (element != 0) { - if (direction == beforeCursor) { - element->moveLeft(cursor, this); - } - else { - element->moveRight(cursor, this); - } - } -} - - -TQDomElement BasicElement::getElementDom( TQDomDocument& doc) -{ - TQDomElement de = doc.createElement(getTagName()); - writeDom(de); - return de; -} - - -void BasicElement::writeMathML( TQDomDocument& doc, TQDomNode& parent, bool oasisFormat ) const -{ - TQDomElement de = doc.createElement( oasisFormat ? "math:" + getElementName() : getElementName() ); - writeMathMLAttributes( de ); - writeMathMLContent( doc, de, oasisFormat ); - parent.appendChild( de ); -} - -bool BasicElement::buildFromDom(TQDomElement element) -{ - if (element.tagName() != getTagName()) { - kdWarning( DEBUGID ) << "Wrong tag name " << element.tagName().latin1() << " for " << getTagName().latin1() << ".\n"; - return false; - } - if (!readAttributesFromDom(element)) { - return false; - } - TQDomNode node = element.firstChild(); - return readContentFromDom(node); -} - -int BasicElement::buildFromMathMLDom(TQDomElement element) -{/* - if (element.tagName() != getTagName()) { - kdWarning( DEBUGID ) << "Wrong tag name " << element.tagName().latin1() << " for " << getTagName().latin1() << ".\n"; - return false; - }*/ - if (!readAttributesFromMathMLDom(element)) { - return -1; - } - TQDomNode node = element.firstChild(); - return readContentFromMathMLDom(node); -} - -/** - * Appends our attributes to the dom element. - */ -void BasicElement::writeDom(TQDomElement) -{ -} - -/** - * Reads our attributes from the element. - * Returns false if it failed. - */ -bool BasicElement::readAttributesFromDom(TQDomElement) -{ - return true; -} - -/** - * Reads our content from the node. Sets the node to the next node - * that needs to be read. - * Returns false if it failed. - */ -bool BasicElement::readContentFromDom(TQDomNode&) -{ - return true; -} - -/** - * Returns a SequenceElement constructed from the nodes first child - * if the nodes name matches the given name. - */ -bool BasicElement::buildChild( SequenceElement* child, TQDomNode node, TQString name ) -{ - if (node.isElement()) { - TQDomElement e = node.toElement(); - if (e.tagName().upper() == name) { - TQDomNode nodeInner = e.firstChild(); - if (nodeInner.isElement()) { - TQDomElement element = nodeInner.toElement(); - return child->buildFromDom( element ); - } - } - } - return false; -} - -/** - * Reads our attributes from the MathML element. - * Returns false if it failed. - */ -bool BasicElement::readAttributesFromMathMLDom(const TQDomElement& ) -{ - return true; -} - -/** - * Reads our content from the MathML node. Sets the node to the next node - * that needs to be read. - * Returns false if it failed. - */ -int BasicElement::readContentFromMathMLDom(TQDomNode&) -{ - return 1; -} - -TQString BasicElement::toLatex() -{ - return "{}"; -} - -/** - * Utility function that sets the size type and returns the size value from - * a MathML attribute string with unit as defined in Section 2.4.4.2 - * - * @returns the size value - * - * @param str the attribute string. - * @param st size type container. It will be properly assigned to its size - * type or NoSize if str is invalid - */ -double BasicElement::getSize( const TQString& str, SizeType* st ) -{ - int index = str.find( "%" ); - if ( index != -1 ) { - return str2size( str, st, index, RelativeSize ) / 100.0; - } - index = str.find( "pt", 0, false ); - if ( index != -1 ) { - return str2size( str, st, index, AbsoluteSize ); - } - index = str.find( "mm", 0, false ); - if ( index != -1 ) { - return str2size( str, st, index, AbsoluteSize ) * 72.0 / 20.54; - } - index = str.find( "cm", 0, false ); - if ( index != -1 ) { - return str2size( str, st, index, AbsoluteSize ) * 72.0 / 2.54; - } - index = str.find( "in", 0, false ); - if ( index != -1 ) { - return str2size( str, st, index, AbsoluteSize ) * 72.0; - } - index = str.find( "em", 0, false ); - if ( index != -1 ) { - return str2size( str, st, index, RelativeSize ); - } - index = str.find( "ex", 0, false ); - if ( index != -1 ) { - return str2size( str, st, index, RelativeSize ); - } - index = str.find( "pc", 0, false ); - if ( index != -1 ) { - return str2size( str, st, index, AbsoluteSize ) * 12.0; - } - index = str.find( "px", 0, false ); - if ( index != -1 ) { - return str2size( str, st, index, PixelSize ); - } - // If there's no unit, assume 'pt' - return str2size( str, st, str.length(),AbsoluteSize ); -} - -SizeType BasicElement::getSpace( const TQString& str ) -{ - if ( str == "negativeveryverythinmathspace" ) { - return NegativeVeryVeryThinMathSpace; - } - if ( str == "negativeverythinmathspace" ) { - return NegativeVeryThinMathSpace; - } - if ( str == "negativethinmathspace" ) { - return NegativeThinMathSpace; - } - if ( str == "negativemediummathspace" ) { - return NegativeMediumMathSpace; - } - if ( str == "negativethickmathspace" ) { - return NegativeThickMathSpace; - } - if ( str == "negativeverythickmathspace" ) { - return NegativeVeryThickMathSpace; - } - if ( str == "negativeveryverythickmathspace" ) { - return NegativeVeryVeryThickMathSpace; - } - if ( str == "veryverythinmathspace" ) { - return VeryVeryThinMathSpace; - } - if ( str == "verythinmathspace" ) { - return VeryThinMathSpace; - } - if ( str == "thinmathspace" ) { - return ThinMathSpace; - } - if ( str == "mediummathspace" ) { - return MediumMathSpace; - } - if ( str == "thickmathspace" ) { - return ThickMathSpace; - } - if ( str == "verythickmathspace" ) { - return VeryThickMathSpace; - } - if ( str == "veryverythickmathspace" ) { - return VeryVeryThickMathSpace; - } - return NoSize; -} - - -/** - * Used internally by getSize() - */ -double BasicElement::str2size( const TQString& str, SizeType *st, uint index, SizeType type ) -{ - TQString num = str.left( index ); - bool ok; - double size = num.toDouble( &ok ); - if ( ok ) { - if ( st ) { - *st = type; - } - return size; - } - if ( st ) { - *st = NoSize; - } - return -1; -} - -KFORMULA_NAMESPACE_END diff --git a/lib/kformula/basicelement.cpp b/lib/kformula/basicelement.cpp new file mode 100644 index 00000000..096814aa --- /dev/null +++ b/lib/kformula/basicelement.cpp @@ -0,0 +1,400 @@ +/* This file is part of the KDE project + Copyright (C) 2001 Andrea Rizzi + Ulrich Kuettler + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include + +#include "contextstyle.h" +#include "basicelement.h" +#include "formulacursor.h" +#include "formulaelement.h" +#include "sequenceelement.h" + +KFORMULA_NAMESPACE_BEGIN +using namespace std; + + +int BasicElement::evilDestructionCount = 0; + +BasicElement::BasicElement( BasicElement* p ) + : parent( p ), m_baseline( 0 ), elementType( 0 ) +{ + setX( 0 ); + setY( 0 ); + setWidth( 0 ); + setHeight( 0 ); + evilDestructionCount++; +} + +BasicElement::~BasicElement() +{ + evilDestructionCount--; +} + +BasicElement::BasicElement( const BasicElement& other ) + : parent( 0 ), + m_baseline( other.m_baseline ), + elementType( other.elementType ) +{ + setX( other.getX() ); + setY( other.getY() ); + setWidth( other.getWidth() ); + setHeight( other.getHeight() ); + evilDestructionCount++; +} + + +bool BasicElement::readOnly( const BasicElement* /*child*/ ) const +{ + return parent->readOnly( this ); +} + + +FormulaElement* BasicElement::formula() +{ + //if ( parent != 0 ) { + return parent->formula(); + //} + //return 0; +} + + +/** + * Returns the element the point is in. + */ +BasicElement* BasicElement::goToPos( FormulaCursor*, bool&, + const LuPixelPoint& point, const LuPixelPoint& parentOrigin ) +{ + luPixel x = point.x() - (parentOrigin.x() + getX()); + if ((x >= 0) && (x < getWidth())) { + luPixel y = point.y() - (parentOrigin.y() + getY()); + if ((y >= 0) && (y < getHeight())) { + return this; + } + } + return 0; +} + +/** + * Returns our position inside the widget. + */ +LuPixelPoint BasicElement::widgetPos() +{ + luPixel x = 0; + luPixel y = 0; + for (BasicElement* element = this; element != 0; element = element->parent) { + x += element->getX(); + y += element->getY(); + } + return LuPixelPoint(x, y); +} + + +/** + * Sets the cursor inside this element to its start position. + * For most elements that is the main child. + */ +void BasicElement::goInside(FormulaCursor* cursor) +{ + BasicElement* mainChild = getMainChild(); + if (mainChild != 0) { + mainChild->goInside(cursor); + } +} + + +void BasicElement::entered( SequenceElement* /*child*/ ) +{ + formula()->tell( "" ); +} + + +/** + * Enters this element while moving to the left starting inside + * the element `from'. Searches for a cursor position inside + * this element or to the left of it. + */ +void BasicElement::moveLeft(FormulaCursor* cursor, BasicElement*) +{ + getParent()->moveLeft(cursor, this); +} + + +/** + * Enters this element while moving to the right starting inside + * the element `from'. Searches for a cursor position inside + * this element or to the right of it. + */ +void BasicElement::moveRight(FormulaCursor* cursor, BasicElement*) +{ + getParent()->moveRight(cursor, this); +} + + +/** + * Moves the cursor to a normal place where new elements + * might be inserted. + */ +void BasicElement::normalize(FormulaCursor* cursor, Direction direction) +{ + BasicElement* element = getMainChild(); + if (element != 0) { + if (direction == beforeCursor) { + element->moveLeft(cursor, this); + } + else { + element->moveRight(cursor, this); + } + } +} + + +TQDomElement BasicElement::getElementDom( TQDomDocument& doc) +{ + TQDomElement de = doc.createElement(getTagName()); + writeDom(de); + return de; +} + + +void BasicElement::writeMathML( TQDomDocument& doc, TQDomNode& parent, bool oasisFormat ) const +{ + TQDomElement de = doc.createElement( oasisFormat ? "math:" + getElementName() : getElementName() ); + writeMathMLAttributes( de ); + writeMathMLContent( doc, de, oasisFormat ); + parent.appendChild( de ); +} + +bool BasicElement::buildFromDom(TQDomElement element) +{ + if (element.tagName() != getTagName()) { + kdWarning( DEBUGID ) << "Wrong tag name " << element.tagName().latin1() << " for " << getTagName().latin1() << ".\n"; + return false; + } + if (!readAttributesFromDom(element)) { + return false; + } + TQDomNode node = element.firstChild(); + return readContentFromDom(node); +} + +int BasicElement::buildFromMathMLDom(TQDomElement element) +{/* + if (element.tagName() != getTagName()) { + kdWarning( DEBUGID ) << "Wrong tag name " << element.tagName().latin1() << " for " << getTagName().latin1() << ".\n"; + return false; + }*/ + if (!readAttributesFromMathMLDom(element)) { + return -1; + } + TQDomNode node = element.firstChild(); + return readContentFromMathMLDom(node); +} + +/** + * Appends our attributes to the dom element. + */ +void BasicElement::writeDom(TQDomElement) +{ +} + +/** + * Reads our attributes from the element. + * Returns false if it failed. + */ +bool BasicElement::readAttributesFromDom(TQDomElement) +{ + return true; +} + +/** + * Reads our content from the node. Sets the node to the next node + * that needs to be read. + * Returns false if it failed. + */ +bool BasicElement::readContentFromDom(TQDomNode&) +{ + return true; +} + +/** + * Returns a SequenceElement constructed from the nodes first child + * if the nodes name matches the given name. + */ +bool BasicElement::buildChild( SequenceElement* child, TQDomNode node, TQString name ) +{ + if (node.isElement()) { + TQDomElement e = node.toElement(); + if (e.tagName().upper() == name) { + TQDomNode nodeInner = e.firstChild(); + if (nodeInner.isElement()) { + TQDomElement element = nodeInner.toElement(); + return child->buildFromDom( element ); + } + } + } + return false; +} + +/** + * Reads our attributes from the MathML element. + * Returns false if it failed. + */ +bool BasicElement::readAttributesFromMathMLDom(const TQDomElement& ) +{ + return true; +} + +/** + * Reads our content from the MathML node. Sets the node to the next node + * that needs to be read. + * Returns false if it failed. + */ +int BasicElement::readContentFromMathMLDom(TQDomNode&) +{ + return 1; +} + +TQString BasicElement::toLatex() +{ + return "{}"; +} + +/** + * Utility function that sets the size type and returns the size value from + * a MathML attribute string with unit as defined in Section 2.4.4.2 + * + * @returns the size value + * + * @param str the attribute string. + * @param st size type container. It will be properly assigned to its size + * type or NoSize if str is invalid + */ +double BasicElement::getSize( const TQString& str, SizeType* st ) +{ + int index = str.find( "%" ); + if ( index != -1 ) { + return str2size( str, st, index, RelativeSize ) / 100.0; + } + index = str.find( "pt", 0, false ); + if ( index != -1 ) { + return str2size( str, st, index, AbsoluteSize ); + } + index = str.find( "mm", 0, false ); + if ( index != -1 ) { + return str2size( str, st, index, AbsoluteSize ) * 72.0 / 20.54; + } + index = str.find( "cm", 0, false ); + if ( index != -1 ) { + return str2size( str, st, index, AbsoluteSize ) * 72.0 / 2.54; + } + index = str.find( "in", 0, false ); + if ( index != -1 ) { + return str2size( str, st, index, AbsoluteSize ) * 72.0; + } + index = str.find( "em", 0, false ); + if ( index != -1 ) { + return str2size( str, st, index, RelativeSize ); + } + index = str.find( "ex", 0, false ); + if ( index != -1 ) { + return str2size( str, st, index, RelativeSize ); + } + index = str.find( "pc", 0, false ); + if ( index != -1 ) { + return str2size( str, st, index, AbsoluteSize ) * 12.0; + } + index = str.find( "px", 0, false ); + if ( index != -1 ) { + return str2size( str, st, index, PixelSize ); + } + // If there's no unit, assume 'pt' + return str2size( str, st, str.length(),AbsoluteSize ); +} + +SizeType BasicElement::getSpace( const TQString& str ) +{ + if ( str == "negativeveryverythinmathspace" ) { + return NegativeVeryVeryThinMathSpace; + } + if ( str == "negativeverythinmathspace" ) { + return NegativeVeryThinMathSpace; + } + if ( str == "negativethinmathspace" ) { + return NegativeThinMathSpace; + } + if ( str == "negativemediummathspace" ) { + return NegativeMediumMathSpace; + } + if ( str == "negativethickmathspace" ) { + return NegativeThickMathSpace; + } + if ( str == "negativeverythickmathspace" ) { + return NegativeVeryThickMathSpace; + } + if ( str == "negativeveryverythickmathspace" ) { + return NegativeVeryVeryThickMathSpace; + } + if ( str == "veryverythinmathspace" ) { + return VeryVeryThinMathSpace; + } + if ( str == "verythinmathspace" ) { + return VeryThinMathSpace; + } + if ( str == "thinmathspace" ) { + return ThinMathSpace; + } + if ( str == "mediummathspace" ) { + return MediumMathSpace; + } + if ( str == "thickmathspace" ) { + return ThickMathSpace; + } + if ( str == "verythickmathspace" ) { + return VeryThickMathSpace; + } + if ( str == "veryverythickmathspace" ) { + return VeryVeryThickMathSpace; + } + return NoSize; +} + + +/** + * Used internally by getSize() + */ +double BasicElement::str2size( const TQString& str, SizeType *st, uint index, SizeType type ) +{ + TQString num = str.left( index ); + bool ok; + double size = num.toDouble( &ok ); + if ( ok ) { + if ( st ) { + *st = type; + } + return size; + } + if ( st ) { + *st = NoSize; + } + return -1; +} + +KFORMULA_NAMESPACE_END diff --git a/lib/kformula/bracketelement.cc b/lib/kformula/bracketelement.cc deleted file mode 100644 index 45aa5469..00000000 --- a/lib/kformula/bracketelement.cc +++ /dev/null @@ -1,1005 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2001 Andrea Rizzi - Ulrich Kuettler - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - -#include -#include -#include -#include - -#include -#include - -#include "bracketelement.h" -#include "elementvisitor.h" -#include "fontstyle.h" -#include "formulacursor.h" -#include "formulaelement.h" -#include "sequenceelement.h" - -KFORMULA_NAMESPACE_BEGIN - -SingleContentElement::SingleContentElement(BasicElement* parent ) - : BasicElement( parent ) -{ - content = new SequenceElement( this ); -} - - -SingleContentElement::SingleContentElement( const SingleContentElement& other ) - : BasicElement( other ) -{ - content = new SequenceElement( other.content ); - content->setParent( this ); -} - - -SingleContentElement::~SingleContentElement() -{ - delete content; -} - - -TQChar SingleContentElement::getCharacter() const -{ - // This is meant to make the SingleContentElement text only. - // This "fixes" the parenthesis problem (parenthesis too large). - // I'm not sure if we really want this. There should be better ways. - if ( content->isTextOnly() ) { - return '\\'; - } - return content->getCharacter(); -} - -BasicElement* SingleContentElement::goToPos( FormulaCursor* cursor, bool& handled, - const LuPixelPoint& point, const LuPixelPoint& parentOrigin ) -{ - BasicElement* e = BasicElement::goToPos(cursor, handled, point, parentOrigin); - if (e != 0) { - LuPixelPoint myPos(parentOrigin.x() + getX(), - parentOrigin.y() + getY()); - - e = content->goToPos(cursor, handled, point, myPos); - if (e != 0) { - return e; - } - return this; - } - return 0; -} - -void SingleContentElement::dispatchFontCommand( FontCommand* cmd ) -{ - content->dispatchFontCommand( cmd ); -} - -void SingleContentElement::moveLeft(FormulaCursor* cursor, BasicElement* from) -{ - if (cursor->isSelectionMode()) { - getParent()->moveLeft(cursor, this); - } - else { - //bool linear = cursor->getLinearMovement(); - if (from == getParent()) { - content->moveLeft(cursor, this); - } - else { - getParent()->moveLeft(cursor, this); - } - } -} - -void SingleContentElement::moveRight(FormulaCursor* cursor, BasicElement* from) -{ - if (cursor->isSelectionMode()) { - getParent()->moveRight(cursor, this); - } - else { - //bool linear = cursor->getLinearMovement(); - if (from == getParent()) { - content->moveRight(cursor, this); - } - else { - getParent()->moveRight(cursor, this); - } - } -} - -void SingleContentElement::moveUp(FormulaCursor* cursor, BasicElement* /*from*/) -{ - getParent()->moveUp(cursor, this); -} - -void SingleContentElement::moveDown(FormulaCursor* cursor, BasicElement* /*from*/) -{ - getParent()->moveDown(cursor, this); -} - -void SingleContentElement::remove( FormulaCursor* cursor, - TQPtrList& removedChildren, - Direction direction ) -{ - switch (cursor->getPos()) { - case contentPos: - BasicElement* parent = getParent(); - parent->selectChild(cursor, this); - parent->remove(cursor, removedChildren, direction); - } -} - -void SingleContentElement::normalize( FormulaCursor* cursor, Direction direction ) -{ - if (direction == beforeCursor) { - content->moveLeft(cursor, this); - } - else { - content->moveRight(cursor, this); - } -} - -SequenceElement* SingleContentElement::getMainChild() -{ - return content; -} - -void SingleContentElement::selectChild(FormulaCursor* cursor, BasicElement* child) -{ - if (child == content) { - cursor->setTo(this, contentPos); - } -} - -void SingleContentElement::writeDom(TQDomElement element) -{ - BasicElement::writeDom(element); - - TQDomDocument doc = element.ownerDocument(); - - TQDomElement con = doc.createElement("CONTENT"); - con.appendChild(content->getElementDom(doc)); - element.appendChild(con); -} - -bool SingleContentElement::readContentFromDom(TQDomNode& node) -{ - if (!BasicElement::readContentFromDom(node)) { - return false; - } - - if ( !buildChild( content, node, "CONTENT" ) ) { - kdWarning( DEBUGID ) << "Empty content in " << getTagName() << endl; - return false; - } - node = node.nextSibling(); - - return true; -} - -int SingleContentElement::readContentFromMathMLDom( TQDomNode& node ) -{ - if ( BasicElement::readContentFromMathMLDom( node ) == -1 ) { - return -1; - } - - int nodeCounter = content->buildMathMLChild( node ); - if ( nodeCounter == -1 ) { - kdWarning( DEBUGID) << "Empty content in SingleContentElement\n"; - return -1; - } - - return nodeCounter; -} - -void SingleContentElement::writeMathMLContent( TQDomDocument& doc, TQDomElement& element, bool oasisFormat ) const -{ - content->writeMathML( doc, element, oasisFormat ); -} - - - -BracketElement::BracketElement(SymbolType l, SymbolType r, BasicElement* parent) - : SingleContentElement(parent), - left( 0 ), right( 0 ), - leftType( l ), rightType( r ), - m_operator( false ), m_customLeft( false ), m_customRight( false ) -{ -} - - -BracketElement::~BracketElement() -{ - delete left; - delete right; -} - - -BracketElement::BracketElement( const BracketElement& other ) - : SingleContentElement( other ), - left( 0 ), right( 0 ), - leftType( other.leftType ), rightType( other.rightType ), - m_operator( other.m_operator ), - m_customLeft( other.m_customLeft ), m_customRight( other.m_customRight ) -{ -} - - -bool BracketElement::accept( ElementVisitor* visitor ) -{ - return visitor->visit( this ); -} - - -void BracketElement::entered( SequenceElement* /*child*/ ) -{ - formula()->tell( i18n( "Delimited list" ) ); -} - - -BasicElement* BracketElement::goToPos( FormulaCursor* cursor, bool& handled, - const LuPixelPoint& point, const LuPixelPoint& parentOrigin ) -{ - BasicElement* e = BasicElement::goToPos(cursor, handled, point, parentOrigin); - if (e != 0) { - LuPixelPoint myPos(parentOrigin.x() + getX(), - parentOrigin.y() + getY()); - e = getContent()->goToPos(cursor, handled, point, myPos); - if (e != 0) { - return e; - } - - // We are in one of those gaps. - luPixel dx = point.x() - myPos.x(); - luPixel dy = point.y() - myPos.y(); - - if ((dx > getContent()->getX()+getContent()->getWidth()) || - (dy > getContent()->getY()+getContent()->getHeight())) { - getContent()->moveEnd(cursor); - handled = true; - return getContent(); - } - return this; - } - return 0; -} - - -/** - * Calculates our width and height and - * our children's parentPosition. - */ -void BracketElement::calcSizes( const ContextStyle& context, - ContextStyle::TextStyle tstyle, - ContextStyle::IndexStyle istyle, - StyleAttributes& style ) -{ - SequenceElement* content = getContent(); - content->calcSizes( context, tstyle, istyle, style ); - - //if ( left == 0 ) { - delete left; - delete right; - left = context.fontStyle().createArtwork( leftType ); - right = context.fontStyle().createArtwork( rightType ); - //} - - double factor = style.sizeFactor(); - if (content->isTextOnly()) { - left->calcSizes(context, tstyle, factor); - right->calcSizes(context, tstyle, factor); - - setBaseline(TQMAX(content->getBaseline(), - TQMAX(left->getBaseline(), right->getBaseline()))); - - content->setY(getBaseline() - content->getBaseline()); - left ->setY(getBaseline() - left ->getBaseline()); - right ->setY(getBaseline() - right ->getBaseline()); - - //setMidline(content->getY() + content->getMidline()); - setHeight(TQMAX(content->getY() + content->getHeight(), - TQMAX(left ->getY() + left ->getHeight(), - right->getY() + right->getHeight()))); - } - else { - //kdDebug( DEBUGID ) << "BracketElement::calcSizes " << content->axis( context, tstyle ) << " " << content->getHeight() << endl; - luPixel contentHeight = 2 * TQMAX( content->axis( context, tstyle, factor ), - content->getHeight() - content->axis( context, tstyle, factor ) ); - left->calcSizes( context, tstyle, factor, contentHeight ); - right->calcSizes( context, tstyle, factor, contentHeight ); - - // height - setHeight(TQMAX(contentHeight, - TQMAX(left->getHeight(), right->getHeight()))); - //setMidline(getHeight() / 2); - - content->setY(getHeight() / 2 - content->axis( context, tstyle, factor )); - setBaseline(content->getBaseline() + content->getY()); - - if ( left->isNormalChar() ) { - left->setY(getBaseline() - left->getBaseline()); - } - else { - left->setY((getHeight() - left->getHeight())/2); - } - if ( right->isNormalChar() ) { - right->setY(getBaseline() - right->getBaseline()); - } - else { - right->setY((getHeight() - right->getHeight())/2); - } - -// kdDebug() << "BracketElement::calcSizes" << endl -// << "getHeight(): " << getHeight() << endl -// << "left->getHeight(): " << left->getHeight() << endl -// << "right->getHeight(): " << right->getHeight() << endl -// << "left->getY(): " << left->getY() << endl -// << "right->getY(): " << right->getY() << endl -// << endl; - } - - // width - setWidth(left->getWidth() + content->getWidth() + right->getWidth()); - content->setX(left->getWidth()); - right ->setX(left->getWidth()+content->getWidth()); -} - - -/** - * Draws the whole element including its children. - * The `parentOrigin' is the point this element's parent starts. - * We can use our parentPosition to get our own origin then. - */ -void BracketElement::draw( TQPainter& painter, const LuPixelRect& r, - const ContextStyle& context, - ContextStyle::TextStyle tstyle, - ContextStyle::IndexStyle istyle, - StyleAttributes& style, - const LuPixelPoint& parentOrigin ) -{ - LuPixelPoint myPos( parentOrigin.x()+getX(), parentOrigin.y()+getY() ); - //if ( !LuPixelRect( myPos.x(), myPos.y(), getWidth(), getHeight() ).intersects( r ) ) - // return; - - SequenceElement* content = getContent(); - content->draw(painter, r, context, tstyle, istyle, style, myPos); - - if (content->isTextOnly()) { - left->draw(painter, r, context, tstyle, style, myPos); - right->draw(painter, r, context, tstyle, style, myPos); - } - else { - double factor = style.sizeFactor(); - luPixel contentHeight = 2 * TQMAX(content->axis( context, tstyle, factor ), - content->getHeight() - content->axis( context, tstyle, factor )); - left->draw(painter, r, context, tstyle, style, contentHeight, myPos); - right->draw(painter, r, context, tstyle, style, contentHeight, myPos); - } - - // Debug -#if 0 - painter.setBrush( TQt::NoBrush ); - painter.setPen( TQt::red ); - painter.drawRect( context.layoutUnitToPixelX( myPos.x()+left->getX() ), - context.layoutUnitToPixelY( myPos.y()+left->getY() ), - context.layoutUnitToPixelX( left->getWidth() ), - context.layoutUnitToPixelY( left->getHeight() ) ); - painter.drawRect( context.layoutUnitToPixelX( myPos.x()+right->getX() ), - context.layoutUnitToPixelY( myPos.y()+right->getY() ), - context.layoutUnitToPixelX( right->getWidth() ), - context.layoutUnitToPixelY( right->getHeight() ) ); -#endif -} - - -/** - * Appends our attributes to the dom element. - */ -void BracketElement::writeDom(TQDomElement element) -{ - SingleContentElement::writeDom(element); - element.setAttribute("LEFT", leftType); - element.setAttribute("RIGHT", rightType); -} - -/** - * Reads our attributes from the element. - * Returns false if it failed. - */ -bool BracketElement::readAttributesFromDom(TQDomElement element) -{ - if (!BasicElement::readAttributesFromDom(element)) { - return false; - } - TQString leftStr = element.attribute("LEFT"); - if(!leftStr.isNull()) { - leftType = static_cast(leftStr.toInt()); - } - TQString rightStr = element.attribute("RIGHT"); - if(!rightStr.isNull()) { - rightType = static_cast(rightStr.toInt()); - } - return true; -} - -/** - * Reads our attributes from the MathML element. - * Returns false if it failed. - */ -bool BracketElement::readAttributesFromMathMLDom(const TQDomElement& element) -{ - if ( !BasicElement::readAttributesFromMathMLDom( element ) ) { - return false; - } - - if ( element.tagName().lower() == "mo" ) { - m_operator = true; - // TODO: parse attributes in section 3.2.5.2 - } - else { // mfenced, see attributes in section 3.3.8.2 - leftType = LeftRoundBracket; - rightType = RightRoundBracket; - TQString openStr = element.attribute( "open" ).stripWhiteSpace(); - if ( !openStr.isNull() ) { - m_customLeft = true; - if ( openStr == "[" ) - leftType = LeftSquareBracket; - else if ( openStr == "]" ) - leftType = RightSquareBracket; - else if ( openStr == "{" ) - leftType = LeftCurlyBracket; - else if ( openStr == "}" ) - leftType = RightCurlyBracket; - else if ( openStr == "<" ) - leftType = LeftCornerBracket; - else if ( openStr == ">" ) - leftType = RightCornerBracket; - else if ( openStr == "(" ) - leftType = LeftRoundBracket; - else if ( openStr == ")" ) - leftType = RightRoundBracket; - else if ( openStr == "/" ) - leftType = SlashBracket; - else if ( openStr == "\\" ) - leftType = BackSlashBracket; - else // TODO: Check for entity references - leftType = LeftRoundBracket; - } - TQString closeStr = element.attribute( "close" ).stripWhiteSpace(); - if ( !closeStr.isNull() ) { - m_customRight = true; - if ( closeStr == "[" ) - rightType = LeftSquareBracket; - else if ( closeStr == "]" ) - rightType = RightSquareBracket; - else if ( closeStr == "{" ) - rightType = LeftCurlyBracket; - else if ( closeStr == "}" ) - rightType = RightCurlyBracket; - else if ( closeStr == "<" ) - rightType = LeftCornerBracket; - else if ( closeStr == ">" ) - rightType = RightCornerBracket; - else if ( closeStr == "(" ) - rightType = LeftRoundBracket; - else if ( closeStr == ")" ) - rightType = RightRoundBracket; - else if ( closeStr == "/" ) - rightType = SlashBracket; - else if ( closeStr == "\\" ) - rightType = BackSlashBracket; - else // TODO: Check for entity references - rightType = LeftRoundBracket; - } - m_separators = element.attribute( "separators" ).simplifyWhiteSpace(); - } - return true; -} - -/** - * Reads our content from the MathML node. Sets the node to the next node - * that needs to be read. - * Returns false if it failed. - */ -int BracketElement::readContentFromMathMLDom(TQDomNode& node) -{ - bool empty = false; - int nodeCounter = 0; - if ( m_operator ) { - node = node.parentNode(); - TQDomNode open = node; - TQDomNode parent = node.parentNode(); - if ( ! operatorType( node, true ) ) - return -1; - int nodeNum = searchOperator( node ); - if ( nodeNum == -1 ) // Closing bracket not found - return -1; - if ( nodeNum == 0 ) { // Empty content - empty = true; - } - else if ( nodeNum == 1 ) { - do { - node = node.nextSibling(); - nodeCounter++; - } while ( ! node.isElement() ); - } - else { // More than two elements inside, infer a mrow - nodeCounter += nodeNum; - kdWarning() << "NodeNum: " << nodeNum << endl; - TQDomDocument doc = node.ownerDocument(); - TQDomElement de = doc.createElement( "mrow" ); - int i = 0; - do { - TQDomNode n = node.nextSibling(); - de.appendChild( node.toElement() ); - node = n; - } while ( ++i < nodeNum ); - parent.insertAfter( de, open ); - node = de; - kdWarning() << doc.toString() << endl; - } - } - else { - // if it's a mfence tag, we need to convert to equivalent expanded form. - // See section 3.3.8 - while ( ! node.isNull() && ! node.isElement() ) - node = node.nextSibling(); - TQDomNode next = node.nextSibling(); - while ( ! next.isNull() && ! next.isElement() ) - next = next.nextSibling(); - if ( ! next.isNull()) { - TQDomDocument doc = node.ownerDocument(); - TQDomNode parent = node.parentNode(); - TQString ns = parent.prefix(); - TQDomElement de = doc.createElementNS( ns, "mrow" ); - uint pos = 0; - while ( ! node.isNull() ) { - TQDomNode no = node.nextSibling(); - while ( ! no.isNull() && ! no.isElement() ) - no = no.nextSibling(); - de.appendChild( node.toElement() ); - if ( ! no.isNull() && ( m_separators.isNull() || ! m_separators.isEmpty() ) ) { - TQDomElement sep = doc.createElementNS( ns, "mo" ); - de.appendChild( sep ); - if ( m_separators.isNull() ) { - sep.appendChild( doc.createTextNode( "," ) ); - } - else { - if ( m_separators.at( pos ).isSpace() ) { - pos++; - } - sep.appendChild( doc.createTextNode( TQString ( m_separators.at( pos ) ) ) ); - } - if ( pos < m_separators.length() - 1 ) { - pos++; - } - } - node = no; - } - parent.appendChild( de ); - node = parent.firstChild(); - while ( ! node.isElement() ) - node = node.nextSibling(); - } - } - if ( ! empty ) { - int contentNumber = inherited::readContentFromMathMLDom( node ); - if ( contentNumber == -1 ) - return -1; - nodeCounter += contentNumber; - for (int i = 0; i < contentNumber; i++ ) { - if ( node.isNull() ) { - return -1; - } - node = node.nextSibling(); - } - } - if ( m_operator ) { - int operatorNumber = operatorType( node, false ); - if ( operatorNumber == -1 ) { - return -1; - } - nodeCounter += operatorNumber; - } - kdDebug( DEBUGID ) << "Number of bracket nodes: " << nodeCounter << endl; - return nodeCounter; -} - -TQString BracketElement::toLatex() -{ - TQString ls,rs,cs; - cs=getContent()->toLatex(); - ls="\\left"+latexString(leftType) + " "; - rs=" \\right"+latexString(rightType); - - return ls+cs+rs; -} - -TQString BracketElement::latexString(char type) -{ - switch (type) { - case ']': - return "]"; - case '[': - return "["; - case '{': - return "\\{"; - case '}': - return "\\}"; - case '(': - return "("; - case ')': - return ")"; - case '|': - return "|"; - case '<': - return "\\langle"; - case '>': - return "\\rangle"; - case '/': - return "/"; - case '\\': - return "\\backslash"; - } - return "."; -} - -TQString BracketElement::formulaString() -{ - return "(" + getContent()->formulaString() + ")"; -} - -int BracketElement::operatorType( TQDomNode& node, bool open ) -{ - int counter = 1; - SymbolType* type = open ? &leftType : &rightType; - while ( ! node.isNull() && ! node.isElement() ) { - node = node.nextSibling(); - counter++; - } - if ( node.isElement() ) { - TQDomElement e = node.toElement(); - TQDomNode child = e.firstChild(); - if ( child.isEntityReference() ) { - kdWarning() << "Entity Reference\n"; - TQString name = node.nodeName(); - // TODO: To fully support these, SymbolType has to be extended, - // and better Unicode support is a must - // CloseCurlyDoubleQuote 0x201D - // CloseCurlyQoute 0x2019 - // LeftCeiling 0x2308 - // LeftDoubleBracket 0x301A - // LeftFloor 0x230A - // OpenCurlyDoubleQuote 0x201C - // OpenCurlyQuote 0x2018 - // RightCeiling 0x2309 - // RightDoubleBracket 0x301B - // RightFloor 0x230B - if ( name == "LeftAngleBracket" ) { - *type = LeftCornerBracket; - } - else if ( name == "RightAngleBracket" ) { - *type = RightCornerBracket; - } - else { - if ( open ) { - *type = LeftRoundBracket; - } - else - *type = RightRoundBracket; - } - } - else { - TQString s = e.text(); - if ( s.isNull() ) - return -1; - *type = static_cast( TQString::number( s.at( 0 ).latin1() ).toInt() ); - } - } - else { - return -1; - } - return counter; -} - -int BracketElement::searchOperator( const TQDomNode& node ) -{ - TQDomNode n = node; - for ( int i = -2; ! n.isNull(); n = n.nextSibling() ) { - if ( n.isElement() ) { - i++; - TQDomElement e = n.toElement(); - if ( e.tagName().lower() == "mo" ) { - // Try to guess looking at attributes - TQString form = e.attribute( "form" ); - TQString f; - if ( ! form.isNull() ) { - f = form.stripWhiteSpace().lower(); - } - TQString fence = e.attribute( "fence" ); - if ( ! fence.isNull() ) { - if ( fence.stripWhiteSpace().lower() == "false" ) { - continue; - } - if ( ! f.isNull() ) { - if ( f == "postfix" ) { - return i; - } - else { - continue; - } - } - } - - // Guess looking at contents - TQDomNode child = e.firstChild(); - TQString name; - if ( child.isText() ) - name = child.toText().data().stripWhiteSpace(); - else if ( child.isEntityReference() ) - name = child.nodeName(); - else - continue; - if ( name == ")" - || name == "]" - || name == "}" - || name == "CloseCurlyDoubleQuote" - || name == "CloseCurlyQuote" - || name == "RightAngleBracket" - || name == "RightCeiling" - || name == "RightDoubleBracket" - || name == "RightFloor" ) { - if ( f.isNull() || f == "postfix" ) - return i; - } - if ( name == "(" - || name == "[" - || name == "{" - || name == "LeftAngleBracket" - || name == "LeftCeiling" - || name == "LeftDoubleBracket" - || name == "LeftFloor" - || name == "OpenCurlyQuote" ) { - if ( ! f.isNull() && f == "postfix" ) - return i; - } - } - } - } - return -1; -} - - -void BracketElement::writeMathMLAttributes( TQDomElement& element ) const -{ - if ( left->getType() != LeftRoundBracket || - right->getType() != RightRoundBracket ) - { - element.setAttribute( "open", TQString( TQChar( leftType ) ) ); - element.setAttribute( "close", TQString( TQChar( rightType ) ) ); - } - if ( ! m_separators.isNull() ) { - element.setAttribute( "separators", m_separators ); - } -} - -OverlineElement::OverlineElement( BasicElement* parent ) - : SingleContentElement( parent ) -{ -} - -OverlineElement::~OverlineElement() -{ -} - -OverlineElement::OverlineElement( const OverlineElement& other ) - : SingleContentElement( other ) -{ -} - - -bool OverlineElement::accept( ElementVisitor* visitor ) -{ - return visitor->visit( this ); -} - - -void OverlineElement::entered( SequenceElement* /*child*/ ) -{ - formula()->tell( i18n( "Overline" ) ); -} - - -void OverlineElement::calcSizes( const ContextStyle& context, - ContextStyle::TextStyle tstyle, - ContextStyle::IndexStyle istyle, - StyleAttributes& style ) -{ - SequenceElement* content = getContent(); - content->calcSizes(context, tstyle, - context.convertIndexStyleLower(istyle), style ); - - //luPixel distX = context.ptToPixelX( context.getThinSpace( tstyle, style.sizeFactor() ) ); - luPixel distY = context.ptToPixelY( context.getThinSpace( tstyle, style.sizeFactor() ) ); - //luPixel unit = (content->getHeight() + distY)/ 3; - - setWidth( content->getWidth() ); - setHeight( content->getHeight() + distY ); - - content->setX( 0 ); - content->setY( distY ); - setBaseline(content->getBaseline() + content->getY()); -} - -void OverlineElement::draw( TQPainter& painter, const LuPixelRect& r, - const ContextStyle& context, - ContextStyle::TextStyle tstyle, - ContextStyle::IndexStyle istyle, - StyleAttributes& style, - const LuPixelPoint& parentOrigin ) -{ - LuPixelPoint myPos( parentOrigin.x()+getX(), parentOrigin.y()+getY() ); - //if ( !LuPixelRect( myPos.x(), myPos.y(), getWidth(), getHeight() ).intersects( r ) ) - // return; - - SequenceElement* content = getContent(); - content->draw( painter, r, context, tstyle, - context.convertIndexStyleLower( istyle ), style, myPos ); - - luPixel x = myPos.x(); - luPixel y = myPos.y(); - //int distX = context.getDistanceX(tstyle); - double factor = style.sizeFactor(); - luPixel distY = context.ptToPixelY( context.getThinSpace( tstyle, factor ) ); - //luPixel unit = (content->getHeight() + distY)/ 3; - - painter.setPen( TQPen( context.getDefaultColor(), - context.layoutUnitToPixelY( context.getLineWidth( factor ) ) ) ); - - painter.drawLine( context.layoutUnitToPixelX( x ), - context.layoutUnitToPixelY( y+distY/3 ), - context.layoutUnitToPixelX( x+content->getWidth() ), - context.layoutUnitToPixelY( y+distY/3 ) ); -} - - -TQString OverlineElement::toLatex() -{ - return "\\overline{" + getContent()->toLatex() + "}"; -} - -TQString OverlineElement::formulaString() -{ - return getContent()->formulaString(); -} - -void OverlineElement::writeMathML( TQDomDocument& doc, TQDomNode& parent, bool oasisFormat ) const -{ - TQDomElement de = doc.createElement( oasisFormat ? "math:mover" : "mover" ); - SingleContentElement::writeMathML( doc, de, oasisFormat ); - TQDomElement op = doc.createElement( oasisFormat ? "math:mo" : "mo" ); - // is this the right entity? Mozilla renders it correctly. - op.appendChild( doc.createEntityReference( "OverBar" ) ); - de.appendChild( op ); - parent.appendChild( de ); -} - - -UnderlineElement::UnderlineElement( BasicElement* parent ) - : SingleContentElement( parent ) -{ -} - -UnderlineElement::~UnderlineElement() -{ -} - - -UnderlineElement::UnderlineElement( const UnderlineElement& other ) - : SingleContentElement( other ) -{ -} - - -bool UnderlineElement::accept( ElementVisitor* visitor ) -{ - return visitor->visit( this ); -} - - -void UnderlineElement::entered( SequenceElement* /*child*/ ) -{ - formula()->tell( i18n( "Underline" ) ); -} - - -void UnderlineElement::calcSizes( const ContextStyle& context, - ContextStyle::TextStyle tstyle, - ContextStyle::IndexStyle istyle, - StyleAttributes& style ) -{ - SequenceElement* content = getContent(); - double factor = style.sizeFactor(); - content->calcSizes(context, tstyle, - context.convertIndexStyleLower(istyle), style ); - - //luPixel distX = context.ptToPixelX( context.getThinSpace( tstyle ) ); - luPixel distY = context.ptToPixelY( context.getThinSpace( tstyle, factor ) ); - //luPixel unit = (content->getHeight() + distY)/ 3; - - setWidth( content->getWidth() ); - setHeight( content->getHeight() + distY ); - - content->setX( 0 ); - content->setY( 0 ); - setBaseline(content->getBaseline() + content->getY()); -} - -void UnderlineElement::draw( TQPainter& painter, const LuPixelRect& r, - const ContextStyle& context, - ContextStyle::TextStyle tstyle, - ContextStyle::IndexStyle istyle, - StyleAttributes& style, - const LuPixelPoint& parentOrigin ) -{ - LuPixelPoint myPos( parentOrigin.x()+getX(), parentOrigin.y()+getY() ); - //if ( !LuPixelRect( myPos.x(), myPos.y(), getWidth(), getHeight() ).intersects( r ) ) - // return; - - SequenceElement* content = getContent(); - content->draw( painter, r, context, tstyle, - context.convertIndexStyleLower( istyle ), style, myPos ); - - luPixel x = myPos.x(); - luPixel y = myPos.y(); - //int distX = context.getDistanceX(tstyle); - //luPixel distY = context.ptToPixelY( context.getThinSpace( tstyle ) ); - //luPixel unit = (content->getHeight() + distY)/ 3; - - double factor = style.sizeFactor(); - painter.setPen( TQPen( context.getDefaultColor(), - context.layoutUnitToPixelY( context.getLineWidth( factor ) ) ) ); - - painter.drawLine( context.layoutUnitToPixelX( x ), - context.layoutUnitToPixelY( y+getHeight()-context.getLineWidth( factor ) ), - context.layoutUnitToPixelX( x+content->getWidth() ), - context.layoutUnitToPixelY( y+getHeight()-context.getLineWidth( factor ) ) ); -} - - -TQString UnderlineElement::toLatex() -{ - return "\\underline{" + getContent()->toLatex() + "}"; -} - -TQString UnderlineElement::formulaString() -{ - return getContent()->formulaString(); -} - -void UnderlineElement::writeMathML( TQDomDocument& doc, TQDomNode& parent, bool oasisFormat ) const -{ - TQDomElement de = doc.createElement( oasisFormat ? "math:munder" : "munder" ); - SingleContentElement::writeMathML( doc, de, oasisFormat ); - TQDomElement op = doc.createElement( oasisFormat ? "math:mo" : "mo" ); - // is this the right entity? Mozilla renders it correctly. - op.appendChild( doc.createEntityReference( "UnderBar" ) ); - de.appendChild( op ); - parent.appendChild( de ); -} - -KFORMULA_NAMESPACE_END diff --git a/lib/kformula/bracketelement.cpp b/lib/kformula/bracketelement.cpp new file mode 100644 index 00000000..45aa5469 --- /dev/null +++ b/lib/kformula/bracketelement.cpp @@ -0,0 +1,1005 @@ +/* This file is part of the KDE project + Copyright (C) 2001 Andrea Rizzi + Ulrich Kuettler + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include +#include + +#include +#include + +#include "bracketelement.h" +#include "elementvisitor.h" +#include "fontstyle.h" +#include "formulacursor.h" +#include "formulaelement.h" +#include "sequenceelement.h" + +KFORMULA_NAMESPACE_BEGIN + +SingleContentElement::SingleContentElement(BasicElement* parent ) + : BasicElement( parent ) +{ + content = new SequenceElement( this ); +} + + +SingleContentElement::SingleContentElement( const SingleContentElement& other ) + : BasicElement( other ) +{ + content = new SequenceElement( other.content ); + content->setParent( this ); +} + + +SingleContentElement::~SingleContentElement() +{ + delete content; +} + + +TQChar SingleContentElement::getCharacter() const +{ + // This is meant to make the SingleContentElement text only. + // This "fixes" the parenthesis problem (parenthesis too large). + // I'm not sure if we really want this. There should be better ways. + if ( content->isTextOnly() ) { + return '\\'; + } + return content->getCharacter(); +} + +BasicElement* SingleContentElement::goToPos( FormulaCursor* cursor, bool& handled, + const LuPixelPoint& point, const LuPixelPoint& parentOrigin ) +{ + BasicElement* e = BasicElement::goToPos(cursor, handled, point, parentOrigin); + if (e != 0) { + LuPixelPoint myPos(parentOrigin.x() + getX(), + parentOrigin.y() + getY()); + + e = content->goToPos(cursor, handled, point, myPos); + if (e != 0) { + return e; + } + return this; + } + return 0; +} + +void SingleContentElement::dispatchFontCommand( FontCommand* cmd ) +{ + content->dispatchFontCommand( cmd ); +} + +void SingleContentElement::moveLeft(FormulaCursor* cursor, BasicElement* from) +{ + if (cursor->isSelectionMode()) { + getParent()->moveLeft(cursor, this); + } + else { + //bool linear = cursor->getLinearMovement(); + if (from == getParent()) { + content->moveLeft(cursor, this); + } + else { + getParent()->moveLeft(cursor, this); + } + } +} + +void SingleContentElement::moveRight(FormulaCursor* cursor, BasicElement* from) +{ + if (cursor->isSelectionMode()) { + getParent()->moveRight(cursor, this); + } + else { + //bool linear = cursor->getLinearMovement(); + if (from == getParent()) { + content->moveRight(cursor, this); + } + else { + getParent()->moveRight(cursor, this); + } + } +} + +void SingleContentElement::moveUp(FormulaCursor* cursor, BasicElement* /*from*/) +{ + getParent()->moveUp(cursor, this); +} + +void SingleContentElement::moveDown(FormulaCursor* cursor, BasicElement* /*from*/) +{ + getParent()->moveDown(cursor, this); +} + +void SingleContentElement::remove( FormulaCursor* cursor, + TQPtrList& removedChildren, + Direction direction ) +{ + switch (cursor->getPos()) { + case contentPos: + BasicElement* parent = getParent(); + parent->selectChild(cursor, this); + parent->remove(cursor, removedChildren, direction); + } +} + +void SingleContentElement::normalize( FormulaCursor* cursor, Direction direction ) +{ + if (direction == beforeCursor) { + content->moveLeft(cursor, this); + } + else { + content->moveRight(cursor, this); + } +} + +SequenceElement* SingleContentElement::getMainChild() +{ + return content; +} + +void SingleContentElement::selectChild(FormulaCursor* cursor, BasicElement* child) +{ + if (child == content) { + cursor->setTo(this, contentPos); + } +} + +void SingleContentElement::writeDom(TQDomElement element) +{ + BasicElement::writeDom(element); + + TQDomDocument doc = element.ownerDocument(); + + TQDomElement con = doc.createElement("CONTENT"); + con.appendChild(content->getElementDom(doc)); + element.appendChild(con); +} + +bool SingleContentElement::readContentFromDom(TQDomNode& node) +{ + if (!BasicElement::readContentFromDom(node)) { + return false; + } + + if ( !buildChild( content, node, "CONTENT" ) ) { + kdWarning( DEBUGID ) << "Empty content in " << getTagName() << endl; + return false; + } + node = node.nextSibling(); + + return true; +} + +int SingleContentElement::readContentFromMathMLDom( TQDomNode& node ) +{ + if ( BasicElement::readContentFromMathMLDom( node ) == -1 ) { + return -1; + } + + int nodeCounter = content->buildMathMLChild( node ); + if ( nodeCounter == -1 ) { + kdWarning( DEBUGID) << "Empty content in SingleContentElement\n"; + return -1; + } + + return nodeCounter; +} + +void SingleContentElement::writeMathMLContent( TQDomDocument& doc, TQDomElement& element, bool oasisFormat ) const +{ + content->writeMathML( doc, element, oasisFormat ); +} + + + +BracketElement::BracketElement(SymbolType l, SymbolType r, BasicElement* parent) + : SingleContentElement(parent), + left( 0 ), right( 0 ), + leftType( l ), rightType( r ), + m_operator( false ), m_customLeft( false ), m_customRight( false ) +{ +} + + +BracketElement::~BracketElement() +{ + delete left; + delete right; +} + + +BracketElement::BracketElement( const BracketElement& other ) + : SingleContentElement( other ), + left( 0 ), right( 0 ), + leftType( other.leftType ), rightType( other.rightType ), + m_operator( other.m_operator ), + m_customLeft( other.m_customLeft ), m_customRight( other.m_customRight ) +{ +} + + +bool BracketElement::accept( ElementVisitor* visitor ) +{ + return visitor->visit( this ); +} + + +void BracketElement::entered( SequenceElement* /*child*/ ) +{ + formula()->tell( i18n( "Delimited list" ) ); +} + + +BasicElement* BracketElement::goToPos( FormulaCursor* cursor, bool& handled, + const LuPixelPoint& point, const LuPixelPoint& parentOrigin ) +{ + BasicElement* e = BasicElement::goToPos(cursor, handled, point, parentOrigin); + if (e != 0) { + LuPixelPoint myPos(parentOrigin.x() + getX(), + parentOrigin.y() + getY()); + e = getContent()->goToPos(cursor, handled, point, myPos); + if (e != 0) { + return e; + } + + // We are in one of those gaps. + luPixel dx = point.x() - myPos.x(); + luPixel dy = point.y() - myPos.y(); + + if ((dx > getContent()->getX()+getContent()->getWidth()) || + (dy > getContent()->getY()+getContent()->getHeight())) { + getContent()->moveEnd(cursor); + handled = true; + return getContent(); + } + return this; + } + return 0; +} + + +/** + * Calculates our width and height and + * our children's parentPosition. + */ +void BracketElement::calcSizes( const ContextStyle& context, + ContextStyle::TextStyle tstyle, + ContextStyle::IndexStyle istyle, + StyleAttributes& style ) +{ + SequenceElement* content = getContent(); + content->calcSizes( context, tstyle, istyle, style ); + + //if ( left == 0 ) { + delete left; + delete right; + left = context.fontStyle().createArtwork( leftType ); + right = context.fontStyle().createArtwork( rightType ); + //} + + double factor = style.sizeFactor(); + if (content->isTextOnly()) { + left->calcSizes(context, tstyle, factor); + right->calcSizes(context, tstyle, factor); + + setBaseline(TQMAX(content->getBaseline(), + TQMAX(left->getBaseline(), right->getBaseline()))); + + content->setY(getBaseline() - content->getBaseline()); + left ->setY(getBaseline() - left ->getBaseline()); + right ->setY(getBaseline() - right ->getBaseline()); + + //setMidline(content->getY() + content->getMidline()); + setHeight(TQMAX(content->getY() + content->getHeight(), + TQMAX(left ->getY() + left ->getHeight(), + right->getY() + right->getHeight()))); + } + else { + //kdDebug( DEBUGID ) << "BracketElement::calcSizes " << content->axis( context, tstyle ) << " " << content->getHeight() << endl; + luPixel contentHeight = 2 * TQMAX( content->axis( context, tstyle, factor ), + content->getHeight() - content->axis( context, tstyle, factor ) ); + left->calcSizes( context, tstyle, factor, contentHeight ); + right->calcSizes( context, tstyle, factor, contentHeight ); + + // height + setHeight(TQMAX(contentHeight, + TQMAX(left->getHeight(), right->getHeight()))); + //setMidline(getHeight() / 2); + + content->setY(getHeight() / 2 - content->axis( context, tstyle, factor )); + setBaseline(content->getBaseline() + content->getY()); + + if ( left->isNormalChar() ) { + left->setY(getBaseline() - left->getBaseline()); + } + else { + left->setY((getHeight() - left->getHeight())/2); + } + if ( right->isNormalChar() ) { + right->setY(getBaseline() - right->getBaseline()); + } + else { + right->setY((getHeight() - right->getHeight())/2); + } + +// kdDebug() << "BracketElement::calcSizes" << endl +// << "getHeight(): " << getHeight() << endl +// << "left->getHeight(): " << left->getHeight() << endl +// << "right->getHeight(): " << right->getHeight() << endl +// << "left->getY(): " << left->getY() << endl +// << "right->getY(): " << right->getY() << endl +// << endl; + } + + // width + setWidth(left->getWidth() + content->getWidth() + right->getWidth()); + content->setX(left->getWidth()); + right ->setX(left->getWidth()+content->getWidth()); +} + + +/** + * Draws the whole element including its children. + * The `parentOrigin' is the point this element's parent starts. + * We can use our parentPosition to get our own origin then. + */ +void BracketElement::draw( TQPainter& painter, const LuPixelRect& r, + const ContextStyle& context, + ContextStyle::TextStyle tstyle, + ContextStyle::IndexStyle istyle, + StyleAttributes& style, + const LuPixelPoint& parentOrigin ) +{ + LuPixelPoint myPos( parentOrigin.x()+getX(), parentOrigin.y()+getY() ); + //if ( !LuPixelRect( myPos.x(), myPos.y(), getWidth(), getHeight() ).intersects( r ) ) + // return; + + SequenceElement* content = getContent(); + content->draw(painter, r, context, tstyle, istyle, style, myPos); + + if (content->isTextOnly()) { + left->draw(painter, r, context, tstyle, style, myPos); + right->draw(painter, r, context, tstyle, style, myPos); + } + else { + double factor = style.sizeFactor(); + luPixel contentHeight = 2 * TQMAX(content->axis( context, tstyle, factor ), + content->getHeight() - content->axis( context, tstyle, factor )); + left->draw(painter, r, context, tstyle, style, contentHeight, myPos); + right->draw(painter, r, context, tstyle, style, contentHeight, myPos); + } + + // Debug +#if 0 + painter.setBrush( TQt::NoBrush ); + painter.setPen( TQt::red ); + painter.drawRect( context.layoutUnitToPixelX( myPos.x()+left->getX() ), + context.layoutUnitToPixelY( myPos.y()+left->getY() ), + context.layoutUnitToPixelX( left->getWidth() ), + context.layoutUnitToPixelY( left->getHeight() ) ); + painter.drawRect( context.layoutUnitToPixelX( myPos.x()+right->getX() ), + context.layoutUnitToPixelY( myPos.y()+right->getY() ), + context.layoutUnitToPixelX( right->getWidth() ), + context.layoutUnitToPixelY( right->getHeight() ) ); +#endif +} + + +/** + * Appends our attributes to the dom element. + */ +void BracketElement::writeDom(TQDomElement element) +{ + SingleContentElement::writeDom(element); + element.setAttribute("LEFT", leftType); + element.setAttribute("RIGHT", rightType); +} + +/** + * Reads our attributes from the element. + * Returns false if it failed. + */ +bool BracketElement::readAttributesFromDom(TQDomElement element) +{ + if (!BasicElement::readAttributesFromDom(element)) { + return false; + } + TQString leftStr = element.attribute("LEFT"); + if(!leftStr.isNull()) { + leftType = static_cast(leftStr.toInt()); + } + TQString rightStr = element.attribute("RIGHT"); + if(!rightStr.isNull()) { + rightType = static_cast(rightStr.toInt()); + } + return true; +} + +/** + * Reads our attributes from the MathML element. + * Returns false if it failed. + */ +bool BracketElement::readAttributesFromMathMLDom(const TQDomElement& element) +{ + if ( !BasicElement::readAttributesFromMathMLDom( element ) ) { + return false; + } + + if ( element.tagName().lower() == "mo" ) { + m_operator = true; + // TODO: parse attributes in section 3.2.5.2 + } + else { // mfenced, see attributes in section 3.3.8.2 + leftType = LeftRoundBracket; + rightType = RightRoundBracket; + TQString openStr = element.attribute( "open" ).stripWhiteSpace(); + if ( !openStr.isNull() ) { + m_customLeft = true; + if ( openStr == "[" ) + leftType = LeftSquareBracket; + else if ( openStr == "]" ) + leftType = RightSquareBracket; + else if ( openStr == "{" ) + leftType = LeftCurlyBracket; + else if ( openStr == "}" ) + leftType = RightCurlyBracket; + else if ( openStr == "<" ) + leftType = LeftCornerBracket; + else if ( openStr == ">" ) + leftType = RightCornerBracket; + else if ( openStr == "(" ) + leftType = LeftRoundBracket; + else if ( openStr == ")" ) + leftType = RightRoundBracket; + else if ( openStr == "/" ) + leftType = SlashBracket; + else if ( openStr == "\\" ) + leftType = BackSlashBracket; + else // TODO: Check for entity references + leftType = LeftRoundBracket; + } + TQString closeStr = element.attribute( "close" ).stripWhiteSpace(); + if ( !closeStr.isNull() ) { + m_customRight = true; + if ( closeStr == "[" ) + rightType = LeftSquareBracket; + else if ( closeStr == "]" ) + rightType = RightSquareBracket; + else if ( closeStr == "{" ) + rightType = LeftCurlyBracket; + else if ( closeStr == "}" ) + rightType = RightCurlyBracket; + else if ( closeStr == "<" ) + rightType = LeftCornerBracket; + else if ( closeStr == ">" ) + rightType = RightCornerBracket; + else if ( closeStr == "(" ) + rightType = LeftRoundBracket; + else if ( closeStr == ")" ) + rightType = RightRoundBracket; + else if ( closeStr == "/" ) + rightType = SlashBracket; + else if ( closeStr == "\\" ) + rightType = BackSlashBracket; + else // TODO: Check for entity references + rightType = LeftRoundBracket; + } + m_separators = element.attribute( "separators" ).simplifyWhiteSpace(); + } + return true; +} + +/** + * Reads our content from the MathML node. Sets the node to the next node + * that needs to be read. + * Returns false if it failed. + */ +int BracketElement::readContentFromMathMLDom(TQDomNode& node) +{ + bool empty = false; + int nodeCounter = 0; + if ( m_operator ) { + node = node.parentNode(); + TQDomNode open = node; + TQDomNode parent = node.parentNode(); + if ( ! operatorType( node, true ) ) + return -1; + int nodeNum = searchOperator( node ); + if ( nodeNum == -1 ) // Closing bracket not found + return -1; + if ( nodeNum == 0 ) { // Empty content + empty = true; + } + else if ( nodeNum == 1 ) { + do { + node = node.nextSibling(); + nodeCounter++; + } while ( ! node.isElement() ); + } + else { // More than two elements inside, infer a mrow + nodeCounter += nodeNum; + kdWarning() << "NodeNum: " << nodeNum << endl; + TQDomDocument doc = node.ownerDocument(); + TQDomElement de = doc.createElement( "mrow" ); + int i = 0; + do { + TQDomNode n = node.nextSibling(); + de.appendChild( node.toElement() ); + node = n; + } while ( ++i < nodeNum ); + parent.insertAfter( de, open ); + node = de; + kdWarning() << doc.toString() << endl; + } + } + else { + // if it's a mfence tag, we need to convert to equivalent expanded form. + // See section 3.3.8 + while ( ! node.isNull() && ! node.isElement() ) + node = node.nextSibling(); + TQDomNode next = node.nextSibling(); + while ( ! next.isNull() && ! next.isElement() ) + next = next.nextSibling(); + if ( ! next.isNull()) { + TQDomDocument doc = node.ownerDocument(); + TQDomNode parent = node.parentNode(); + TQString ns = parent.prefix(); + TQDomElement de = doc.createElementNS( ns, "mrow" ); + uint pos = 0; + while ( ! node.isNull() ) { + TQDomNode no = node.nextSibling(); + while ( ! no.isNull() && ! no.isElement() ) + no = no.nextSibling(); + de.appendChild( node.toElement() ); + if ( ! no.isNull() && ( m_separators.isNull() || ! m_separators.isEmpty() ) ) { + TQDomElement sep = doc.createElementNS( ns, "mo" ); + de.appendChild( sep ); + if ( m_separators.isNull() ) { + sep.appendChild( doc.createTextNode( "," ) ); + } + else { + if ( m_separators.at( pos ).isSpace() ) { + pos++; + } + sep.appendChild( doc.createTextNode( TQString ( m_separators.at( pos ) ) ) ); + } + if ( pos < m_separators.length() - 1 ) { + pos++; + } + } + node = no; + } + parent.appendChild( de ); + node = parent.firstChild(); + while ( ! node.isElement() ) + node = node.nextSibling(); + } + } + if ( ! empty ) { + int contentNumber = inherited::readContentFromMathMLDom( node ); + if ( contentNumber == -1 ) + return -1; + nodeCounter += contentNumber; + for (int i = 0; i < contentNumber; i++ ) { + if ( node.isNull() ) { + return -1; + } + node = node.nextSibling(); + } + } + if ( m_operator ) { + int operatorNumber = operatorType( node, false ); + if ( operatorNumber == -1 ) { + return -1; + } + nodeCounter += operatorNumber; + } + kdDebug( DEBUGID ) << "Number of bracket nodes: " << nodeCounter << endl; + return nodeCounter; +} + +TQString BracketElement::toLatex() +{ + TQString ls,rs,cs; + cs=getContent()->toLatex(); + ls="\\left"+latexString(leftType) + " "; + rs=" \\right"+latexString(rightType); + + return ls+cs+rs; +} + +TQString BracketElement::latexString(char type) +{ + switch (type) { + case ']': + return "]"; + case '[': + return "["; + case '{': + return "\\{"; + case '}': + return "\\}"; + case '(': + return "("; + case ')': + return ")"; + case '|': + return "|"; + case '<': + return "\\langle"; + case '>': + return "\\rangle"; + case '/': + return "/"; + case '\\': + return "\\backslash"; + } + return "."; +} + +TQString BracketElement::formulaString() +{ + return "(" + getContent()->formulaString() + ")"; +} + +int BracketElement::operatorType( TQDomNode& node, bool open ) +{ + int counter = 1; + SymbolType* type = open ? &leftType : &rightType; + while ( ! node.isNull() && ! node.isElement() ) { + node = node.nextSibling(); + counter++; + } + if ( node.isElement() ) { + TQDomElement e = node.toElement(); + TQDomNode child = e.firstChild(); + if ( child.isEntityReference() ) { + kdWarning() << "Entity Reference\n"; + TQString name = node.nodeName(); + // TODO: To fully support these, SymbolType has to be extended, + // and better Unicode support is a must + // CloseCurlyDoubleQuote 0x201D + // CloseCurlyQoute 0x2019 + // LeftCeiling 0x2308 + // LeftDoubleBracket 0x301A + // LeftFloor 0x230A + // OpenCurlyDoubleQuote 0x201C + // OpenCurlyQuote 0x2018 + // RightCeiling 0x2309 + // RightDoubleBracket 0x301B + // RightFloor 0x230B + if ( name == "LeftAngleBracket" ) { + *type = LeftCornerBracket; + } + else if ( name == "RightAngleBracket" ) { + *type = RightCornerBracket; + } + else { + if ( open ) { + *type = LeftRoundBracket; + } + else + *type = RightRoundBracket; + } + } + else { + TQString s = e.text(); + if ( s.isNull() ) + return -1; + *type = static_cast( TQString::number( s.at( 0 ).latin1() ).toInt() ); + } + } + else { + return -1; + } + return counter; +} + +int BracketElement::searchOperator( const TQDomNode& node ) +{ + TQDomNode n = node; + for ( int i = -2; ! n.isNull(); n = n.nextSibling() ) { + if ( n.isElement() ) { + i++; + TQDomElement e = n.toElement(); + if ( e.tagName().lower() == "mo" ) { + // Try to guess looking at attributes + TQString form = e.attribute( "form" ); + TQString f; + if ( ! form.isNull() ) { + f = form.stripWhiteSpace().lower(); + } + TQString fence = e.attribute( "fence" ); + if ( ! fence.isNull() ) { + if ( fence.stripWhiteSpace().lower() == "false" ) { + continue; + } + if ( ! f.isNull() ) { + if ( f == "postfix" ) { + return i; + } + else { + continue; + } + } + } + + // Guess looking at contents + TQDomNode child = e.firstChild(); + TQString name; + if ( child.isText() ) + name = child.toText().data().stripWhiteSpace(); + else if ( child.isEntityReference() ) + name = child.nodeName(); + else + continue; + if ( name == ")" + || name == "]" + || name == "}" + || name == "CloseCurlyDoubleQuote" + || name == "CloseCurlyQuote" + || name == "RightAngleBracket" + || name == "RightCeiling" + || name == "RightDoubleBracket" + || name == "RightFloor" ) { + if ( f.isNull() || f == "postfix" ) + return i; + } + if ( name == "(" + || name == "[" + || name == "{" + || name == "LeftAngleBracket" + || name == "LeftCeiling" + || name == "LeftDoubleBracket" + || name == "LeftFloor" + || name == "OpenCurlyQuote" ) { + if ( ! f.isNull() && f == "postfix" ) + return i; + } + } + } + } + return -1; +} + + +void BracketElement::writeMathMLAttributes( TQDomElement& element ) const +{ + if ( left->getType() != LeftRoundBracket || + right->getType() != RightRoundBracket ) + { + element.setAttribute( "open", TQString( TQChar( leftType ) ) ); + element.setAttribute( "close", TQString( TQChar( rightType ) ) ); + } + if ( ! m_separators.isNull() ) { + element.setAttribute( "separators", m_separators ); + } +} + +OverlineElement::OverlineElement( BasicElement* parent ) + : SingleContentElement( parent ) +{ +} + +OverlineElement::~OverlineElement() +{ +} + +OverlineElement::OverlineElement( const OverlineElement& other ) + : SingleContentElement( other ) +{ +} + + +bool OverlineElement::accept( ElementVisitor* visitor ) +{ + return visitor->visit( this ); +} + + +void OverlineElement::entered( SequenceElement* /*child*/ ) +{ + formula()->tell( i18n( "Overline" ) ); +} + + +void OverlineElement::calcSizes( const ContextStyle& context, + ContextStyle::TextStyle tstyle, + ContextStyle::IndexStyle istyle, + StyleAttributes& style ) +{ + SequenceElement* content = getContent(); + content->calcSizes(context, tstyle, + context.convertIndexStyleLower(istyle), style ); + + //luPixel distX = context.ptToPixelX( context.getThinSpace( tstyle, style.sizeFactor() ) ); + luPixel distY = context.ptToPixelY( context.getThinSpace( tstyle, style.sizeFactor() ) ); + //luPixel unit = (content->getHeight() + distY)/ 3; + + setWidth( content->getWidth() ); + setHeight( content->getHeight() + distY ); + + content->setX( 0 ); + content->setY( distY ); + setBaseline(content->getBaseline() + content->getY()); +} + +void OverlineElement::draw( TQPainter& painter, const LuPixelRect& r, + const ContextStyle& context, + ContextStyle::TextStyle tstyle, + ContextStyle::IndexStyle istyle, + StyleAttributes& style, + const LuPixelPoint& parentOrigin ) +{ + LuPixelPoint myPos( parentOrigin.x()+getX(), parentOrigin.y()+getY() ); + //if ( !LuPixelRect( myPos.x(), myPos.y(), getWidth(), getHeight() ).intersects( r ) ) + // return; + + SequenceElement* content = getContent(); + content->draw( painter, r, context, tstyle, + context.convertIndexStyleLower( istyle ), style, myPos ); + + luPixel x = myPos.x(); + luPixel y = myPos.y(); + //int distX = context.getDistanceX(tstyle); + double factor = style.sizeFactor(); + luPixel distY = context.ptToPixelY( context.getThinSpace( tstyle, factor ) ); + //luPixel unit = (content->getHeight() + distY)/ 3; + + painter.setPen( TQPen( context.getDefaultColor(), + context.layoutUnitToPixelY( context.getLineWidth( factor ) ) ) ); + + painter.drawLine( context.layoutUnitToPixelX( x ), + context.layoutUnitToPixelY( y+distY/3 ), + context.layoutUnitToPixelX( x+content->getWidth() ), + context.layoutUnitToPixelY( y+distY/3 ) ); +} + + +TQString OverlineElement::toLatex() +{ + return "\\overline{" + getContent()->toLatex() + "}"; +} + +TQString OverlineElement::formulaString() +{ + return getContent()->formulaString(); +} + +void OverlineElement::writeMathML( TQDomDocument& doc, TQDomNode& parent, bool oasisFormat ) const +{ + TQDomElement de = doc.createElement( oasisFormat ? "math:mover" : "mover" ); + SingleContentElement::writeMathML( doc, de, oasisFormat ); + TQDomElement op = doc.createElement( oasisFormat ? "math:mo" : "mo" ); + // is this the right entity? Mozilla renders it correctly. + op.appendChild( doc.createEntityReference( "OverBar" ) ); + de.appendChild( op ); + parent.appendChild( de ); +} + + +UnderlineElement::UnderlineElement( BasicElement* parent ) + : SingleContentElement( parent ) +{ +} + +UnderlineElement::~UnderlineElement() +{ +} + + +UnderlineElement::UnderlineElement( const UnderlineElement& other ) + : SingleContentElement( other ) +{ +} + + +bool UnderlineElement::accept( ElementVisitor* visitor ) +{ + return visitor->visit( this ); +} + + +void UnderlineElement::entered( SequenceElement* /*child*/ ) +{ + formula()->tell( i18n( "Underline" ) ); +} + + +void UnderlineElement::calcSizes( const ContextStyle& context, + ContextStyle::TextStyle tstyle, + ContextStyle::IndexStyle istyle, + StyleAttributes& style ) +{ + SequenceElement* content = getContent(); + double factor = style.sizeFactor(); + content->calcSizes(context, tstyle, + context.convertIndexStyleLower(istyle), style ); + + //luPixel distX = context.ptToPixelX( context.getThinSpace( tstyle ) ); + luPixel distY = context.ptToPixelY( context.getThinSpace( tstyle, factor ) ); + //luPixel unit = (content->getHeight() + distY)/ 3; + + setWidth( content->getWidth() ); + setHeight( content->getHeight() + distY ); + + content->setX( 0 ); + content->setY( 0 ); + setBaseline(content->getBaseline() + content->getY()); +} + +void UnderlineElement::draw( TQPainter& painter, const LuPixelRect& r, + const ContextStyle& context, + ContextStyle::TextStyle tstyle, + ContextStyle::IndexStyle istyle, + StyleAttributes& style, + const LuPixelPoint& parentOrigin ) +{ + LuPixelPoint myPos( parentOrigin.x()+getX(), parentOrigin.y()+getY() ); + //if ( !LuPixelRect( myPos.x(), myPos.y(), getWidth(), getHeight() ).intersects( r ) ) + // return; + + SequenceElement* content = getContent(); + content->draw( painter, r, context, tstyle, + context.convertIndexStyleLower( istyle ), style, myPos ); + + luPixel x = myPos.x(); + luPixel y = myPos.y(); + //int distX = context.getDistanceX(tstyle); + //luPixel distY = context.ptToPixelY( context.getThinSpace( tstyle ) ); + //luPixel unit = (content->getHeight() + distY)/ 3; + + double factor = style.sizeFactor(); + painter.setPen( TQPen( context.getDefaultColor(), + context.layoutUnitToPixelY( context.getLineWidth( factor ) ) ) ); + + painter.drawLine( context.layoutUnitToPixelX( x ), + context.layoutUnitToPixelY( y+getHeight()-context.getLineWidth( factor ) ), + context.layoutUnitToPixelX( x+content->getWidth() ), + context.layoutUnitToPixelY( y+getHeight()-context.getLineWidth( factor ) ) ); +} + + +TQString UnderlineElement::toLatex() +{ + return "\\underline{" + getContent()->toLatex() + "}"; +} + +TQString UnderlineElement::formulaString() +{ + return getContent()->formulaString(); +} + +void UnderlineElement::writeMathML( TQDomDocument& doc, TQDomNode& parent, bool oasisFormat ) const +{ + TQDomElement de = doc.createElement( oasisFormat ? "math:munder" : "munder" ); + SingleContentElement::writeMathML( doc, de, oasisFormat ); + TQDomElement op = doc.createElement( oasisFormat ? "math:mo" : "mo" ); + // is this the right entity? Mozilla renders it correctly. + op.appendChild( doc.createEntityReference( "UnderBar" ) ); + de.appendChild( op ); + parent.appendChild( de ); +} + +KFORMULA_NAMESPACE_END diff --git a/lib/kformula/contextstyle.cc b/lib/kformula/contextstyle.cc deleted file mode 100644 index a744e02d..00000000 --- a/lib/kformula/contextstyle.cc +++ /dev/null @@ -1,765 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2001 Andrea Rizzi - Ulrich Kuettler - 2006 Alfredo Beaumont Sainz - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - -#include -#include - -#include -#include - -#include "contextstyle.h" -#include "fontstyle.h" - - -KFORMULA_NAMESPACE_BEGIN - - -ContextStyle::ContextStyle() - : symbolFont( "Symbol" ), - defaultColor(TQt::black), numberColor(TQt::blue), - operatorColor(TQt::darkGreen), errorColor(TQt::darkRed), - emptyColor(TQt::blue), helpColor( TQt::gray ), m_sizeFactor( 0 ) -{ -// kdDebug() << "ContextStyle::ContextStyle" << endl -// << "defaultFont: " << defaultFont.rawName() << endl -// << "nameFont: " << nameFont.rawName() << endl -// << "numberFont: " << numberFont.rawName() << endl -// << "operatorFont: " << operatorFont.rawName() << endl -// << "symbolFont: " << symbolFont.rawName() << endl; - - textStyleValues[ displayStyle ].setup( 1. ); - textStyleValues[ textStyle ].setup( 1. ); - textStyleValues[ scriptStyle ].setup( .7 ); - textStyleValues[ scriptScriptStyle ].setup( .49 ); - - m_baseTextStyle = displayStyle; - - lineWidth = 1; - linearMovement = false; - centerSymbol = true; - m_syntaxHighlighting = true; - - m_fontStyle = 0; -} - - -ContextStyle::~ContextStyle() -{ - delete m_fontStyle; -} - - -void ContextStyle::init( bool init ) -{ - setup(); - setFontStyle( m_fontStyleName, init ); -} - - -void ContextStyle::setFontStyle( const TQString& fontStyle, bool init ) -{ - delete m_fontStyle; - m_fontStyleName = fontStyle; - m_fontStyle = new FontStyle(); - m_fontStyle->init( this, init ); -} - - -const SymbolTable& ContextStyle::symbolTable() const -{ - return *( m_fontStyle->symbolTable() ); -} - - -void ContextStyle::readConfig( TDEConfig* config, bool init ) -{ - config->setGroup( "kformula Font" ); - TQString fontName = config->readEntry( "defaultFont", "Times,12,-1,5,50,1,0,0,0,0" ); - defaultFont.fromString( fontName ); - fontName = config->readEntry( "nameFont", "Times,12,-1,5,50,0,0,0,0,0" ); - nameFont.fromString( fontName ); - fontName = config->readEntry( "numberFont", "Times,12,-1,5,50,0,0,0,0,0" ); - numberFont.fromString( fontName ); - fontName = config->readEntry( "operatorFont", "Times,12,-1,5,50,0,0,0,0,0" ); - operatorFont.fromString( fontName ); - TQString baseSize = config->readEntry( "baseSize", "20" ); - m_baseSize = baseSize.toInt(); - - if ( ! FontStyle::missingFonts( init ).isEmpty() ) { - kdWarning( DEBUGID) << "Not all basic fonts found\n"; - } - mathFont.fromString("Arev Sans"); - bracketFont.fromString("cmex10"); - - - // There's no gui right anymore but I'll leave it here... - config->setGroup( "kformula Color" ); - defaultColor = config->readColorEntry( "defaultColor", &defaultColor ); - numberColor = config->readColorEntry( "numberColor", &numberColor ); - operatorColor = config->readColorEntry( "operatorColor", &operatorColor ); - emptyColor = config->readColorEntry( "emptyColor", &emptyColor ); - errorColor = config->readColorEntry( "errorColor", &errorColor ); - helpColor = config->readColorEntry( "helpColor", &helpColor ); - - m_syntaxHighlighting = config->readBoolEntry( "syntaxHighlighting", true ); -} - -void ContextStyle::setZoomAndResolution( int zoom, int dpiX, int dpiY ) -{ - KoZoomHandler::setZoomAndResolution( zoom, dpiX, dpiY ); -} - -bool ContextStyle::setZoomAndResolution( int zoom, double zoomX, double zoomY, bool, bool ) -{ - bool changes = m_zoom != zoom || m_zoomedResolutionX != zoomX || m_zoomedResolutionY != zoomY; - m_zoom = zoom; - m_zoomedResolutionX = zoomX; - m_zoomedResolutionY = zoomY; - return changes; -} - -TQColor ContextStyle::getNumberColor() const -{ - if ( edit() && syntaxHighlighting() ) { - return numberColor; - } - return getDefaultColor(); -} - -TQColor ContextStyle::getOperatorColor() const -{ - if ( edit() && syntaxHighlighting() ) { - return operatorColor; - } - return getDefaultColor(); -} - -TQColor ContextStyle::getErrorColor() const -{ - if ( edit() && syntaxHighlighting() ) { - return errorColor; - } - return getDefaultColor(); -} - -TQColor ContextStyle::getEmptyColor() const -{ - if ( edit() && syntaxHighlighting() ) { - return emptyColor; - } - return getDefaultColor(); -} - -TQColor ContextStyle::getHelpColor() const -{ - if ( edit() && syntaxHighlighting() ) { - return helpColor; - } - return getDefaultColor(); -} - -void ContextStyle::setDefaultColor( const TQColor& color ) -{ - defaultColor = color; -} -void ContextStyle::setNumberColor( const TQColor& color ) -{ - numberColor = color; -} -void ContextStyle::setOperatorColor( const TQColor& color ) -{ - operatorColor = color; -} -void ContextStyle::setErrorColor( const TQColor& color ) -{ - errorColor = color; -} -void ContextStyle::setEmptyColor( const TQColor& color ) -{ - emptyColor = color; -} -void ContextStyle::setHelpColor( const TQColor& color ) -{ - helpColor = color; -} - -#if 0 -const TQStringList& ContextStyle::requestedFonts() const -{ - return m_requestedFonts; -} - -void ContextStyle::setRequestedFonts( const TQStringList& list ) -{ - m_requestedFonts = list; - //table.init( this ); -} -#endif - -double ContextStyle::getReductionFactor( TextStyle tstyle ) const -{ - return textStyleValues[ tstyle ].reductionFactor; -} - -luPt ContextStyle::getAdjustedSize( TextStyle tstyle, double factor ) const -{ - return tqRound( ptToLayoutUnitPt( m_sizeFactor - * m_baseSize - * getReductionFactor( tstyle ) - * factor - * zoom() / 100.0 ) ); -} - -luPixel ContextStyle::getSpace( TextStyle tstyle, SpaceWidth space, double factor ) const -{ - switch ( space ) { - case NEGTHIN: return -getThinSpace( tstyle, factor ); - case THIN: return getThinSpace( tstyle, factor ); - case MEDIUM: return getMediumSpace( tstyle, factor ); - case THICK: return getThickSpace( tstyle, factor ); - case QUAD: return getQuadSpace( tstyle, factor ); - } - return 0; -} - -luPixel ContextStyle::getThinSpace( TextStyle tstyle, double factor ) const -{ - return ptToPixelX( m_sizeFactor - * textStyleValues[ tstyle ].thinSpace( quad ) - * factor - * zoom() / 100.0 ); -} - -luPixel ContextStyle::getMediumSpace( TextStyle tstyle, double factor ) const -{ - return ptToPixelX( m_sizeFactor - * textStyleValues[ tstyle ].mediumSpace( quad ) - * factor - * zoom() / 100.0 ); -} - -luPixel ContextStyle::getThickSpace( TextStyle tstyle, double factor ) const -{ - return ptToPixelX( m_sizeFactor - * textStyleValues[ tstyle ].thickSpace( quad ) - * factor - * zoom() / 100.0 ); -} - -luPixel ContextStyle::getQuadSpace( TextStyle tstyle, double factor ) const -{ - return ptToPixelX( m_sizeFactor - * textStyleValues[ tstyle ].quadSpace( quad ) - * factor - * zoom() / 100.0 ); -} - -luPixel ContextStyle::axisHeight( TextStyle tstyle, double factor ) const -{ - //return ptToPixelY( textStyleValues[ tstyle ].axisHeight( m_axisHeight ) ); - return static_cast( m_sizeFactor - * textStyleValues[ tstyle ].axisHeight( m_axisHeight ) - * factor - * zoom() / 100.0 ); -} - -luPt ContextStyle::getBaseSize() const -{ - return static_cast( ptToLayoutUnitPt( m_sizeFactor*m_baseSize ) ); -} - -void ContextStyle::setBaseSize( int size ) -{ - //kdDebug( 40000 ) << "ContextStyle::setBaseSize" << endl; - if ( size != m_baseSize ) { - m_baseSize = size; - setup(); - } -} - -void ContextStyle::setSizeFactor( double factor ) -{ - m_sizeFactor = factor; -} - - -luPixel ContextStyle::getLineWidth( double factor ) const -{ - return ptToLayoutUnitPixX( m_sizeFactor*lineWidth*factor*zoom() / 100.0 ); -} - -luPixel ContextStyle::getEmptyRectWidth( double factor ) const -{ - return ptToLayoutUnitPixX( m_sizeFactor*m_baseSize*factor*(zoom() / 100.0)/1.8 ); -} - -luPixel ContextStyle::getEmptyRectHeight( double factor ) const -{ - return ptToLayoutUnitPixX( m_sizeFactor*m_baseSize*factor*(zoom() / 100.0)/1.8 ); -} - - -ContextStyle::TextStyle ContextStyle::convertTextStyleFraction( TextStyle tstyle ) const -{ - TextStyle result; - - switch ( tstyle ){ - case displayStyle: - result = textStyle; - break; - case textStyle: - result = scriptStyle; - break; - default: - result = scriptScriptStyle; - break; - } - - return result; -} - - -ContextStyle::TextStyle ContextStyle::convertTextStyleIndex( TextStyle tstyle ) const -{ - TextStyle result; - - switch ( tstyle ){ - case displayStyle: - result = scriptStyle; - break; - case textStyle: - result = scriptStyle; - break; - default: - result = scriptScriptStyle; - break; - } - - return result; -} - - -void ContextStyle::setup() -{ - luPt size = static_cast( m_baseSize ); - TQFont font = symbolFont; - font.setPointSize( size ); - TQFontMetrics fm( font ); - - // Or better the real space required? ( boundingRect ) - quad = ptToLayoutUnitPt( fm.width( 'M' ) ); - - font = TQFont(defaultFont); - font.setPointSize( size ); - TQFontMetrics fm2( font ); - //m_axisHeight = ptToLayoutUnitPt( fm2.strikeOutPos() ); - //ptToLayoutUnitPixY - //m_axisHeight = ptToLayoutUnitPt( pixelYToPt( fm2.strikeOutPos() ) ); - m_axisHeight = ptToLayoutUnitPixY( pixelYToPt( fm2.strikeOutPos() ) ); -} - - -double StyleAttributes::sizeFactor() const -{ - if ( m_size.empty() ) { -// kdWarning( DEBUGID ) << "SizeFactor stack is empty.\n"; - return 1.0; - } - return m_size.top(); -} - -bool StyleAttributes::customMathVariant() const -{ - if ( m_customMathVariant.empty() ) { - return false; - } - return m_customMathVariant.top(); -} - -CharStyle StyleAttributes::charStyle() const -{ - if ( m_charStyle.empty() ) { -// kdWarning( DEBUGID ) << "CharStyle stack is empty.\n"; - return anyChar; - } - return m_charStyle.top(); -} - -CharFamily StyleAttributes::charFamily() const -{ - if ( m_charFamily.empty() ) { -// kdWarning( DEBUGID ) << "CharFamily stack is empty.\n"; - return anyFamily; - } - return m_charFamily.top(); -} - -TQColor StyleAttributes::color() const -{ - if ( m_color.empty() ) { -// kdWarning( DEBUGID ) << "Color stack is empty.\n"; - return TQColor( TQt::black ); - //return getDefaultColor(); - } - return m_color.top(); -} - -TQColor StyleAttributes::background() const -{ - if ( m_background.empty() ) { -// kdWarning( DEBUGID ) << "Background stack is empty.\n"; - return TQColor( TQt::color0 ); - } - return m_background.top(); -} - -TQFont StyleAttributes::font() const -{ - if ( m_font.empty() ) { - return TQFont(); - } - return m_font.top(); -} - -bool StyleAttributes::fontWeight() const -{ - if ( m_fontWeight.empty() ) { - return false; - } - return m_fontWeight.top(); -} - -bool StyleAttributes::customFontWeight() const -{ - if ( m_customFontWeight.empty() ) { - return false; - } - return m_customFontWeight.top(); -} - -bool StyleAttributes::fontStyle() const -{ - if ( m_fontStyle.empty() ) { - return false; - } - return m_fontStyle.top(); -} - -bool StyleAttributes::customFontStyle() const -{ - if ( m_customFontStyle.empty() ) { - return false; - } - return m_customFontStyle.top(); -} - -bool StyleAttributes::customFont() const -{ - if ( m_customFontFamily.empty() ) { - return false; - } - return m_customFontFamily.top(); -} - -int StyleAttributes::scriptLevel() const -{ - if ( m_scriptLevel.empty() ) { - return 0; - } - return m_scriptLevel.top(); -} - -double StyleAttributes::scriptSizeMultiplier() const -{ - if ( m_scriptSizeMultiplier.empty() ) { - return scriptsizemultiplier; - } - return m_scriptSizeMultiplier.top(); -} - -double StyleAttributes::scriptMinSize() const -{ - if ( m_scriptMinSize.empty() ) { - return scriptminsize; - } - return m_scriptMinSize.top(); -} - -double StyleAttributes::veryVeryThinMathSpace() const -{ - if ( m_veryVeryThinMathSpace.empty() ) { - return veryverythinmathspace; - } - return m_veryVeryThinMathSpace.top(); -} - -double StyleAttributes::veryThinMathSpace() const -{ - if ( m_veryThinMathSpace.empty() ) { - return verythinmathspace; - } - return m_veryThinMathSpace.top(); -} - -double StyleAttributes::thinMathSpace() const -{ - if ( m_thinMathSpace.empty() ) { - return thinmathspace; - } - return m_thinMathSpace.top(); -} - -double StyleAttributes::mediumMathSpace() const -{ - if ( m_mediumMathSpace.empty() ) { - return mediummathspace; - } - return m_mediumMathSpace.top(); -} - -double StyleAttributes::thickMathSpace() const -{ - if ( m_thickMathSpace.empty() ) { - return thickmathspace; - } - return m_thickMathSpace.top(); -} - -double StyleAttributes::veryThickMathSpace() const -{ - if ( m_veryThickMathSpace.empty() ) { - return verythickmathspace; - } - return m_veryThickMathSpace.top(); -} - -double StyleAttributes::veryVeryThickMathSpace() const -{ - if ( m_veryVeryThickMathSpace.empty() ) { - return veryverythickmathspace; - } - return m_veryVeryThickMathSpace.top(); -} - -bool StyleAttributes::displayStyle() const -{ - if ( m_displayStyle.empty() ) { - return true; - } - return m_displayStyle.top(); -} - -bool StyleAttributes::customDisplayStyle() const -{ - if ( m_customDisplayStyle.empty() ) { - return false; - } - return m_customDisplayStyle.top(); -} - -double StyleAttributes::getSpace( SizeType type, double length ) const -{ - switch ( type ) { - case NegativeVeryVeryThinMathSpace: - return - veryVeryThinMathSpace(); - case NegativeVeryThinMathSpace: - return - veryThinMathSpace(); - case NegativeThinMathSpace: - return - thinMathSpace(); - case NegativeMediumMathSpace: - return - mediumMathSpace(); - case NegativeThickMathSpace: - return - thickMathSpace(); - case NegativeVeryThickMathSpace: - return - veryThickMathSpace(); - case NegativeVeryVeryThickMathSpace: - return - veryVeryThickMathSpace(); - case VeryVeryThinMathSpace: - return veryVeryThinMathSpace(); - case VeryThinMathSpace: - return veryThinMathSpace(); - case ThinMathSpace: - return thinMathSpace(); - case MediumMathSpace: - return mediumMathSpace(); - case ThickMathSpace: - return thickMathSpace(); - case VeryThickMathSpace: - return veryThickMathSpace(); - case VeryVeryThickMathSpace: - return veryVeryThickMathSpace(); - default: - break; - } - return length; -} - -void StyleAttributes::resetSize() -{ - if ( ! m_size.empty() ) { - m_size.pop(); - } -} - -void StyleAttributes::resetCharStyle() -{ - if ( ! m_charStyle.empty() ) { - m_charStyle.pop(); - } -} - -void StyleAttributes::resetCharFamily() -{ - if ( ! m_charFamily.empty() ) { - m_charFamily.pop(); - } -} - -void StyleAttributes::resetColor() -{ - if ( ! m_color.empty() ) { - m_color.pop(); - } -} - -void StyleAttributes::resetBackground() -{ - if ( ! m_background.empty() ) { - m_background.pop(); - } -} - -void StyleAttributes::resetFontFamily() -{ - if ( ! m_customFontFamily.empty() ) { - if ( m_customFontFamily.pop() ) { - if ( ! m_font.empty() ) { - m_font.pop(); - } - } - } -} - -void StyleAttributes::resetFontWeight() -{ - if ( ! m_customFontWeight.empty() ) { - if ( m_customFontWeight.pop() ) { - if ( ! m_fontWeight.empty() ) { - m_fontWeight.pop(); - } - } - } -} - -void StyleAttributes::resetFontStyle() -{ - if ( ! m_customFontStyle.empty() ) { - if ( m_customFontStyle.pop() ) { - if ( ! m_fontStyle.empty() ) { - m_fontStyle.pop(); - } - } - } -} - -void StyleAttributes::resetScriptLevel() -{ - if ( ! m_scriptLevel.empty() ) { - m_scriptLevel.pop(); - } -} - -void StyleAttributes::resetScriptSizeMultiplier() -{ - if ( ! m_scriptSizeMultiplier.empty() ) { - m_scriptSizeMultiplier.pop(); - } -} - -void StyleAttributes::resetScriptMinSize() -{ - if ( ! m_scriptMinSize.empty() ) { - m_scriptMinSize.pop(); - } -} - -void StyleAttributes::resetVeryVeryThinMathSpace() -{ - if ( ! m_veryVeryThinMathSpace.empty() ) { - m_veryVeryThinMathSpace.pop(); - } -} - -void StyleAttributes::resetVeryThinMathSpace() -{ - if ( ! m_veryThinMathSpace.empty() ) { - m_veryThinMathSpace.pop(); - } -} - -void StyleAttributes::resetThinMathSpace() -{ - if ( ! m_thinMathSpace.empty() ) { - m_thinMathSpace.pop(); - } -} - -void StyleAttributes::resetMediumMathSpace() -{ - if ( ! m_mediumMathSpace.empty() ) { - m_mediumMathSpace.pop(); - } -} - -void StyleAttributes::resetThickMathSpace() -{ - if ( ! m_thickMathSpace.empty() ) { - m_thickMathSpace.pop(); - } -} - -void StyleAttributes::resetVeryThickMathSpace() -{ - if ( ! m_veryThickMathSpace.empty() ) { - m_veryThickMathSpace.pop(); - } -} - -void StyleAttributes::resetVeryVeryThickMathSpace() -{ - if ( ! m_veryVeryThickMathSpace.empty() ) { - m_veryVeryThickMathSpace.pop(); - } -} - -void StyleAttributes::resetDisplayStyle() -{ - if ( ! m_customDisplayStyle.empty() ) { - if ( m_customDisplayStyle.pop() ) { - if ( ! m_displayStyle.empty() ) { - m_displayStyle.pop(); - } - } - } -} - - -KFORMULA_NAMESPACE_END diff --git a/lib/kformula/contextstyle.cpp b/lib/kformula/contextstyle.cpp new file mode 100644 index 00000000..a744e02d --- /dev/null +++ b/lib/kformula/contextstyle.cpp @@ -0,0 +1,765 @@ +/* This file is part of the KDE project + Copyright (C) 2001 Andrea Rizzi + Ulrich Kuettler + 2006 Alfredo Beaumont Sainz + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include + +#include +#include + +#include "contextstyle.h" +#include "fontstyle.h" + + +KFORMULA_NAMESPACE_BEGIN + + +ContextStyle::ContextStyle() + : symbolFont( "Symbol" ), + defaultColor(TQt::black), numberColor(TQt::blue), + operatorColor(TQt::darkGreen), errorColor(TQt::darkRed), + emptyColor(TQt::blue), helpColor( TQt::gray ), m_sizeFactor( 0 ) +{ +// kdDebug() << "ContextStyle::ContextStyle" << endl +// << "defaultFont: " << defaultFont.rawName() << endl +// << "nameFont: " << nameFont.rawName() << endl +// << "numberFont: " << numberFont.rawName() << endl +// << "operatorFont: " << operatorFont.rawName() << endl +// << "symbolFont: " << symbolFont.rawName() << endl; + + textStyleValues[ displayStyle ].setup( 1. ); + textStyleValues[ textStyle ].setup( 1. ); + textStyleValues[ scriptStyle ].setup( .7 ); + textStyleValues[ scriptScriptStyle ].setup( .49 ); + + m_baseTextStyle = displayStyle; + + lineWidth = 1; + linearMovement = false; + centerSymbol = true; + m_syntaxHighlighting = true; + + m_fontStyle = 0; +} + + +ContextStyle::~ContextStyle() +{ + delete m_fontStyle; +} + + +void ContextStyle::init( bool init ) +{ + setup(); + setFontStyle( m_fontStyleName, init ); +} + + +void ContextStyle::setFontStyle( const TQString& fontStyle, bool init ) +{ + delete m_fontStyle; + m_fontStyleName = fontStyle; + m_fontStyle = new FontStyle(); + m_fontStyle->init( this, init ); +} + + +const SymbolTable& ContextStyle::symbolTable() const +{ + return *( m_fontStyle->symbolTable() ); +} + + +void ContextStyle::readConfig( TDEConfig* config, bool init ) +{ + config->setGroup( "kformula Font" ); + TQString fontName = config->readEntry( "defaultFont", "Times,12,-1,5,50,1,0,0,0,0" ); + defaultFont.fromString( fontName ); + fontName = config->readEntry( "nameFont", "Times,12,-1,5,50,0,0,0,0,0" ); + nameFont.fromString( fontName ); + fontName = config->readEntry( "numberFont", "Times,12,-1,5,50,0,0,0,0,0" ); + numberFont.fromString( fontName ); + fontName = config->readEntry( "operatorFont", "Times,12,-1,5,50,0,0,0,0,0" ); + operatorFont.fromString( fontName ); + TQString baseSize = config->readEntry( "baseSize", "20" ); + m_baseSize = baseSize.toInt(); + + if ( ! FontStyle::missingFonts( init ).isEmpty() ) { + kdWarning( DEBUGID) << "Not all basic fonts found\n"; + } + mathFont.fromString("Arev Sans"); + bracketFont.fromString("cmex10"); + + + // There's no gui right anymore but I'll leave it here... + config->setGroup( "kformula Color" ); + defaultColor = config->readColorEntry( "defaultColor", &defaultColor ); + numberColor = config->readColorEntry( "numberColor", &numberColor ); + operatorColor = config->readColorEntry( "operatorColor", &operatorColor ); + emptyColor = config->readColorEntry( "emptyColor", &emptyColor ); + errorColor = config->readColorEntry( "errorColor", &errorColor ); + helpColor = config->readColorEntry( "helpColor", &helpColor ); + + m_syntaxHighlighting = config->readBoolEntry( "syntaxHighlighting", true ); +} + +void ContextStyle::setZoomAndResolution( int zoom, int dpiX, int dpiY ) +{ + KoZoomHandler::setZoomAndResolution( zoom, dpiX, dpiY ); +} + +bool ContextStyle::setZoomAndResolution( int zoom, double zoomX, double zoomY, bool, bool ) +{ + bool changes = m_zoom != zoom || m_zoomedResolutionX != zoomX || m_zoomedResolutionY != zoomY; + m_zoom = zoom; + m_zoomedResolutionX = zoomX; + m_zoomedResolutionY = zoomY; + return changes; +} + +TQColor ContextStyle::getNumberColor() const +{ + if ( edit() && syntaxHighlighting() ) { + return numberColor; + } + return getDefaultColor(); +} + +TQColor ContextStyle::getOperatorColor() const +{ + if ( edit() && syntaxHighlighting() ) { + return operatorColor; + } + return getDefaultColor(); +} + +TQColor ContextStyle::getErrorColor() const +{ + if ( edit() && syntaxHighlighting() ) { + return errorColor; + } + return getDefaultColor(); +} + +TQColor ContextStyle::getEmptyColor() const +{ + if ( edit() && syntaxHighlighting() ) { + return emptyColor; + } + return getDefaultColor(); +} + +TQColor ContextStyle::getHelpColor() const +{ + if ( edit() && syntaxHighlighting() ) { + return helpColor; + } + return getDefaultColor(); +} + +void ContextStyle::setDefaultColor( const TQColor& color ) +{ + defaultColor = color; +} +void ContextStyle::setNumberColor( const TQColor& color ) +{ + numberColor = color; +} +void ContextStyle::setOperatorColor( const TQColor& color ) +{ + operatorColor = color; +} +void ContextStyle::setErrorColor( const TQColor& color ) +{ + errorColor = color; +} +void ContextStyle::setEmptyColor( const TQColor& color ) +{ + emptyColor = color; +} +void ContextStyle::setHelpColor( const TQColor& color ) +{ + helpColor = color; +} + +#if 0 +const TQStringList& ContextStyle::requestedFonts() const +{ + return m_requestedFonts; +} + +void ContextStyle::setRequestedFonts( const TQStringList& list ) +{ + m_requestedFonts = list; + //table.init( this ); +} +#endif + +double ContextStyle::getReductionFactor( TextStyle tstyle ) const +{ + return textStyleValues[ tstyle ].reductionFactor; +} + +luPt ContextStyle::getAdjustedSize( TextStyle tstyle, double factor ) const +{ + return tqRound( ptToLayoutUnitPt( m_sizeFactor + * m_baseSize + * getReductionFactor( tstyle ) + * factor + * zoom() / 100.0 ) ); +} + +luPixel ContextStyle::getSpace( TextStyle tstyle, SpaceWidth space, double factor ) const +{ + switch ( space ) { + case NEGTHIN: return -getThinSpace( tstyle, factor ); + case THIN: return getThinSpace( tstyle, factor ); + case MEDIUM: return getMediumSpace( tstyle, factor ); + case THICK: return getThickSpace( tstyle, factor ); + case QUAD: return getQuadSpace( tstyle, factor ); + } + return 0; +} + +luPixel ContextStyle::getThinSpace( TextStyle tstyle, double factor ) const +{ + return ptToPixelX( m_sizeFactor + * textStyleValues[ tstyle ].thinSpace( quad ) + * factor + * zoom() / 100.0 ); +} + +luPixel ContextStyle::getMediumSpace( TextStyle tstyle, double factor ) const +{ + return ptToPixelX( m_sizeFactor + * textStyleValues[ tstyle ].mediumSpace( quad ) + * factor + * zoom() / 100.0 ); +} + +luPixel ContextStyle::getThickSpace( TextStyle tstyle, double factor ) const +{ + return ptToPixelX( m_sizeFactor + * textStyleValues[ tstyle ].thickSpace( quad ) + * factor + * zoom() / 100.0 ); +} + +luPixel ContextStyle::getQuadSpace( TextStyle tstyle, double factor ) const +{ + return ptToPixelX( m_sizeFactor + * textStyleValues[ tstyle ].quadSpace( quad ) + * factor + * zoom() / 100.0 ); +} + +luPixel ContextStyle::axisHeight( TextStyle tstyle, double factor ) const +{ + //return ptToPixelY( textStyleValues[ tstyle ].axisHeight( m_axisHeight ) ); + return static_cast( m_sizeFactor + * textStyleValues[ tstyle ].axisHeight( m_axisHeight ) + * factor + * zoom() / 100.0 ); +} + +luPt ContextStyle::getBaseSize() const +{ + return static_cast( ptToLayoutUnitPt( m_sizeFactor*m_baseSize ) ); +} + +void ContextStyle::setBaseSize( int size ) +{ + //kdDebug( 40000 ) << "ContextStyle::setBaseSize" << endl; + if ( size != m_baseSize ) { + m_baseSize = size; + setup(); + } +} + +void ContextStyle::setSizeFactor( double factor ) +{ + m_sizeFactor = factor; +} + + +luPixel ContextStyle::getLineWidth( double factor ) const +{ + return ptToLayoutUnitPixX( m_sizeFactor*lineWidth*factor*zoom() / 100.0 ); +} + +luPixel ContextStyle::getEmptyRectWidth( double factor ) const +{ + return ptToLayoutUnitPixX( m_sizeFactor*m_baseSize*factor*(zoom() / 100.0)/1.8 ); +} + +luPixel ContextStyle::getEmptyRectHeight( double factor ) const +{ + return ptToLayoutUnitPixX( m_sizeFactor*m_baseSize*factor*(zoom() / 100.0)/1.8 ); +} + + +ContextStyle::TextStyle ContextStyle::convertTextStyleFraction( TextStyle tstyle ) const +{ + TextStyle result; + + switch ( tstyle ){ + case displayStyle: + result = textStyle; + break; + case textStyle: + result = scriptStyle; + break; + default: + result = scriptScriptStyle; + break; + } + + return result; +} + + +ContextStyle::TextStyle ContextStyle::convertTextStyleIndex( TextStyle tstyle ) const +{ + TextStyle result; + + switch ( tstyle ){ + case displayStyle: + result = scriptStyle; + break; + case textStyle: + result = scriptStyle; + break; + default: + result = scriptScriptStyle; + break; + } + + return result; +} + + +void ContextStyle::setup() +{ + luPt size = static_cast( m_baseSize ); + TQFont font = symbolFont; + font.setPointSize( size ); + TQFontMetrics fm( font ); + + // Or better the real space required? ( boundingRect ) + quad = ptToLayoutUnitPt( fm.width( 'M' ) ); + + font = TQFont(defaultFont); + font.setPointSize( size ); + TQFontMetrics fm2( font ); + //m_axisHeight = ptToLayoutUnitPt( fm2.strikeOutPos() ); + //ptToLayoutUnitPixY + //m_axisHeight = ptToLayoutUnitPt( pixelYToPt( fm2.strikeOutPos() ) ); + m_axisHeight = ptToLayoutUnitPixY( pixelYToPt( fm2.strikeOutPos() ) ); +} + + +double StyleAttributes::sizeFactor() const +{ + if ( m_size.empty() ) { +// kdWarning( DEBUGID ) << "SizeFactor stack is empty.\n"; + return 1.0; + } + return m_size.top(); +} + +bool StyleAttributes::customMathVariant() const +{ + if ( m_customMathVariant.empty() ) { + return false; + } + return m_customMathVariant.top(); +} + +CharStyle StyleAttributes::charStyle() const +{ + if ( m_charStyle.empty() ) { +// kdWarning( DEBUGID ) << "CharStyle stack is empty.\n"; + return anyChar; + } + return m_charStyle.top(); +} + +CharFamily StyleAttributes::charFamily() const +{ + if ( m_charFamily.empty() ) { +// kdWarning( DEBUGID ) << "CharFamily stack is empty.\n"; + return anyFamily; + } + return m_charFamily.top(); +} + +TQColor StyleAttributes::color() const +{ + if ( m_color.empty() ) { +// kdWarning( DEBUGID ) << "Color stack is empty.\n"; + return TQColor( TQt::black ); + //return getDefaultColor(); + } + return m_color.top(); +} + +TQColor StyleAttributes::background() const +{ + if ( m_background.empty() ) { +// kdWarning( DEBUGID ) << "Background stack is empty.\n"; + return TQColor( TQt::color0 ); + } + return m_background.top(); +} + +TQFont StyleAttributes::font() const +{ + if ( m_font.empty() ) { + return TQFont(); + } + return m_font.top(); +} + +bool StyleAttributes::fontWeight() const +{ + if ( m_fontWeight.empty() ) { + return false; + } + return m_fontWeight.top(); +} + +bool StyleAttributes::customFontWeight() const +{ + if ( m_customFontWeight.empty() ) { + return false; + } + return m_customFontWeight.top(); +} + +bool StyleAttributes::fontStyle() const +{ + if ( m_fontStyle.empty() ) { + return false; + } + return m_fontStyle.top(); +} + +bool StyleAttributes::customFontStyle() const +{ + if ( m_customFontStyle.empty() ) { + return false; + } + return m_customFontStyle.top(); +} + +bool StyleAttributes::customFont() const +{ + if ( m_customFontFamily.empty() ) { + return false; + } + return m_customFontFamily.top(); +} + +int StyleAttributes::scriptLevel() const +{ + if ( m_scriptLevel.empty() ) { + return 0; + } + return m_scriptLevel.top(); +} + +double StyleAttributes::scriptSizeMultiplier() const +{ + if ( m_scriptSizeMultiplier.empty() ) { + return scriptsizemultiplier; + } + return m_scriptSizeMultiplier.top(); +} + +double StyleAttributes::scriptMinSize() const +{ + if ( m_scriptMinSize.empty() ) { + return scriptminsize; + } + return m_scriptMinSize.top(); +} + +double StyleAttributes::veryVeryThinMathSpace() const +{ + if ( m_veryVeryThinMathSpace.empty() ) { + return veryverythinmathspace; + } + return m_veryVeryThinMathSpace.top(); +} + +double StyleAttributes::veryThinMathSpace() const +{ + if ( m_veryThinMathSpace.empty() ) { + return verythinmathspace; + } + return m_veryThinMathSpace.top(); +} + +double StyleAttributes::thinMathSpace() const +{ + if ( m_thinMathSpace.empty() ) { + return thinmathspace; + } + return m_thinMathSpace.top(); +} + +double StyleAttributes::mediumMathSpace() const +{ + if ( m_mediumMathSpace.empty() ) { + return mediummathspace; + } + return m_mediumMathSpace.top(); +} + +double StyleAttributes::thickMathSpace() const +{ + if ( m_thickMathSpace.empty() ) { + return thickmathspace; + } + return m_thickMathSpace.top(); +} + +double StyleAttributes::veryThickMathSpace() const +{ + if ( m_veryThickMathSpace.empty() ) { + return verythickmathspace; + } + return m_veryThickMathSpace.top(); +} + +double StyleAttributes::veryVeryThickMathSpace() const +{ + if ( m_veryVeryThickMathSpace.empty() ) { + return veryverythickmathspace; + } + return m_veryVeryThickMathSpace.top(); +} + +bool StyleAttributes::displayStyle() const +{ + if ( m_displayStyle.empty() ) { + return true; + } + return m_displayStyle.top(); +} + +bool StyleAttributes::customDisplayStyle() const +{ + if ( m_customDisplayStyle.empty() ) { + return false; + } + return m_customDisplayStyle.top(); +} + +double StyleAttributes::getSpace( SizeType type, double length ) const +{ + switch ( type ) { + case NegativeVeryVeryThinMathSpace: + return - veryVeryThinMathSpace(); + case NegativeVeryThinMathSpace: + return - veryThinMathSpace(); + case NegativeThinMathSpace: + return - thinMathSpace(); + case NegativeMediumMathSpace: + return - mediumMathSpace(); + case NegativeThickMathSpace: + return - thickMathSpace(); + case NegativeVeryThickMathSpace: + return - veryThickMathSpace(); + case NegativeVeryVeryThickMathSpace: + return - veryVeryThickMathSpace(); + case VeryVeryThinMathSpace: + return veryVeryThinMathSpace(); + case VeryThinMathSpace: + return veryThinMathSpace(); + case ThinMathSpace: + return thinMathSpace(); + case MediumMathSpace: + return mediumMathSpace(); + case ThickMathSpace: + return thickMathSpace(); + case VeryThickMathSpace: + return veryThickMathSpace(); + case VeryVeryThickMathSpace: + return veryVeryThickMathSpace(); + default: + break; + } + return length; +} + +void StyleAttributes::resetSize() +{ + if ( ! m_size.empty() ) { + m_size.pop(); + } +} + +void StyleAttributes::resetCharStyle() +{ + if ( ! m_charStyle.empty() ) { + m_charStyle.pop(); + } +} + +void StyleAttributes::resetCharFamily() +{ + if ( ! m_charFamily.empty() ) { + m_charFamily.pop(); + } +} + +void StyleAttributes::resetColor() +{ + if ( ! m_color.empty() ) { + m_color.pop(); + } +} + +void StyleAttributes::resetBackground() +{ + if ( ! m_background.empty() ) { + m_background.pop(); + } +} + +void StyleAttributes::resetFontFamily() +{ + if ( ! m_customFontFamily.empty() ) { + if ( m_customFontFamily.pop() ) { + if ( ! m_font.empty() ) { + m_font.pop(); + } + } + } +} + +void StyleAttributes::resetFontWeight() +{ + if ( ! m_customFontWeight.empty() ) { + if ( m_customFontWeight.pop() ) { + if ( ! m_fontWeight.empty() ) { + m_fontWeight.pop(); + } + } + } +} + +void StyleAttributes::resetFontStyle() +{ + if ( ! m_customFontStyle.empty() ) { + if ( m_customFontStyle.pop() ) { + if ( ! m_fontStyle.empty() ) { + m_fontStyle.pop(); + } + } + } +} + +void StyleAttributes::resetScriptLevel() +{ + if ( ! m_scriptLevel.empty() ) { + m_scriptLevel.pop(); + } +} + +void StyleAttributes::resetScriptSizeMultiplier() +{ + if ( ! m_scriptSizeMultiplier.empty() ) { + m_scriptSizeMultiplier.pop(); + } +} + +void StyleAttributes::resetScriptMinSize() +{ + if ( ! m_scriptMinSize.empty() ) { + m_scriptMinSize.pop(); + } +} + +void StyleAttributes::resetVeryVeryThinMathSpace() +{ + if ( ! m_veryVeryThinMathSpace.empty() ) { + m_veryVeryThinMathSpace.pop(); + } +} + +void StyleAttributes::resetVeryThinMathSpace() +{ + if ( ! m_veryThinMathSpace.empty() ) { + m_veryThinMathSpace.pop(); + } +} + +void StyleAttributes::resetThinMathSpace() +{ + if ( ! m_thinMathSpace.empty() ) { + m_thinMathSpace.pop(); + } +} + +void StyleAttributes::resetMediumMathSpace() +{ + if ( ! m_mediumMathSpace.empty() ) { + m_mediumMathSpace.pop(); + } +} + +void StyleAttributes::resetThickMathSpace() +{ + if ( ! m_thickMathSpace.empty() ) { + m_thickMathSpace.pop(); + } +} + +void StyleAttributes::resetVeryThickMathSpace() +{ + if ( ! m_veryThickMathSpace.empty() ) { + m_veryThickMathSpace.pop(); + } +} + +void StyleAttributes::resetVeryVeryThickMathSpace() +{ + if ( ! m_veryVeryThickMathSpace.empty() ) { + m_veryVeryThickMathSpace.pop(); + } +} + +void StyleAttributes::resetDisplayStyle() +{ + if ( ! m_customDisplayStyle.empty() ) { + if ( m_customDisplayStyle.pop() ) { + if ( ! m_displayStyle.empty() ) { + m_displayStyle.pop(); + } + } + } +} + + +KFORMULA_NAMESPACE_END diff --git a/lib/kformula/creationstrategy.cc b/lib/kformula/creationstrategy.cc deleted file mode 100644 index 592c744b..00000000 --- a/lib/kformula/creationstrategy.cc +++ /dev/null @@ -1,144 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2003 Ulrich Kuettler - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - -#include - -#include "bracketelement.h" -#include "creationstrategy.h" -#include "elementtype.h" -#include "fractionelement.h" -#include "identifierelement.h" -#include "indexelement.h" -#include "matrixelement.h" -#include "operatorelement.h" -#include "rootelement.h" -#include "sequenceelement.h" -#include "spaceelement.h" -#include "symbolelement.h" -#include "textelement.h" -#include "numberelement.h" - -KFORMULA_NAMESPACE_BEGIN - -BasicElement* OrdinaryCreationStrategy::createElement( TQString type, const TQDomElement& ) -{ - if ( type == "TEXT" ) return new TextElement(); - else if ( type == "EMPTY" ) return new EmptyElement(); - else if ( type == "SPACE" ) return new SpaceElement(); - else if ( type == "ROOT" ) return new RootElement(); - else if ( type == "BRACKET" ) return new BracketElement(); - else if ( type == "MATRIX" ) return new MatrixElement(); - else if ( type == "INDEX" ) return new IndexElement(); - else if ( type == "FRACTION" ) return new FractionElement(); - else if ( type == "SYMBOL" ) return new SymbolElement(); - else if ( type == "NAMESEQUENCE" ) return new NameSequence(); - else if ( type == "OVERLINE" ) return new OverlineElement(); - else if ( type == "UNDERLINE" ) return new UnderlineElement(); - else if ( type == "MULTILINE" ) return new MultilineElement(); - else if ( type == "SEQUENCE" ) { - kdWarning() << "malformed data: sequence inside sequence." << endl; - return 0; - } - return 0; -} - - -TextElement* OrdinaryCreationStrategy::createTextElement( const TQChar& ch, bool symbol ) -{ - return new TextElement( ch, symbol ); -} - -EmptyElement* OrdinaryCreationStrategy::createEmptyElement() -{ - return new EmptyElement; -} - -NameSequence* OrdinaryCreationStrategy::createNameSequence() -{ - return new NameSequence; -} - -BracketElement* OrdinaryCreationStrategy::createBracketElement( SymbolType lhs, SymbolType rhs ) -{ - return new BracketElement( lhs, rhs ); -} - -OverlineElement* OrdinaryCreationStrategy::createOverlineElement() -{ - return new OverlineElement; -} - -UnderlineElement* OrdinaryCreationStrategy::createUnderlineElement() -{ - return new UnderlineElement; -} - -MultilineElement* OrdinaryCreationStrategy::createMultilineElement() -{ - return new MultilineElement; -} - -SpaceElement* OrdinaryCreationStrategy::createSpaceElement( SpaceWidth width ) -{ - return new SpaceElement( width ); -} - -FractionElement* OrdinaryCreationStrategy::createFractionElement() -{ - return new FractionElement; -} - -RootElement* OrdinaryCreationStrategy::createRootElement() -{ - return new RootElement; -} - -SymbolElement* OrdinaryCreationStrategy::createSymbolElement( SymbolType type ) -{ - return new SymbolElement( type ); -} - -MatrixElement* OrdinaryCreationStrategy::createMatrixElement( uint rows, uint columns ) -{ - return new MatrixElement( rows, columns ); -} - -IndexElement* OrdinaryCreationStrategy::createIndexElement() -{ - return new IndexElement; -} - -IdentifierElement* OrdinaryCreationStrategy::createIdentifierElement() -{ - return new IdentifierElement(); -} - -OperatorElement* OrdinaryCreationStrategy::createOperatorElement() -{ - return new OperatorElement(); -} - -NumberElement* OrdinaryCreationStrategy::createNumberElement() -{ - return new NumberElement(); -} - - - -KFORMULA_NAMESPACE_END diff --git a/lib/kformula/creationstrategy.cpp b/lib/kformula/creationstrategy.cpp new file mode 100644 index 00000000..592c744b --- /dev/null +++ b/lib/kformula/creationstrategy.cpp @@ -0,0 +1,144 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Ulrich Kuettler + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include + +#include "bracketelement.h" +#include "creationstrategy.h" +#include "elementtype.h" +#include "fractionelement.h" +#include "identifierelement.h" +#include "indexelement.h" +#include "matrixelement.h" +#include "operatorelement.h" +#include "rootelement.h" +#include "sequenceelement.h" +#include "spaceelement.h" +#include "symbolelement.h" +#include "textelement.h" +#include "numberelement.h" + +KFORMULA_NAMESPACE_BEGIN + +BasicElement* OrdinaryCreationStrategy::createElement( TQString type, const TQDomElement& ) +{ + if ( type == "TEXT" ) return new TextElement(); + else if ( type == "EMPTY" ) return new EmptyElement(); + else if ( type == "SPACE" ) return new SpaceElement(); + else if ( type == "ROOT" ) return new RootElement(); + else if ( type == "BRACKET" ) return new BracketElement(); + else if ( type == "MATRIX" ) return new MatrixElement(); + else if ( type == "INDEX" ) return new IndexElement(); + else if ( type == "FRACTION" ) return new FractionElement(); + else if ( type == "SYMBOL" ) return new SymbolElement(); + else if ( type == "NAMESEQUENCE" ) return new NameSequence(); + else if ( type == "OVERLINE" ) return new OverlineElement(); + else if ( type == "UNDERLINE" ) return new UnderlineElement(); + else if ( type == "MULTILINE" ) return new MultilineElement(); + else if ( type == "SEQUENCE" ) { + kdWarning() << "malformed data: sequence inside sequence." << endl; + return 0; + } + return 0; +} + + +TextElement* OrdinaryCreationStrategy::createTextElement( const TQChar& ch, bool symbol ) +{ + return new TextElement( ch, symbol ); +} + +EmptyElement* OrdinaryCreationStrategy::createEmptyElement() +{ + return new EmptyElement; +} + +NameSequence* OrdinaryCreationStrategy::createNameSequence() +{ + return new NameSequence; +} + +BracketElement* OrdinaryCreationStrategy::createBracketElement( SymbolType lhs, SymbolType rhs ) +{ + return new BracketElement( lhs, rhs ); +} + +OverlineElement* OrdinaryCreationStrategy::createOverlineElement() +{ + return new OverlineElement; +} + +UnderlineElement* OrdinaryCreationStrategy::createUnderlineElement() +{ + return new UnderlineElement; +} + +MultilineElement* OrdinaryCreationStrategy::createMultilineElement() +{ + return new MultilineElement; +} + +SpaceElement* OrdinaryCreationStrategy::createSpaceElement( SpaceWidth width ) +{ + return new SpaceElement( width ); +} + +FractionElement* OrdinaryCreationStrategy::createFractionElement() +{ + return new FractionElement; +} + +RootElement* OrdinaryCreationStrategy::createRootElement() +{ + return new RootElement; +} + +SymbolElement* OrdinaryCreationStrategy::createSymbolElement( SymbolType type ) +{ + return new SymbolElement( type ); +} + +MatrixElement* OrdinaryCreationStrategy::createMatrixElement( uint rows, uint columns ) +{ + return new MatrixElement( rows, columns ); +} + +IndexElement* OrdinaryCreationStrategy::createIndexElement() +{ + return new IndexElement; +} + +IdentifierElement* OrdinaryCreationStrategy::createIdentifierElement() +{ + return new IdentifierElement(); +} + +OperatorElement* OrdinaryCreationStrategy::createOperatorElement() +{ + return new OperatorElement(); +} + +NumberElement* OrdinaryCreationStrategy::createNumberElement() +{ + return new NumberElement(); +} + + + +KFORMULA_NAMESPACE_END diff --git a/lib/kformula/elementtype.cc b/lib/kformula/elementtype.cc deleted file mode 100644 index bd2c3373..00000000 --- a/lib/kformula/elementtype.cc +++ /dev/null @@ -1,765 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2001 Andrea Rizzi - Ulrich Kuettler - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - -#include -#include -#include - -#include - -#include "basicelement.h" -#include "contextstyle.h" -#include "elementtype.h" -#include "sequenceelement.h" -#include "sequenceparser.h" -#include "textelement.h" - - -KFORMULA_NAMESPACE_BEGIN - -int ElementType::evilDestructionCount = 0; - -/* - * Converts CharStyle and CharFamily to the MathML 'mathvariant' - * attribute (see MathML spec 3.2.2). - */ -TQString format2variant( CharStyle style, CharFamily family ) -{ - TQString result; - - switch( family ) { - case normalFamily: - case anyFamily: - switch( style ) { - case normalChar: - result = "normal"; break; - case boldChar: - result = "bold"; break; - case italicChar: - result = "italic"; break; - case boldItalicChar: - result = "bold-italic"; break; - case anyChar: - break; - } - break; - case scriptFamily: - result = "script"; - if ( style == boldChar || style == boldItalicChar ) - result = "bold-" + result; - break; - case frakturFamily: - result = "fraktur"; - if ( style == boldChar || style == boldItalicChar ) - result = "bold-" + result; - break; - case doubleStruckFamily: - result = "double-struck"; break; - } - - return result; -} - -ElementType::ElementType( SequenceParser* parser ) - : from( parser->getStart() ), to( parser->getEnd() ), prev( 0 ) -{ - evilDestructionCount++; -} - -ElementType::~ElementType() -{ - delete prev; - evilDestructionCount--; -} - - -TQString ElementType::text( SequenceElement* seq ) const -{ - TQString str; - for ( uint i=start(); igetChild( i )->getCharacter() ); - } - return str; -} - - -luPt ElementType::getSpaceBefore( const ContextStyle&, - ContextStyle::TextStyle, - double ) -{ - return 0; -} - -luPt ElementType::getSpaceAfter( MultiElementType*, - const ContextStyle&, - ContextStyle::TextStyle, - double ) -{ - return 0; -} - -luPt ElementType::getSpaceAfter( OperatorType*, - const ContextStyle&, - ContextStyle::TextStyle, - double ) -{ - return 0; -} - -luPt ElementType::getSpaceAfter( RelationType*, - const ContextStyle&, - ContextStyle::TextStyle, - double ) -{ - return 0; -} - -luPt ElementType::getSpaceAfter( PunctuationType*, - const ContextStyle&, - ContextStyle::TextStyle, - double ) -{ - return 0; -} - -luPt ElementType::getSpaceAfter( BracketType*, - const ContextStyle&, - ContextStyle::TextStyle, - double ) -{ - return 0; -} - -luPt ElementType::getSpaceAfter( ComplexElementType*, - const ContextStyle&, - ContextStyle::TextStyle, - double ) -{ - return 0; -} - -luPt ElementType::getSpaceAfter( InnerElementType*, - const ContextStyle&, - ContextStyle::TextStyle, - double ) -{ - return 0; -} - -luPt ElementType::thinSpaceIfNotScript( const ContextStyle& context, - ContextStyle::TextStyle tstyle, - double factor ) -{ - if ( !context.isScript( tstyle ) ) { - return context.getThinSpace( tstyle, factor ); - } - return 0; -} - -luPt ElementType::mediumSpaceIfNotScript( const ContextStyle& context, - ContextStyle::TextStyle tstyle, - double factor ) -{ - if ( !context.isScript( tstyle ) ) { - return context.getMediumSpace( tstyle, factor ); - } - return 0; -} - -luPt ElementType::thickSpaceIfNotScript( const ContextStyle& context, - ContextStyle::TextStyle tstyle, - double factor ) -{ - if ( !context.isScript( tstyle ) ) { - return context.getThickSpace( tstyle, factor ); - } - return 0; -} - - -TQFont ElementType::getFont(const ContextStyle& context) -{ - return context.getDefaultFont(); -} - -void ElementType::setUpPainter(const ContextStyle& context, TQPainter& painter) -{ - painter.setPen(context.getDefaultColor()); -} - -void ElementType::append( ElementType* element ) -{ - element->prev = this; -} - -void ElementType::output() -{ - kdDebug( DEBUGID ) << start() << " - " << end() << endl; -} - -void ElementType::saveMathML( SequenceElement* se, TQDomDocument& doc, TQDomElement de, bool oasisFormat ) -{ - for ( uint i = from; i < to; ++i ) { - se->getChild( i )->writeMathML( doc, de, oasisFormat ); - } -} - - -SequenceType::SequenceType( SequenceParser* parser ) - : ElementType( parser ), last( 0 ) -{ - while ( true ) { - parser->nextToken(); - //cerr << "SequenceType::SequenceType(): " << parser->getTokenType() << " " - // << parser->getStart() << " " << parser->getEnd() << endl; - if ( parser->getTokenType() == END ) { - break; - } - ElementType* nextType = parser->getPrimitive(); - if ( nextType == 0 ) { - break; - } - if ( last != 0 ) { - last->append( nextType ); - } - last = nextType; - } -} - -SequenceType::~SequenceType() -{ - delete last; -} - - -void SequenceType::output() -{ -} - - -MultiElementType::MultiElementType( SequenceParser* parser ) - : ElementType( parser ) -{ - for ( uint i = start(); i < end(); i++ ) { - parser->setElementType( i, this ); - } - m_text = parser->text(); -} - - -luPt MultiElementType::getSpaceBefore( const ContextStyle& context, - ContextStyle::TextStyle tstyle, - double factor ) -{ - if ( getPrev() != 0 ) { - return getPrev()->getSpaceAfter( this, context, tstyle, factor ); - } - return 0; -} - -luPt MultiElementType::getSpaceAfter( OperatorType*, - const ContextStyle& context, - ContextStyle::TextStyle tstyle, - double factor ) -{ - return mediumSpaceIfNotScript( context, tstyle, factor ); -} - -luPt MultiElementType::getSpaceAfter( RelationType*, - const ContextStyle& context, - ContextStyle::TextStyle tstyle, - double factor ) -{ - return thickSpaceIfNotScript( context, tstyle, factor ); -} - -luPt MultiElementType::getSpaceAfter( InnerElementType*, - const ContextStyle& context, - ContextStyle::TextStyle tstyle, - double factor ) -{ - return thinSpaceIfNotScript( context, tstyle, factor ); -} - - -TextType::TextType( SequenceParser* parser ) - : MultiElementType( parser ) -{ -} - -void TextType::saveMathML( SequenceElement* se, TQDomDocument& doc, TQDomElement de, bool oasisFormat ) -{ - for ( uint i = start(); i < end(); ++i ) { - TQDomElement text = doc.createElement( oasisFormat ? "math:mi" : "mi" ); - BasicElement* be = se->getChild( i ); - TextElement* te = static_cast( be ); - TQString mathvariant = format2variant( te->getCharStyle(), te->getCharFamily()); - if ( !mathvariant.isNull() ) - text.setAttribute( "mathvariant", mathvariant ); - - text.appendChild( doc.createTextNode( be->getCharacter() ) ); - - de.appendChild( text ); - if ( i != end() - 1 ) { - TQDomElement op = doc.createElement( oasisFormat ? "math:mo" : "mo" ); - op.appendChild( doc.createEntityReference( "InvisibleTimes" ) ); - de.appendChild( op ); - } - } -} - - -NameType::NameType( SequenceParser* parser ) - : MultiElementType( parser ) -{ -} - -void NameType::saveMathML( SequenceElement* se, TQDomDocument& doc, TQDomElement de, bool oasisFormat ) -{ - se->getChild( start() )->writeMathML( doc, de, oasisFormat ); - - /* - TQDomElement name = doc.createElement( "mi" ); - TQString value; - for ( uint i = start(); i < end(); ++i ) { - BasicElement* be = se->getChild( i ); - //TextElement* te = static_cast( be ); - value += be->getCharacter(); - } - name.appendChild( doc.createTextNode( value ) ); - de.appendChild( name );*/ -} - - -TQFont NameType::getFont(const ContextStyle& context) -{ - return context.getNameFont(); -} - -NumberType::NumberType( SequenceParser* parser ) - : MultiElementType( parser ) -{ -} - -TQFont NumberType::getFont(const ContextStyle& context) -{ - return context.getNumberFont(); -} - -void NumberType::setUpPainter(const ContextStyle& context, TQPainter& painter) -{ - painter.setPen(context.getNumberColor()); -} - -void NumberType::saveMathML( SequenceElement* se, TQDomDocument& doc, TQDomElement de, bool oasisFormat ) -{ - TQDomElement name = doc.createElement( oasisFormat ? "math:mn" : "mn" ); - TQString value; - for ( uint i = start(); i < end(); ++i ) { - BasicElement* be = se->getChild( i ); - value += be->getCharacter(); - } - TextElement* te = static_cast( se->getChild( start() ) ); - TQString mathvariant = format2variant( te->getCharStyle(), te->getCharFamily() ); - if ( !mathvariant.isNull() ) - name.setAttribute( "mathvariant", mathvariant ); - - name.appendChild( doc.createTextNode( value ) ); - de.appendChild( name ); -} - - -SingleElementType::SingleElementType( SequenceParser* parser ) - : ElementType( parser ) -{ - parser->setElementType( start(), this ); -} - -AbstractOperatorType::AbstractOperatorType( SequenceParser* parser ) - : SingleElementType( parser ) -{ -} - -void AbstractOperatorType::saveMathML( SequenceElement* se, TQDomDocument& doc, TQDomElement de, bool oasisFormat ) -{ - TQDomElement op = doc.createElement( oasisFormat ? "math:mo" : "mo" ); - BasicElement* be = se->getChild( start() ); - if ( be->getCharacter().latin1() != 0 ) { - // latin-1 char - op.appendChild( doc.createTextNode( be->getCharacter() ) ); - } - else { - // unicode char - TQString s; - op.appendChild( doc.createEntityReference( s.sprintf( "#x%05X", be->getCharacter().unicode() ) ) ); - } - TextElement* te = static_cast( be ); - TQString mathvariant = format2variant( te->getCharStyle(), te->getCharFamily() ); - if ( !mathvariant.isNull() ) - op.setAttribute( "mathvariant", mathvariant ); - - de.appendChild( op ); -} - -OperatorType::OperatorType( SequenceParser* parser ) - : AbstractOperatorType( parser ) -{ -} - -luPt OperatorType::getSpaceBefore( const ContextStyle& context, - ContextStyle::TextStyle tstyle, - double factor ) -{ - if ( getPrev() != 0 ) { - return getPrev()->getSpaceAfter( this, context, tstyle, factor ); - } - return 0; -} - -luPt OperatorType::getSpaceAfter( MultiElementType*, - const ContextStyle& context, - ContextStyle::TextStyle tstyle, - double factor ) -{ - return mediumSpaceIfNotScript( context, tstyle, factor ); -} - -luPt OperatorType::getSpaceAfter( BracketType*, - const ContextStyle& context, - ContextStyle::TextStyle tstyle, - double factor ) -{ - return mediumSpaceIfNotScript( context, tstyle, factor ); -} - -luPt OperatorType::getSpaceAfter( ComplexElementType*, - const ContextStyle& context, - ContextStyle::TextStyle tstyle, - double factor ) -{ - return mediumSpaceIfNotScript( context, tstyle, factor ); -} - -luPt OperatorType::getSpaceAfter( InnerElementType*, - const ContextStyle& context, - ContextStyle::TextStyle tstyle, - double factor ) -{ - return mediumSpaceIfNotScript( context, tstyle, factor ); -} - - -TQFont OperatorType::getFont(const ContextStyle& context) -{ - return context.getOperatorFont(); -} - -void OperatorType::setUpPainter(const ContextStyle& context, TQPainter& painter) -{ - painter.setPen(context.getOperatorColor()); -} - - -RelationType::RelationType( SequenceParser* parser ) - : AbstractOperatorType( parser ) -{ -} - -luPt RelationType::getSpaceBefore( const ContextStyle& context, - ContextStyle::TextStyle tstyle, - double factor ) -{ - if ( getPrev() != 0 ) { - return getPrev()->getSpaceAfter( this, context, tstyle, factor ); - } - return 0; -} - -luPt RelationType::getSpaceAfter( MultiElementType*, - const ContextStyle& context, - ContextStyle::TextStyle tstyle, - double factor ) -{ - return thickSpaceIfNotScript( context, tstyle, factor ); -} - -luPt RelationType::getSpaceAfter( BracketType*, - const ContextStyle& context, - ContextStyle::TextStyle tstyle, - double factor ) -{ - return thickSpaceIfNotScript( context, tstyle, factor ); -} - -luPt RelationType::getSpaceAfter( ComplexElementType*, - const ContextStyle& context, - ContextStyle::TextStyle tstyle, - double factor ) -{ - return thickSpaceIfNotScript( context, tstyle, factor ); -} - -luPt RelationType::getSpaceAfter( InnerElementType*, - const ContextStyle& context, - ContextStyle::TextStyle tstyle, - double factor ) -{ - return thickSpaceIfNotScript( context, tstyle, factor ); -} - -TQFont RelationType::getFont( const ContextStyle& context ) -{ - return context.getOperatorFont(); -} - -void RelationType::setUpPainter( const ContextStyle& context, TQPainter& painter ) -{ - painter.setPen(context.getOperatorColor()); -} - - - -PunctuationType::PunctuationType( SequenceParser* parser ) - : AbstractOperatorType( parser ) -{ -} - -luPt PunctuationType::getSpaceBefore( const ContextStyle& context, - ContextStyle::TextStyle tstyle, - double factor ) -{ - if ( getPrev() != 0 ) { - return getPrev()->getSpaceAfter( this, context, tstyle, factor ); - } - return 0; -} - -luPt PunctuationType::getSpaceAfter( MultiElementType*, - const ContextStyle& context, - ContextStyle::TextStyle tstyle, - double factor ) -{ - return thinSpaceIfNotScript( context, tstyle, factor ); -} - -luPt PunctuationType::getSpaceAfter( RelationType*, - const ContextStyle& context, - ContextStyle::TextStyle tstyle, - double factor ) -{ - return thickSpaceIfNotScript( context, tstyle, factor ); -} - -luPt PunctuationType::getSpaceAfter( PunctuationType*, - const ContextStyle& context, - ContextStyle::TextStyle tstyle, - double factor ) -{ - return thinSpaceIfNotScript( context, tstyle, factor ); -} - -luPt PunctuationType::getSpaceAfter( BracketType*, - const ContextStyle& context, - ContextStyle::TextStyle tstyle, - double factor ) -{ - return thinSpaceIfNotScript( context, tstyle, factor ); -} - -luPt PunctuationType::getSpaceAfter( ComplexElementType*, - const ContextStyle& context, - ContextStyle::TextStyle tstyle, - double factor ) -{ - return thinSpaceIfNotScript( context, tstyle, factor ); -} - -luPt PunctuationType::getSpaceAfter( InnerElementType*, - const ContextStyle& context, - ContextStyle::TextStyle tstyle, - double factor ) -{ - return thinSpaceIfNotScript( context, tstyle, factor ); -} - -TQFont PunctuationType::getFont( const ContextStyle& context ) -{ - return context.getOperatorFont(); -} - -void PunctuationType::setUpPainter( const ContextStyle& context, TQPainter& painter ) -{ - painter.setPen( context.getDefaultColor() ); -} - - -BracketType::BracketType( SequenceParser* parser ) - : SingleElementType( parser ) -{ -} - -luPt BracketType::getSpaceBefore( const ContextStyle& context, - ContextStyle::TextStyle tstyle, - double factor ) -{ - if ( getPrev() != 0 ) { - return getPrev()->getSpaceAfter( this, context, tstyle, factor ); - } - return 0; -} - -luPt BracketType::getSpaceAfter( OperatorType*, - const ContextStyle& context, - ContextStyle::TextStyle tstyle, - double factor ) -{ - return mediumSpaceIfNotScript( context, tstyle, factor ); -} - -luPt BracketType::getSpaceAfter( RelationType*, - const ContextStyle& context, - ContextStyle::TextStyle tstyle, - double factor ) -{ - return thickSpaceIfNotScript( context, tstyle, factor ); -} - -luPt BracketType::getSpaceAfter( InnerElementType*, - const ContextStyle& context, - ContextStyle::TextStyle tstyle, - double factor ) -{ - return thinSpaceIfNotScript( context, tstyle, factor ); -} - - -ComplexElementType::ComplexElementType( SequenceParser* parser ) - : SingleElementType( parser ) -{ -} - -luPt ComplexElementType::getSpaceBefore( const ContextStyle& context, - ContextStyle::TextStyle tstyle, - double factor ) -{ - if ( getPrev() != 0 ) { - return getPrev()->getSpaceAfter( this, context, tstyle, factor ); - } - return 0; -} - -luPt ComplexElementType::getSpaceAfter( OperatorType*, - const ContextStyle& context, - ContextStyle::TextStyle tstyle, - double factor ) -{ - return mediumSpaceIfNotScript( context, tstyle, factor ); -} - -luPt ComplexElementType::getSpaceAfter( RelationType*, - const ContextStyle& context, - ContextStyle::TextStyle tstyle, - double factor ) -{ - return thickSpaceIfNotScript( context, tstyle, factor ); -} - -luPt ComplexElementType::getSpaceAfter( InnerElementType*, - const ContextStyle& context, - ContextStyle::TextStyle tstyle, - double factor ) -{ - return thinSpaceIfNotScript( context, tstyle, factor ); -} - - -InnerElementType::InnerElementType( SequenceParser* parser ) - : SingleElementType( parser ) -{ -} - -luPt InnerElementType::getSpaceBefore( const ContextStyle& context, - ContextStyle::TextStyle tstyle, - double factor ) -{ - if ( getPrev() != 0 ) { - return getPrev()->getSpaceAfter( this, context, tstyle, factor ); - } - return 0; -} - -luPt InnerElementType::getSpaceAfter( MultiElementType*, - const ContextStyle& context, - ContextStyle::TextStyle tstyle, - double factor ) -{ - return thinSpaceIfNotScript( context, tstyle, factor ); -} - -luPt InnerElementType::getSpaceAfter( OperatorType*, - const ContextStyle& context, - ContextStyle::TextStyle tstyle, - double factor ) -{ - return mediumSpaceIfNotScript( context, tstyle, factor ); -} - -luPt InnerElementType::getSpaceAfter( RelationType*, - const ContextStyle& context, - ContextStyle::TextStyle tstyle, - double factor ) -{ - return thickSpaceIfNotScript( context, tstyle, factor ); -} - -luPt InnerElementType::getSpaceAfter( PunctuationType*, - const ContextStyle& context, - ContextStyle::TextStyle tstyle, - double factor ) -{ - return thinSpaceIfNotScript( context, tstyle, factor ); -} - -luPt InnerElementType::getSpaceAfter( BracketType*, - const ContextStyle& context, - ContextStyle::TextStyle tstyle, - double factor ) -{ - return thinSpaceIfNotScript( context, tstyle, factor ); -} - -luPt InnerElementType::getSpaceAfter( ComplexElementType*, - const ContextStyle& context, - ContextStyle::TextStyle tstyle, - double factor ) -{ - return thinSpaceIfNotScript( context, tstyle, factor ); -} - -luPt InnerElementType::getSpaceAfter( InnerElementType*, - const ContextStyle& context, - ContextStyle::TextStyle tstyle, - double factor ) -{ - return thinSpaceIfNotScript( context, tstyle, factor ); -} - - -KFORMULA_NAMESPACE_END diff --git a/lib/kformula/elementtype.cpp b/lib/kformula/elementtype.cpp new file mode 100644 index 00000000..bd2c3373 --- /dev/null +++ b/lib/kformula/elementtype.cpp @@ -0,0 +1,765 @@ +/* This file is part of the KDE project + Copyright (C) 2001 Andrea Rizzi + Ulrich Kuettler + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include + +#include + +#include "basicelement.h" +#include "contextstyle.h" +#include "elementtype.h" +#include "sequenceelement.h" +#include "sequenceparser.h" +#include "textelement.h" + + +KFORMULA_NAMESPACE_BEGIN + +int ElementType::evilDestructionCount = 0; + +/* + * Converts CharStyle and CharFamily to the MathML 'mathvariant' + * attribute (see MathML spec 3.2.2). + */ +TQString format2variant( CharStyle style, CharFamily family ) +{ + TQString result; + + switch( family ) { + case normalFamily: + case anyFamily: + switch( style ) { + case normalChar: + result = "normal"; break; + case boldChar: + result = "bold"; break; + case italicChar: + result = "italic"; break; + case boldItalicChar: + result = "bold-italic"; break; + case anyChar: + break; + } + break; + case scriptFamily: + result = "script"; + if ( style == boldChar || style == boldItalicChar ) + result = "bold-" + result; + break; + case frakturFamily: + result = "fraktur"; + if ( style == boldChar || style == boldItalicChar ) + result = "bold-" + result; + break; + case doubleStruckFamily: + result = "double-struck"; break; + } + + return result; +} + +ElementType::ElementType( SequenceParser* parser ) + : from( parser->getStart() ), to( parser->getEnd() ), prev( 0 ) +{ + evilDestructionCount++; +} + +ElementType::~ElementType() +{ + delete prev; + evilDestructionCount--; +} + + +TQString ElementType::text( SequenceElement* seq ) const +{ + TQString str; + for ( uint i=start(); igetChild( i )->getCharacter() ); + } + return str; +} + + +luPt ElementType::getSpaceBefore( const ContextStyle&, + ContextStyle::TextStyle, + double ) +{ + return 0; +} + +luPt ElementType::getSpaceAfter( MultiElementType*, + const ContextStyle&, + ContextStyle::TextStyle, + double ) +{ + return 0; +} + +luPt ElementType::getSpaceAfter( OperatorType*, + const ContextStyle&, + ContextStyle::TextStyle, + double ) +{ + return 0; +} + +luPt ElementType::getSpaceAfter( RelationType*, + const ContextStyle&, + ContextStyle::TextStyle, + double ) +{ + return 0; +} + +luPt ElementType::getSpaceAfter( PunctuationType*, + const ContextStyle&, + ContextStyle::TextStyle, + double ) +{ + return 0; +} + +luPt ElementType::getSpaceAfter( BracketType*, + const ContextStyle&, + ContextStyle::TextStyle, + double ) +{ + return 0; +} + +luPt ElementType::getSpaceAfter( ComplexElementType*, + const ContextStyle&, + ContextStyle::TextStyle, + double ) +{ + return 0; +} + +luPt ElementType::getSpaceAfter( InnerElementType*, + const ContextStyle&, + ContextStyle::TextStyle, + double ) +{ + return 0; +} + +luPt ElementType::thinSpaceIfNotScript( const ContextStyle& context, + ContextStyle::TextStyle tstyle, + double factor ) +{ + if ( !context.isScript( tstyle ) ) { + return context.getThinSpace( tstyle, factor ); + } + return 0; +} + +luPt ElementType::mediumSpaceIfNotScript( const ContextStyle& context, + ContextStyle::TextStyle tstyle, + double factor ) +{ + if ( !context.isScript( tstyle ) ) { + return context.getMediumSpace( tstyle, factor ); + } + return 0; +} + +luPt ElementType::thickSpaceIfNotScript( const ContextStyle& context, + ContextStyle::TextStyle tstyle, + double factor ) +{ + if ( !context.isScript( tstyle ) ) { + return context.getThickSpace( tstyle, factor ); + } + return 0; +} + + +TQFont ElementType::getFont(const ContextStyle& context) +{ + return context.getDefaultFont(); +} + +void ElementType::setUpPainter(const ContextStyle& context, TQPainter& painter) +{ + painter.setPen(context.getDefaultColor()); +} + +void ElementType::append( ElementType* element ) +{ + element->prev = this; +} + +void ElementType::output() +{ + kdDebug( DEBUGID ) << start() << " - " << end() << endl; +} + +void ElementType::saveMathML( SequenceElement* se, TQDomDocument& doc, TQDomElement de, bool oasisFormat ) +{ + for ( uint i = from; i < to; ++i ) { + se->getChild( i )->writeMathML( doc, de, oasisFormat ); + } +} + + +SequenceType::SequenceType( SequenceParser* parser ) + : ElementType( parser ), last( 0 ) +{ + while ( true ) { + parser->nextToken(); + //cerr << "SequenceType::SequenceType(): " << parser->getTokenType() << " " + // << parser->getStart() << " " << parser->getEnd() << endl; + if ( parser->getTokenType() == END ) { + break; + } + ElementType* nextType = parser->getPrimitive(); + if ( nextType == 0 ) { + break; + } + if ( last != 0 ) { + last->append( nextType ); + } + last = nextType; + } +} + +SequenceType::~SequenceType() +{ + delete last; +} + + +void SequenceType::output() +{ +} + + +MultiElementType::MultiElementType( SequenceParser* parser ) + : ElementType( parser ) +{ + for ( uint i = start(); i < end(); i++ ) { + parser->setElementType( i, this ); + } + m_text = parser->text(); +} + + +luPt MultiElementType::getSpaceBefore( const ContextStyle& context, + ContextStyle::TextStyle tstyle, + double factor ) +{ + if ( getPrev() != 0 ) { + return getPrev()->getSpaceAfter( this, context, tstyle, factor ); + } + return 0; +} + +luPt MultiElementType::getSpaceAfter( OperatorType*, + const ContextStyle& context, + ContextStyle::TextStyle tstyle, + double factor ) +{ + return mediumSpaceIfNotScript( context, tstyle, factor ); +} + +luPt MultiElementType::getSpaceAfter( RelationType*, + const ContextStyle& context, + ContextStyle::TextStyle tstyle, + double factor ) +{ + return thickSpaceIfNotScript( context, tstyle, factor ); +} + +luPt MultiElementType::getSpaceAfter( InnerElementType*, + const ContextStyle& context, + ContextStyle::TextStyle tstyle, + double factor ) +{ + return thinSpaceIfNotScript( context, tstyle, factor ); +} + + +TextType::TextType( SequenceParser* parser ) + : MultiElementType( parser ) +{ +} + +void TextType::saveMathML( SequenceElement* se, TQDomDocument& doc, TQDomElement de, bool oasisFormat ) +{ + for ( uint i = start(); i < end(); ++i ) { + TQDomElement text = doc.createElement( oasisFormat ? "math:mi" : "mi" ); + BasicElement* be = se->getChild( i ); + TextElement* te = static_cast( be ); + TQString mathvariant = format2variant( te->getCharStyle(), te->getCharFamily()); + if ( !mathvariant.isNull() ) + text.setAttribute( "mathvariant", mathvariant ); + + text.appendChild( doc.createTextNode( be->getCharacter() ) ); + + de.appendChild( text ); + if ( i != end() - 1 ) { + TQDomElement op = doc.createElement( oasisFormat ? "math:mo" : "mo" ); + op.appendChild( doc.createEntityReference( "InvisibleTimes" ) ); + de.appendChild( op ); + } + } +} + + +NameType::NameType( SequenceParser* parser ) + : MultiElementType( parser ) +{ +} + +void NameType::saveMathML( SequenceElement* se, TQDomDocument& doc, TQDomElement de, bool oasisFormat ) +{ + se->getChild( start() )->writeMathML( doc, de, oasisFormat ); + + /* + TQDomElement name = doc.createElement( "mi" ); + TQString value; + for ( uint i = start(); i < end(); ++i ) { + BasicElement* be = se->getChild( i ); + //TextElement* te = static_cast( be ); + value += be->getCharacter(); + } + name.appendChild( doc.createTextNode( value ) ); + de.appendChild( name );*/ +} + + +TQFont NameType::getFont(const ContextStyle& context) +{ + return context.getNameFont(); +} + +NumberType::NumberType( SequenceParser* parser ) + : MultiElementType( parser ) +{ +} + +TQFont NumberType::getFont(const ContextStyle& context) +{ + return context.getNumberFont(); +} + +void NumberType::setUpPainter(const ContextStyle& context, TQPainter& painter) +{ + painter.setPen(context.getNumberColor()); +} + +void NumberType::saveMathML( SequenceElement* se, TQDomDocument& doc, TQDomElement de, bool oasisFormat ) +{ + TQDomElement name = doc.createElement( oasisFormat ? "math:mn" : "mn" ); + TQString value; + for ( uint i = start(); i < end(); ++i ) { + BasicElement* be = se->getChild( i ); + value += be->getCharacter(); + } + TextElement* te = static_cast( se->getChild( start() ) ); + TQString mathvariant = format2variant( te->getCharStyle(), te->getCharFamily() ); + if ( !mathvariant.isNull() ) + name.setAttribute( "mathvariant", mathvariant ); + + name.appendChild( doc.createTextNode( value ) ); + de.appendChild( name ); +} + + +SingleElementType::SingleElementType( SequenceParser* parser ) + : ElementType( parser ) +{ + parser->setElementType( start(), this ); +} + +AbstractOperatorType::AbstractOperatorType( SequenceParser* parser ) + : SingleElementType( parser ) +{ +} + +void AbstractOperatorType::saveMathML( SequenceElement* se, TQDomDocument& doc, TQDomElement de, bool oasisFormat ) +{ + TQDomElement op = doc.createElement( oasisFormat ? "math:mo" : "mo" ); + BasicElement* be = se->getChild( start() ); + if ( be->getCharacter().latin1() != 0 ) { + // latin-1 char + op.appendChild( doc.createTextNode( be->getCharacter() ) ); + } + else { + // unicode char + TQString s; + op.appendChild( doc.createEntityReference( s.sprintf( "#x%05X", be->getCharacter().unicode() ) ) ); + } + TextElement* te = static_cast( be ); + TQString mathvariant = format2variant( te->getCharStyle(), te->getCharFamily() ); + if ( !mathvariant.isNull() ) + op.setAttribute( "mathvariant", mathvariant ); + + de.appendChild( op ); +} + +OperatorType::OperatorType( SequenceParser* parser ) + : AbstractOperatorType( parser ) +{ +} + +luPt OperatorType::getSpaceBefore( const ContextStyle& context, + ContextStyle::TextStyle tstyle, + double factor ) +{ + if ( getPrev() != 0 ) { + return getPrev()->getSpaceAfter( this, context, tstyle, factor ); + } + return 0; +} + +luPt OperatorType::getSpaceAfter( MultiElementType*, + const ContextStyle& context, + ContextStyle::TextStyle tstyle, + double factor ) +{ + return mediumSpaceIfNotScript( context, tstyle, factor ); +} + +luPt OperatorType::getSpaceAfter( BracketType*, + const ContextStyle& context, + ContextStyle::TextStyle tstyle, + double factor ) +{ + return mediumSpaceIfNotScript( context, tstyle, factor ); +} + +luPt OperatorType::getSpaceAfter( ComplexElementType*, + const ContextStyle& context, + ContextStyle::TextStyle tstyle, + double factor ) +{ + return mediumSpaceIfNotScript( context, tstyle, factor ); +} + +luPt OperatorType::getSpaceAfter( InnerElementType*, + const ContextStyle& context, + ContextStyle::TextStyle tstyle, + double factor ) +{ + return mediumSpaceIfNotScript( context, tstyle, factor ); +} + + +TQFont OperatorType::getFont(const ContextStyle& context) +{ + return context.getOperatorFont(); +} + +void OperatorType::setUpPainter(const ContextStyle& context, TQPainter& painter) +{ + painter.setPen(context.getOperatorColor()); +} + + +RelationType::RelationType( SequenceParser* parser ) + : AbstractOperatorType( parser ) +{ +} + +luPt RelationType::getSpaceBefore( const ContextStyle& context, + ContextStyle::TextStyle tstyle, + double factor ) +{ + if ( getPrev() != 0 ) { + return getPrev()->getSpaceAfter( this, context, tstyle, factor ); + } + return 0; +} + +luPt RelationType::getSpaceAfter( MultiElementType*, + const ContextStyle& context, + ContextStyle::TextStyle tstyle, + double factor ) +{ + return thickSpaceIfNotScript( context, tstyle, factor ); +} + +luPt RelationType::getSpaceAfter( BracketType*, + const ContextStyle& context, + ContextStyle::TextStyle tstyle, + double factor ) +{ + return thickSpaceIfNotScript( context, tstyle, factor ); +} + +luPt RelationType::getSpaceAfter( ComplexElementType*, + const ContextStyle& context, + ContextStyle::TextStyle tstyle, + double factor ) +{ + return thickSpaceIfNotScript( context, tstyle, factor ); +} + +luPt RelationType::getSpaceAfter( InnerElementType*, + const ContextStyle& context, + ContextStyle::TextStyle tstyle, + double factor ) +{ + return thickSpaceIfNotScript( context, tstyle, factor ); +} + +TQFont RelationType::getFont( const ContextStyle& context ) +{ + return context.getOperatorFont(); +} + +void RelationType::setUpPainter( const ContextStyle& context, TQPainter& painter ) +{ + painter.setPen(context.getOperatorColor()); +} + + + +PunctuationType::PunctuationType( SequenceParser* parser ) + : AbstractOperatorType( parser ) +{ +} + +luPt PunctuationType::getSpaceBefore( const ContextStyle& context, + ContextStyle::TextStyle tstyle, + double factor ) +{ + if ( getPrev() != 0 ) { + return getPrev()->getSpaceAfter( this, context, tstyle, factor ); + } + return 0; +} + +luPt PunctuationType::getSpaceAfter( MultiElementType*, + const ContextStyle& context, + ContextStyle::TextStyle tstyle, + double factor ) +{ + return thinSpaceIfNotScript( context, tstyle, factor ); +} + +luPt PunctuationType::getSpaceAfter( RelationType*, + const ContextStyle& context, + ContextStyle::TextStyle tstyle, + double factor ) +{ + return thickSpaceIfNotScript( context, tstyle, factor ); +} + +luPt PunctuationType::getSpaceAfter( PunctuationType*, + const ContextStyle& context, + ContextStyle::TextStyle tstyle, + double factor ) +{ + return thinSpaceIfNotScript( context, tstyle, factor ); +} + +luPt PunctuationType::getSpaceAfter( BracketType*, + const ContextStyle& context, + ContextStyle::TextStyle tstyle, + double factor ) +{ + return thinSpaceIfNotScript( context, tstyle, factor ); +} + +luPt PunctuationType::getSpaceAfter( ComplexElementType*, + const ContextStyle& context, + ContextStyle::TextStyle tstyle, + double factor ) +{ + return thinSpaceIfNotScript( context, tstyle, factor ); +} + +luPt PunctuationType::getSpaceAfter( InnerElementType*, + const ContextStyle& context, + ContextStyle::TextStyle tstyle, + double factor ) +{ + return thinSpaceIfNotScript( context, tstyle, factor ); +} + +TQFont PunctuationType::getFont( const ContextStyle& context ) +{ + return context.getOperatorFont(); +} + +void PunctuationType::setUpPainter( const ContextStyle& context, TQPainter& painter ) +{ + painter.setPen( context.getDefaultColor() ); +} + + +BracketType::BracketType( SequenceParser* parser ) + : SingleElementType( parser ) +{ +} + +luPt BracketType::getSpaceBefore( const ContextStyle& context, + ContextStyle::TextStyle tstyle, + double factor ) +{ + if ( getPrev() != 0 ) { + return getPrev()->getSpaceAfter( this, context, tstyle, factor ); + } + return 0; +} + +luPt BracketType::getSpaceAfter( OperatorType*, + const ContextStyle& context, + ContextStyle::TextStyle tstyle, + double factor ) +{ + return mediumSpaceIfNotScript( context, tstyle, factor ); +} + +luPt BracketType::getSpaceAfter( RelationType*, + const ContextStyle& context, + ContextStyle::TextStyle tstyle, + double factor ) +{ + return thickSpaceIfNotScript( context, tstyle, factor ); +} + +luPt BracketType::getSpaceAfter( InnerElementType*, + const ContextStyle& context, + ContextStyle::TextStyle tstyle, + double factor ) +{ + return thinSpaceIfNotScript( context, tstyle, factor ); +} + + +ComplexElementType::ComplexElementType( SequenceParser* parser ) + : SingleElementType( parser ) +{ +} + +luPt ComplexElementType::getSpaceBefore( const ContextStyle& context, + ContextStyle::TextStyle tstyle, + double factor ) +{ + if ( getPrev() != 0 ) { + return getPrev()->getSpaceAfter( this, context, tstyle, factor ); + } + return 0; +} + +luPt ComplexElementType::getSpaceAfter( OperatorType*, + const ContextStyle& context, + ContextStyle::TextStyle tstyle, + double factor ) +{ + return mediumSpaceIfNotScript( context, tstyle, factor ); +} + +luPt ComplexElementType::getSpaceAfter( RelationType*, + const ContextStyle& context, + ContextStyle::TextStyle tstyle, + double factor ) +{ + return thickSpaceIfNotScript( context, tstyle, factor ); +} + +luPt ComplexElementType::getSpaceAfter( InnerElementType*, + const ContextStyle& context, + ContextStyle::TextStyle tstyle, + double factor ) +{ + return thinSpaceIfNotScript( context, tstyle, factor ); +} + + +InnerElementType::InnerElementType( SequenceParser* parser ) + : SingleElementType( parser ) +{ +} + +luPt InnerElementType::getSpaceBefore( const ContextStyle& context, + ContextStyle::TextStyle tstyle, + double factor ) +{ + if ( getPrev() != 0 ) { + return getPrev()->getSpaceAfter( this, context, tstyle, factor ); + } + return 0; +} + +luPt InnerElementType::getSpaceAfter( MultiElementType*, + const ContextStyle& context, + ContextStyle::TextStyle tstyle, + double factor ) +{ + return thinSpaceIfNotScript( context, tstyle, factor ); +} + +luPt InnerElementType::getSpaceAfter( OperatorType*, + const ContextStyle& context, + ContextStyle::TextStyle tstyle, + double factor ) +{ + return mediumSpaceIfNotScript( context, tstyle, factor ); +} + +luPt InnerElementType::getSpaceAfter( RelationType*, + const ContextStyle& context, + ContextStyle::TextStyle tstyle, + double factor ) +{ + return thickSpaceIfNotScript( context, tstyle, factor ); +} + +luPt InnerElementType::getSpaceAfter( PunctuationType*, + const ContextStyle& context, + ContextStyle::TextStyle tstyle, + double factor ) +{ + return thinSpaceIfNotScript( context, tstyle, factor ); +} + +luPt InnerElementType::getSpaceAfter( BracketType*, + const ContextStyle& context, + ContextStyle::TextStyle tstyle, + double factor ) +{ + return thinSpaceIfNotScript( context, tstyle, factor ); +} + +luPt InnerElementType::getSpaceAfter( ComplexElementType*, + const ContextStyle& context, + ContextStyle::TextStyle tstyle, + double factor ) +{ + return thinSpaceIfNotScript( context, tstyle, factor ); +} + +luPt InnerElementType::getSpaceAfter( InnerElementType*, + const ContextStyle& context, + ContextStyle::TextStyle tstyle, + double factor ) +{ + return thinSpaceIfNotScript( context, tstyle, factor ); +} + + +KFORMULA_NAMESPACE_END diff --git a/lib/kformula/encloseelement.cc b/lib/kformula/encloseelement.cc deleted file mode 100644 index 846f6bb2..00000000 --- a/lib/kformula/encloseelement.cc +++ /dev/null @@ -1,44 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2006 Alfredo Beaumont Sainz - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - -#include "encloseelement.h" - -KFORMULA_NAMESPACE_BEGIN - -EncloseElement::EncloseElement( BasicElement* parent ) : SequenceElement( parent ) { -} - -bool EncloseElement::readAttributesFromMathMLDom(const TQDomElement& element) -{ - if ( ! BasicElement::readAttributesFromMathMLDom( element ) ) { - return false; - } - - m_notation = element.attribute( "notation" ); - return true; -} - -void EncloseElement::writeMathMLAttributes( TQDomElement& element ) const -{ - if ( ! m_notation.isNull() ) { - element.setAttribute( "notation", m_notation ); - } -} - -KFORMULA_NAMESPACE_END diff --git a/lib/kformula/encloseelement.cpp b/lib/kformula/encloseelement.cpp new file mode 100644 index 00000000..846f6bb2 --- /dev/null +++ b/lib/kformula/encloseelement.cpp @@ -0,0 +1,44 @@ +/* This file is part of the KDE project + Copyright (C) 2006 Alfredo Beaumont Sainz + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "encloseelement.h" + +KFORMULA_NAMESPACE_BEGIN + +EncloseElement::EncloseElement( BasicElement* parent ) : SequenceElement( parent ) { +} + +bool EncloseElement::readAttributesFromMathMLDom(const TQDomElement& element) +{ + if ( ! BasicElement::readAttributesFromMathMLDom( element ) ) { + return false; + } + + m_notation = element.attribute( "notation" ); + return true; +} + +void EncloseElement::writeMathMLAttributes( TQDomElement& element ) const +{ + if ( ! m_notation.isNull() ) { + element.setAttribute( "notation", m_notation ); + } +} + +KFORMULA_NAMESPACE_END diff --git a/lib/kformula/entities.cc b/lib/kformula/entities.cc deleted file mode 100644 index c6696e1f..00000000 --- a/lib/kformula/entities.cc +++ /dev/null @@ -1,2037 +0,0 @@ -// -// Created: Tue Aug 29 16:20:33 2006 -// by: bynames.py -// from: byalpha.html -// -// WARNING! All changes made in this file will be lost! - -/* This file is part of the KDE project - Copyright (C) 2006 Alfredo Beaumont Sainz - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - - -#include "entities.h" - -KFORMULA_NAMESPACE_BEGIN - -const entityMap entities[] = { - {"AElig", 0x000C6} , - {"Aacute", 0x000C1} , - {"Abreve", 0x00102} , - {"Acirc", 0x000C2} , - {"Acy", 0x00410} , - {"Afr", 0x1D504} , - {"Agrave", 0x000C0} , - {"Amacr", 0x00100} , - {"And", 0x02A53} , - {"Aogon", 0x00104} , - {"Aopf", 0x1D538} , - {"ApplyFunction", 0x02061} , - {"Aring", 0x000C5} , - {"Ascr", 0x1D49C} , - {"Assign", 0x02254} , - {"Atilde", 0x000C3} , - {"Auml", 0x000C4} , - {"Backslash", 0x02216} , - {"Barv", 0x02AE7} , - {"Barwed", 0x02306} , - {"Bcy", 0x00411} , - {"Because", 0x02235} , - {"Bernoullis", 0x0212C} , - {"Bfr", 0x1D505} , - {"Bopf", 0x1D539} , - {"Breve", 0x002D8} , - {"Bscr", 0x0212C} , - {"Bumpeq", 0x0224E} , - {"CHcy", 0x00427} , - {"Cacute", 0x00106} , - {"Cap", 0x022D2} , - {"CapitalDifferentialD", 0x02145} , - {"Cayleys", 0x0212D} , - {"Ccaron", 0x0010C} , - {"Ccedil", 0x000C7} , - {"Ccirc", 0x00108} , - {"Cconint", 0x02230} , - {"Cdot", 0x0010A} , - {"Cedilla", 0x000B8} , - {"CenterDot", 0x000B7} , - {"Cfr", 0x0212D} , - {"CircleDot", 0x02299} , - {"CircleMinus", 0x02296} , - {"CirclePlus", 0x02295} , - {"CircleTimes", 0x02297} , - {"ClockwiseContourIntegral", 0x02232} , - {"CloseCurlyDoubleQuote", 0x0201D} , - {"CloseCurlyQuote", 0x02019} , - {"Colon", 0x02237} , - {"Colone", 0x02A74} , - {"Congruent", 0x02261} , - {"Conint", 0x0222F} , - {"ContourIntegral", 0x0222E} , - {"Copf", 0x02102} , - {"Coproduct", 0x02210} , - {"CounterClockwiseContourIntegral", 0x02233} , - {"Cross", 0x02A2F} , - {"Cscr", 0x1D49E} , - {"Cup", 0x022D3} , - {"CupCap", 0x0224D} , - {"DD", 0x02145} , - {"DDotrahd", 0x02911} , - {"DJcy", 0x00402} , - {"DScy", 0x00405} , - {"DZcy", 0x0040F} , - {"Dagger", 0x02021} , - {"Dagger", 0x02021} , - {"Darr", 0x021A1} , - {"Dashv", 0x02AE4} , - {"Dcaron", 0x0010E} , - {"Dcy", 0x00414} , - {"Del", 0x02207} , - {"Delta", 0x00394} , - {"Dfr", 0x1D507} , - {"DiacriticalAcute", 0x000B4} , - {"DiacriticalDot", 0x002D9} , - {"DiacriticalDoubleAcute", 0x002DD} , - {"DiacriticalGrave", 0x00060} , - {"DiacriticalTilde", 0x002DC} , - {"Diamond", 0x022C4} , - {"DifferentialD", 0x02146} , - {"Dopf", 0x1D53B} , - {"Dot", 0x000A8} , - {"DotDot", 0x020DC} , - {"DotEqual", 0x02250} , - {"DoubleContourIntegral", 0x0222F} , - {"DoubleDot", 0x000A8} , - {"DoubleDownArrow", 0x021D3} , - {"DoubleLeftArrow", 0x021D0} , - {"DoubleLeftRightArrow", 0x021D4} , - {"DoubleLeftTee", 0x02AE4} , - {"DoubleLongLeftArrow", 0x027F8} , - {"DoubleLongLeftRightArrow", 0x027FA} , - {"DoubleLongRightArrow", 0x027F9} , - {"DoubleRightArrow", 0x021D2} , - {"DoubleRightTee", 0x022A8} , - {"DoubleUpArrow", 0x021D1} , - {"DoubleUpDownArrow", 0x021D5} , - {"DoubleVerticalBar", 0x02225} , - {"DownArrow", 0x02193} , - {"DownArrowBar", 0x02913} , - {"DownArrowUpArrow", 0x021F5} , - {"DownBreve", 0x00311} , - {"DownLeftRightVector", 0x02950} , - {"DownLeftTeeVector", 0x0295E} , - {"DownLeftVector", 0x021BD} , - {"DownLeftVectorBar", 0x02956} , - {"DownRightTeeVector", 0x0295F} , - {"DownRightVector", 0x021C1} , - {"DownRightVectorBar", 0x02957} , - {"DownTee", 0x022A4} , - {"DownTeeArrow", 0x021A7} , - {"Downarrow", 0x021D3} , - {"Dscr", 0x1D49F} , - {"Dstrok", 0x00110} , - {"ENG", 0x0014A} , - {"ETH", 0x000D0} , - {"Eacute", 0x000C9} , - {"Ecaron", 0x0011A} , - {"Ecirc", 0x000CA} , - {"Ecy", 0x0042D} , - {"Edot", 0x00116} , - {"Efr", 0x1D508} , - {"Egrave", 0x000C8} , - {"Element", 0x02208} , - {"Emacr", 0x00112} , - {"EmptySmallSquare", 0x025FB} , - {"EmptyVerySmallSquare", 0x025AB} , - {"Eogon", 0x00118} , - {"Eopf", 0x1D53C} , - {"Equal", 0x02A75} , - {"EqualTilde", 0x02242} , - {"Equilibrium", 0x021CC} , - {"Escr", 0x02130} , - {"Esim", 0x02A73} , - {"Euml", 0x000CB} , - {"Exists", 0x02203} , - {"ExponentialE", 0x02147} , - {"Fcy", 0x00424} , - {"Ffr", 0x1D509} , - {"FilledSmallSquare", 0x025FC} , - {"FilledVerySmallSquare", 0x025AA} , - {"Fopf", 0x1D53D} , - {"ForAll", 0x02200} , - {"Fouriertrf", 0x02131} , - {"Fscr", 0x02131} , - {"GJcy", 0x00403} , - {"Gamma", 0x00393} , - {"Gammad", 0x003DC} , - {"Gbreve", 0x0011E} , - {"Gcedil", 0x00122} , - {"Gcirc", 0x0011C} , - {"Gcy", 0x00413} , - {"Gdot", 0x00120} , - {"Gfr", 0x1D50A} , - {"Gg", 0x022D9} , - {"Gopf", 0x1D53E} , - {"GreaterEqual", 0x02265} , - {"GreaterEqualLess", 0x022DB} , - {"GreaterFullEqual", 0x02267} , - {"GreaterGreater", 0x02AA2} , - {"GreaterLess", 0x02277} , - {"GreaterSlantEqual", 0x02A7E} , - {"GreaterTilde", 0x02273} , - {"Gscr", 0x1D4A2} , - {"Gt", 0x0226B} , - {"HARDcy", 0x0042A} , - {"Hacek", 0x002C7} , - {"Hat", 0x0005E} , - {"Hcirc", 0x00124} , - {"Hfr", 0x0210C} , - {"HilbertSpace", 0x0210B} , - {"Hopf", 0x0210D} , - {"HorizontalLine", 0x02500} , - {"Hscr", 0x0210B} , - {"Hstrok", 0x00126} , - {"HumpDownHump", 0x0224E} , - {"HumpEqual", 0x0224F} , - {"IEcy", 0x00415} , - {"IJlig", 0x00132} , - {"IOcy", 0x00401} , - {"Iacute", 0x000CD} , - {"Icirc", 0x000CE} , - {"Icy", 0x00418} , - {"Idot", 0x00130} , - {"Ifr", 0x02111} , - {"Igrave", 0x000CC} , - {"Im", 0x02111} , - {"Imacr", 0x0012A} , - {"ImaginaryI", 0x02148} , - {"Implies", 0x021D2} , - {"Int", 0x0222C} , - {"Integral", 0x0222B} , - {"Intersection", 0x022C2} , - {"InvisibleComma", 0x02063} , - {"InvisibleTimes", 0x02062} , - {"Iogon", 0x0012E} , - {"Iopf", 0x1D540} , - {"Iscr", 0x02110} , - {"Itilde", 0x00128} , - {"Iukcy", 0x00406} , - {"Iuml", 0x000CF} , - {"Jcirc", 0x00134} , - {"Jcy", 0x00419} , - {"Jfr", 0x1D50D} , - {"Jopf", 0x1D541} , - {"Jscr", 0x1D4A5} , - {"Jsercy", 0x00408} , - {"Jukcy", 0x00404} , - {"KHcy", 0x00425} , - {"KJcy", 0x0040C} , - {"Kcedil", 0x00136} , - {"Kcy", 0x0041A} , - {"Kfr", 0x1D50E} , - {"Kopf", 0x1D542} , - {"Kscr", 0x1D4A6} , - {"LJcy", 0x00409} , - {"Lacute", 0x00139} , - {"Lambda", 0x0039B} , - {"Lang", 0x0300A} , - {"Laplacetrf", 0x02112} , - {"Larr", 0x0219E} , - {"Lcaron", 0x0013D} , - {"Lcedil", 0x0013B} , - {"Lcy", 0x0041B} , - {"LeftAngleBracket", 0x02329} , - {"LeftArrow", 0x02190} , - {"LeftArrowBar", 0x021E4} , - {"LeftArrowRightArrow", 0x021C6} , - {"LeftCeiling", 0x02308} , - {"LeftDoubleBracket", 0x0301A} , - {"LeftDownTeeVector", 0x02961} , - {"LeftDownVector", 0x021C3} , - {"LeftDownVectorBar", 0x02959} , - {"LeftFloor", 0x0230A} , - {"LeftRightArrow", 0x02194} , - {"LeftRightVector", 0x0294E} , - {"LeftTee", 0x022A3} , - {"LeftTeeArrow", 0x021A4} , - {"LeftTeeVector", 0x0295A} , - {"LeftTriangle", 0x022B2} , - {"LeftTriangleBar", 0x029CF} , - {"LeftTriangleEqual", 0x022B4} , - {"LeftUpDownVector", 0x02951} , - {"LeftUpTeeVector", 0x02960} , - {"LeftUpVector", 0x021BF} , - {"LeftUpVectorBar", 0x02958} , - {"LeftVector", 0x021BC} , - {"LeftVectorBar", 0x02952} , - {"Leftarrow", 0x021D0} , - {"Leftrightarrow", 0x021D4} , - {"LessEqualGreater", 0x022DA} , - {"LessFullEqual", 0x02266} , - {"LessGreater", 0x02276} , - {"LessLess", 0x02AA1} , - {"LessSlantEqual", 0x02A7D} , - {"LessTilde", 0x02272} , - {"Lfr", 0x1D50F} , - {"Ll", 0x022D8} , - {"Lleftarrow", 0x021DA} , - {"Lmidot", 0x0013F} , - {"LongLeftArrow", 0x027F5} , - {"LongLeftRightArrow", 0x027F7} , - {"LongRightArrow", 0x027F6} , - {"Longleftarrow", 0x027F8} , - {"Longleftrightarrow", 0x027FA} , - {"Longrightarrow", 0x027F9} , - {"Lopf", 0x1D543} , - {"LowerLeftArrow", 0x02199} , - {"LowerRightArrow", 0x02198} , - {"Lscr", 0x02112} , - {"Lsh", 0x021B0} , - {"Lstrok", 0x00141} , - {"Lt", 0x0226A} , - {"Map", 0x02905} , - {"Mcy", 0x0041C} , - {"MediumSpace", 0x0205F} , - {"Mellintrf", 0x02133} , - {"Mfr", 0x1D510} , - {"MinusPlus", 0x02213} , - {"Mopf", 0x1D544} , - {"Mscr", 0x02133} , - {"NJcy", 0x0040A} , - {"Nacute", 0x00143} , - {"Ncaron", 0x00147} , - {"Ncedil", 0x00145} , - {"Ncy", 0x0041D} , - {"NegativeMediumSpace", 0x0200B} , - {"NegativeThickSpace", 0x0200B} , - {"NegativeThinSpace", 0x0200B} , - {"NegativeVeryThinSpace", 0x0200B} , - {"NestedGreaterGreater", 0x0226B} , - {"NestedLessLess", 0x0226A} , - {"NewLine", 0x0000A} , - {"Nfr", 0x1D511} , - {"NoBreak", 0x02060} , - {"NonBreakingSpace", 0x000A0} , - {"Nopf", 0x02115} , - {"Not", 0x02AEC} , - {"NotCongruent", 0x02262} , - {"NotCupCap", 0x0226D} , - {"NotDoubleVerticalBar", 0x02226} , - {"NotElement", 0x02209} , - {"NotEqual", 0x02260} , - {"NotExists", 0x02204} , - {"NotGreater", 0x0226F} , - {"NotGreaterEqual", 0x02271} , - {"NotGreaterLess", 0x02279} , - {"NotGreaterTilde", 0x02275} , - {"NotLeftTriangle", 0x022EA} , - {"NotLeftTriangleEqual", 0x022EC} , - {"NotLess", 0x0226E} , - {"NotLessEqual", 0x02270} , - {"NotLessGreater", 0x02278} , - {"NotLessTilde", 0x02274} , - {"NotPrecedes", 0x02280} , - {"NotPrecedesSlantEqual", 0x022E0} , - {"NotReverseElement", 0x0220C} , - {"NotRightTriangle", 0x022EB} , - {"NotRightTriangleEqual", 0x022ED} , - {"NotSquareSubsetEqual", 0x022E2} , - {"NotSquareSupersetEqual", 0x022E3} , - {"NotSubsetEqual", 0x02288} , - {"NotSucceeds", 0x02281} , - {"NotSucceedsSlantEqual", 0x022E1} , - {"NotSupersetEqual", 0x02289} , - {"NotTilde", 0x02241} , - {"NotTildeEqual", 0x02244} , - {"NotTildeFullEqual", 0x02247} , - {"NotTildeTilde", 0x02249} , - {"NotVerticalBar", 0x02224} , - {"Nscr", 0x1D4A9} , - {"Ntilde", 0x000D1} , - {"OElig", 0x00152} , - {"Oacute", 0x000D3} , - {"Ocirc", 0x000D4} , - {"Ocy", 0x0041E} , - {"Odblac", 0x00150} , - {"Ofr", 0x1D512} , - {"Ograve", 0x000D2} , - {"Omacr", 0x0014C} , - {"Omega", 0x003A9} , - {"Oopf", 0x1D546} , - {"OpenCurlyDoubleQuote", 0x0201C} , - {"OpenCurlyQuote", 0x02018} , - {"Or", 0x02A54} , - {"Oscr", 0x1D4AA} , - {"Oslash", 0x000D8} , - {"Otilde", 0x000D5} , - {"Otimes", 0x02A37} , - {"Ouml", 0x000D6} , - {"OverBar", 0x000AF} , - {"OverBrace", 0x0FE37} , - {"OverBracket", 0x023B4} , - {"OverParenthesis", 0x0FE35} , - {"PartialD", 0x02202} , - {"Pcy", 0x0041F} , - {"Pfr", 0x1D513} , - {"Phi", 0x003A6} , - {"Pi", 0x003A0} , - {"PlusMinus", 0x000B1} , - {"Poincareplane", 0x0210C} , - {"Popf", 0x02119} , - {"Pr", 0x02ABB} , - {"Precedes", 0x0227A} , - {"PrecedesEqual", 0x02AAF} , - {"PrecedesSlantEqual", 0x0227C} , - {"PrecedesTilde", 0x0227E} , - {"Prime", 0x02033} , - {"Product", 0x0220F} , - {"Proportion", 0x02237} , - {"Proportional", 0x0221D} , - {"Pscr", 0x1D4AB} , - {"Psi", 0x003A8} , - {"Qfr", 0x1D514} , - {"Qopf", 0x0211A} , - {"Qscr", 0x1D4AC} , - {"RBarr", 0x02910} , - {"Racute", 0x00154} , - {"Rang", 0x0300B} , - {"Rarr", 0x021A0} , - {"Rarrtl", 0x02916} , - {"Rcaron", 0x00158} , - {"Rcedil", 0x00156} , - {"Rcy", 0x00420} , - {"Re", 0x0211C} , - {"ReverseElement", 0x0220B} , - {"ReverseEquilibrium", 0x021CB} , - {"ReverseUpEquilibrium", 0x0296F} , - {"Rfr", 0x0211C} , - {"RightAngleBracket", 0x0232A} , - {"RightArrow", 0x02192} , - {"RightArrowBar", 0x021E5} , - {"RightArrowLeftArrow", 0x021C4} , - {"RightCeiling", 0x02309} , - {"RightDoubleBracket", 0x0301B} , - {"RightDownTeeVector", 0x0295D} , - {"RightDownVector", 0x021C2} , - {"RightDownVectorBar", 0x02955} , - {"RightFloor", 0x0230B} , - {"RightTee", 0x022A2} , - {"RightTeeArrow", 0x021A6} , - {"RightTeeVector", 0x0295B} , - {"RightTriangle", 0x022B3} , - {"RightTriangleBar", 0x029D0} , - {"RightTriangleEqual", 0x022B5} , - {"RightUpDownVector", 0x0294F} , - {"RightUpTeeVector", 0x0295C} , - {"RightUpVector", 0x021BE} , - {"RightUpVectorBar", 0x02954} , - {"RightVector", 0x021C0} , - {"RightVectorBar", 0x02953} , - {"Rightarrow", 0x021D2} , - {"Ropf", 0x0211D} , - {"RoundImplies", 0x02970} , - {"Rrightarrow", 0x021DB} , - {"Rscr", 0x0211B} , - {"Rsh", 0x021B1} , - {"RuleDelayed", 0x029F4} , - {"SHCHcy", 0x00429} , - {"SHcy", 0x00428} , - {"SOFTcy", 0x0042C} , - {"Sacute", 0x0015A} , - {"Sc", 0x02ABC} , - {"Scaron", 0x00160} , - {"Scedil", 0x0015E} , - {"Scirc", 0x0015C} , - {"Scy", 0x00421} , - {"Sfr", 0x1D516} , - {"ShortDownArrow", 0x02193} , - {"ShortLeftArrow", 0x02190} , - {"ShortRightArrow", 0x02192} , - {"ShortUpArrow", 0x02191} , - {"Sigma", 0x003A3} , - {"SmallCircle", 0x02218} , - {"Sopf", 0x1D54A} , - {"Sqrt", 0x0221A} , - {"Square", 0x025A1} , - {"SquareIntersection", 0x02293} , - {"SquareSubset", 0x0228F} , - {"SquareSubsetEqual", 0x02291} , - {"SquareSuperset", 0x02290} , - {"SquareSupersetEqual", 0x02292} , - {"SquareUnion", 0x02294} , - {"Sscr", 0x1D4AE} , - {"Star", 0x022C6} , - {"Sub", 0x022D0} , - {"Subset", 0x022D0} , - {"SubsetEqual", 0x02286} , - {"Succeeds", 0x0227B} , - {"SucceedsEqual", 0x02AB0} , - {"SucceedsSlantEqual", 0x0227D} , - {"SucceedsTilde", 0x0227F} , - {"SuchThat", 0x0220B} , - {"Sum", 0x02211} , - {"Sup", 0x022D1} , - {"Superset", 0x02283} , - {"SupersetEqual", 0x02287} , - {"Supset", 0x022D1} , - {"THORN", 0x000DE} , - {"TSHcy", 0x0040B} , - {"TScy", 0x00426} , - {"Tab", 0x00009} , - {"Tcaron", 0x00164} , - {"Tcedil", 0x00162} , - {"Tcy", 0x00422} , - {"Tfr", 0x1D517} , - {"Therefore", 0x02234} , - {"Theta", 0x00398} , - {"ThinSpace", 0x02009} , - {"Tilde", 0x0223C} , - {"TildeEqual", 0x02243} , - {"TildeFullEqual", 0x02245} , - {"TildeTilde", 0x02248} , - {"Topf", 0x1D54B} , - {"TripleDot", 0x020DB} , - {"Tscr", 0x1D4AF} , - {"Tstrok", 0x00166} , - {"Uacute", 0x000DA} , - {"Uarr", 0x0219F} , - {"Uarrocir", 0x02949} , - {"Ubrcy", 0x0040E} , - {"Ubreve", 0x0016C} , - {"Ucirc", 0x000DB} , - {"Ucy", 0x00423} , - {"Udblac", 0x00170} , - {"Ufr", 0x1D518} , - {"Ugrave", 0x000D9} , - {"Umacr", 0x0016A} , - {"UnderBar", 0x00332} , - {"UnderBrace", 0x0FE38} , - {"UnderBracket", 0x023B5} , - {"UnderParenthesis", 0x0FE36} , - {"Union", 0x022C3} , - {"UnionPlus", 0x0228E} , - {"Uogon", 0x00172} , - {"Uopf", 0x1D54C} , - {"UpArrow", 0x02191} , - {"UpArrowBar", 0x02912} , - {"UpArrowDownArrow", 0x021C5} , - {"UpDownArrow", 0x02195} , - {"UpEquilibrium", 0x0296E} , - {"UpTee", 0x022A5} , - {"UpTeeArrow", 0x021A5} , - {"Uparrow", 0x021D1} , - {"Updownarrow", 0x021D5} , - {"UpperLeftArrow", 0x02196} , - {"UpperRightArrow", 0x02197} , - {"Upsi", 0x003D2} , - {"Upsilon", 0x003A5} , - {"Uring", 0x0016E} , - {"Uscr", 0x1D4B0} , - {"Utilde", 0x00168} , - {"Uuml", 0x000DC} , - {"VDash", 0x022AB} , - {"Vbar", 0x02AEB} , - {"Vcy", 0x00412} , - {"Vdash", 0x022A9} , - {"Vdashl", 0x02AE6} , - {"Vee", 0x022C1} , - {"Verbar", 0x02016} , - {"Vert", 0x02016} , - {"VerticalBar", 0x02223} , - {"VerticalLine", 0x0007C} , - {"VerticalSeparator", 0x02758} , - {"VerticalTilde", 0x02240} , - {"VeryThinSpace", 0x0200A} , - {"Vfr", 0x1D519} , - {"Vopf", 0x1D54D} , - {"Vscr", 0x1D4B1} , - {"Vvdash", 0x022AA} , - {"Wcirc", 0x00174} , - {"Wedge", 0x022C0} , - {"Wfr", 0x1D51A} , - {"Wopf", 0x1D54E} , - {"Wscr", 0x1D4B2} , - {"Xfr", 0x1D51B} , - {"Xi", 0x0039E} , - {"Xopf", 0x1D54F} , - {"Xscr", 0x1D4B3} , - {"YAcy", 0x0042F} , - {"YIcy", 0x00407} , - {"YUcy", 0x0042E} , - {"Yacute", 0x000DD} , - {"Ycirc", 0x00176} , - {"Ycy", 0x0042B} , - {"Yfr", 0x1D51C} , - {"Yopf", 0x1D550} , - {"Yscr", 0x1D4B4} , - {"Yuml", 0x00178} , - {"ZHcy", 0x00416} , - {"Zacute", 0x00179} , - {"Zcaron", 0x0017D} , - {"Zcy", 0x00417} , - {"Zdot", 0x0017B} , - {"ZeroWidthSpace", 0x0200B} , - {"Zfr", 0x02128} , - {"Zopf", 0x02124} , - {"Zscr", 0x1D4B5} , - {"aacute", 0x000E1} , - {"abreve", 0x00103} , - {"ac", 0x0223E} , - {"acd", 0x0223F} , - {"acirc", 0x000E2} , - {"acute", 0x000B4} , - {"acy", 0x00430} , - {"aelig", 0x000E6} , - {"af", 0x02061} , - {"afr", 0x1D51E} , - {"agrave", 0x000E0} , - {"aleph", 0x02135} , - {"alpha", 0x003B1} , - {"amacr", 0x00101} , - {"amalg", 0x02A3F} , - {"amp", 0x00026} , - {"and", 0x02227} , - {"andand", 0x02A55} , - {"andd", 0x02A5C} , - {"andslope", 0x02A58} , - {"andv", 0x02A5A} , - {"ang", 0x02220} , - {"ange", 0x029A4} , - {"angle", 0x02220} , - {"angmsd", 0x02221} , - {"angmsdaa", 0x029A8} , - {"angmsdab", 0x029A9} , - {"angmsdac", 0x029AA} , - {"angmsdad", 0x029AB} , - {"angmsdae", 0x029AC} , - {"angmsdaf", 0x029AD} , - {"angmsdag", 0x029AE} , - {"angmsdah", 0x029AF} , - {"angrt", 0x0221F} , - {"angrtvb", 0x022BE} , - {"angrtvbd", 0x0299D} , - {"angsph", 0x02222} , - {"angst", 0x0212B} , - {"angzarr", 0x0237C} , - {"aogon", 0x00105} , - {"aopf", 0x1D552} , - {"ap", 0x02248} , - {"apE", 0x02A70} , - {"apacir", 0x02A6F} , - {"ape", 0x0224A} , - {"apid", 0x0224B} , - {"apos", 0x00027} , - {"approx", 0x02248} , - {"approxeq", 0x0224A} , - {"aring", 0x000E5} , - {"ascr", 0x1D4B6} , - {"ast", 0x0002A} , - {"asymp", 0x02248} , - {"asympeq", 0x0224D} , - {"atilde", 0x000E3} , - {"auml", 0x000E4} , - {"awconint", 0x02233} , - {"awint", 0x02A11} , - {"bNot", 0x02AED} , - {"backcong", 0x0224C} , - {"backepsilon", 0x003F6} , - {"backprime", 0x02035} , - {"backsim", 0x0223D} , - {"backsimeq", 0x022CD} , - {"barvee", 0x022BD} , - {"barwed", 0x02305} , - {"barwedge", 0x02305} , - {"bbrk", 0x023B5} , - {"bbrktbrk", 0x023B6} , - {"bcong", 0x0224C} , - {"bcy", 0x00431} , - {"becaus", 0x02235} , - {"because", 0x02235} , - {"bemptyv", 0x029B0} , - {"bepsi", 0x003F6} , - {"bernou", 0x0212C} , - {"beta", 0x003B2} , - {"beth", 0x02136} , - {"between", 0x0226C} , - {"bfr", 0x1D51F} , - {"bigcap", 0x022C2} , - {"bigcirc", 0x025EF} , - {"bigcup", 0x022C3} , - {"bigodot", 0x02A00} , - {"bigoplus", 0x02A01} , - {"bigotimes", 0x02A02} , - {"bigsqcup", 0x02A06} , - {"bigstar", 0x02605} , - {"bigtriangledown", 0x025BD} , - {"bigtriangleup", 0x025B3} , - {"biguplus", 0x02A04} , - {"bigvee", 0x022C1} , - {"bigwedge", 0x022C0} , - {"bkarow", 0x0290D} , - {"blacklozenge", 0x029EB} , - {"blacksquare", 0x025AA} , - {"blacktriangle", 0x025B4} , - {"blacktriangledown", 0x025BE} , - {"blacktriangleleft", 0x025C2} , - {"blacktriangleright", 0x025B8} , - {"blank", 0x02423} , - {"blk12", 0x02592} , - {"blk14", 0x02591} , - {"blk34", 0x02593} , - {"block", 0x02588} , - {"bnot", 0x02310} , - {"bopf", 0x1D553} , - {"bot", 0x022A5} , - {"bottom", 0x022A5} , - {"bowtie", 0x022C8} , - {"boxDL", 0x02557} , - {"boxDR", 0x02554} , - {"boxDl", 0x02556} , - {"boxDr", 0x02553} , - {"boxH", 0x02550} , - {"boxHD", 0x02566} , - {"boxHU", 0x02569} , - {"boxHd", 0x02564} , - {"boxHu", 0x02567} , - {"boxUL", 0x0255D} , - {"boxUR", 0x0255A} , - {"boxUl", 0x0255C} , - {"boxUr", 0x02559} , - {"boxV", 0x02551} , - {"boxVH", 0x0256C} , - {"boxVL", 0x02563} , - {"boxVR", 0x02560} , - {"boxVh", 0x0256B} , - {"boxVl", 0x02562} , - {"boxVr", 0x0255F} , - {"boxbox", 0x029C9} , - {"boxdL", 0x02555} , - {"boxdR", 0x02552} , - {"boxdl", 0x02510} , - {"boxdr", 0x0250C} , - {"boxh", 0x02500} , - {"boxhD", 0x02565} , - {"boxhU", 0x02568} , - {"boxhd", 0x0252C} , - {"boxhu", 0x02534} , - {"boxminus", 0x0229F} , - {"boxplus", 0x0229E} , - {"boxtimes", 0x022A0} , - {"boxuL", 0x0255B} , - {"boxuR", 0x02558} , - {"boxul", 0x02518} , - {"boxur", 0x02514} , - {"boxv", 0x02502} , - {"boxvH", 0x0256A} , - {"boxvL", 0x02561} , - {"boxvR", 0x0255E} , - {"boxvh", 0x0253C} , - {"boxvl", 0x02524} , - {"boxvr", 0x0251C} , - {"bprime", 0x02035} , - {"breve", 0x002D8} , - {"brvbar", 0x000A6} , - {"bscr", 0x1D4B7} , - {"bsemi", 0x0204F} , - {"bsim", 0x0223D} , - {"bsime", 0x022CD} , - {"bsol", 0x0005C} , - {"bsolb", 0x029C5} , - {"bull", 0x02022} , - {"bullet", 0x02022} , - {"bump", 0x0224E} , - {"bumpE", 0x02AAE} , - {"bumpe", 0x0224F} , - {"bumpeq", 0x0224F} , - {"cacute", 0x00107} , - {"cap", 0x02229} , - {"capand", 0x02A44} , - {"capbrcup", 0x02A49} , - {"capcap", 0x02A4B} , - {"capcup", 0x02A47} , - {"capdot", 0x02A40} , - {"caret", 0x02041} , - {"caron", 0x002C7} , - {"ccaps", 0x02A4D} , - {"ccaron", 0x0010D} , - {"ccedil", 0x000E7} , - {"ccirc", 0x00109} , - {"ccups", 0x02A4C} , - {"ccupssm", 0x02A50} , - {"cdot", 0x0010B} , - {"cedil", 0x000B8} , - {"cemptyv", 0x029B2} , - {"cent", 0x000A2} , - {"centerdot", 0x000B7} , - {"cfr", 0x1D520} , - {"chcy", 0x00447} , - {"check", 0x02713} , - {"checkmark", 0x02713} , - {"chi", 0x003C7} , - {"cir", 0x025CB} , - {"cirE", 0x029C3} , - {"circ", 0x002C6} , - {"circeq", 0x02257} , - {"circlearrowleft", 0x021BA} , - {"circlearrowright", 0x021BB} , - {"circledR", 0x000AE} , - {"circledS", 0x024C8} , - {"circledast", 0x0229B} , - {"circledcirc", 0x0229A} , - {"circleddash", 0x0229D} , - {"cire", 0x02257} , - {"cirfnint", 0x02A10} , - {"cirmid", 0x02AEF} , - {"cirscir", 0x029C2} , - {"clubs", 0x02663} , - {"clubsuit", 0x02663} , - {"colon", 0x0003A} , - {"colone", 0x02254} , - {"coloneq", 0x02254} , - {"comma", 0x0002C} , - {"commat", 0x00040} , - {"comp", 0x02201} , - {"compfn", 0x02218} , - {"complement", 0x02201} , - {"complexes", 0x02102} , - {"cong", 0x02245} , - {"congdot", 0x02A6D} , - {"conint", 0x0222E} , - {"copf", 0x1D554} , - {"coprod", 0x02210} , - {"copy", 0x000A9} , - {"copysr", 0x02117} , - {"cross", 0x02717} , - {"cscr", 0x1D4B8} , - {"csub", 0x02ACF} , - {"csube", 0x02AD1} , - {"csup", 0x02AD0} , - {"csupe", 0x02AD2} , - {"ctdot", 0x022EF} , - {"cudarrl", 0x02938} , - {"cudarrr", 0x02935} , - {"cuepr", 0x022DE} , - {"cuesc", 0x022DF} , - {"cularr", 0x021B6} , - {"cularrp", 0x0293D} , - {"cup", 0x0222A} , - {"cupbrcap", 0x02A48} , - {"cupcap", 0x02A46} , - {"cupcup", 0x02A4A} , - {"cupdot", 0x0228D} , - {"cupor", 0x02A45} , - {"curarr", 0x021B7} , - {"curarrm", 0x0293C} , - {"curlyeqprec", 0x022DE} , - {"curlyeqsucc", 0x022DF} , - {"curlyvee", 0x022CE} , - {"curlywedge", 0x022CF} , - {"curren", 0x000A4} , - {"curvearrowleft", 0x021B6} , - {"curvearrowright", 0x021B7} , - {"cuvee", 0x022CE} , - {"cuwed", 0x022CF} , - {"cwconint", 0x02232} , - {"cwint", 0x02231} , - {"cylcty", 0x0232D} , - {"dArr", 0x021D3} , - {"dHar", 0x02965} , - {"dagger", 0x02020} , - {"dagger", 0x02020} , - {"daleth", 0x02138} , - {"darr", 0x02193} , - {"dash", 0x02010} , - {"dashv", 0x022A3} , - {"dbkarow", 0x0290F} , - {"dblac", 0x002DD} , - {"dcaron", 0x0010F} , - {"dcy", 0x00434} , - {"dd", 0x02146} , - {"ddagger", 0x02021} , - {"ddarr", 0x021CA} , - {"ddotseq", 0x02A77} , - {"deg", 0x000B0} , - {"delta", 0x003B4} , - {"demptyv", 0x029B1} , - {"dfisht", 0x0297F} , - {"dfr", 0x1D521} , - {"dharl", 0x021C3} , - {"dharr", 0x021C2} , - {"diam", 0x022C4} , - {"diamond", 0x022C4} , - {"diamondsuit", 0x02666} , - {"diams", 0x02666} , - {"die", 0x000A8} , - {"digamma", 0x003DD} , - {"disin", 0x022F2} , - {"div", 0x000F7} , - {"divide", 0x000F7} , - {"divideontimes", 0x022C7} , - {"divonx", 0x022C7} , - {"djcy", 0x00452} , - {"dlcorn", 0x0231E} , - {"dlcrop", 0x0230D} , - {"dollar", 0x00024} , - {"dopf", 0x1D555} , - {"dot", 0x002D9} , - {"doteq", 0x02250} , - {"doteqdot", 0x02251} , - {"dotminus", 0x02238} , - {"dotplus", 0x02214} , - {"dotsquare", 0x022A1} , - {"doublebarwedge", 0x02306} , - {"downarrow", 0x02193} , - {"downdownarrows", 0x021CA} , - {"downharpoonleft", 0x021C3} , - {"downharpoonright", 0x021C2} , - {"drbkarow", 0x02910} , - {"drcorn", 0x0231F} , - {"drcrop", 0x0230C} , - {"dscr", 0x1D4B9} , - {"dscy", 0x00455} , - {"dsol", 0x029F6} , - {"dstrok", 0x00111} , - {"dtdot", 0x022F1} , - {"dtri", 0x025BF} , - {"dtrif", 0x025BE} , - {"duarr", 0x021F5} , - {"duhar", 0x0296F} , - {"dwangle", 0x029A6} , - {"dzcy", 0x0045F} , - {"dzigrarr", 0x027FF} , - {"eDDot", 0x02A77} , - {"eDot", 0x02251} , - {"eacute", 0x000E9} , - {"easter", 0x02A6E} , - {"ecaron", 0x0011B} , - {"ecir", 0x02256} , - {"ecirc", 0x000EA} , - {"ecolon", 0x02255} , - {"ecy", 0x0044D} , - {"edot", 0x00117} , - {"ee", 0x02147} , - {"efDot", 0x02252} , - {"efr", 0x1D522} , - {"eg", 0x02A9A} , - {"egrave", 0x000E8} , - {"egs", 0x02A96} , - {"egsdot", 0x02A98} , - {"el", 0x02A99} , - {"elinters", 0x0FFFD} , - {"ell", 0x02113} , - {"els", 0x02A95} , - {"elsdot", 0x02A97} , - {"emacr", 0x00113} , - {"empty", 0x02205} , - {"emptyset", 0x02205} , - {"emptyv", 0x02205} , - {"emsp", 0x02003} , - {"emsp13", 0x02004} , - {"emsp14", 0x02005} , - {"eng", 0x0014B} , - {"ensp", 0x02002} , - {"eogon", 0x00119} , - {"eopf", 0x1D556} , - {"epar", 0x022D5} , - {"eparsl", 0x029E3} , - {"eplus", 0x02A71} , - {"epsi", 0x003F5} , - {"epsiv", 0x003B5} , - {"eqcirc", 0x02256} , - {"eqcolon", 0x02255} , - {"eqsim", 0x02242} , - {"eqslantgtr", 0x02A96} , - {"eqslantless", 0x02A95} , - {"equals", 0x0003D} , - {"equest", 0x0225F} , - {"equiv", 0x02261} , - {"equivDD", 0x02A78} , - {"eqvparsl", 0x029E5} , - {"erDot", 0x02253} , - {"erarr", 0x02971} , - {"escr", 0x0212F} , - {"esdot", 0x02250} , - {"esim", 0x02242} , - {"eta", 0x003B7} , - {"eth", 0x000F0} , - {"euml", 0x000EB} , - {"excl", 0x00021} , - {"exist", 0x02203} , - {"expectation", 0x02130} , - {"exponentiale", 0x02147} , - {"fallingdotseq", 0x02252} , - {"fcy", 0x00444} , - {"female", 0x02640} , - {"ffilig", 0x0FB03} , - {"fflig", 0x0FB00} , - {"ffllig", 0x0FB04} , - {"ffr", 0x1D523} , - {"filig", 0x0FB01} , - {"flat", 0x0266D} , - {"fllig", 0x0FB02} , - {"fltns", 0x025B1} , - {"fnof", 0x00192} , - {"fopf", 0x1D557} , - {"forall", 0x02200} , - {"fork", 0x022D4} , - {"forkv", 0x02AD9} , - {"fpartint", 0x02A0D} , - {"frac12", 0x000BD} , - {"frac13", 0x02153} , - {"frac14", 0x000BC} , - {"frac15", 0x02155} , - {"frac16", 0x02159} , - {"frac18", 0x0215B} , - {"frac23", 0x02154} , - {"frac25", 0x02156} , - {"frac34", 0x000BE} , - {"frac35", 0x02157} , - {"frac38", 0x0215C} , - {"frac45", 0x02158} , - {"frac56", 0x0215A} , - {"frac58", 0x0215D} , - {"frac78", 0x0215E} , - {"frown", 0x02322} , - {"fscr", 0x1D4BB} , - {"gE", 0x02267} , - {"gEl", 0x02A8C} , - {"gacute", 0x001F5} , - {"gamma", 0x003B3} , - {"gammad", 0x003DD} , - {"gap", 0x02A86} , - {"gbreve", 0x0011F} , - {"gcirc", 0x0011D} , - {"gcy", 0x00433} , - {"gdot", 0x00121} , - {"ge", 0x02265} , - {"gel", 0x022DB} , - {"geq", 0x02265} , - {"geqq", 0x02267} , - {"geqslant", 0x02A7E} , - {"ges", 0x02A7E} , - {"gescc", 0x02AA9} , - {"gesdot", 0x02A80} , - {"gesdoto", 0x02A82} , - {"gesdotol", 0x02A84} , - {"gesles", 0x02A94} , - {"gfr", 0x1D524} , - {"gg", 0x0226B} , - {"ggg", 0x022D9} , - {"gimel", 0x02137} , - {"gjcy", 0x00453} , - {"gl", 0x02277} , - {"glE", 0x02A92} , - {"gla", 0x02AA5} , - {"glj", 0x02AA4} , - {"gnE", 0x02269} , - {"gnap", 0x02A8A} , - {"gnapprox", 0x02A8A} , - {"gne", 0x02A88} , - {"gneq", 0x02A88} , - {"gneqq", 0x02269} , - {"gnsim", 0x022E7} , - {"gopf", 0x1D558} , - {"grave", 0x00060} , - {"gscr", 0x0210A} , - {"gsim", 0x02273} , - {"gsime", 0x02A8E} , - {"gsiml", 0x02A90} , - {"gt", 0x0003E} , - {"gtcc", 0x02AA7} , - {"gtcir", 0x02A7A} , - {"gtdot", 0x022D7} , - {"gtlPar", 0x02995} , - {"gtquest", 0x02A7C} , - {"gtrapprox", 0x02A86} , - {"gtrarr", 0x02978} , - {"gtrdot", 0x022D7} , - {"gtreqless", 0x022DB} , - {"gtreqqless", 0x02A8C} , - {"gtrless", 0x02277} , - {"gtrsim", 0x02273} , - {"hArr", 0x021D4} , - {"hairsp", 0x0200A} , - {"half", 0x000BD} , - {"hamilt", 0x0210B} , - {"hardcy", 0x0044A} , - {"harr", 0x02194} , - {"harrcir", 0x02948} , - {"harrw", 0x021AD} , - {"hbar", 0x0210F} , - {"hcirc", 0x00125} , - {"hearts", 0x02665} , - {"heartsuit", 0x02665} , - {"hellip", 0x02026} , - {"hercon", 0x022B9} , - {"hfr", 0x1D525} , - {"hksearow", 0x02925} , - {"hkswarow", 0x02926} , - {"hoarr", 0x021FF} , - {"homtht", 0x0223B} , - {"hookleftarrow", 0x021A9} , - {"hookrightarrow", 0x021AA} , - {"hopf", 0x1D559} , - {"horbar", 0x02015} , - {"hscr", 0x1D4BD} , - {"hslash", 0x0210F} , - {"hstrok", 0x00127} , - {"hybull", 0x02043} , - {"hyphen", 0x02010} , - {"iacute", 0x000ED} , - {"ic", 0x02063} , - {"icirc", 0x000EE} , - {"icy", 0x00438} , - {"iecy", 0x00435} , - {"iexcl", 0x000A1} , - {"iff", 0x021D4} , - {"ifr", 0x1D526} , - {"igrave", 0x000EC} , - {"ii", 0x02148} , - {"iiiint", 0x02A0C} , - {"iiint", 0x0222D} , - {"iinfin", 0x029DC} , - {"iiota", 0x02129} , - {"ijlig", 0x00133} , - {"imacr", 0x0012B} , - {"image", 0x02111} , - {"imagline", 0x02110} , - {"imagpart", 0x02111} , - {"imath", 0x00131} , - {"imof", 0x022B7} , - {"imped", 0x001B5} , - {"in", 0x02208} , - {"incare", 0x02105} , - {"infin", 0x0221E} , - {"infintie", 0x029DD} , - {"inodot", 0x00131} , - {"int", 0x0222B} , - {"intcal", 0x022BA} , - {"integers", 0x02124} , - {"intercal", 0x022BA} , - {"intlarhk", 0x02A17} , - {"intprod", 0x02A3C} , - {"iocy", 0x00451} , - {"iogon", 0x0012F} , - {"iopf", 0x1D55A} , - {"iota", 0x003B9} , - {"iprod", 0x02A3C} , - {"iquest", 0x000BF} , - {"iscr", 0x1D4BE} , - {"isin", 0x02208} , - {"isinE", 0x022F9} , - {"isindot", 0x022F5} , - {"isins", 0x022F4} , - {"isinsv", 0x022F3} , - {"isinv", 0x02208} , - {"it", 0x02062} , - {"itilde", 0x00129} , - {"iukcy", 0x00456} , - {"iuml", 0x000EF} , - {"jcirc", 0x00135} , - {"jcy", 0x00439} , - {"jfr", 0x1D527} , - {"jmath", 0x0006A} , - {"jopf", 0x1D55B} , - {"jscr", 0x1D4BF} , - {"jsercy", 0x00458} , - {"jukcy", 0x00454} , - {"kappa", 0x003BA} , - {"kappav", 0x003F0} , - {"kcedil", 0x00137} , - {"kcy", 0x0043A} , - {"kfr", 0x1D528} , - {"kgreen", 0x00138} , - {"khcy", 0x00445} , - {"kjcy", 0x0045C} , - {"kopf", 0x1D55C} , - {"kscr", 0x1D4C0} , - {"lAarr", 0x021DA} , - {"lArr", 0x021D0} , - {"lAtail", 0x0291B} , - {"lBarr", 0x0290E} , - {"lE", 0x02266} , - {"lEg", 0x02A8B} , - {"lHar", 0x02962} , - {"lacute", 0x0013A} , - {"laemptyv", 0x029B4} , - {"lagran", 0x02112} , - {"lambda", 0x003BB} , - {"lang", 0x02329} , - {"langd", 0x02991} , - {"langle", 0x02329} , - {"lap", 0x02A85} , - {"laquo", 0x000AB} , - {"larr", 0x02190} , - {"larrb", 0x021E4} , - {"larrbfs", 0x0291F} , - {"larrfs", 0x0291D} , - {"larrhk", 0x021A9} , - {"larrlp", 0x021AB} , - {"larrpl", 0x02939} , - {"larrsim", 0x02973} , - {"larrtl", 0x021A2} , - {"lat", 0x02AAB} , - {"latail", 0x02919} , - {"late", 0x02AAD} , - {"lbarr", 0x0290C} , - {"lbbrk", 0x03014} , - {"lbrace", 0x0007B} , - {"lbrack", 0x0005B} , - {"lbrke", 0x0298B} , - {"lbrksld", 0x0298F} , - {"lbrkslu", 0x0298D} , - {"lcaron", 0x0013E} , - {"lcedil", 0x0013C} , - {"lceil", 0x02308} , - {"lcub", 0x0007B} , - {"lcy", 0x0043B} , - {"ldca", 0x02936} , - {"ldquo", 0x0201C} , - {"ldquor", 0x0201E} , - {"ldrdhar", 0x02967} , - {"ldrushar", 0x0294B} , - {"ldsh", 0x021B2} , - {"le", 0x02264} , - {"leftarrow", 0x02190} , - {"leftarrowtail", 0x021A2} , - {"leftharpoondown", 0x021BD} , - {"leftharpoonup", 0x021BC} , - {"leftleftarrows", 0x021C7} , - {"leftrightarrow", 0x02194} , - {"leftrightarrows", 0x021C6} , - {"leftrightharpoons", 0x021CB} , - {"leftrightsquigarrow", 0x021AD} , - {"leftthreetimes", 0x022CB} , - {"leg", 0x022DA} , - {"leq", 0x02264} , - {"leqq", 0x02266} , - {"leqslant", 0x02A7D} , - {"les", 0x02A7D} , - {"lescc", 0x02AA8} , - {"lesdot", 0x02A7F} , - {"lesdoto", 0x02A81} , - {"lesdotor", 0x02A83} , - {"lesges", 0x02A93} , - {"lessapprox", 0x02A85} , - {"lessdot", 0x022D6} , - {"lesseqgtr", 0x022DA} , - {"lesseqqgtr", 0x02A8B} , - {"lessgtr", 0x02276} , - {"lesssim", 0x02272} , - {"lfisht", 0x0297C} , - {"lfloor", 0x0230A} , - {"lfr", 0x1D529} , - {"lg", 0x02276} , - {"lgE", 0x02A91} , - {"lhard", 0x021BD} , - {"lharu", 0x021BC} , - {"lharul", 0x0296A} , - {"lhblk", 0x02584} , - {"ljcy", 0x00459} , - {"ll", 0x0226A} , - {"llarr", 0x021C7} , - {"llcorner", 0x0231E} , - {"llhard", 0x0296B} , - {"lltri", 0x025FA} , - {"lmidot", 0x00140} , - {"lmoust", 0x023B0} , - {"lmoustache", 0x023B0} , - {"lnE", 0x02268} , - {"lnap", 0x02A89} , - {"lnapprox", 0x02A89} , - {"lne", 0x02A87} , - {"lneq", 0x02A87} , - {"lneqq", 0x02268} , - {"lnsim", 0x022E6} , - {"loang", 0x03018} , - {"loarr", 0x021FD} , - {"lobrk", 0x0301A} , - {"longleftarrow", 0x027F5} , - {"longleftrightarrow", 0x027F7} , - {"longmapsto", 0x027FC} , - {"longrightarrow", 0x027F6} , - {"looparrowleft", 0x021AB} , - {"looparrowright", 0x021AC} , - {"lopar", 0x02985} , - {"lopf", 0x1D55D} , - {"loplus", 0x02A2D} , - {"lotimes", 0x02A34} , - {"lowast", 0x02217} , - {"lowbar", 0x0005F} , - {"loz", 0x025CA} , - {"lozenge", 0x025CA} , - {"lozf", 0x029EB} , - {"lpar", 0x00028} , - {"lparlt", 0x02993} , - {"lrarr", 0x021C6} , - {"lrcorner", 0x0231F} , - {"lrhar", 0x021CB} , - {"lrhard", 0x0296D} , - {"lrtri", 0x022BF} , - {"lscr", 0x1D4C1} , - {"lsh", 0x021B0} , - {"lsim", 0x02272} , - {"lsime", 0x02A8D} , - {"lsimg", 0x02A8F} , - {"lsqb", 0x0005B} , - {"lsquo", 0x02018} , - {"lsquor", 0x0201A} , - {"lstrok", 0x00142} , - {"lt", 0x0003C} , - {"ltcc", 0x02AA6} , - {"ltcir", 0x02A79} , - {"ltdot", 0x022D6} , - {"lthree", 0x022CB} , - {"ltimes", 0x022C9} , - {"ltlarr", 0x02976} , - {"ltquest", 0x02A7B} , - {"ltrPar", 0x02996} , - {"ltri", 0x025C3} , - {"ltrie", 0x022B4} , - {"ltrif", 0x025C2} , - {"lurdshar", 0x0294A} , - {"luruhar", 0x02966} , - {"mDDot", 0x0223A} , - {"macr", 0x000AF} , - {"male", 0x02642} , - {"malt", 0x02720} , - {"maltese", 0x02720} , - {"map", 0x021A6} , - {"mapsto", 0x021A6} , - {"mapstodown", 0x021A7} , - {"mapstoleft", 0x021A4} , - {"mapstoup", 0x021A5} , - {"marker", 0x025AE} , - {"mcomma", 0x02A29} , - {"mcy", 0x0043C} , - {"mdash", 0x02014} , - {"measuredangle", 0x02221} , - {"mfr", 0x1D52A} , - {"mho", 0x02127} , - {"micro", 0x000B5} , - {"mid", 0x02223} , - {"midast", 0x0002A} , - {"midcir", 0x02AF0} , - {"middot", 0x000B7} , - {"minus", 0x02212} , - {"minusb", 0x0229F} , - {"minusd", 0x02238} , - {"minusdu", 0x02A2A} , - {"mlcp", 0x02ADB} , - {"mldr", 0x02026} , - {"mnplus", 0x02213} , - {"models", 0x022A7} , - {"mopf", 0x1D55E} , - {"mp", 0x02213} , - {"mscr", 0x1D4C2} , - {"mstpos", 0x0223E} , - {"mu", 0x003BC} , - {"multimap", 0x022B8} , - {"mumap", 0x022B8} , - {"nLeftarrow", 0x021CD} , - {"nLeftrightarrow", 0x021CE} , - {"nRightarrow", 0x021CF} , - {"nVDash", 0x022AF} , - {"nVdash", 0x022AE} , - {"nabla", 0x02207} , - {"nacute", 0x00144} , - {"nap", 0x02249} , - {"napos", 0x00149} , - {"napprox", 0x02249} , - {"natur", 0x0266E} , - {"natural", 0x0266E} , - {"naturals", 0x02115} , - {"nbsp", 0x000A0} , - {"ncap", 0x02A43} , - {"ncaron", 0x00148} , - {"ncedil", 0x00146} , - {"ncong", 0x02247} , - {"ncup", 0x02A42} , - {"ncy", 0x0043D} , - {"ndash", 0x02013} , - {"ne", 0x02260} , - {"neArr", 0x021D7} , - {"nearhk", 0x02924} , - {"nearr", 0x02197} , - {"nearrow", 0x02197} , - {"nequiv", 0x02262} , - {"nesear", 0x02928} , - {"nexist", 0x02204} , - {"nexists", 0x02204} , - {"nfr", 0x1D52B} , - {"nge", 0x02271} , - {"ngeq", 0x02271} , - {"ngsim", 0x02275} , - {"ngt", 0x0226F} , - {"ngtr", 0x0226F} , - {"nhArr", 0x021CE} , - {"nharr", 0x021AE} , - {"nhpar", 0x02AF2} , - {"ni", 0x0220B} , - {"nis", 0x022FC} , - {"nisd", 0x022FA} , - {"niv", 0x0220B} , - {"njcy", 0x0045A} , - {"nlArr", 0x021CD} , - {"nlarr", 0x0219A} , - {"nldr", 0x02025} , - {"nle", 0x02270} , - {"nleftarrow", 0x0219A} , - {"nleftrightarrow", 0x021AE} , - {"nleq", 0x02270} , - {"nless", 0x0226E} , - {"nlsim", 0x02274} , - {"nlt", 0x0226E} , - {"nltri", 0x022EA} , - {"nltrie", 0x022EC} , - {"nmid", 0x02224} , - {"nopf", 0x1D55F} , - {"not", 0x000AC} , - {"notin", 0x02209} , - {"notinva", 0x02209} , - {"notinvb", 0x022F7} , - {"notinvc", 0x022F6} , - {"notni", 0x0220C} , - {"notniva", 0x0220C} , - {"notnivb", 0x022FE} , - {"notnivc", 0x022FD} , - {"npar", 0x02226} , - {"nparallel", 0x02226} , - {"npolint", 0x02A14} , - {"npr", 0x02280} , - {"nprcue", 0x022E0} , - {"nprec", 0x02280} , - {"nrArr", 0x021CF} , - {"nrarr", 0x0219B} , - {"nrightarrow", 0x0219B} , - {"nrtri", 0x022EB} , - {"nrtrie", 0x022ED} , - {"nsc", 0x02281} , - {"nsccue", 0x022E1} , - {"nscr", 0x1D4C3} , - {"nshortmid", 0x02224} , - {"nshortparallel", 0x02226} , - {"nsim", 0x02241} , - {"nsime", 0x02244} , - {"nsimeq", 0x02244} , - {"nsmid", 0x02224} , - {"nspar", 0x02226} , - {"nsqsube", 0x022E2} , - {"nsqsupe", 0x022E3} , - {"nsub", 0x02284} , - {"nsube", 0x02288} , - {"nsubseteq", 0x02288} , - {"nsucc", 0x02281} , - {"nsup", 0x02285} , - {"nsupe", 0x02289} , - {"nsupseteq", 0x02289} , - {"ntgl", 0x02279} , - {"ntilde", 0x000F1} , - {"ntlg", 0x02278} , - {"ntriangleleft", 0x022EA} , - {"ntrianglelefteq", 0x022EC} , - {"ntriangleright", 0x022EB} , - {"ntrianglerighteq", 0x022ED} , - {"nu", 0x003BD} , - {"num", 0x00023} , - {"numero", 0x02116} , - {"numsp", 0x02007} , - {"nvDash", 0x022AD} , - {"nvHarr", 0x02904} , - {"nvdash", 0x022AC} , - {"nvinfin", 0x029DE} , - {"nvlArr", 0x02902} , - {"nvrArr", 0x02903} , - {"nwArr", 0x021D6} , - {"nwarhk", 0x02923} , - {"nwarr", 0x02196} , - {"nwarrow", 0x02196} , - {"nwnear", 0x02927} , - {"oS", 0x024C8} , - {"oacute", 0x000F3} , - {"oast", 0x0229B} , - {"ocir", 0x0229A} , - {"ocirc", 0x000F4} , - {"ocy", 0x0043E} , - {"odash", 0x0229D} , - {"odblac", 0x00151} , - {"odiv", 0x02A38} , - {"odot", 0x02299} , - {"odsold", 0x029BC} , - {"oelig", 0x00153} , - {"ofcir", 0x029BF} , - {"ofr", 0x1D52C} , - {"ogon", 0x002DB} , - {"ograve", 0x000F2} , - {"ogt", 0x029C1} , - {"ohbar", 0x029B5} , - {"ohm", 0x02126} , - {"oint", 0x0222E} , - {"olarr", 0x021BA} , - {"olcir", 0x029BE} , - {"olcross", 0x029BB} , - {"olt", 0x029C0} , - {"omacr", 0x0014D} , - {"omega", 0x003C9} , - {"omid", 0x029B6} , - {"ominus", 0x02296} , - {"oopf", 0x1D560} , - {"opar", 0x029B7} , - {"operp", 0x029B9} , - {"oplus", 0x02295} , - {"or", 0x02228} , - {"orarr", 0x021BB} , - {"ord", 0x02A5D} , - {"order", 0x02134} , - {"orderof", 0x02134} , - {"ordf", 0x000AA} , - {"ordm", 0x000BA} , - {"origof", 0x022B6} , - {"oror", 0x02A56} , - {"orslope", 0x02A57} , - {"orv", 0x02A5B} , - {"oscr", 0x02134} , - {"oslash", 0x000F8} , - {"osol", 0x02298} , - {"otilde", 0x000F5} , - {"otimes", 0x02297} , - {"otimesas", 0x02A36} , - {"ouml", 0x000F6} , - {"ovbar", 0x0233D} , - {"par", 0x02225} , - {"para", 0x000B6} , - {"parallel", 0x02225} , - {"parsim", 0x02AF3} , - {"parsl", 0x02AFD} , - {"part", 0x02202} , - {"pcy", 0x0043F} , - {"percnt", 0x00025} , - {"period", 0x0002E} , - {"permil", 0x02030} , - {"perp", 0x022A5} , - {"pertenk", 0x02031} , - {"pfr", 0x1D52D} , - {"phi", 0x003D5} , - {"phiv", 0x003C6} , - {"phmmat", 0x02133} , - {"phone", 0x0260E} , - {"pi", 0x003C0} , - {"pitchfork", 0x022D4} , - {"piv", 0x003D6} , - {"planck", 0x0210F} , - {"planckh", 0x0210E} , - {"plankv", 0x0210F} , - {"plus", 0x0002B} , - {"plusacir", 0x02A23} , - {"plusb", 0x0229E} , - {"pluscir", 0x02A22} , - {"plusdo", 0x02214} , - {"plusdu", 0x02A25} , - {"pluse", 0x02A72} , - {"plusmn", 0x000B1} , - {"plussim", 0x02A26} , - {"plustwo", 0x02A27} , - {"pm", 0x000B1} , - {"pointint", 0x02A15} , - {"popf", 0x1D561} , - {"pound", 0x000A3} , - {"pr", 0x0227A} , - {"prE", 0x02AB3} , - {"prap", 0x02AB7} , - {"prcue", 0x0227C} , - {"pre", 0x02AAF} , - {"prec", 0x0227A} , - {"precapprox", 0x02AB7} , - {"preccurlyeq", 0x0227C} , - {"preceq", 0x02AAF} , - {"precnapprox", 0x02AB9} , - {"precneqq", 0x02AB5} , - {"precnsim", 0x022E8} , - {"precsim", 0x0227E} , - {"prime", 0x02032} , - {"primes", 0x02119} , - {"prnE", 0x02AB5} , - {"prnap", 0x02AB9} , - {"prnsim", 0x022E8} , - {"prod", 0x0220F} , - {"profalar", 0x0232E} , - {"profline", 0x02312} , - {"profsurf", 0x02313} , - {"prop", 0x0221D} , - {"propto", 0x0221D} , - {"prsim", 0x0227E} , - {"prurel", 0x022B0} , - {"pscr", 0x1D4C5} , - {"psi", 0x003C8} , - {"puncsp", 0x02008} , - {"qfr", 0x1D52E} , - {"qint", 0x02A0C} , - {"qopf", 0x1D562} , - {"qprime", 0x02057} , - {"qscr", 0x1D4C6} , - {"quaternions", 0x0210D} , - {"quatint", 0x02A16} , - {"quest", 0x0003F} , - {"questeq", 0x0225F} , - {"quot", 0x00022} , - {"rAarr", 0x021DB} , - {"rArr", 0x021D2} , - {"rAtail", 0x0291C} , - {"rBarr", 0x0290F} , - {"rHar", 0x02964} , - {"race", 0x029DA} , - {"racute", 0x00155} , - {"radic", 0x0221A} , - {"raemptyv", 0x029B3} , - {"rang", 0x0232A} , - {"rangd", 0x02992} , - {"range", 0x029A5} , - {"rangle", 0x0232A} , - {"raquo", 0x000BB} , - {"rarr", 0x02192} , - {"rarrap", 0x02975} , - {"rarrb", 0x021E5} , - {"rarrbfs", 0x02920} , - {"rarrc", 0x02933} , - {"rarrfs", 0x0291E} , - {"rarrhk", 0x021AA} , - {"rarrlp", 0x021AC} , - {"rarrpl", 0x02945} , - {"rarrsim", 0x02974} , - {"rarrtl", 0x021A3} , - {"rarrw", 0x0219D} , - {"ratail", 0x0291A} , - {"ratio", 0x02236} , - {"rationals", 0x0211A} , - {"rbarr", 0x0290D} , - {"rbbrk", 0x03015} , - {"rbrace", 0x0007D} , - {"rbrack", 0x0005D} , - {"rbrke", 0x0298C} , - {"rbrksld", 0x0298E} , - {"rbrkslu", 0x02990} , - {"rcaron", 0x00159} , - {"rcedil", 0x00157} , - {"rceil", 0x02309} , - {"rcub", 0x0007D} , - {"rcy", 0x00440} , - {"rdca", 0x02937} , - {"rdldhar", 0x02969} , - {"rdquo", 0x0201D} , - {"rdquor", 0x0201D} , - {"rdsh", 0x021B3} , - {"real", 0x0211C} , - {"realine", 0x0211B} , - {"realpart", 0x0211C} , - {"reals", 0x0211D} , - {"rect", 0x025AD} , - {"reg", 0x000AE} , - {"rfisht", 0x0297D} , - {"rfloor", 0x0230B} , - {"rfr", 0x1D52F} , - {"rhard", 0x021C1} , - {"rharu", 0x021C0} , - {"rharul", 0x0296C} , - {"rho", 0x003C1} , - {"rhov", 0x003F1} , - {"rightarrow", 0x02192} , - {"rightarrowtail", 0x021A3} , - {"rightharpoondown", 0x021C1} , - {"rightharpoonup", 0x021C0} , - {"rightleftarrows", 0x021C4} , - {"rightleftharpoons", 0x021CC} , - {"rightrightarrows", 0x021C9} , - {"rightsquigarrow", 0x0219D} , - {"rightthreetimes", 0x022CC} , - {"ring", 0x002DA} , - {"risingdotseq", 0x02253} , - {"rlarr", 0x021C4} , - {"rlhar", 0x021CC} , - {"rmoust", 0x023B1} , - {"rmoustache", 0x023B1} , - {"rnmid", 0x02AEE} , - {"roang", 0x03019} , - {"roarr", 0x021FE} , - {"robrk", 0x0301B} , - {"ropar", 0x02986} , - {"ropf", 0x1D563} , - {"roplus", 0x02A2E} , - {"rotimes", 0x02A35} , - {"rpar", 0x00029} , - {"rpargt", 0x02994} , - {"rppolint", 0x02A12} , - {"rrarr", 0x021C9} , - {"rscr", 0x1D4C7} , - {"rsh", 0x021B1} , - {"rsqb", 0x0005D} , - {"rsquo", 0x02019} , - {"rsquor", 0x02019} , - {"rthree", 0x022CC} , - {"rtimes", 0x022CA} , - {"rtri", 0x025B9} , - {"rtrie", 0x022B5} , - {"rtrif", 0x025B8} , - {"rtriltri", 0x029CE} , - {"ruluhar", 0x02968} , - {"rx", 0x0211E} , - {"sacute", 0x0015B} , - {"sc", 0x0227B} , - {"scE", 0x02AB4} , - {"scap", 0x02AB8} , - {"scaron", 0x00161} , - {"sccue", 0x0227D} , - {"sce", 0x02AB0} , - {"scedil", 0x0015F} , - {"scirc", 0x0015D} , - {"scnE", 0x02AB6} , - {"scnap", 0x02ABA} , - {"scnsim", 0x022E9} , - {"scpolint", 0x02A13} , - {"scsim", 0x0227F} , - {"scy", 0x00441} , - {"sdot", 0x022C5} , - {"sdotb", 0x022A1} , - {"sdote", 0x02A66} , - {"seArr", 0x021D8} , - {"searhk", 0x02925} , - {"searr", 0x02198} , - {"searrow", 0x02198} , - {"sect", 0x000A7} , - {"semi", 0x0003B} , - {"seswar", 0x02929} , - {"setminus", 0x02216} , - {"setmn", 0x02216} , - {"sext", 0x02736} , - {"sfr", 0x1D530} , - {"sfrown", 0x02322} , - {"sharp", 0x0266F} , - {"shchcy", 0x00449} , - {"shcy", 0x00448} , - {"shortmid", 0x02223} , - {"shortparallel", 0x02225} , - {"shy", 0x000AD} , - {"sigma", 0x003C3} , - {"sigmav", 0x003C2} , - {"sim", 0x0223C} , - {"simdot", 0x02A6A} , - {"sime", 0x02243} , - {"simeq", 0x02243} , - {"simg", 0x02A9E} , - {"simgE", 0x02AA0} , - {"siml", 0x02A9D} , - {"simlE", 0x02A9F} , - {"simne", 0x02246} , - {"simplus", 0x02A24} , - {"simrarr", 0x02972} , - {"slarr", 0x02190} , - {"smallsetminus", 0x02216} , - {"smashp", 0x02A33} , - {"smeparsl", 0x029E4} , - {"smid", 0x02223} , - {"smile", 0x02323} , - {"smt", 0x02AAA} , - {"smte", 0x02AAC} , - {"softcy", 0x0044C} , - {"sol", 0x0002F} , - {"solb", 0x029C4} , - {"solbar", 0x0233F} , - {"sopf", 0x1D564} , - {"spades", 0x02660} , - {"spadesuit", 0x02660} , - {"spar", 0x02225} , - {"sqcap", 0x02293} , - {"sqcup", 0x02294} , - {"sqsub", 0x0228F} , - {"sqsube", 0x02291} , - {"sqsubset", 0x0228F} , - {"sqsubseteq", 0x02291} , - {"sqsup", 0x02290} , - {"sqsupe", 0x02292} , - {"sqsupset", 0x02290} , - {"sqsupseteq", 0x02292} , - {"squ", 0x025A1} , - {"square", 0x025A1} , - {"squarf", 0x025AA} , - {"squf", 0x025AA} , - {"srarr", 0x02192} , - {"sscr", 0x1D4C8} , - {"ssetmn", 0x02216} , - {"ssmile", 0x02323} , - {"sstarf", 0x022C6} , - {"star", 0x02606} , - {"starf", 0x02605} , - {"straightepsilon", 0x003F5} , - {"straightphi", 0x003D5} , - {"strns", 0x000AF} , - {"sub", 0x02282} , - {"subE", 0x02AC5} , - {"subdot", 0x02ABD} , - {"sube", 0x02286} , - {"subedot", 0x02AC3} , - {"submult", 0x02AC1} , - {"subnE", 0x02ACB} , - {"subne", 0x0228A} , - {"subplus", 0x02ABF} , - {"subrarr", 0x02979} , - {"subset", 0x02282} , - {"subseteq", 0x02286} , - {"subseteqq", 0x02AC5} , - {"subsetneq", 0x0228A} , - {"subsetneqq", 0x02ACB} , - {"subsim", 0x02AC7} , - {"subsub", 0x02AD5} , - {"subsup", 0x02AD3} , - {"succ", 0x0227B} , - {"succapprox", 0x02AB8} , - {"succcurlyeq", 0x0227D} , - {"succeq", 0x02AB0} , - {"succnapprox", 0x02ABA} , - {"succneqq", 0x02AB6} , - {"succnsim", 0x022E9} , - {"succsim", 0x0227F} , - {"sum", 0x02211} , - {"sung", 0x0266A} , - {"sup", 0x02283} , - {"sup1", 0x000B9} , - {"sup2", 0x000B2} , - {"sup3", 0x000B3} , - {"supE", 0x02AC6} , - {"supdot", 0x02ABE} , - {"supdsub", 0x02AD8} , - {"supe", 0x02287} , - {"supedot", 0x02AC4} , - {"suphsub", 0x02AD7} , - {"suplarr", 0x0297B} , - {"supmult", 0x02AC2} , - {"supnE", 0x02ACC} , - {"supne", 0x0228B} , - {"supplus", 0x02AC0} , - {"supset", 0x02283} , - {"supseteq", 0x02287} , - {"supseteqq", 0x02AC6} , - {"supsetneq", 0x0228B} , - {"supsetneqq", 0x02ACC} , - {"supsim", 0x02AC8} , - {"supsub", 0x02AD4} , - {"supsup", 0x02AD6} , - {"swArr", 0x021D9} , - {"swarhk", 0x02926} , - {"swarr", 0x02199} , - {"swarrow", 0x02199} , - {"swnwar", 0x0292A} , - {"szlig", 0x000DF} , - {"target", 0x02316} , - {"tau", 0x003C4} , - {"tbrk", 0x023B4} , - {"tcaron", 0x00165} , - {"tcedil", 0x00163} , - {"tcy", 0x00442} , - {"tdot", 0x020DB} , - {"telrec", 0x02315} , - {"tfr", 0x1D531} , - {"there4", 0x02234} , - {"therefore", 0x02234} , - {"theta", 0x003B8} , - {"thetav", 0x003D1} , - {"thickapprox", 0x02248} , - {"thicksim", 0x0223C} , - {"thinsp", 0x02009} , - {"thkap", 0x02248} , - {"thksim", 0x0223C} , - {"thorn", 0x000FE} , - {"tilde", 0x002DC} , - {"times", 0x000D7} , - {"timesb", 0x022A0} , - {"timesbar", 0x02A31} , - {"timesd", 0x02A30} , - {"tint", 0x0222D} , - {"toea", 0x02928} , - {"top", 0x022A4} , - {"topbot", 0x02336} , - {"topcir", 0x02AF1} , - {"topf", 0x1D565} , - {"topfork", 0x02ADA} , - {"tosa", 0x02929} , - {"tprime", 0x02034} , - {"trade", 0x02122} , - {"triangle", 0x025B5} , - {"triangledown", 0x025BF} , - {"triangleleft", 0x025C3} , - {"trianglelefteq", 0x022B4} , - {"triangleq", 0x0225C} , - {"triangleright", 0x025B9} , - {"trianglerighteq", 0x022B5} , - {"tridot", 0x025EC} , - {"trie", 0x0225C} , - {"triminus", 0x02A3A} , - {"triplus", 0x02A39} , - {"trisb", 0x029CD} , - {"tritime", 0x02A3B} , - {"trpezium", 0x0FFFD} , - {"tscr", 0x1D4C9} , - {"tscy", 0x00446} , - {"tshcy", 0x0045B} , - {"tstrok", 0x00167} , - {"twixt", 0x0226C} , - {"twoheadleftarrow", 0x0219E} , - {"twoheadrightarrow", 0x021A0} , - {"uArr", 0x021D1} , - {"uHar", 0x02963} , - {"uacute", 0x000FA} , - {"uarr", 0x02191} , - {"ubrcy", 0x0045E} , - {"ubreve", 0x0016D} , - {"ucirc", 0x000FB} , - {"ucy", 0x00443} , - {"udarr", 0x021C5} , - {"udblac", 0x00171} , - {"udhar", 0x0296E} , - {"ufisht", 0x0297E} , - {"ufr", 0x1D532} , - {"ugrave", 0x000F9} , - {"uharl", 0x021BF} , - {"uharr", 0x021BE} , - {"uhblk", 0x02580} , - {"ulcorn", 0x0231C} , - {"ulcorner", 0x0231C} , - {"ulcrop", 0x0230F} , - {"ultri", 0x025F8} , - {"umacr", 0x0016B} , - {"uml", 0x000A8} , - {"uogon", 0x00173} , - {"uopf", 0x1D566} , - {"uparrow", 0x02191} , - {"updownarrow", 0x02195} , - {"upharpoonleft", 0x021BF} , - {"upharpoonright", 0x021BE} , - {"uplus", 0x0228E} , - {"upsi", 0x003C5} , - {"upsilon", 0x003C5} , - {"upuparrows", 0x021C8} , - {"urcorn", 0x0231D} , - {"urcorner", 0x0231D} , - {"urcrop", 0x0230E} , - {"uring", 0x0016F} , - {"urtri", 0x025F9} , - {"uscr", 0x1D4CA} , - {"utdot", 0x022F0} , - {"utilde", 0x00169} , - {"utri", 0x025B5} , - {"utrif", 0x025B4} , - {"uuarr", 0x021C8} , - {"uuml", 0x000FC} , - {"uwangle", 0x029A7} , - {"vArr", 0x021D5} , - {"vBar", 0x02AE8} , - {"vBarv", 0x02AE9} , - {"vDash", 0x022A8} , - {"vangrt", 0x0299C} , - {"varepsilon", 0x003B5} , - {"varkappa", 0x003F0} , - {"varnothing", 0x02205} , - {"varphi", 0x003C6} , - {"varpi", 0x003D6} , - {"varpropto", 0x0221D} , - {"varr", 0x02195} , - {"varrho", 0x003F1} , - {"varsigma", 0x003C2} , - {"vartheta", 0x003D1} , - {"vartriangleleft", 0x022B2} , - {"vartriangleright", 0x022B3} , - {"vcy", 0x00432} , - {"vdash", 0x022A2} , - {"vee", 0x02228} , - {"veebar", 0x022BB} , - {"veeeq", 0x0225A} , - {"vellip", 0x022EE} , - {"verbar", 0x0007C} , - {"vert", 0x0007C} , - {"vfr", 0x1D533} , - {"vltri", 0x022B2} , - {"vopf", 0x1D567} , - {"vprop", 0x0221D} , - {"vrtri", 0x022B3} , - {"vscr", 0x1D4CB} , - {"vzigzag", 0x0299A} , - {"wcirc", 0x00175} , - {"wedbar", 0x02A5F} , - {"wedge", 0x02227} , - {"wedgeq", 0x02259} , - {"weierp", 0x02118} , - {"wfr", 0x1D534} , - {"wopf", 0x1D568} , - {"wp", 0x02118} , - {"wr", 0x02240} , - {"wreath", 0x02240} , - {"wscr", 0x1D4CC} , - {"xcap", 0x022C2} , - {"xcirc", 0x025EF} , - {"xcup", 0x022C3} , - {"xdtri", 0x025BD} , - {"xfr", 0x1D535} , - {"xhArr", 0x027FA} , - {"xharr", 0x027F7} , - {"xi", 0x003BE} , - {"xlArr", 0x027F8} , - {"xlarr", 0x027F5} , - {"xmap", 0x027FC} , - {"xnis", 0x022FB} , - {"xodot", 0x02A00} , - {"xopf", 0x1D569} , - {"xoplus", 0x02A01} , - {"xotime", 0x02A02} , - {"xrArr", 0x027F9} , - {"xrarr", 0x027F6} , - {"xscr", 0x1D4CD} , - {"xsqcup", 0x02A06} , - {"xuplus", 0x02A04} , - {"xutri", 0x025B3} , - {"xvee", 0x022C1} , - {"xwedge", 0x022C0} , - {"yacute", 0x000FD} , - {"yacy", 0x0044F} , - {"ycirc", 0x00177} , - {"ycy", 0x0044B} , - {"yen", 0x000A5} , - {"yfr", 0x1D536} , - {"yicy", 0x00457} , - {"yopf", 0x1D56A} , - {"yscr", 0x1D4CE} , - {"yucy", 0x0044E} , - {"yuml", 0x000FF} , - {"zacute", 0x0017A} , - {"zcaron", 0x0017E} , - {"zcy", 0x00437} , - {"zdot", 0x0017C} , - {"zeetrf", 0x02128} , - {"zeta", 0x003B6} , - {"zfr", 0x1D537} , - {"zhcy", 0x00436} , - {"zigrarr", 0x021DD} , - {"zopf", 0x1D56B} , - {"zscr", 0x1D4CF} -}; - -// Needed since sizeof is a macro and we cannot be used until size is known -int entityMap::size() -{ - return sizeof( entities ) / sizeof( entityMap ); -} - -KFORMULA_NAMESPACE_END - diff --git a/lib/kformula/entities.cpp b/lib/kformula/entities.cpp new file mode 100644 index 00000000..c6696e1f --- /dev/null +++ b/lib/kformula/entities.cpp @@ -0,0 +1,2037 @@ +// +// Created: Tue Aug 29 16:20:33 2006 +// by: bynames.py +// from: byalpha.html +// +// WARNING! All changes made in this file will be lost! + +/* This file is part of the KDE project + Copyright (C) 2006 Alfredo Beaumont Sainz + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + + +#include "entities.h" + +KFORMULA_NAMESPACE_BEGIN + +const entityMap entities[] = { + {"AElig", 0x000C6} , + {"Aacute", 0x000C1} , + {"Abreve", 0x00102} , + {"Acirc", 0x000C2} , + {"Acy", 0x00410} , + {"Afr", 0x1D504} , + {"Agrave", 0x000C0} , + {"Amacr", 0x00100} , + {"And", 0x02A53} , + {"Aogon", 0x00104} , + {"Aopf", 0x1D538} , + {"ApplyFunction", 0x02061} , + {"Aring", 0x000C5} , + {"Ascr", 0x1D49C} , + {"Assign", 0x02254} , + {"Atilde", 0x000C3} , + {"Auml", 0x000C4} , + {"Backslash", 0x02216} , + {"Barv", 0x02AE7} , + {"Barwed", 0x02306} , + {"Bcy", 0x00411} , + {"Because", 0x02235} , + {"Bernoullis", 0x0212C} , + {"Bfr", 0x1D505} , + {"Bopf", 0x1D539} , + {"Breve", 0x002D8} , + {"Bscr", 0x0212C} , + {"Bumpeq", 0x0224E} , + {"CHcy", 0x00427} , + {"Cacute", 0x00106} , + {"Cap", 0x022D2} , + {"CapitalDifferentialD", 0x02145} , + {"Cayleys", 0x0212D} , + {"Ccaron", 0x0010C} , + {"Ccedil", 0x000C7} , + {"Ccirc", 0x00108} , + {"Cconint", 0x02230} , + {"Cdot", 0x0010A} , + {"Cedilla", 0x000B8} , + {"CenterDot", 0x000B7} , + {"Cfr", 0x0212D} , + {"CircleDot", 0x02299} , + {"CircleMinus", 0x02296} , + {"CirclePlus", 0x02295} , + {"CircleTimes", 0x02297} , + {"ClockwiseContourIntegral", 0x02232} , + {"CloseCurlyDoubleQuote", 0x0201D} , + {"CloseCurlyQuote", 0x02019} , + {"Colon", 0x02237} , + {"Colone", 0x02A74} , + {"Congruent", 0x02261} , + {"Conint", 0x0222F} , + {"ContourIntegral", 0x0222E} , + {"Copf", 0x02102} , + {"Coproduct", 0x02210} , + {"CounterClockwiseContourIntegral", 0x02233} , + {"Cross", 0x02A2F} , + {"Cscr", 0x1D49E} , + {"Cup", 0x022D3} , + {"CupCap", 0x0224D} , + {"DD", 0x02145} , + {"DDotrahd", 0x02911} , + {"DJcy", 0x00402} , + {"DScy", 0x00405} , + {"DZcy", 0x0040F} , + {"Dagger", 0x02021} , + {"Dagger", 0x02021} , + {"Darr", 0x021A1} , + {"Dashv", 0x02AE4} , + {"Dcaron", 0x0010E} , + {"Dcy", 0x00414} , + {"Del", 0x02207} , + {"Delta", 0x00394} , + {"Dfr", 0x1D507} , + {"DiacriticalAcute", 0x000B4} , + {"DiacriticalDot", 0x002D9} , + {"DiacriticalDoubleAcute", 0x002DD} , + {"DiacriticalGrave", 0x00060} , + {"DiacriticalTilde", 0x002DC} , + {"Diamond", 0x022C4} , + {"DifferentialD", 0x02146} , + {"Dopf", 0x1D53B} , + {"Dot", 0x000A8} , + {"DotDot", 0x020DC} , + {"DotEqual", 0x02250} , + {"DoubleContourIntegral", 0x0222F} , + {"DoubleDot", 0x000A8} , + {"DoubleDownArrow", 0x021D3} , + {"DoubleLeftArrow", 0x021D0} , + {"DoubleLeftRightArrow", 0x021D4} , + {"DoubleLeftTee", 0x02AE4} , + {"DoubleLongLeftArrow", 0x027F8} , + {"DoubleLongLeftRightArrow", 0x027FA} , + {"DoubleLongRightArrow", 0x027F9} , + {"DoubleRightArrow", 0x021D2} , + {"DoubleRightTee", 0x022A8} , + {"DoubleUpArrow", 0x021D1} , + {"DoubleUpDownArrow", 0x021D5} , + {"DoubleVerticalBar", 0x02225} , + {"DownArrow", 0x02193} , + {"DownArrowBar", 0x02913} , + {"DownArrowUpArrow", 0x021F5} , + {"DownBreve", 0x00311} , + {"DownLeftRightVector", 0x02950} , + {"DownLeftTeeVector", 0x0295E} , + {"DownLeftVector", 0x021BD} , + {"DownLeftVectorBar", 0x02956} , + {"DownRightTeeVector", 0x0295F} , + {"DownRightVector", 0x021C1} , + {"DownRightVectorBar", 0x02957} , + {"DownTee", 0x022A4} , + {"DownTeeArrow", 0x021A7} , + {"Downarrow", 0x021D3} , + {"Dscr", 0x1D49F} , + {"Dstrok", 0x00110} , + {"ENG", 0x0014A} , + {"ETH", 0x000D0} , + {"Eacute", 0x000C9} , + {"Ecaron", 0x0011A} , + {"Ecirc", 0x000CA} , + {"Ecy", 0x0042D} , + {"Edot", 0x00116} , + {"Efr", 0x1D508} , + {"Egrave", 0x000C8} , + {"Element", 0x02208} , + {"Emacr", 0x00112} , + {"EmptySmallSquare", 0x025FB} , + {"EmptyVerySmallSquare", 0x025AB} , + {"Eogon", 0x00118} , + {"Eopf", 0x1D53C} , + {"Equal", 0x02A75} , + {"EqualTilde", 0x02242} , + {"Equilibrium", 0x021CC} , + {"Escr", 0x02130} , + {"Esim", 0x02A73} , + {"Euml", 0x000CB} , + {"Exists", 0x02203} , + {"ExponentialE", 0x02147} , + {"Fcy", 0x00424} , + {"Ffr", 0x1D509} , + {"FilledSmallSquare", 0x025FC} , + {"FilledVerySmallSquare", 0x025AA} , + {"Fopf", 0x1D53D} , + {"ForAll", 0x02200} , + {"Fouriertrf", 0x02131} , + {"Fscr", 0x02131} , + {"GJcy", 0x00403} , + {"Gamma", 0x00393} , + {"Gammad", 0x003DC} , + {"Gbreve", 0x0011E} , + {"Gcedil", 0x00122} , + {"Gcirc", 0x0011C} , + {"Gcy", 0x00413} , + {"Gdot", 0x00120} , + {"Gfr", 0x1D50A} , + {"Gg", 0x022D9} , + {"Gopf", 0x1D53E} , + {"GreaterEqual", 0x02265} , + {"GreaterEqualLess", 0x022DB} , + {"GreaterFullEqual", 0x02267} , + {"GreaterGreater", 0x02AA2} , + {"GreaterLess", 0x02277} , + {"GreaterSlantEqual", 0x02A7E} , + {"GreaterTilde", 0x02273} , + {"Gscr", 0x1D4A2} , + {"Gt", 0x0226B} , + {"HARDcy", 0x0042A} , + {"Hacek", 0x002C7} , + {"Hat", 0x0005E} , + {"Hcirc", 0x00124} , + {"Hfr", 0x0210C} , + {"HilbertSpace", 0x0210B} , + {"Hopf", 0x0210D} , + {"HorizontalLine", 0x02500} , + {"Hscr", 0x0210B} , + {"Hstrok", 0x00126} , + {"HumpDownHump", 0x0224E} , + {"HumpEqual", 0x0224F} , + {"IEcy", 0x00415} , + {"IJlig", 0x00132} , + {"IOcy", 0x00401} , + {"Iacute", 0x000CD} , + {"Icirc", 0x000CE} , + {"Icy", 0x00418} , + {"Idot", 0x00130} , + {"Ifr", 0x02111} , + {"Igrave", 0x000CC} , + {"Im", 0x02111} , + {"Imacr", 0x0012A} , + {"ImaginaryI", 0x02148} , + {"Implies", 0x021D2} , + {"Int", 0x0222C} , + {"Integral", 0x0222B} , + {"Intersection", 0x022C2} , + {"InvisibleComma", 0x02063} , + {"InvisibleTimes", 0x02062} , + {"Iogon", 0x0012E} , + {"Iopf", 0x1D540} , + {"Iscr", 0x02110} , + {"Itilde", 0x00128} , + {"Iukcy", 0x00406} , + {"Iuml", 0x000CF} , + {"Jcirc", 0x00134} , + {"Jcy", 0x00419} , + {"Jfr", 0x1D50D} , + {"Jopf", 0x1D541} , + {"Jscr", 0x1D4A5} , + {"Jsercy", 0x00408} , + {"Jukcy", 0x00404} , + {"KHcy", 0x00425} , + {"KJcy", 0x0040C} , + {"Kcedil", 0x00136} , + {"Kcy", 0x0041A} , + {"Kfr", 0x1D50E} , + {"Kopf", 0x1D542} , + {"Kscr", 0x1D4A6} , + {"LJcy", 0x00409} , + {"Lacute", 0x00139} , + {"Lambda", 0x0039B} , + {"Lang", 0x0300A} , + {"Laplacetrf", 0x02112} , + {"Larr", 0x0219E} , + {"Lcaron", 0x0013D} , + {"Lcedil", 0x0013B} , + {"Lcy", 0x0041B} , + {"LeftAngleBracket", 0x02329} , + {"LeftArrow", 0x02190} , + {"LeftArrowBar", 0x021E4} , + {"LeftArrowRightArrow", 0x021C6} , + {"LeftCeiling", 0x02308} , + {"LeftDoubleBracket", 0x0301A} , + {"LeftDownTeeVector", 0x02961} , + {"LeftDownVector", 0x021C3} , + {"LeftDownVectorBar", 0x02959} , + {"LeftFloor", 0x0230A} , + {"LeftRightArrow", 0x02194} , + {"LeftRightVector", 0x0294E} , + {"LeftTee", 0x022A3} , + {"LeftTeeArrow", 0x021A4} , + {"LeftTeeVector", 0x0295A} , + {"LeftTriangle", 0x022B2} , + {"LeftTriangleBar", 0x029CF} , + {"LeftTriangleEqual", 0x022B4} , + {"LeftUpDownVector", 0x02951} , + {"LeftUpTeeVector", 0x02960} , + {"LeftUpVector", 0x021BF} , + {"LeftUpVectorBar", 0x02958} , + {"LeftVector", 0x021BC} , + {"LeftVectorBar", 0x02952} , + {"Leftarrow", 0x021D0} , + {"Leftrightarrow", 0x021D4} , + {"LessEqualGreater", 0x022DA} , + {"LessFullEqual", 0x02266} , + {"LessGreater", 0x02276} , + {"LessLess", 0x02AA1} , + {"LessSlantEqual", 0x02A7D} , + {"LessTilde", 0x02272} , + {"Lfr", 0x1D50F} , + {"Ll", 0x022D8} , + {"Lleftarrow", 0x021DA} , + {"Lmidot", 0x0013F} , + {"LongLeftArrow", 0x027F5} , + {"LongLeftRightArrow", 0x027F7} , + {"LongRightArrow", 0x027F6} , + {"Longleftarrow", 0x027F8} , + {"Longleftrightarrow", 0x027FA} , + {"Longrightarrow", 0x027F9} , + {"Lopf", 0x1D543} , + {"LowerLeftArrow", 0x02199} , + {"LowerRightArrow", 0x02198} , + {"Lscr", 0x02112} , + {"Lsh", 0x021B0} , + {"Lstrok", 0x00141} , + {"Lt", 0x0226A} , + {"Map", 0x02905} , + {"Mcy", 0x0041C} , + {"MediumSpace", 0x0205F} , + {"Mellintrf", 0x02133} , + {"Mfr", 0x1D510} , + {"MinusPlus", 0x02213} , + {"Mopf", 0x1D544} , + {"Mscr", 0x02133} , + {"NJcy", 0x0040A} , + {"Nacute", 0x00143} , + {"Ncaron", 0x00147} , + {"Ncedil", 0x00145} , + {"Ncy", 0x0041D} , + {"NegativeMediumSpace", 0x0200B} , + {"NegativeThickSpace", 0x0200B} , + {"NegativeThinSpace", 0x0200B} , + {"NegativeVeryThinSpace", 0x0200B} , + {"NestedGreaterGreater", 0x0226B} , + {"NestedLessLess", 0x0226A} , + {"NewLine", 0x0000A} , + {"Nfr", 0x1D511} , + {"NoBreak", 0x02060} , + {"NonBreakingSpace", 0x000A0} , + {"Nopf", 0x02115} , + {"Not", 0x02AEC} , + {"NotCongruent", 0x02262} , + {"NotCupCap", 0x0226D} , + {"NotDoubleVerticalBar", 0x02226} , + {"NotElement", 0x02209} , + {"NotEqual", 0x02260} , + {"NotExists", 0x02204} , + {"NotGreater", 0x0226F} , + {"NotGreaterEqual", 0x02271} , + {"NotGreaterLess", 0x02279} , + {"NotGreaterTilde", 0x02275} , + {"NotLeftTriangle", 0x022EA} , + {"NotLeftTriangleEqual", 0x022EC} , + {"NotLess", 0x0226E} , + {"NotLessEqual", 0x02270} , + {"NotLessGreater", 0x02278} , + {"NotLessTilde", 0x02274} , + {"NotPrecedes", 0x02280} , + {"NotPrecedesSlantEqual", 0x022E0} , + {"NotReverseElement", 0x0220C} , + {"NotRightTriangle", 0x022EB} , + {"NotRightTriangleEqual", 0x022ED} , + {"NotSquareSubsetEqual", 0x022E2} , + {"NotSquareSupersetEqual", 0x022E3} , + {"NotSubsetEqual", 0x02288} , + {"NotSucceeds", 0x02281} , + {"NotSucceedsSlantEqual", 0x022E1} , + {"NotSupersetEqual", 0x02289} , + {"NotTilde", 0x02241} , + {"NotTildeEqual", 0x02244} , + {"NotTildeFullEqual", 0x02247} , + {"NotTildeTilde", 0x02249} , + {"NotVerticalBar", 0x02224} , + {"Nscr", 0x1D4A9} , + {"Ntilde", 0x000D1} , + {"OElig", 0x00152} , + {"Oacute", 0x000D3} , + {"Ocirc", 0x000D4} , + {"Ocy", 0x0041E} , + {"Odblac", 0x00150} , + {"Ofr", 0x1D512} , + {"Ograve", 0x000D2} , + {"Omacr", 0x0014C} , + {"Omega", 0x003A9} , + {"Oopf", 0x1D546} , + {"OpenCurlyDoubleQuote", 0x0201C} , + {"OpenCurlyQuote", 0x02018} , + {"Or", 0x02A54} , + {"Oscr", 0x1D4AA} , + {"Oslash", 0x000D8} , + {"Otilde", 0x000D5} , + {"Otimes", 0x02A37} , + {"Ouml", 0x000D6} , + {"OverBar", 0x000AF} , + {"OverBrace", 0x0FE37} , + {"OverBracket", 0x023B4} , + {"OverParenthesis", 0x0FE35} , + {"PartialD", 0x02202} , + {"Pcy", 0x0041F} , + {"Pfr", 0x1D513} , + {"Phi", 0x003A6} , + {"Pi", 0x003A0} , + {"PlusMinus", 0x000B1} , + {"Poincareplane", 0x0210C} , + {"Popf", 0x02119} , + {"Pr", 0x02ABB} , + {"Precedes", 0x0227A} , + {"PrecedesEqual", 0x02AAF} , + {"PrecedesSlantEqual", 0x0227C} , + {"PrecedesTilde", 0x0227E} , + {"Prime", 0x02033} , + {"Product", 0x0220F} , + {"Proportion", 0x02237} , + {"Proportional", 0x0221D} , + {"Pscr", 0x1D4AB} , + {"Psi", 0x003A8} , + {"Qfr", 0x1D514} , + {"Qopf", 0x0211A} , + {"Qscr", 0x1D4AC} , + {"RBarr", 0x02910} , + {"Racute", 0x00154} , + {"Rang", 0x0300B} , + {"Rarr", 0x021A0} , + {"Rarrtl", 0x02916} , + {"Rcaron", 0x00158} , + {"Rcedil", 0x00156} , + {"Rcy", 0x00420} , + {"Re", 0x0211C} , + {"ReverseElement", 0x0220B} , + {"ReverseEquilibrium", 0x021CB} , + {"ReverseUpEquilibrium", 0x0296F} , + {"Rfr", 0x0211C} , + {"RightAngleBracket", 0x0232A} , + {"RightArrow", 0x02192} , + {"RightArrowBar", 0x021E5} , + {"RightArrowLeftArrow", 0x021C4} , + {"RightCeiling", 0x02309} , + {"RightDoubleBracket", 0x0301B} , + {"RightDownTeeVector", 0x0295D} , + {"RightDownVector", 0x021C2} , + {"RightDownVectorBar", 0x02955} , + {"RightFloor", 0x0230B} , + {"RightTee", 0x022A2} , + {"RightTeeArrow", 0x021A6} , + {"RightTeeVector", 0x0295B} , + {"RightTriangle", 0x022B3} , + {"RightTriangleBar", 0x029D0} , + {"RightTriangleEqual", 0x022B5} , + {"RightUpDownVector", 0x0294F} , + {"RightUpTeeVector", 0x0295C} , + {"RightUpVector", 0x021BE} , + {"RightUpVectorBar", 0x02954} , + {"RightVector", 0x021C0} , + {"RightVectorBar", 0x02953} , + {"Rightarrow", 0x021D2} , + {"Ropf", 0x0211D} , + {"RoundImplies", 0x02970} , + {"Rrightarrow", 0x021DB} , + {"Rscr", 0x0211B} , + {"Rsh", 0x021B1} , + {"RuleDelayed", 0x029F4} , + {"SHCHcy", 0x00429} , + {"SHcy", 0x00428} , + {"SOFTcy", 0x0042C} , + {"Sacute", 0x0015A} , + {"Sc", 0x02ABC} , + {"Scaron", 0x00160} , + {"Scedil", 0x0015E} , + {"Scirc", 0x0015C} , + {"Scy", 0x00421} , + {"Sfr", 0x1D516} , + {"ShortDownArrow", 0x02193} , + {"ShortLeftArrow", 0x02190} , + {"ShortRightArrow", 0x02192} , + {"ShortUpArrow", 0x02191} , + {"Sigma", 0x003A3} , + {"SmallCircle", 0x02218} , + {"Sopf", 0x1D54A} , + {"Sqrt", 0x0221A} , + {"Square", 0x025A1} , + {"SquareIntersection", 0x02293} , + {"SquareSubset", 0x0228F} , + {"SquareSubsetEqual", 0x02291} , + {"SquareSuperset", 0x02290} , + {"SquareSupersetEqual", 0x02292} , + {"SquareUnion", 0x02294} , + {"Sscr", 0x1D4AE} , + {"Star", 0x022C6} , + {"Sub", 0x022D0} , + {"Subset", 0x022D0} , + {"SubsetEqual", 0x02286} , + {"Succeeds", 0x0227B} , + {"SucceedsEqual", 0x02AB0} , + {"SucceedsSlantEqual", 0x0227D} , + {"SucceedsTilde", 0x0227F} , + {"SuchThat", 0x0220B} , + {"Sum", 0x02211} , + {"Sup", 0x022D1} , + {"Superset", 0x02283} , + {"SupersetEqual", 0x02287} , + {"Supset", 0x022D1} , + {"THORN", 0x000DE} , + {"TSHcy", 0x0040B} , + {"TScy", 0x00426} , + {"Tab", 0x00009} , + {"Tcaron", 0x00164} , + {"Tcedil", 0x00162} , + {"Tcy", 0x00422} , + {"Tfr", 0x1D517} , + {"Therefore", 0x02234} , + {"Theta", 0x00398} , + {"ThinSpace", 0x02009} , + {"Tilde", 0x0223C} , + {"TildeEqual", 0x02243} , + {"TildeFullEqual", 0x02245} , + {"TildeTilde", 0x02248} , + {"Topf", 0x1D54B} , + {"TripleDot", 0x020DB} , + {"Tscr", 0x1D4AF} , + {"Tstrok", 0x00166} , + {"Uacute", 0x000DA} , + {"Uarr", 0x0219F} , + {"Uarrocir", 0x02949} , + {"Ubrcy", 0x0040E} , + {"Ubreve", 0x0016C} , + {"Ucirc", 0x000DB} , + {"Ucy", 0x00423} , + {"Udblac", 0x00170} , + {"Ufr", 0x1D518} , + {"Ugrave", 0x000D9} , + {"Umacr", 0x0016A} , + {"UnderBar", 0x00332} , + {"UnderBrace", 0x0FE38} , + {"UnderBracket", 0x023B5} , + {"UnderParenthesis", 0x0FE36} , + {"Union", 0x022C3} , + {"UnionPlus", 0x0228E} , + {"Uogon", 0x00172} , + {"Uopf", 0x1D54C} , + {"UpArrow", 0x02191} , + {"UpArrowBar", 0x02912} , + {"UpArrowDownArrow", 0x021C5} , + {"UpDownArrow", 0x02195} , + {"UpEquilibrium", 0x0296E} , + {"UpTee", 0x022A5} , + {"UpTeeArrow", 0x021A5} , + {"Uparrow", 0x021D1} , + {"Updownarrow", 0x021D5} , + {"UpperLeftArrow", 0x02196} , + {"UpperRightArrow", 0x02197} , + {"Upsi", 0x003D2} , + {"Upsilon", 0x003A5} , + {"Uring", 0x0016E} , + {"Uscr", 0x1D4B0} , + {"Utilde", 0x00168} , + {"Uuml", 0x000DC} , + {"VDash", 0x022AB} , + {"Vbar", 0x02AEB} , + {"Vcy", 0x00412} , + {"Vdash", 0x022A9} , + {"Vdashl", 0x02AE6} , + {"Vee", 0x022C1} , + {"Verbar", 0x02016} , + {"Vert", 0x02016} , + {"VerticalBar", 0x02223} , + {"VerticalLine", 0x0007C} , + {"VerticalSeparator", 0x02758} , + {"VerticalTilde", 0x02240} , + {"VeryThinSpace", 0x0200A} , + {"Vfr", 0x1D519} , + {"Vopf", 0x1D54D} , + {"Vscr", 0x1D4B1} , + {"Vvdash", 0x022AA} , + {"Wcirc", 0x00174} , + {"Wedge", 0x022C0} , + {"Wfr", 0x1D51A} , + {"Wopf", 0x1D54E} , + {"Wscr", 0x1D4B2} , + {"Xfr", 0x1D51B} , + {"Xi", 0x0039E} , + {"Xopf", 0x1D54F} , + {"Xscr", 0x1D4B3} , + {"YAcy", 0x0042F} , + {"YIcy", 0x00407} , + {"YUcy", 0x0042E} , + {"Yacute", 0x000DD} , + {"Ycirc", 0x00176} , + {"Ycy", 0x0042B} , + {"Yfr", 0x1D51C} , + {"Yopf", 0x1D550} , + {"Yscr", 0x1D4B4} , + {"Yuml", 0x00178} , + {"ZHcy", 0x00416} , + {"Zacute", 0x00179} , + {"Zcaron", 0x0017D} , + {"Zcy", 0x00417} , + {"Zdot", 0x0017B} , + {"ZeroWidthSpace", 0x0200B} , + {"Zfr", 0x02128} , + {"Zopf", 0x02124} , + {"Zscr", 0x1D4B5} , + {"aacute", 0x000E1} , + {"abreve", 0x00103} , + {"ac", 0x0223E} , + {"acd", 0x0223F} , + {"acirc", 0x000E2} , + {"acute", 0x000B4} , + {"acy", 0x00430} , + {"aelig", 0x000E6} , + {"af", 0x02061} , + {"afr", 0x1D51E} , + {"agrave", 0x000E0} , + {"aleph", 0x02135} , + {"alpha", 0x003B1} , + {"amacr", 0x00101} , + {"amalg", 0x02A3F} , + {"amp", 0x00026} , + {"and", 0x02227} , + {"andand", 0x02A55} , + {"andd", 0x02A5C} , + {"andslope", 0x02A58} , + {"andv", 0x02A5A} , + {"ang", 0x02220} , + {"ange", 0x029A4} , + {"angle", 0x02220} , + {"angmsd", 0x02221} , + {"angmsdaa", 0x029A8} , + {"angmsdab", 0x029A9} , + {"angmsdac", 0x029AA} , + {"angmsdad", 0x029AB} , + {"angmsdae", 0x029AC} , + {"angmsdaf", 0x029AD} , + {"angmsdag", 0x029AE} , + {"angmsdah", 0x029AF} , + {"angrt", 0x0221F} , + {"angrtvb", 0x022BE} , + {"angrtvbd", 0x0299D} , + {"angsph", 0x02222} , + {"angst", 0x0212B} , + {"angzarr", 0x0237C} , + {"aogon", 0x00105} , + {"aopf", 0x1D552} , + {"ap", 0x02248} , + {"apE", 0x02A70} , + {"apacir", 0x02A6F} , + {"ape", 0x0224A} , + {"apid", 0x0224B} , + {"apos", 0x00027} , + {"approx", 0x02248} , + {"approxeq", 0x0224A} , + {"aring", 0x000E5} , + {"ascr", 0x1D4B6} , + {"ast", 0x0002A} , + {"asymp", 0x02248} , + {"asympeq", 0x0224D} , + {"atilde", 0x000E3} , + {"auml", 0x000E4} , + {"awconint", 0x02233} , + {"awint", 0x02A11} , + {"bNot", 0x02AED} , + {"backcong", 0x0224C} , + {"backepsilon", 0x003F6} , + {"backprime", 0x02035} , + {"backsim", 0x0223D} , + {"backsimeq", 0x022CD} , + {"barvee", 0x022BD} , + {"barwed", 0x02305} , + {"barwedge", 0x02305} , + {"bbrk", 0x023B5} , + {"bbrktbrk", 0x023B6} , + {"bcong", 0x0224C} , + {"bcy", 0x00431} , + {"becaus", 0x02235} , + {"because", 0x02235} , + {"bemptyv", 0x029B0} , + {"bepsi", 0x003F6} , + {"bernou", 0x0212C} , + {"beta", 0x003B2} , + {"beth", 0x02136} , + {"between", 0x0226C} , + {"bfr", 0x1D51F} , + {"bigcap", 0x022C2} , + {"bigcirc", 0x025EF} , + {"bigcup", 0x022C3} , + {"bigodot", 0x02A00} , + {"bigoplus", 0x02A01} , + {"bigotimes", 0x02A02} , + {"bigsqcup", 0x02A06} , + {"bigstar", 0x02605} , + {"bigtriangledown", 0x025BD} , + {"bigtriangleup", 0x025B3} , + {"biguplus", 0x02A04} , + {"bigvee", 0x022C1} , + {"bigwedge", 0x022C0} , + {"bkarow", 0x0290D} , + {"blacklozenge", 0x029EB} , + {"blacksquare", 0x025AA} , + {"blacktriangle", 0x025B4} , + {"blacktriangledown", 0x025BE} , + {"blacktriangleleft", 0x025C2} , + {"blacktriangleright", 0x025B8} , + {"blank", 0x02423} , + {"blk12", 0x02592} , + {"blk14", 0x02591} , + {"blk34", 0x02593} , + {"block", 0x02588} , + {"bnot", 0x02310} , + {"bopf", 0x1D553} , + {"bot", 0x022A5} , + {"bottom", 0x022A5} , + {"bowtie", 0x022C8} , + {"boxDL", 0x02557} , + {"boxDR", 0x02554} , + {"boxDl", 0x02556} , + {"boxDr", 0x02553} , + {"boxH", 0x02550} , + {"boxHD", 0x02566} , + {"boxHU", 0x02569} , + {"boxHd", 0x02564} , + {"boxHu", 0x02567} , + {"boxUL", 0x0255D} , + {"boxUR", 0x0255A} , + {"boxUl", 0x0255C} , + {"boxUr", 0x02559} , + {"boxV", 0x02551} , + {"boxVH", 0x0256C} , + {"boxVL", 0x02563} , + {"boxVR", 0x02560} , + {"boxVh", 0x0256B} , + {"boxVl", 0x02562} , + {"boxVr", 0x0255F} , + {"boxbox", 0x029C9} , + {"boxdL", 0x02555} , + {"boxdR", 0x02552} , + {"boxdl", 0x02510} , + {"boxdr", 0x0250C} , + {"boxh", 0x02500} , + {"boxhD", 0x02565} , + {"boxhU", 0x02568} , + {"boxhd", 0x0252C} , + {"boxhu", 0x02534} , + {"boxminus", 0x0229F} , + {"boxplus", 0x0229E} , + {"boxtimes", 0x022A0} , + {"boxuL", 0x0255B} , + {"boxuR", 0x02558} , + {"boxul", 0x02518} , + {"boxur", 0x02514} , + {"boxv", 0x02502} , + {"boxvH", 0x0256A} , + {"boxvL", 0x02561} , + {"boxvR", 0x0255E} , + {"boxvh", 0x0253C} , + {"boxvl", 0x02524} , + {"boxvr", 0x0251C} , + {"bprime", 0x02035} , + {"breve", 0x002D8} , + {"brvbar", 0x000A6} , + {"bscr", 0x1D4B7} , + {"bsemi", 0x0204F} , + {"bsim", 0x0223D} , + {"bsime", 0x022CD} , + {"bsol", 0x0005C} , + {"bsolb", 0x029C5} , + {"bull", 0x02022} , + {"bullet", 0x02022} , + {"bump", 0x0224E} , + {"bumpE", 0x02AAE} , + {"bumpe", 0x0224F} , + {"bumpeq", 0x0224F} , + {"cacute", 0x00107} , + {"cap", 0x02229} , + {"capand", 0x02A44} , + {"capbrcup", 0x02A49} , + {"capcap", 0x02A4B} , + {"capcup", 0x02A47} , + {"capdot", 0x02A40} , + {"caret", 0x02041} , + {"caron", 0x002C7} , + {"ccaps", 0x02A4D} , + {"ccaron", 0x0010D} , + {"ccedil", 0x000E7} , + {"ccirc", 0x00109} , + {"ccups", 0x02A4C} , + {"ccupssm", 0x02A50} , + {"cdot", 0x0010B} , + {"cedil", 0x000B8} , + {"cemptyv", 0x029B2} , + {"cent", 0x000A2} , + {"centerdot", 0x000B7} , + {"cfr", 0x1D520} , + {"chcy", 0x00447} , + {"check", 0x02713} , + {"checkmark", 0x02713} , + {"chi", 0x003C7} , + {"cir", 0x025CB} , + {"cirE", 0x029C3} , + {"circ", 0x002C6} , + {"circeq", 0x02257} , + {"circlearrowleft", 0x021BA} , + {"circlearrowright", 0x021BB} , + {"circledR", 0x000AE} , + {"circledS", 0x024C8} , + {"circledast", 0x0229B} , + {"circledcirc", 0x0229A} , + {"circleddash", 0x0229D} , + {"cire", 0x02257} , + {"cirfnint", 0x02A10} , + {"cirmid", 0x02AEF} , + {"cirscir", 0x029C2} , + {"clubs", 0x02663} , + {"clubsuit", 0x02663} , + {"colon", 0x0003A} , + {"colone", 0x02254} , + {"coloneq", 0x02254} , + {"comma", 0x0002C} , + {"commat", 0x00040} , + {"comp", 0x02201} , + {"compfn", 0x02218} , + {"complement", 0x02201} , + {"complexes", 0x02102} , + {"cong", 0x02245} , + {"congdot", 0x02A6D} , + {"conint", 0x0222E} , + {"copf", 0x1D554} , + {"coprod", 0x02210} , + {"copy", 0x000A9} , + {"copysr", 0x02117} , + {"cross", 0x02717} , + {"cscr", 0x1D4B8} , + {"csub", 0x02ACF} , + {"csube", 0x02AD1} , + {"csup", 0x02AD0} , + {"csupe", 0x02AD2} , + {"ctdot", 0x022EF} , + {"cudarrl", 0x02938} , + {"cudarrr", 0x02935} , + {"cuepr", 0x022DE} , + {"cuesc", 0x022DF} , + {"cularr", 0x021B6} , + {"cularrp", 0x0293D} , + {"cup", 0x0222A} , + {"cupbrcap", 0x02A48} , + {"cupcap", 0x02A46} , + {"cupcup", 0x02A4A} , + {"cupdot", 0x0228D} , + {"cupor", 0x02A45} , + {"curarr", 0x021B7} , + {"curarrm", 0x0293C} , + {"curlyeqprec", 0x022DE} , + {"curlyeqsucc", 0x022DF} , + {"curlyvee", 0x022CE} , + {"curlywedge", 0x022CF} , + {"curren", 0x000A4} , + {"curvearrowleft", 0x021B6} , + {"curvearrowright", 0x021B7} , + {"cuvee", 0x022CE} , + {"cuwed", 0x022CF} , + {"cwconint", 0x02232} , + {"cwint", 0x02231} , + {"cylcty", 0x0232D} , + {"dArr", 0x021D3} , + {"dHar", 0x02965} , + {"dagger", 0x02020} , + {"dagger", 0x02020} , + {"daleth", 0x02138} , + {"darr", 0x02193} , + {"dash", 0x02010} , + {"dashv", 0x022A3} , + {"dbkarow", 0x0290F} , + {"dblac", 0x002DD} , + {"dcaron", 0x0010F} , + {"dcy", 0x00434} , + {"dd", 0x02146} , + {"ddagger", 0x02021} , + {"ddarr", 0x021CA} , + {"ddotseq", 0x02A77} , + {"deg", 0x000B0} , + {"delta", 0x003B4} , + {"demptyv", 0x029B1} , + {"dfisht", 0x0297F} , + {"dfr", 0x1D521} , + {"dharl", 0x021C3} , + {"dharr", 0x021C2} , + {"diam", 0x022C4} , + {"diamond", 0x022C4} , + {"diamondsuit", 0x02666} , + {"diams", 0x02666} , + {"die", 0x000A8} , + {"digamma", 0x003DD} , + {"disin", 0x022F2} , + {"div", 0x000F7} , + {"divide", 0x000F7} , + {"divideontimes", 0x022C7} , + {"divonx", 0x022C7} , + {"djcy", 0x00452} , + {"dlcorn", 0x0231E} , + {"dlcrop", 0x0230D} , + {"dollar", 0x00024} , + {"dopf", 0x1D555} , + {"dot", 0x002D9} , + {"doteq", 0x02250} , + {"doteqdot", 0x02251} , + {"dotminus", 0x02238} , + {"dotplus", 0x02214} , + {"dotsquare", 0x022A1} , + {"doublebarwedge", 0x02306} , + {"downarrow", 0x02193} , + {"downdownarrows", 0x021CA} , + {"downharpoonleft", 0x021C3} , + {"downharpoonright", 0x021C2} , + {"drbkarow", 0x02910} , + {"drcorn", 0x0231F} , + {"drcrop", 0x0230C} , + {"dscr", 0x1D4B9} , + {"dscy", 0x00455} , + {"dsol", 0x029F6} , + {"dstrok", 0x00111} , + {"dtdot", 0x022F1} , + {"dtri", 0x025BF} , + {"dtrif", 0x025BE} , + {"duarr", 0x021F5} , + {"duhar", 0x0296F} , + {"dwangle", 0x029A6} , + {"dzcy", 0x0045F} , + {"dzigrarr", 0x027FF} , + {"eDDot", 0x02A77} , + {"eDot", 0x02251} , + {"eacute", 0x000E9} , + {"easter", 0x02A6E} , + {"ecaron", 0x0011B} , + {"ecir", 0x02256} , + {"ecirc", 0x000EA} , + {"ecolon", 0x02255} , + {"ecy", 0x0044D} , + {"edot", 0x00117} , + {"ee", 0x02147} , + {"efDot", 0x02252} , + {"efr", 0x1D522} , + {"eg", 0x02A9A} , + {"egrave", 0x000E8} , + {"egs", 0x02A96} , + {"egsdot", 0x02A98} , + {"el", 0x02A99} , + {"elinters", 0x0FFFD} , + {"ell", 0x02113} , + {"els", 0x02A95} , + {"elsdot", 0x02A97} , + {"emacr", 0x00113} , + {"empty", 0x02205} , + {"emptyset", 0x02205} , + {"emptyv", 0x02205} , + {"emsp", 0x02003} , + {"emsp13", 0x02004} , + {"emsp14", 0x02005} , + {"eng", 0x0014B} , + {"ensp", 0x02002} , + {"eogon", 0x00119} , + {"eopf", 0x1D556} , + {"epar", 0x022D5} , + {"eparsl", 0x029E3} , + {"eplus", 0x02A71} , + {"epsi", 0x003F5} , + {"epsiv", 0x003B5} , + {"eqcirc", 0x02256} , + {"eqcolon", 0x02255} , + {"eqsim", 0x02242} , + {"eqslantgtr", 0x02A96} , + {"eqslantless", 0x02A95} , + {"equals", 0x0003D} , + {"equest", 0x0225F} , + {"equiv", 0x02261} , + {"equivDD", 0x02A78} , + {"eqvparsl", 0x029E5} , + {"erDot", 0x02253} , + {"erarr", 0x02971} , + {"escr", 0x0212F} , + {"esdot", 0x02250} , + {"esim", 0x02242} , + {"eta", 0x003B7} , + {"eth", 0x000F0} , + {"euml", 0x000EB} , + {"excl", 0x00021} , + {"exist", 0x02203} , + {"expectation", 0x02130} , + {"exponentiale", 0x02147} , + {"fallingdotseq", 0x02252} , + {"fcy", 0x00444} , + {"female", 0x02640} , + {"ffilig", 0x0FB03} , + {"fflig", 0x0FB00} , + {"ffllig", 0x0FB04} , + {"ffr", 0x1D523} , + {"filig", 0x0FB01} , + {"flat", 0x0266D} , + {"fllig", 0x0FB02} , + {"fltns", 0x025B1} , + {"fnof", 0x00192} , + {"fopf", 0x1D557} , + {"forall", 0x02200} , + {"fork", 0x022D4} , + {"forkv", 0x02AD9} , + {"fpartint", 0x02A0D} , + {"frac12", 0x000BD} , + {"frac13", 0x02153} , + {"frac14", 0x000BC} , + {"frac15", 0x02155} , + {"frac16", 0x02159} , + {"frac18", 0x0215B} , + {"frac23", 0x02154} , + {"frac25", 0x02156} , + {"frac34", 0x000BE} , + {"frac35", 0x02157} , + {"frac38", 0x0215C} , + {"frac45", 0x02158} , + {"frac56", 0x0215A} , + {"frac58", 0x0215D} , + {"frac78", 0x0215E} , + {"frown", 0x02322} , + {"fscr", 0x1D4BB} , + {"gE", 0x02267} , + {"gEl", 0x02A8C} , + {"gacute", 0x001F5} , + {"gamma", 0x003B3} , + {"gammad", 0x003DD} , + {"gap", 0x02A86} , + {"gbreve", 0x0011F} , + {"gcirc", 0x0011D} , + {"gcy", 0x00433} , + {"gdot", 0x00121} , + {"ge", 0x02265} , + {"gel", 0x022DB} , + {"geq", 0x02265} , + {"geqq", 0x02267} , + {"geqslant", 0x02A7E} , + {"ges", 0x02A7E} , + {"gescc", 0x02AA9} , + {"gesdot", 0x02A80} , + {"gesdoto", 0x02A82} , + {"gesdotol", 0x02A84} , + {"gesles", 0x02A94} , + {"gfr", 0x1D524} , + {"gg", 0x0226B} , + {"ggg", 0x022D9} , + {"gimel", 0x02137} , + {"gjcy", 0x00453} , + {"gl", 0x02277} , + {"glE", 0x02A92} , + {"gla", 0x02AA5} , + {"glj", 0x02AA4} , + {"gnE", 0x02269} , + {"gnap", 0x02A8A} , + {"gnapprox", 0x02A8A} , + {"gne", 0x02A88} , + {"gneq", 0x02A88} , + {"gneqq", 0x02269} , + {"gnsim", 0x022E7} , + {"gopf", 0x1D558} , + {"grave", 0x00060} , + {"gscr", 0x0210A} , + {"gsim", 0x02273} , + {"gsime", 0x02A8E} , + {"gsiml", 0x02A90} , + {"gt", 0x0003E} , + {"gtcc", 0x02AA7} , + {"gtcir", 0x02A7A} , + {"gtdot", 0x022D7} , + {"gtlPar", 0x02995} , + {"gtquest", 0x02A7C} , + {"gtrapprox", 0x02A86} , + {"gtrarr", 0x02978} , + {"gtrdot", 0x022D7} , + {"gtreqless", 0x022DB} , + {"gtreqqless", 0x02A8C} , + {"gtrless", 0x02277} , + {"gtrsim", 0x02273} , + {"hArr", 0x021D4} , + {"hairsp", 0x0200A} , + {"half", 0x000BD} , + {"hamilt", 0x0210B} , + {"hardcy", 0x0044A} , + {"harr", 0x02194} , + {"harrcir", 0x02948} , + {"harrw", 0x021AD} , + {"hbar", 0x0210F} , + {"hcirc", 0x00125} , + {"hearts", 0x02665} , + {"heartsuit", 0x02665} , + {"hellip", 0x02026} , + {"hercon", 0x022B9} , + {"hfr", 0x1D525} , + {"hksearow", 0x02925} , + {"hkswarow", 0x02926} , + {"hoarr", 0x021FF} , + {"homtht", 0x0223B} , + {"hookleftarrow", 0x021A9} , + {"hookrightarrow", 0x021AA} , + {"hopf", 0x1D559} , + {"horbar", 0x02015} , + {"hscr", 0x1D4BD} , + {"hslash", 0x0210F} , + {"hstrok", 0x00127} , + {"hybull", 0x02043} , + {"hyphen", 0x02010} , + {"iacute", 0x000ED} , + {"ic", 0x02063} , + {"icirc", 0x000EE} , + {"icy", 0x00438} , + {"iecy", 0x00435} , + {"iexcl", 0x000A1} , + {"iff", 0x021D4} , + {"ifr", 0x1D526} , + {"igrave", 0x000EC} , + {"ii", 0x02148} , + {"iiiint", 0x02A0C} , + {"iiint", 0x0222D} , + {"iinfin", 0x029DC} , + {"iiota", 0x02129} , + {"ijlig", 0x00133} , + {"imacr", 0x0012B} , + {"image", 0x02111} , + {"imagline", 0x02110} , + {"imagpart", 0x02111} , + {"imath", 0x00131} , + {"imof", 0x022B7} , + {"imped", 0x001B5} , + {"in", 0x02208} , + {"incare", 0x02105} , + {"infin", 0x0221E} , + {"infintie", 0x029DD} , + {"inodot", 0x00131} , + {"int", 0x0222B} , + {"intcal", 0x022BA} , + {"integers", 0x02124} , + {"intercal", 0x022BA} , + {"intlarhk", 0x02A17} , + {"intprod", 0x02A3C} , + {"iocy", 0x00451} , + {"iogon", 0x0012F} , + {"iopf", 0x1D55A} , + {"iota", 0x003B9} , + {"iprod", 0x02A3C} , + {"iquest", 0x000BF} , + {"iscr", 0x1D4BE} , + {"isin", 0x02208} , + {"isinE", 0x022F9} , + {"isindot", 0x022F5} , + {"isins", 0x022F4} , + {"isinsv", 0x022F3} , + {"isinv", 0x02208} , + {"it", 0x02062} , + {"itilde", 0x00129} , + {"iukcy", 0x00456} , + {"iuml", 0x000EF} , + {"jcirc", 0x00135} , + {"jcy", 0x00439} , + {"jfr", 0x1D527} , + {"jmath", 0x0006A} , + {"jopf", 0x1D55B} , + {"jscr", 0x1D4BF} , + {"jsercy", 0x00458} , + {"jukcy", 0x00454} , + {"kappa", 0x003BA} , + {"kappav", 0x003F0} , + {"kcedil", 0x00137} , + {"kcy", 0x0043A} , + {"kfr", 0x1D528} , + {"kgreen", 0x00138} , + {"khcy", 0x00445} , + {"kjcy", 0x0045C} , + {"kopf", 0x1D55C} , + {"kscr", 0x1D4C0} , + {"lAarr", 0x021DA} , + {"lArr", 0x021D0} , + {"lAtail", 0x0291B} , + {"lBarr", 0x0290E} , + {"lE", 0x02266} , + {"lEg", 0x02A8B} , + {"lHar", 0x02962} , + {"lacute", 0x0013A} , + {"laemptyv", 0x029B4} , + {"lagran", 0x02112} , + {"lambda", 0x003BB} , + {"lang", 0x02329} , + {"langd", 0x02991} , + {"langle", 0x02329} , + {"lap", 0x02A85} , + {"laquo", 0x000AB} , + {"larr", 0x02190} , + {"larrb", 0x021E4} , + {"larrbfs", 0x0291F} , + {"larrfs", 0x0291D} , + {"larrhk", 0x021A9} , + {"larrlp", 0x021AB} , + {"larrpl", 0x02939} , + {"larrsim", 0x02973} , + {"larrtl", 0x021A2} , + {"lat", 0x02AAB} , + {"latail", 0x02919} , + {"late", 0x02AAD} , + {"lbarr", 0x0290C} , + {"lbbrk", 0x03014} , + {"lbrace", 0x0007B} , + {"lbrack", 0x0005B} , + {"lbrke", 0x0298B} , + {"lbrksld", 0x0298F} , + {"lbrkslu", 0x0298D} , + {"lcaron", 0x0013E} , + {"lcedil", 0x0013C} , + {"lceil", 0x02308} , + {"lcub", 0x0007B} , + {"lcy", 0x0043B} , + {"ldca", 0x02936} , + {"ldquo", 0x0201C} , + {"ldquor", 0x0201E} , + {"ldrdhar", 0x02967} , + {"ldrushar", 0x0294B} , + {"ldsh", 0x021B2} , + {"le", 0x02264} , + {"leftarrow", 0x02190} , + {"leftarrowtail", 0x021A2} , + {"leftharpoondown", 0x021BD} , + {"leftharpoonup", 0x021BC} , + {"leftleftarrows", 0x021C7} , + {"leftrightarrow", 0x02194} , + {"leftrightarrows", 0x021C6} , + {"leftrightharpoons", 0x021CB} , + {"leftrightsquigarrow", 0x021AD} , + {"leftthreetimes", 0x022CB} , + {"leg", 0x022DA} , + {"leq", 0x02264} , + {"leqq", 0x02266} , + {"leqslant", 0x02A7D} , + {"les", 0x02A7D} , + {"lescc", 0x02AA8} , + {"lesdot", 0x02A7F} , + {"lesdoto", 0x02A81} , + {"lesdotor", 0x02A83} , + {"lesges", 0x02A93} , + {"lessapprox", 0x02A85} , + {"lessdot", 0x022D6} , + {"lesseqgtr", 0x022DA} , + {"lesseqqgtr", 0x02A8B} , + {"lessgtr", 0x02276} , + {"lesssim", 0x02272} , + {"lfisht", 0x0297C} , + {"lfloor", 0x0230A} , + {"lfr", 0x1D529} , + {"lg", 0x02276} , + {"lgE", 0x02A91} , + {"lhard", 0x021BD} , + {"lharu", 0x021BC} , + {"lharul", 0x0296A} , + {"lhblk", 0x02584} , + {"ljcy", 0x00459} , + {"ll", 0x0226A} , + {"llarr", 0x021C7} , + {"llcorner", 0x0231E} , + {"llhard", 0x0296B} , + {"lltri", 0x025FA} , + {"lmidot", 0x00140} , + {"lmoust", 0x023B0} , + {"lmoustache", 0x023B0} , + {"lnE", 0x02268} , + {"lnap", 0x02A89} , + {"lnapprox", 0x02A89} , + {"lne", 0x02A87} , + {"lneq", 0x02A87} , + {"lneqq", 0x02268} , + {"lnsim", 0x022E6} , + {"loang", 0x03018} , + {"loarr", 0x021FD} , + {"lobrk", 0x0301A} , + {"longleftarrow", 0x027F5} , + {"longleftrightarrow", 0x027F7} , + {"longmapsto", 0x027FC} , + {"longrightarrow", 0x027F6} , + {"looparrowleft", 0x021AB} , + {"looparrowright", 0x021AC} , + {"lopar", 0x02985} , + {"lopf", 0x1D55D} , + {"loplus", 0x02A2D} , + {"lotimes", 0x02A34} , + {"lowast", 0x02217} , + {"lowbar", 0x0005F} , + {"loz", 0x025CA} , + {"lozenge", 0x025CA} , + {"lozf", 0x029EB} , + {"lpar", 0x00028} , + {"lparlt", 0x02993} , + {"lrarr", 0x021C6} , + {"lrcorner", 0x0231F} , + {"lrhar", 0x021CB} , + {"lrhard", 0x0296D} , + {"lrtri", 0x022BF} , + {"lscr", 0x1D4C1} , + {"lsh", 0x021B0} , + {"lsim", 0x02272} , + {"lsime", 0x02A8D} , + {"lsimg", 0x02A8F} , + {"lsqb", 0x0005B} , + {"lsquo", 0x02018} , + {"lsquor", 0x0201A} , + {"lstrok", 0x00142} , + {"lt", 0x0003C} , + {"ltcc", 0x02AA6} , + {"ltcir", 0x02A79} , + {"ltdot", 0x022D6} , + {"lthree", 0x022CB} , + {"ltimes", 0x022C9} , + {"ltlarr", 0x02976} , + {"ltquest", 0x02A7B} , + {"ltrPar", 0x02996} , + {"ltri", 0x025C3} , + {"ltrie", 0x022B4} , + {"ltrif", 0x025C2} , + {"lurdshar", 0x0294A} , + {"luruhar", 0x02966} , + {"mDDot", 0x0223A} , + {"macr", 0x000AF} , + {"male", 0x02642} , + {"malt", 0x02720} , + {"maltese", 0x02720} , + {"map", 0x021A6} , + {"mapsto", 0x021A6} , + {"mapstodown", 0x021A7} , + {"mapstoleft", 0x021A4} , + {"mapstoup", 0x021A5} , + {"marker", 0x025AE} , + {"mcomma", 0x02A29} , + {"mcy", 0x0043C} , + {"mdash", 0x02014} , + {"measuredangle", 0x02221} , + {"mfr", 0x1D52A} , + {"mho", 0x02127} , + {"micro", 0x000B5} , + {"mid", 0x02223} , + {"midast", 0x0002A} , + {"midcir", 0x02AF0} , + {"middot", 0x000B7} , + {"minus", 0x02212} , + {"minusb", 0x0229F} , + {"minusd", 0x02238} , + {"minusdu", 0x02A2A} , + {"mlcp", 0x02ADB} , + {"mldr", 0x02026} , + {"mnplus", 0x02213} , + {"models", 0x022A7} , + {"mopf", 0x1D55E} , + {"mp", 0x02213} , + {"mscr", 0x1D4C2} , + {"mstpos", 0x0223E} , + {"mu", 0x003BC} , + {"multimap", 0x022B8} , + {"mumap", 0x022B8} , + {"nLeftarrow", 0x021CD} , + {"nLeftrightarrow", 0x021CE} , + {"nRightarrow", 0x021CF} , + {"nVDash", 0x022AF} , + {"nVdash", 0x022AE} , + {"nabla", 0x02207} , + {"nacute", 0x00144} , + {"nap", 0x02249} , + {"napos", 0x00149} , + {"napprox", 0x02249} , + {"natur", 0x0266E} , + {"natural", 0x0266E} , + {"naturals", 0x02115} , + {"nbsp", 0x000A0} , + {"ncap", 0x02A43} , + {"ncaron", 0x00148} , + {"ncedil", 0x00146} , + {"ncong", 0x02247} , + {"ncup", 0x02A42} , + {"ncy", 0x0043D} , + {"ndash", 0x02013} , + {"ne", 0x02260} , + {"neArr", 0x021D7} , + {"nearhk", 0x02924} , + {"nearr", 0x02197} , + {"nearrow", 0x02197} , + {"nequiv", 0x02262} , + {"nesear", 0x02928} , + {"nexist", 0x02204} , + {"nexists", 0x02204} , + {"nfr", 0x1D52B} , + {"nge", 0x02271} , + {"ngeq", 0x02271} , + {"ngsim", 0x02275} , + {"ngt", 0x0226F} , + {"ngtr", 0x0226F} , + {"nhArr", 0x021CE} , + {"nharr", 0x021AE} , + {"nhpar", 0x02AF2} , + {"ni", 0x0220B} , + {"nis", 0x022FC} , + {"nisd", 0x022FA} , + {"niv", 0x0220B} , + {"njcy", 0x0045A} , + {"nlArr", 0x021CD} , + {"nlarr", 0x0219A} , + {"nldr", 0x02025} , + {"nle", 0x02270} , + {"nleftarrow", 0x0219A} , + {"nleftrightarrow", 0x021AE} , + {"nleq", 0x02270} , + {"nless", 0x0226E} , + {"nlsim", 0x02274} , + {"nlt", 0x0226E} , + {"nltri", 0x022EA} , + {"nltrie", 0x022EC} , + {"nmid", 0x02224} , + {"nopf", 0x1D55F} , + {"not", 0x000AC} , + {"notin", 0x02209} , + {"notinva", 0x02209} , + {"notinvb", 0x022F7} , + {"notinvc", 0x022F6} , + {"notni", 0x0220C} , + {"notniva", 0x0220C} , + {"notnivb", 0x022FE} , + {"notnivc", 0x022FD} , + {"npar", 0x02226} , + {"nparallel", 0x02226} , + {"npolint", 0x02A14} , + {"npr", 0x02280} , + {"nprcue", 0x022E0} , + {"nprec", 0x02280} , + {"nrArr", 0x021CF} , + {"nrarr", 0x0219B} , + {"nrightarrow", 0x0219B} , + {"nrtri", 0x022EB} , + {"nrtrie", 0x022ED} , + {"nsc", 0x02281} , + {"nsccue", 0x022E1} , + {"nscr", 0x1D4C3} , + {"nshortmid", 0x02224} , + {"nshortparallel", 0x02226} , + {"nsim", 0x02241} , + {"nsime", 0x02244} , + {"nsimeq", 0x02244} , + {"nsmid", 0x02224} , + {"nspar", 0x02226} , + {"nsqsube", 0x022E2} , + {"nsqsupe", 0x022E3} , + {"nsub", 0x02284} , + {"nsube", 0x02288} , + {"nsubseteq", 0x02288} , + {"nsucc", 0x02281} , + {"nsup", 0x02285} , + {"nsupe", 0x02289} , + {"nsupseteq", 0x02289} , + {"ntgl", 0x02279} , + {"ntilde", 0x000F1} , + {"ntlg", 0x02278} , + {"ntriangleleft", 0x022EA} , + {"ntrianglelefteq", 0x022EC} , + {"ntriangleright", 0x022EB} , + {"ntrianglerighteq", 0x022ED} , + {"nu", 0x003BD} , + {"num", 0x00023} , + {"numero", 0x02116} , + {"numsp", 0x02007} , + {"nvDash", 0x022AD} , + {"nvHarr", 0x02904} , + {"nvdash", 0x022AC} , + {"nvinfin", 0x029DE} , + {"nvlArr", 0x02902} , + {"nvrArr", 0x02903} , + {"nwArr", 0x021D6} , + {"nwarhk", 0x02923} , + {"nwarr", 0x02196} , + {"nwarrow", 0x02196} , + {"nwnear", 0x02927} , + {"oS", 0x024C8} , + {"oacute", 0x000F3} , + {"oast", 0x0229B} , + {"ocir", 0x0229A} , + {"ocirc", 0x000F4} , + {"ocy", 0x0043E} , + {"odash", 0x0229D} , + {"odblac", 0x00151} , + {"odiv", 0x02A38} , + {"odot", 0x02299} , + {"odsold", 0x029BC} , + {"oelig", 0x00153} , + {"ofcir", 0x029BF} , + {"ofr", 0x1D52C} , + {"ogon", 0x002DB} , + {"ograve", 0x000F2} , + {"ogt", 0x029C1} , + {"ohbar", 0x029B5} , + {"ohm", 0x02126} , + {"oint", 0x0222E} , + {"olarr", 0x021BA} , + {"olcir", 0x029BE} , + {"olcross", 0x029BB} , + {"olt", 0x029C0} , + {"omacr", 0x0014D} , + {"omega", 0x003C9} , + {"omid", 0x029B6} , + {"ominus", 0x02296} , + {"oopf", 0x1D560} , + {"opar", 0x029B7} , + {"operp", 0x029B9} , + {"oplus", 0x02295} , + {"or", 0x02228} , + {"orarr", 0x021BB} , + {"ord", 0x02A5D} , + {"order", 0x02134} , + {"orderof", 0x02134} , + {"ordf", 0x000AA} , + {"ordm", 0x000BA} , + {"origof", 0x022B6} , + {"oror", 0x02A56} , + {"orslope", 0x02A57} , + {"orv", 0x02A5B} , + {"oscr", 0x02134} , + {"oslash", 0x000F8} , + {"osol", 0x02298} , + {"otilde", 0x000F5} , + {"otimes", 0x02297} , + {"otimesas", 0x02A36} , + {"ouml", 0x000F6} , + {"ovbar", 0x0233D} , + {"par", 0x02225} , + {"para", 0x000B6} , + {"parallel", 0x02225} , + {"parsim", 0x02AF3} , + {"parsl", 0x02AFD} , + {"part", 0x02202} , + {"pcy", 0x0043F} , + {"percnt", 0x00025} , + {"period", 0x0002E} , + {"permil", 0x02030} , + {"perp", 0x022A5} , + {"pertenk", 0x02031} , + {"pfr", 0x1D52D} , + {"phi", 0x003D5} , + {"phiv", 0x003C6} , + {"phmmat", 0x02133} , + {"phone", 0x0260E} , + {"pi", 0x003C0} , + {"pitchfork", 0x022D4} , + {"piv", 0x003D6} , + {"planck", 0x0210F} , + {"planckh", 0x0210E} , + {"plankv", 0x0210F} , + {"plus", 0x0002B} , + {"plusacir", 0x02A23} , + {"plusb", 0x0229E} , + {"pluscir", 0x02A22} , + {"plusdo", 0x02214} , + {"plusdu", 0x02A25} , + {"pluse", 0x02A72} , + {"plusmn", 0x000B1} , + {"plussim", 0x02A26} , + {"plustwo", 0x02A27} , + {"pm", 0x000B1} , + {"pointint", 0x02A15} , + {"popf", 0x1D561} , + {"pound", 0x000A3} , + {"pr", 0x0227A} , + {"prE", 0x02AB3} , + {"prap", 0x02AB7} , + {"prcue", 0x0227C} , + {"pre", 0x02AAF} , + {"prec", 0x0227A} , + {"precapprox", 0x02AB7} , + {"preccurlyeq", 0x0227C} , + {"preceq", 0x02AAF} , + {"precnapprox", 0x02AB9} , + {"precneqq", 0x02AB5} , + {"precnsim", 0x022E8} , + {"precsim", 0x0227E} , + {"prime", 0x02032} , + {"primes", 0x02119} , + {"prnE", 0x02AB5} , + {"prnap", 0x02AB9} , + {"prnsim", 0x022E8} , + {"prod", 0x0220F} , + {"profalar", 0x0232E} , + {"profline", 0x02312} , + {"profsurf", 0x02313} , + {"prop", 0x0221D} , + {"propto", 0x0221D} , + {"prsim", 0x0227E} , + {"prurel", 0x022B0} , + {"pscr", 0x1D4C5} , + {"psi", 0x003C8} , + {"puncsp", 0x02008} , + {"qfr", 0x1D52E} , + {"qint", 0x02A0C} , + {"qopf", 0x1D562} , + {"qprime", 0x02057} , + {"qscr", 0x1D4C6} , + {"quaternions", 0x0210D} , + {"quatint", 0x02A16} , + {"quest", 0x0003F} , + {"questeq", 0x0225F} , + {"quot", 0x00022} , + {"rAarr", 0x021DB} , + {"rArr", 0x021D2} , + {"rAtail", 0x0291C} , + {"rBarr", 0x0290F} , + {"rHar", 0x02964} , + {"race", 0x029DA} , + {"racute", 0x00155} , + {"radic", 0x0221A} , + {"raemptyv", 0x029B3} , + {"rang", 0x0232A} , + {"rangd", 0x02992} , + {"range", 0x029A5} , + {"rangle", 0x0232A} , + {"raquo", 0x000BB} , + {"rarr", 0x02192} , + {"rarrap", 0x02975} , + {"rarrb", 0x021E5} , + {"rarrbfs", 0x02920} , + {"rarrc", 0x02933} , + {"rarrfs", 0x0291E} , + {"rarrhk", 0x021AA} , + {"rarrlp", 0x021AC} , + {"rarrpl", 0x02945} , + {"rarrsim", 0x02974} , + {"rarrtl", 0x021A3} , + {"rarrw", 0x0219D} , + {"ratail", 0x0291A} , + {"ratio", 0x02236} , + {"rationals", 0x0211A} , + {"rbarr", 0x0290D} , + {"rbbrk", 0x03015} , + {"rbrace", 0x0007D} , + {"rbrack", 0x0005D} , + {"rbrke", 0x0298C} , + {"rbrksld", 0x0298E} , + {"rbrkslu", 0x02990} , + {"rcaron", 0x00159} , + {"rcedil", 0x00157} , + {"rceil", 0x02309} , + {"rcub", 0x0007D} , + {"rcy", 0x00440} , + {"rdca", 0x02937} , + {"rdldhar", 0x02969} , + {"rdquo", 0x0201D} , + {"rdquor", 0x0201D} , + {"rdsh", 0x021B3} , + {"real", 0x0211C} , + {"realine", 0x0211B} , + {"realpart", 0x0211C} , + {"reals", 0x0211D} , + {"rect", 0x025AD} , + {"reg", 0x000AE} , + {"rfisht", 0x0297D} , + {"rfloor", 0x0230B} , + {"rfr", 0x1D52F} , + {"rhard", 0x021C1} , + {"rharu", 0x021C0} , + {"rharul", 0x0296C} , + {"rho", 0x003C1} , + {"rhov", 0x003F1} , + {"rightarrow", 0x02192} , + {"rightarrowtail", 0x021A3} , + {"rightharpoondown", 0x021C1} , + {"rightharpoonup", 0x021C0} , + {"rightleftarrows", 0x021C4} , + {"rightleftharpoons", 0x021CC} , + {"rightrightarrows", 0x021C9} , + {"rightsquigarrow", 0x0219D} , + {"rightthreetimes", 0x022CC} , + {"ring", 0x002DA} , + {"risingdotseq", 0x02253} , + {"rlarr", 0x021C4} , + {"rlhar", 0x021CC} , + {"rmoust", 0x023B1} , + {"rmoustache", 0x023B1} , + {"rnmid", 0x02AEE} , + {"roang", 0x03019} , + {"roarr", 0x021FE} , + {"robrk", 0x0301B} , + {"ropar", 0x02986} , + {"ropf", 0x1D563} , + {"roplus", 0x02A2E} , + {"rotimes", 0x02A35} , + {"rpar", 0x00029} , + {"rpargt", 0x02994} , + {"rppolint", 0x02A12} , + {"rrarr", 0x021C9} , + {"rscr", 0x1D4C7} , + {"rsh", 0x021B1} , + {"rsqb", 0x0005D} , + {"rsquo", 0x02019} , + {"rsquor", 0x02019} , + {"rthree", 0x022CC} , + {"rtimes", 0x022CA} , + {"rtri", 0x025B9} , + {"rtrie", 0x022B5} , + {"rtrif", 0x025B8} , + {"rtriltri", 0x029CE} , + {"ruluhar", 0x02968} , + {"rx", 0x0211E} , + {"sacute", 0x0015B} , + {"sc", 0x0227B} , + {"scE", 0x02AB4} , + {"scap", 0x02AB8} , + {"scaron", 0x00161} , + {"sccue", 0x0227D} , + {"sce", 0x02AB0} , + {"scedil", 0x0015F} , + {"scirc", 0x0015D} , + {"scnE", 0x02AB6} , + {"scnap", 0x02ABA} , + {"scnsim", 0x022E9} , + {"scpolint", 0x02A13} , + {"scsim", 0x0227F} , + {"scy", 0x00441} , + {"sdot", 0x022C5} , + {"sdotb", 0x022A1} , + {"sdote", 0x02A66} , + {"seArr", 0x021D8} , + {"searhk", 0x02925} , + {"searr", 0x02198} , + {"searrow", 0x02198} , + {"sect", 0x000A7} , + {"semi", 0x0003B} , + {"seswar", 0x02929} , + {"setminus", 0x02216} , + {"setmn", 0x02216} , + {"sext", 0x02736} , + {"sfr", 0x1D530} , + {"sfrown", 0x02322} , + {"sharp", 0x0266F} , + {"shchcy", 0x00449} , + {"shcy", 0x00448} , + {"shortmid", 0x02223} , + {"shortparallel", 0x02225} , + {"shy", 0x000AD} , + {"sigma", 0x003C3} , + {"sigmav", 0x003C2} , + {"sim", 0x0223C} , + {"simdot", 0x02A6A} , + {"sime", 0x02243} , + {"simeq", 0x02243} , + {"simg", 0x02A9E} , + {"simgE", 0x02AA0} , + {"siml", 0x02A9D} , + {"simlE", 0x02A9F} , + {"simne", 0x02246} , + {"simplus", 0x02A24} , + {"simrarr", 0x02972} , + {"slarr", 0x02190} , + {"smallsetminus", 0x02216} , + {"smashp", 0x02A33} , + {"smeparsl", 0x029E4} , + {"smid", 0x02223} , + {"smile", 0x02323} , + {"smt", 0x02AAA} , + {"smte", 0x02AAC} , + {"softcy", 0x0044C} , + {"sol", 0x0002F} , + {"solb", 0x029C4} , + {"solbar", 0x0233F} , + {"sopf", 0x1D564} , + {"spades", 0x02660} , + {"spadesuit", 0x02660} , + {"spar", 0x02225} , + {"sqcap", 0x02293} , + {"sqcup", 0x02294} , + {"sqsub", 0x0228F} , + {"sqsube", 0x02291} , + {"sqsubset", 0x0228F} , + {"sqsubseteq", 0x02291} , + {"sqsup", 0x02290} , + {"sqsupe", 0x02292} , + {"sqsupset", 0x02290} , + {"sqsupseteq", 0x02292} , + {"squ", 0x025A1} , + {"square", 0x025A1} , + {"squarf", 0x025AA} , + {"squf", 0x025AA} , + {"srarr", 0x02192} , + {"sscr", 0x1D4C8} , + {"ssetmn", 0x02216} , + {"ssmile", 0x02323} , + {"sstarf", 0x022C6} , + {"star", 0x02606} , + {"starf", 0x02605} , + {"straightepsilon", 0x003F5} , + {"straightphi", 0x003D5} , + {"strns", 0x000AF} , + {"sub", 0x02282} , + {"subE", 0x02AC5} , + {"subdot", 0x02ABD} , + {"sube", 0x02286} , + {"subedot", 0x02AC3} , + {"submult", 0x02AC1} , + {"subnE", 0x02ACB} , + {"subne", 0x0228A} , + {"subplus", 0x02ABF} , + {"subrarr", 0x02979} , + {"subset", 0x02282} , + {"subseteq", 0x02286} , + {"subseteqq", 0x02AC5} , + {"subsetneq", 0x0228A} , + {"subsetneqq", 0x02ACB} , + {"subsim", 0x02AC7} , + {"subsub", 0x02AD5} , + {"subsup", 0x02AD3} , + {"succ", 0x0227B} , + {"succapprox", 0x02AB8} , + {"succcurlyeq", 0x0227D} , + {"succeq", 0x02AB0} , + {"succnapprox", 0x02ABA} , + {"succneqq", 0x02AB6} , + {"succnsim", 0x022E9} , + {"succsim", 0x0227F} , + {"sum", 0x02211} , + {"sung", 0x0266A} , + {"sup", 0x02283} , + {"sup1", 0x000B9} , + {"sup2", 0x000B2} , + {"sup3", 0x000B3} , + {"supE", 0x02AC6} , + {"supdot", 0x02ABE} , + {"supdsub", 0x02AD8} , + {"supe", 0x02287} , + {"supedot", 0x02AC4} , + {"suphsub", 0x02AD7} , + {"suplarr", 0x0297B} , + {"supmult", 0x02AC2} , + {"supnE", 0x02ACC} , + {"supne", 0x0228B} , + {"supplus", 0x02AC0} , + {"supset", 0x02283} , + {"supseteq", 0x02287} , + {"supseteqq", 0x02AC6} , + {"supsetneq", 0x0228B} , + {"supsetneqq", 0x02ACC} , + {"supsim", 0x02AC8} , + {"supsub", 0x02AD4} , + {"supsup", 0x02AD6} , + {"swArr", 0x021D9} , + {"swarhk", 0x02926} , + {"swarr", 0x02199} , + {"swarrow", 0x02199} , + {"swnwar", 0x0292A} , + {"szlig", 0x000DF} , + {"target", 0x02316} , + {"tau", 0x003C4} , + {"tbrk", 0x023B4} , + {"tcaron", 0x00165} , + {"tcedil", 0x00163} , + {"tcy", 0x00442} , + {"tdot", 0x020DB} , + {"telrec", 0x02315} , + {"tfr", 0x1D531} , + {"there4", 0x02234} , + {"therefore", 0x02234} , + {"theta", 0x003B8} , + {"thetav", 0x003D1} , + {"thickapprox", 0x02248} , + {"thicksim", 0x0223C} , + {"thinsp", 0x02009} , + {"thkap", 0x02248} , + {"thksim", 0x0223C} , + {"thorn", 0x000FE} , + {"tilde", 0x002DC} , + {"times", 0x000D7} , + {"timesb", 0x022A0} , + {"timesbar", 0x02A31} , + {"timesd", 0x02A30} , + {"tint", 0x0222D} , + {"toea", 0x02928} , + {"top", 0x022A4} , + {"topbot", 0x02336} , + {"topcir", 0x02AF1} , + {"topf", 0x1D565} , + {"topfork", 0x02ADA} , + {"tosa", 0x02929} , + {"tprime", 0x02034} , + {"trade", 0x02122} , + {"triangle", 0x025B5} , + {"triangledown", 0x025BF} , + {"triangleleft", 0x025C3} , + {"trianglelefteq", 0x022B4} , + {"triangleq", 0x0225C} , + {"triangleright", 0x025B9} , + {"trianglerighteq", 0x022B5} , + {"tridot", 0x025EC} , + {"trie", 0x0225C} , + {"triminus", 0x02A3A} , + {"triplus", 0x02A39} , + {"trisb", 0x029CD} , + {"tritime", 0x02A3B} , + {"trpezium", 0x0FFFD} , + {"tscr", 0x1D4C9} , + {"tscy", 0x00446} , + {"tshcy", 0x0045B} , + {"tstrok", 0x00167} , + {"twixt", 0x0226C} , + {"twoheadleftarrow", 0x0219E} , + {"twoheadrightarrow", 0x021A0} , + {"uArr", 0x021D1} , + {"uHar", 0x02963} , + {"uacute", 0x000FA} , + {"uarr", 0x02191} , + {"ubrcy", 0x0045E} , + {"ubreve", 0x0016D} , + {"ucirc", 0x000FB} , + {"ucy", 0x00443} , + {"udarr", 0x021C5} , + {"udblac", 0x00171} , + {"udhar", 0x0296E} , + {"ufisht", 0x0297E} , + {"ufr", 0x1D532} , + {"ugrave", 0x000F9} , + {"uharl", 0x021BF} , + {"uharr", 0x021BE} , + {"uhblk", 0x02580} , + {"ulcorn", 0x0231C} , + {"ulcorner", 0x0231C} , + {"ulcrop", 0x0230F} , + {"ultri", 0x025F8} , + {"umacr", 0x0016B} , + {"uml", 0x000A8} , + {"uogon", 0x00173} , + {"uopf", 0x1D566} , + {"uparrow", 0x02191} , + {"updownarrow", 0x02195} , + {"upharpoonleft", 0x021BF} , + {"upharpoonright", 0x021BE} , + {"uplus", 0x0228E} , + {"upsi", 0x003C5} , + {"upsilon", 0x003C5} , + {"upuparrows", 0x021C8} , + {"urcorn", 0x0231D} , + {"urcorner", 0x0231D} , + {"urcrop", 0x0230E} , + {"uring", 0x0016F} , + {"urtri", 0x025F9} , + {"uscr", 0x1D4CA} , + {"utdot", 0x022F0} , + {"utilde", 0x00169} , + {"utri", 0x025B5} , + {"utrif", 0x025B4} , + {"uuarr", 0x021C8} , + {"uuml", 0x000FC} , + {"uwangle", 0x029A7} , + {"vArr", 0x021D5} , + {"vBar", 0x02AE8} , + {"vBarv", 0x02AE9} , + {"vDash", 0x022A8} , + {"vangrt", 0x0299C} , + {"varepsilon", 0x003B5} , + {"varkappa", 0x003F0} , + {"varnothing", 0x02205} , + {"varphi", 0x003C6} , + {"varpi", 0x003D6} , + {"varpropto", 0x0221D} , + {"varr", 0x02195} , + {"varrho", 0x003F1} , + {"varsigma", 0x003C2} , + {"vartheta", 0x003D1} , + {"vartriangleleft", 0x022B2} , + {"vartriangleright", 0x022B3} , + {"vcy", 0x00432} , + {"vdash", 0x022A2} , + {"vee", 0x02228} , + {"veebar", 0x022BB} , + {"veeeq", 0x0225A} , + {"vellip", 0x022EE} , + {"verbar", 0x0007C} , + {"vert", 0x0007C} , + {"vfr", 0x1D533} , + {"vltri", 0x022B2} , + {"vopf", 0x1D567} , + {"vprop", 0x0221D} , + {"vrtri", 0x022B3} , + {"vscr", 0x1D4CB} , + {"vzigzag", 0x0299A} , + {"wcirc", 0x00175} , + {"wedbar", 0x02A5F} , + {"wedge", 0x02227} , + {"wedgeq", 0x02259} , + {"weierp", 0x02118} , + {"wfr", 0x1D534} , + {"wopf", 0x1D568} , + {"wp", 0x02118} , + {"wr", 0x02240} , + {"wreath", 0x02240} , + {"wscr", 0x1D4CC} , + {"xcap", 0x022C2} , + {"xcirc", 0x025EF} , + {"xcup", 0x022C3} , + {"xdtri", 0x025BD} , + {"xfr", 0x1D535} , + {"xhArr", 0x027FA} , + {"xharr", 0x027F7} , + {"xi", 0x003BE} , + {"xlArr", 0x027F8} , + {"xlarr", 0x027F5} , + {"xmap", 0x027FC} , + {"xnis", 0x022FB} , + {"xodot", 0x02A00} , + {"xopf", 0x1D569} , + {"xoplus", 0x02A01} , + {"xotime", 0x02A02} , + {"xrArr", 0x027F9} , + {"xrarr", 0x027F6} , + {"xscr", 0x1D4CD} , + {"xsqcup", 0x02A06} , + {"xuplus", 0x02A04} , + {"xutri", 0x025B3} , + {"xvee", 0x022C1} , + {"xwedge", 0x022C0} , + {"yacute", 0x000FD} , + {"yacy", 0x0044F} , + {"ycirc", 0x00177} , + {"ycy", 0x0044B} , + {"yen", 0x000A5} , + {"yfr", 0x1D536} , + {"yicy", 0x00457} , + {"yopf", 0x1D56A} , + {"yscr", 0x1D4CE} , + {"yucy", 0x0044E} , + {"yuml", 0x000FF} , + {"zacute", 0x0017A} , + {"zcaron", 0x0017E} , + {"zcy", 0x00437} , + {"zdot", 0x0017C} , + {"zeetrf", 0x02128} , + {"zeta", 0x003B6} , + {"zfr", 0x1D537} , + {"zhcy", 0x00436} , + {"zigrarr", 0x021DD} , + {"zopf", 0x1D56B} , + {"zscr", 0x1D4CF} +}; + +// Needed since sizeof is a macro and we cannot be used until size is known +int entityMap::size() +{ + return sizeof( entities ) / sizeof( entityMap ); +} + +KFORMULA_NAMESPACE_END + diff --git a/lib/kformula/errorelement.cc b/lib/kformula/errorelement.cc deleted file mode 100644 index cb1f6c54..00000000 --- a/lib/kformula/errorelement.cc +++ /dev/null @@ -1,51 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2006 Alfredo Beaumont Sainz - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - -#include - -#include "errorelement.h" - -KFORMULA_NAMESPACE_BEGIN - -ErrorElement::ErrorElement( BasicElement* parent ) : SequenceElement( parent ) { -} - -/** - * Draws the whole element including its children. - * The `parentOrigin' is the point this element's parent starts. - * We can use our parentPosition to get our own origin then. - */ -void ErrorElement::draw( TQPainter& painter, const LuPixelRect& r, - const ContextStyle& context, - ContextStyle::TextStyle tstyle, - ContextStyle::IndexStyle istyle, - StyleAttributes& style, - const LuPixelPoint& parentOrigin ) -{ - LuPixelPoint myPos( parentOrigin.x()+getX(), parentOrigin.y()+getY() ); - - painter.fillRect( context.layoutUnitToPixelX( myPos.x() ), - context.layoutUnitToPixelY( myPos.y() ), - context.layoutUnitToPixelX( getWidth() ), - context.layoutUnitToPixelY( getHeight() ), - context.getErrorColor() ); - inherited::draw( painter, r, context, tstyle, istyle, style, parentOrigin ); -} - -KFORMULA_NAMESPACE_END diff --git a/lib/kformula/errorelement.cpp b/lib/kformula/errorelement.cpp new file mode 100644 index 00000000..cb1f6c54 --- /dev/null +++ b/lib/kformula/errorelement.cpp @@ -0,0 +1,51 @@ +/* This file is part of the KDE project + Copyright (C) 2006 Alfredo Beaumont Sainz + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include + +#include "errorelement.h" + +KFORMULA_NAMESPACE_BEGIN + +ErrorElement::ErrorElement( BasicElement* parent ) : SequenceElement( parent ) { +} + +/** + * Draws the whole element including its children. + * The `parentOrigin' is the point this element's parent starts. + * We can use our parentPosition to get our own origin then. + */ +void ErrorElement::draw( TQPainter& painter, const LuPixelRect& r, + const ContextStyle& context, + ContextStyle::TextStyle tstyle, + ContextStyle::IndexStyle istyle, + StyleAttributes& style, + const LuPixelPoint& parentOrigin ) +{ + LuPixelPoint myPos( parentOrigin.x()+getX(), parentOrigin.y()+getY() ); + + painter.fillRect( context.layoutUnitToPixelX( myPos.x() ), + context.layoutUnitToPixelY( myPos.y() ), + context.layoutUnitToPixelX( getWidth() ), + context.layoutUnitToPixelY( getHeight() ), + context.getErrorColor() ); + inherited::draw( painter, r, context, tstyle, istyle, style, parentOrigin ); +} + +KFORMULA_NAMESPACE_END diff --git a/lib/kformula/fontstyle.cc b/lib/kformula/fontstyle.cc deleted file mode 100644 index 32479b0f..00000000 --- a/lib/kformula/fontstyle.cc +++ /dev/null @@ -1,891 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2003 Ulrich Kuettler - Copyright (C) 2006 Alfredo Beaumont Sainz - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "fontstyle.h" - - -KFORMULA_NAMESPACE_BEGIN - -#include "unicodetable.cc" - -bool FontStyle::m_installed = false; - -bool FontStyle::init( ContextStyle* style, bool install ) -{ - if (!m_installed && install) - installFonts(); - m_symbolTable.init( style->getMathFont() ); - - return true; -} - -// Cache the family list from TQFontDatabase after fixing it up (no foundry, lowercase) -class FontList { -public: - FontList() { - TQFontDatabase db; - const TQStringList lst = db.families(); - for ( TQStringList::const_iterator it = lst.begin(), end = lst.end() ; it != end ; ++it ) { - const TQString name = *it; - int i = name.find('['); - TQString family = name; - // Remove foundry - if ( i > -1 ) { - const int li = name.findRev(']'); - if (i < li) { - if (name[i - 1] == ' ') - i--; - family = name.left(i); - } - } - m_fontNames.append( family.lower() ); - } - } - bool hasFont( const TQString& fontName ) const { - return m_fontNames.find( fontName ) != m_fontNames.end(); - } - TQStringList m_fontNames; -}; -static FontList* s_fontList = 0; -static KStaticDeleter s_fontList_sd; - -void FontStyle::testFont( TQStringList& missing, const TQString& fontName ) { - if ( !s_fontList ) - s_fontList_sd.setObject( s_fontList, new FontList() ); - if ( !s_fontList->hasFont( fontName ) ) { - kdWarning(39001) << "Font '" << fontName << "' not found" << endl; - missing.append( fontName ); - } -} - - -TQStringList FontStyle::missingFonts( bool install ) -{ - if (!m_installed && install) - installFonts(); - - TQStringList missing = missingFontsInternal(); - return missing; -} - -TQStringList FontStyle::missingFontsInternal() -{ - TQStringList missing; - - testFont( missing, "cmex10" ); - testFont( missing, "arev sans"); - - return missing; -} - -void FontStyle::installFonts() -{ - if (m_installed) - return; - TQStringList missing = missingFontsInternal(); - if (!missing.isEmpty()) - { - TQStringList urlList; - for (TQStringList::iterator it = missing.begin(); it != missing.end(); ++it) - { - if ( *it == "arev sans" ) { - if (!TDEIO::NetAccess::exists("fonts:/Personal/Arev.ttf", true, NULL)) - urlList.append(locate("data", "kformula/fonts/Arev.ttf")); - if (!TDEIO::NetAccess::exists("fonts:/Personal/ArevIt.ttf", true, NULL)) - urlList.append(locate("data", "kformula/fonts/ArevIt.ttf")); - if (!TDEIO::NetAccess::exists("fonts:/Personal/ArevBd.ttf", true, NULL)) - urlList.append(locate("data", "kformula/fonts/ArevBd.ttf")); - if (!TDEIO::NetAccess::exists("fonts:/Personal/ArevBI.ttf", true, NULL)) - urlList.append(locate("data", "kformula/fonts/ArevBI.ttf")); - } - else { - if (!TDEIO::NetAccess::exists("fonts:/Personal/" + *it + ".ttf", true, NULL)) - urlList.append(locate("data", "kformula/fonts/" + *it + ".ttf")); - } - } - TDEIO::copy(urlList, "fonts:/Personal/", false); - KMessageBox::information(tqApp->mainWidget(), - i18n("Some fonts have been installed to assure that symbols in formulas are properly visualized. You must restart the application in order so that changes take effect")); - } - m_installed = true; -} - -Artwork* FontStyle::createArtwork( SymbolType type ) const -{ - return new Artwork( type ); -} - -// We claim that all chars come from the same font. -// It's up to the font tables to ensure this. -const TQChar leftRoundBracket[] = { - 0x30, // uppercorner - 0x40, // lowercorner - 0x42 // line -}; -const TQChar leftSquareBracket[] = { - 0x32, // uppercorner - 0x34, // lowercorner - 0x36 // line -}; -const TQChar leftCurlyBracket[] = { - 0x38, // uppercorner - 0x3A, // lowercorner - 0x3E, // line - 0x3C // middle -}; - -const TQChar leftLineBracket[] = { - 0x36, // line - 0x36, // line - 0x36 // line -}; -const TQChar rightLineBracket[] = { - 0x37, // line - 0x37, // line - 0x37 // line -}; - -const TQChar rightRoundBracket[] = { - 0x31, // uppercorner - 0x41, // lowercorner - 0x43 // line -}; -const TQChar rightSquareBracket[] = { - 0x33, // uppercorner - 0x35, // lowercorner - 0x37 // line -}; -const TQChar rightCurlyBracket[] = { - 0x39, // uppercorner - 0x3B, // lowercorner - 0x3E, // line - 0x3D // middle -}; - - -static const char cmex_LeftSquareBracket = 163; -static const char cmex_RightSquareBracket = 164; -static const char cmex_LeftCurlyBracket = 169; -static const char cmex_RightCurlyBracket = 170; -static const char cmex_LeftCornerBracket = 173; -static const char cmex_RightCornerBracket = 174; -static const char cmex_LeftRoundBracket = 161; -static const char cmex_RightRoundBracket = 162; -static const char cmex_SlashBracket = 177; -static const char cmex_BackSlashBracket = 178; -//static const char cmex_LeftLineBracket = 0x4b; -//static const char cmex_RightLineBracket = 0x4b; - -// use the big symbols here -static const char cmex_Int = 90; -static const char cmex_Sum = 88; -static const char cmex_Prod = 89; - - -// cmex is a special font with symbols in four sizes. -static short cmex_nextchar( short ch ) -{ - switch ( ch ) { - case 161: return 179; - case 162: return 180; - case 163: return 104; - case 164: return 105; - case 169: return 110; - case 170: return 111; - case 165: return 106; - case 166: return 107; - case 167: return 108; - case 168: return 109; - case 173: return 68; - case 174: return 69; - case 177: return 46; - case 178: return 47; - - case 179: return 181; - case 180: return 182; - case 104: return 183; - case 105: return 184; - case 110: return 189; - case 111: return 190; - case 106: return 185; - case 107: return 186; - case 108: return 187; - case 109: return 188; - case 68: return 191; - case 69: return 192; - case 46: return 193; - case 47: return 194; - - case 181: return 195; - case 182: return 33; - case 183: return 34; - case 184: return 35; - case 189: return 40; - case 190: return 41; - case 185: return 36; - case 186: return 37; - case 187: return 38; - case 188: return 39; - case 191: return 42; - case 192: return 43; - case 193: return 44; - case 194: return 45; - } - return 0; -} - -bool Artwork::calcCMDelimiterSize( const ContextStyle& context, - uchar c, - luPt fontSize, - luPt parentSize ) -{ - TQFont f( "cmex10" ); - f.setPointSizeFloat( context.layoutUnitPtToPt( fontSize ) ); - TQFontMetrics fm( f ); - - for ( char i=1; c != 0; ++i ) { - LuPixelRect bound = fm.boundingRect( c ); - - luPt height = context.ptToLayoutUnitPt( bound.height() ); - if ( height >= parentSize ) { - luPt width = context.ptToLayoutUnitPt( fm.width( c ) ); - luPt baseline = context.ptToLayoutUnitPt( -bound.top() ); - - cmChar = c; - - setHeight( height ); - setWidth( width ); - setBaseline( baseline ); - - return true; - } - c = cmex_nextchar( c ); - } - - // Build it up from pieces. - return false; -} - - -void Artwork::calcLargest( const ContextStyle& context, - uchar c, luPt fontSize ) -{ - TQFont f( "cmex10" ); - f.setPointSizeFloat( context.layoutUnitPtToPt( fontSize ) ); - TQFontMetrics fm( f ); - - cmChar = c; - for ( ;; ) { - c = cmex_nextchar( c ); - if ( c == 0 ) { - break; - } - cmChar = c; - } - - LuPixelRect bound = fm.boundingRect( cmChar ); - - luPt height = context.ptToLayoutUnitPt( bound.height() ); - luPt width = context.ptToLayoutUnitPt( fm.width( cmChar ) ); - luPt baseline = context.ptToLayoutUnitPt( -bound.top() ); - - setHeight( height ); - setWidth( width ); - setBaseline( baseline ); -} - - -void Artwork::drawCMDelimiter( TQPainter& painter, const ContextStyle& style, - luPixel x, luPixel y, - luPt height ) -{ - TQFont f( "cmex10" ); - f.setPointSizeFloat( style.layoutUnitToFontSize( height, false ) ); - - painter.setFont( f ); - painter.drawText( style.layoutUnitToPixelX( x ), - style.layoutUnitToPixelY( y + getBaseline() ), - TQString( TQChar( cmChar ) ) ); - - // Debug -#if 0 - TQFontMetrics fm( f ); - LuPixelRect bound = fm.boundingRect( cmChar ); - painter.setBrush(TQt::NoBrush); - painter.setPen(TQt::green); - painter.drawRect( style.layoutUnitToPixelX( x ), - style.layoutUnitToPixelY( y ), - fm.width( cmChar ), - bound.height() ); -#endif -} - - -Artwork::Artwork(SymbolType t) - : baseline( -1 ), type(t) -{ -} - - -void Artwork::calcSizes( const ContextStyle& style, - ContextStyle::TextStyle tstyle, - double factor, - luPt parentSize ) -{ - setBaseline( -1 ); - cmChar = -1; - luPt mySize = style.getAdjustedSize( tstyle, factor ); - switch (getType()) { - case LeftSquareBracket: - if ( calcCMDelimiterSize( style, cmex_LeftSquareBracket, - mySize, parentSize ) ) { - return; - } - calcRoundBracket( style, leftSquareBracket, parentSize, mySize ); - break; - case RightSquareBracket: - if ( calcCMDelimiterSize( style, cmex_RightSquareBracket, - mySize, parentSize ) ) { - return; - } - calcRoundBracket( style, rightSquareBracket, parentSize, mySize ); - break; - case LeftLineBracket: - calcRoundBracket( style, leftLineBracket, parentSize, mySize ); - setWidth( getWidth()/2 ); - break; - case RightLineBracket: - calcRoundBracket( style, rightLineBracket, parentSize, mySize ); - setWidth( getWidth()/2 ); - break; - case SlashBracket: - if ( calcCMDelimiterSize( style, cmex_SlashBracket, - mySize, parentSize ) ) { - return; - } - calcLargest( style, cmex_SlashBracket, mySize ); - break; - case BackSlashBracket: - if ( calcCMDelimiterSize( style, cmex_BackSlashBracket, - mySize, parentSize ) ) { - return; - } - calcLargest( style, cmex_BackSlashBracket, mySize ); - break; - case LeftCornerBracket: - if ( calcCMDelimiterSize( style, cmex_LeftCornerBracket, - mySize, parentSize ) ) { - return; - } - calcLargest( style, cmex_LeftCornerBracket, mySize ); - break; - case RightCornerBracket: - if ( calcCMDelimiterSize( style, cmex_RightCornerBracket, - mySize, parentSize ) ) { - return; - } - calcLargest( style, cmex_RightCornerBracket, mySize ); - break; - case LeftRoundBracket: - if ( calcCMDelimiterSize( style, cmex_LeftRoundBracket, - mySize, parentSize ) ) { - return; - } - calcRoundBracket( style, leftRoundBracket, parentSize, mySize ); - break; - case RightRoundBracket: - if ( calcCMDelimiterSize( style, cmex_RightRoundBracket, - mySize, parentSize ) ) { - return; - } - calcRoundBracket( style, rightRoundBracket, parentSize, mySize ); - break; - case EmptyBracket: - setHeight(parentSize); - //setWidth(style.getEmptyRectWidth()); - setWidth(0); - break; - case LeftCurlyBracket: - if ( calcCMDelimiterSize( style, cmex_LeftCurlyBracket, - mySize, parentSize ) ) { - return; - } - calcCurlyBracket( style, leftCurlyBracket, parentSize, mySize ); - break; - case RightCurlyBracket: - if ( calcCMDelimiterSize( style, cmex_RightCurlyBracket, - mySize, parentSize ) ) { - return; - } - calcCurlyBracket( style, rightCurlyBracket, parentSize, mySize ); - break; - case Integral: - calcCharSize( style, style.getBracketFont(), mySize, cmex_Int ); - break; - case Sum: - calcCharSize( style, style.getBracketFont(), mySize, cmex_Sum ); - break; - case Product: - calcCharSize( style, style.getBracketFont(), mySize, cmex_Prod ); - break; - } -} - -void Artwork::calcSizes( const ContextStyle& style, - ContextStyle::TextStyle tstyle, - double factor ) -{ - luPt mySize = style.getAdjustedSize( tstyle, factor ); - switch (type) { - case LeftSquareBracket: - calcCharSize(style, mySize, leftSquareBracketChar); - break; - case RightSquareBracket: - calcCharSize(style, mySize, rightSquareBracketChar); - break; - case LeftLineBracket: - case RightLineBracket: - calcCharSize(style, mySize, verticalLineChar); - break; - case SlashBracket: - calcCharSize(style, mySize, slashChar); - break; - case BackSlashBracket: - calcCharSize(style, mySize, backSlashChar); - break; - case LeftCornerBracket: - calcCharSize(style, mySize, leftAngleBracketChar); - break; - case RightCornerBracket: - calcCharSize(style, mySize, rightAngleBracketChar); - break; - case LeftRoundBracket: - calcCharSize(style, mySize, leftParenthesisChar); - break; - case RightRoundBracket: - calcCharSize(style, mySize, rightParenthesisChar); - break; - case EmptyBracket: - //calcCharSize(style, mySize, spaceChar); - setHeight(0); - //setWidth(style.getEmptyRectWidth()); - setWidth(0); - break; - case LeftCurlyBracket: - calcCharSize(style, mySize, leftCurlyBracketChar); - break; - case RightCurlyBracket: - calcCharSize(style, mySize, rightCurlyBracketChar); - break; - case Integral: - case Sum: - case Product: - break; - } -} - - -void Artwork::draw(TQPainter& painter, const LuPixelRect& /*r*/, - const ContextStyle& context, ContextStyle::TextStyle tstyle, - StyleAttributes& style, const LuPixelPoint& parentOrigin) -{ - luPt mySize = context.getAdjustedSize( tstyle, style.sizeFactor() ); - luPixel myX = parentOrigin.x() + getX(); - luPixel myY = parentOrigin.y() + getY(); - /* - if ( !LuPixelRect( myX, myY, getWidth(), getHeight() ).intersects( r ) ) - return; - */ - - painter.setPen(context.getDefaultColor()); - - switch (type) { - case LeftSquareBracket: - drawCharacter(painter, context, myX, myY, mySize, leftSquareBracketChar); - break; - case RightSquareBracket: - drawCharacter(painter, context, myX, myY, mySize, rightSquareBracketChar); - break; - case LeftCurlyBracket: - drawCharacter(painter, context, myX, myY, mySize, leftCurlyBracketChar); - break; - case RightCurlyBracket: - drawCharacter(painter, context, myX, myY, mySize, rightCurlyBracketChar); - break; - case LeftLineBracket: - case RightLineBracket: - drawCharacter(painter, context, myX, myY, mySize, verticalLineChar); - break; - case SlashBracket: - drawCharacter(painter, context, myX, myY, mySize, slashChar); - break; - case BackSlashBracket: - drawCharacter(painter, context, myX, myY, mySize, backSlashChar); - break; - case LeftCornerBracket: - drawCharacter(painter, context, myX, myY, mySize, leftAngleBracketChar); - break; - case RightCornerBracket: - drawCharacter(painter, context, myX, myY, mySize, rightAngleBracketChar); - break; - case LeftRoundBracket: - drawCharacter(painter, context, myX, myY, mySize, leftParenthesisChar); - break; - case RightRoundBracket: - drawCharacter(painter, context, myX, myY, mySize, rightParenthesisChar); - break; - case EmptyBracket: - break; - case Integral: - case Sum: - case Product: - break; - } -} - -void Artwork::draw(TQPainter& painter, const LuPixelRect& , - const ContextStyle& context, ContextStyle::TextStyle tstyle, - StyleAttributes& style, luPt , const LuPixelPoint& origin) -{ - luPt mySize = context.getAdjustedSize( tstyle, style.sizeFactor() ); - luPixel myX = origin.x() + getX(); - luPixel myY = origin.y() + getY(); - /* - if ( !LuPixelRect( myX, myY, getWidth(), getHeight() ).intersects( r ) ) - return; - */ - - painter.setPen(context.getDefaultColor()); - - switch (getType()) { - case LeftSquareBracket: - if ( cmChar != -1 ) { - drawCMDelimiter( painter, context, myX, myY, mySize ); - } - else { - drawBigRoundBracket( painter, context, leftSquareBracket, myX, myY, mySize ); - } - break; - case RightSquareBracket: - if ( cmChar != -1 ) { - drawCMDelimiter( painter, context, myX, myY, mySize ); - } - else { - drawBigRoundBracket( painter, context, rightSquareBracket, myX, myY, mySize ); - } - break; - case LeftCurlyBracket: - if ( cmChar != -1 ) { - drawCMDelimiter( painter, context, myX, myY, mySize ); - } - else { - drawBigCurlyBracket( painter, context, leftCurlyBracket, myX, myY, mySize ); - } - break; - case RightCurlyBracket: - if ( cmChar != -1 ) { - drawCMDelimiter( painter, context, myX, myY, mySize ); - } - else { - drawBigCurlyBracket( painter, context, rightCurlyBracket, myX, myY, mySize ); - } - break; - case LeftLineBracket: { - luPixel halfWidth = getWidth()/2; - drawBigRoundBracket( painter, context, leftLineBracket, - myX-halfWidth, myY, mySize ); - } - break; - case RightLineBracket: { - luPixel halfWidth = getWidth()/2; - drawBigRoundBracket( painter, context, rightLineBracket, - myX-halfWidth, myY, mySize ); - } - break; - case SlashBracket: - if ( cmChar != -1 ) { - drawCMDelimiter( painter, context, myX, myY, mySize ); - } - break; - case BackSlashBracket: - if ( cmChar != -1 ) { - drawCMDelimiter( painter, context, myX, myY, mySize ); - } - break; - case LeftCornerBracket: - if ( cmChar != -1 ) { - drawCMDelimiter( painter, context, myX, myY, mySize ); - } - else drawCharacter(painter, context, myX, myY, mySize, leftAngleBracketChar); - break; - case RightCornerBracket: - if ( cmChar != -1 ) { - drawCMDelimiter( painter, context, myX, myY, mySize ); - } - else drawCharacter(painter, context, myX, myY, mySize, rightAngleBracketChar); - break; - case LeftRoundBracket: - if ( cmChar != -1 ) { - drawCMDelimiter( painter, context, myX, myY, mySize ); - } - else { - drawBigRoundBracket( painter, context, leftRoundBracket, myX, myY, mySize ); - } - break; - case RightRoundBracket: - if ( cmChar != -1 ) { - drawCMDelimiter( painter, context, myX, myY, mySize ); - } - else { - drawBigRoundBracket( painter, context, rightRoundBracket, myX, myY, mySize ); - } - break; - case EmptyBracket: - break; - case Integral: - drawCharacter(painter, context, TQFont( "cmex10" ), myX, myY, mySize, cmex_Int); - break; - case Sum: - drawCharacter(painter, context, TQFont( "cmex10" ), myX, myY, mySize, cmex_Sum); - break; - case Product: - drawCharacter(painter, context, TQFont( "cmex10" ), myX, myY, mySize, cmex_Prod); - break; - } - - // debug -// painter.setBrush(TQt::NoBrush); -// painter.setPen(TQt::green); -// painter.drawRect( context.layoutUnitToPixelX( myX ), -// context.layoutUnitToPixelY( myY ), -// context.layoutUnitToPixelX( getWidth() ), -// context.layoutUnitToPixelY( getHeight() ) ); -} - -void Artwork::calcCharSize( const ContextStyle& style, luPt height, TQChar ch ) -{ - calcCharSize( style, style.getMathFont(), height, ch ); -} - - -void Artwork::drawCharacter( TQPainter& painter, const ContextStyle& style, - luPixel x, luPixel y, - luPt height, TQChar ch ) -{ - drawCharacter( painter, style, style.getMathFont(), x, y, height, ch ); -} - - -void Artwork::calcCharSize( const ContextStyle& style, TQFont f, - luPt height, TQChar c ) -{ - f.setPointSizeFloat( style.layoutUnitPtToPt( height ) ); - //f.setPointSize( height ); - TQFontMetrics fm(f); - setWidth( style.ptToLayoutUnitPt( fm.width( c ) ) ); - LuPixelRect bound = fm.boundingRect( c ); - setHeight( style.ptToLayoutUnitPt( bound.height() ) ); - setBaseline( style.ptToLayoutUnitPt( -bound.top() ) ); -} - - -void Artwork::drawCharacter( TQPainter& painter, const ContextStyle& style, - TQFont f, - luPixel x, luPixel y, luPt height, uchar c ) -{ - f.setPointSizeFloat( style.layoutUnitToFontSize( height, false ) ); - - painter.setFont( f ); - painter.drawText( style.layoutUnitToPixelX( x ), - style.layoutUnitToPixelY( y+getBaseline() ), - TQString( TQChar( c ) ) ); -} - - -void Artwork::calcRoundBracket( const ContextStyle& style, const TQChar chars[], - luPt height, luPt charHeight ) -{ - uchar uppercorner = chars[0]; - uchar lowercorner = chars[1]; - //uchar line = style.symbolTable().character( chars[2] ); - - TQFont f = style.getBracketFont(); - f.setPointSizeFloat( style.layoutUnitPtToPt( charHeight ) ); - TQFontMetrics fm( f ); - LuPtRect upperBound = fm.boundingRect( uppercorner ); - LuPtRect lowerBound = fm.boundingRect( lowercorner ); - //LuPtRect lineBound = fm.boundingRect( line ); - - setWidth( style.ptToLayoutUnitPt( fm.width( TQChar( uppercorner ) ) ) ); - luPt edgeHeight = style.ptToLayoutUnitPt( upperBound.height()+lowerBound.height() ); - //luPt lineHeight = style.ptToLayoutUnitPt( lineBound.height() ); - - //setHeight( edgeHeight + ( ( height-edgeHeight-1 ) / lineHeight + 1 ) * lineHeight ); - setHeight( TQMAX( edgeHeight, height ) ); -} - -void Artwork::drawBigRoundBracket( TQPainter& p, const ContextStyle& style, const TQChar chars[], - luPixel x, luPixel y, luPt charHeight ) -{ - uchar uppercorner = chars[0]; - uchar lowercorner = chars[1]; - uchar line = chars[2]; - - TQFont f = style.getBracketFont(); - f.setPointSizeFloat( style.layoutUnitToFontSize( charHeight, false ) ); - p.setFont(f); - - TQFontMetrics fm(f); - TQRect upperBound = fm.boundingRect(uppercorner); - TQRect lowerBound = fm.boundingRect(lowercorner); - TQRect lineBound = fm.boundingRect(line); - - pixel ptX = style.layoutUnitToPixelX( x ); - pixel ptY = style.layoutUnitToPixelY( y ); - pixel height = style.layoutUnitToPixelY( getHeight() ); - -// p.setPen( TQt::red ); -// //p.drawRect( ptX, ptY, upperBound.width(), upperBound.height() + lowerBound.height() ); -// p.drawRect( ptX, ptY, style.layoutUnitToPixelX( getWidth() ), -// style.layoutUnitToPixelY( getHeight() ) ); - -// p.setPen( TQt::black ); - p.drawText( ptX, ptY-upperBound.top(), TQString( TQChar( uppercorner ) ) ); - p.drawText( ptX, ptY+height-lowerBound.top()-lowerBound.height(), - TQString( TQChar( lowercorner ) ) ); - - // for printing - //pt safety = lineBound.height() / 10.0; - pixel safety = 0; - - pixel gap = height - upperBound.height() - lowerBound.height(); - pixel lineHeight = lineBound.height() - safety; - int lineCount = tqRound( static_cast( gap ) / lineHeight ); - pixel start = upperBound.height()-lineBound.top() - safety; - - for (int i = 0; i < lineCount; i++) { - p.drawText( ptX, ptY+start+i*lineHeight, TQString(TQChar(line))); - } - pixel remaining = gap - lineCount*lineHeight; - pixel dist = ( lineHeight - remaining ) / 2; - p.drawText( ptX, ptY+height-upperBound.height()+dist-lineBound.height()-lineBound.top(), - TQString( TQChar( line ) ) ); -} - -void Artwork::calcCurlyBracket( const ContextStyle& style, const TQChar chars[], - luPt height, luPt charHeight ) -{ - uchar uppercorner = chars[0]; - uchar lowercorner = chars[1]; - //uchar line = style.symbolTable().character( chars[2] ); - uchar middle = chars[3]; - - TQFont f = style.getBracketFont(); - f.setPointSizeFloat( style.layoutUnitPtToPt( charHeight ) ); - TQFontMetrics fm( f ); - LuPtRect upperBound = fm.boundingRect( uppercorner ); - LuPtRect lowerBound = fm.boundingRect( lowercorner ); - //LuPtRect lineBound = fm.boundingRect( line ); - LuPtRect middleBound = fm.boundingRect( middle ); - - setWidth( style.ptToLayoutUnitPt( fm.width( TQChar( uppercorner ) ) ) ); - luPt edgeHeight = style.ptToLayoutUnitPt( upperBound.height()+ - lowerBound.height()+ - middleBound.height() ); - //luPt lineHeight = style.ptToLayoutUnitPt( lineBound.height() ); - - //setHeight( edgeHeight + ( ( height-edgeHeight-1 ) / lineHeight + 1 ) * lineHeight ); - setHeight( TQMAX( edgeHeight, height ) ); -} - -void Artwork::drawBigCurlyBracket( TQPainter& p, const ContextStyle& style, const TQChar chars[], - luPixel x, luPixel y, luPt charHeight ) -{ - //TQFont f = style.getSymbolFont(); - TQFont f = style.getBracketFont(); - f.setPointSizeFloat( style.layoutUnitToFontSize( charHeight, false ) ); - p.setFont(f); - - uchar uppercorner = chars[0]; - uchar lowercorner = chars[1]; - uchar line = chars[2]; - uchar middle = chars[3]; - - TQFontMetrics fm(p.fontMetrics()); - TQRect upperBound = fm.boundingRect(uppercorner); - TQRect lowerBound = fm.boundingRect(lowercorner); - TQRect middleBound = fm.boundingRect(middle); - TQRect lineBound = fm.boundingRect(line); - - pixel ptX = style.layoutUnitToPixelX( x ); - pixel ptY = style.layoutUnitToPixelY( y ); - pixel height = style.layoutUnitToPixelY( getHeight() ); - - //p.setPen(TQt::gray); - //p.drawRect(x, y, upperBound.width() + offset, height); - - p.drawText( ptX, ptY-upperBound.top(), TQString( TQChar( uppercorner ) ) ); - p.drawText( ptX, ptY+(height-middleBound.height())/2-middleBound.top(), - TQString( TQChar( middle ) ) ); - p.drawText( ptX, ptY+height-lowerBound.top()-lowerBound.height(), - TQString( TQChar( lowercorner ) ) ); - - // for printing - // If the world was perfect and the urw-symbol font correct - // this could be 0. - //lu safety = lineBound.height() / 10; - pixel safety = 0; - - pixel lineHeight = lineBound.height() - safety; - pixel gap = height/2 - upperBound.height() - middleBound.height() / 2; - - if (gap > 0) { - TQString ch = TQString(TQChar(line)); - int lineCount = tqRound( gap / lineHeight ) + 1; - - pixel start = (height - middleBound.height()) / 2 + safety; - for (int i = 0; i < lineCount; i++) { - p.drawText( ptX, ptY-lineBound.top()+TQMAX( start-(i+1)*lineHeight, - upperBound.width() ), - ch ); - } - - start = (height + middleBound.height()) / 2 - safety; - for (int i = 0; i < lineCount; i++) { - p.drawText( ptX, ptY-lineBound.top()+TQMIN( start+i*lineHeight, - height-upperBound.width()-lineBound.height() ), - ch ); - } - } -} - -KFORMULA_NAMESPACE_END diff --git a/lib/kformula/fontstyle.cpp b/lib/kformula/fontstyle.cpp new file mode 100644 index 00000000..33f9e9f7 --- /dev/null +++ b/lib/kformula/fontstyle.cpp @@ -0,0 +1,891 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Ulrich Kuettler + Copyright (C) 2006 Alfredo Beaumont Sainz + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "fontstyle.h" + + +KFORMULA_NAMESPACE_BEGIN + +#include "unicodetable.cpp" + +bool FontStyle::m_installed = false; + +bool FontStyle::init( ContextStyle* style, bool install ) +{ + if (!m_installed && install) + installFonts(); + m_symbolTable.init( style->getMathFont() ); + + return true; +} + +// Cache the family list from TQFontDatabase after fixing it up (no foundry, lowercase) +class FontList { +public: + FontList() { + TQFontDatabase db; + const TQStringList lst = db.families(); + for ( TQStringList::const_iterator it = lst.begin(), end = lst.end() ; it != end ; ++it ) { + const TQString name = *it; + int i = name.find('['); + TQString family = name; + // Remove foundry + if ( i > -1 ) { + const int li = name.findRev(']'); + if (i < li) { + if (name[i - 1] == ' ') + i--; + family = name.left(i); + } + } + m_fontNames.append( family.lower() ); + } + } + bool hasFont( const TQString& fontName ) const { + return m_fontNames.find( fontName ) != m_fontNames.end(); + } + TQStringList m_fontNames; +}; +static FontList* s_fontList = 0; +static KStaticDeleter s_fontList_sd; + +void FontStyle::testFont( TQStringList& missing, const TQString& fontName ) { + if ( !s_fontList ) + s_fontList_sd.setObject( s_fontList, new FontList() ); + if ( !s_fontList->hasFont( fontName ) ) { + kdWarning(39001) << "Font '" << fontName << "' not found" << endl; + missing.append( fontName ); + } +} + + +TQStringList FontStyle::missingFonts( bool install ) +{ + if (!m_installed && install) + installFonts(); + + TQStringList missing = missingFontsInternal(); + return missing; +} + +TQStringList FontStyle::missingFontsInternal() +{ + TQStringList missing; + + testFont( missing, "cmex10" ); + testFont( missing, "arev sans"); + + return missing; +} + +void FontStyle::installFonts() +{ + if (m_installed) + return; + TQStringList missing = missingFontsInternal(); + if (!missing.isEmpty()) + { + TQStringList urlList; + for (TQStringList::iterator it = missing.begin(); it != missing.end(); ++it) + { + if ( *it == "arev sans" ) { + if (!TDEIO::NetAccess::exists("fonts:/Personal/Arev.ttf", true, NULL)) + urlList.append(locate("data", "kformula/fonts/Arev.ttf")); + if (!TDEIO::NetAccess::exists("fonts:/Personal/ArevIt.ttf", true, NULL)) + urlList.append(locate("data", "kformula/fonts/ArevIt.ttf")); + if (!TDEIO::NetAccess::exists("fonts:/Personal/ArevBd.ttf", true, NULL)) + urlList.append(locate("data", "kformula/fonts/ArevBd.ttf")); + if (!TDEIO::NetAccess::exists("fonts:/Personal/ArevBI.ttf", true, NULL)) + urlList.append(locate("data", "kformula/fonts/ArevBI.ttf")); + } + else { + if (!TDEIO::NetAccess::exists("fonts:/Personal/" + *it + ".ttf", true, NULL)) + urlList.append(locate("data", "kformula/fonts/" + *it + ".ttf")); + } + } + TDEIO::copy(urlList, "fonts:/Personal/", false); + KMessageBox::information(tqApp->mainWidget(), + i18n("Some fonts have been installed to assure that symbols in formulas are properly visualized. You must restart the application in order so that changes take effect")); + } + m_installed = true; +} + +Artwork* FontStyle::createArtwork( SymbolType type ) const +{ + return new Artwork( type ); +} + +// We claim that all chars come from the same font. +// It's up to the font tables to ensure this. +const TQChar leftRoundBracket[] = { + 0x30, // uppercorner + 0x40, // lowercorner + 0x42 // line +}; +const TQChar leftSquareBracket[] = { + 0x32, // uppercorner + 0x34, // lowercorner + 0x36 // line +}; +const TQChar leftCurlyBracket[] = { + 0x38, // uppercorner + 0x3A, // lowercorner + 0x3E, // line + 0x3C // middle +}; + +const TQChar leftLineBracket[] = { + 0x36, // line + 0x36, // line + 0x36 // line +}; +const TQChar rightLineBracket[] = { + 0x37, // line + 0x37, // line + 0x37 // line +}; + +const TQChar rightRoundBracket[] = { + 0x31, // uppercorner + 0x41, // lowercorner + 0x43 // line +}; +const TQChar rightSquareBracket[] = { + 0x33, // uppercorner + 0x35, // lowercorner + 0x37 // line +}; +const TQChar rightCurlyBracket[] = { + 0x39, // uppercorner + 0x3B, // lowercorner + 0x3E, // line + 0x3D // middle +}; + + +static const char cmex_LeftSquareBracket = 163; +static const char cmex_RightSquareBracket = 164; +static const char cmex_LeftCurlyBracket = 169; +static const char cmex_RightCurlyBracket = 170; +static const char cmex_LeftCornerBracket = 173; +static const char cmex_RightCornerBracket = 174; +static const char cmex_LeftRoundBracket = 161; +static const char cmex_RightRoundBracket = 162; +static const char cmex_SlashBracket = 177; +static const char cmex_BackSlashBracket = 178; +//static const char cmex_LeftLineBracket = 0x4b; +//static const char cmex_RightLineBracket = 0x4b; + +// use the big symbols here +static const char cmex_Int = 90; +static const char cmex_Sum = 88; +static const char cmex_Prod = 89; + + +// cmex is a special font with symbols in four sizes. +static short cmex_nextchar( short ch ) +{ + switch ( ch ) { + case 161: return 179; + case 162: return 180; + case 163: return 104; + case 164: return 105; + case 169: return 110; + case 170: return 111; + case 165: return 106; + case 166: return 107; + case 167: return 108; + case 168: return 109; + case 173: return 68; + case 174: return 69; + case 177: return 46; + case 178: return 47; + + case 179: return 181; + case 180: return 182; + case 104: return 183; + case 105: return 184; + case 110: return 189; + case 111: return 190; + case 106: return 185; + case 107: return 186; + case 108: return 187; + case 109: return 188; + case 68: return 191; + case 69: return 192; + case 46: return 193; + case 47: return 194; + + case 181: return 195; + case 182: return 33; + case 183: return 34; + case 184: return 35; + case 189: return 40; + case 190: return 41; + case 185: return 36; + case 186: return 37; + case 187: return 38; + case 188: return 39; + case 191: return 42; + case 192: return 43; + case 193: return 44; + case 194: return 45; + } + return 0; +} + +bool Artwork::calcCMDelimiterSize( const ContextStyle& context, + uchar c, + luPt fontSize, + luPt parentSize ) +{ + TQFont f( "cmex10" ); + f.setPointSizeFloat( context.layoutUnitPtToPt( fontSize ) ); + TQFontMetrics fm( f ); + + for ( char i=1; c != 0; ++i ) { + LuPixelRect bound = fm.boundingRect( c ); + + luPt height = context.ptToLayoutUnitPt( bound.height() ); + if ( height >= parentSize ) { + luPt width = context.ptToLayoutUnitPt( fm.width( c ) ); + luPt baseline = context.ptToLayoutUnitPt( -bound.top() ); + + cmChar = c; + + setHeight( height ); + setWidth( width ); + setBaseline( baseline ); + + return true; + } + c = cmex_nextchar( c ); + } + + // Build it up from pieces. + return false; +} + + +void Artwork::calcLargest( const ContextStyle& context, + uchar c, luPt fontSize ) +{ + TQFont f( "cmex10" ); + f.setPointSizeFloat( context.layoutUnitPtToPt( fontSize ) ); + TQFontMetrics fm( f ); + + cmChar = c; + for ( ;; ) { + c = cmex_nextchar( c ); + if ( c == 0 ) { + break; + } + cmChar = c; + } + + LuPixelRect bound = fm.boundingRect( cmChar ); + + luPt height = context.ptToLayoutUnitPt( bound.height() ); + luPt width = context.ptToLayoutUnitPt( fm.width( cmChar ) ); + luPt baseline = context.ptToLayoutUnitPt( -bound.top() ); + + setHeight( height ); + setWidth( width ); + setBaseline( baseline ); +} + + +void Artwork::drawCMDelimiter( TQPainter& painter, const ContextStyle& style, + luPixel x, luPixel y, + luPt height ) +{ + TQFont f( "cmex10" ); + f.setPointSizeFloat( style.layoutUnitToFontSize( height, false ) ); + + painter.setFont( f ); + painter.drawText( style.layoutUnitToPixelX( x ), + style.layoutUnitToPixelY( y + getBaseline() ), + TQString( TQChar( cmChar ) ) ); + + // Debug +#if 0 + TQFontMetrics fm( f ); + LuPixelRect bound = fm.boundingRect( cmChar ); + painter.setBrush(TQt::NoBrush); + painter.setPen(TQt::green); + painter.drawRect( style.layoutUnitToPixelX( x ), + style.layoutUnitToPixelY( y ), + fm.width( cmChar ), + bound.height() ); +#endif +} + + +Artwork::Artwork(SymbolType t) + : baseline( -1 ), type(t) +{ +} + + +void Artwork::calcSizes( const ContextStyle& style, + ContextStyle::TextStyle tstyle, + double factor, + luPt parentSize ) +{ + setBaseline( -1 ); + cmChar = -1; + luPt mySize = style.getAdjustedSize( tstyle, factor ); + switch (getType()) { + case LeftSquareBracket: + if ( calcCMDelimiterSize( style, cmex_LeftSquareBracket, + mySize, parentSize ) ) { + return; + } + calcRoundBracket( style, leftSquareBracket, parentSize, mySize ); + break; + case RightSquareBracket: + if ( calcCMDelimiterSize( style, cmex_RightSquareBracket, + mySize, parentSize ) ) { + return; + } + calcRoundBracket( style, rightSquareBracket, parentSize, mySize ); + break; + case LeftLineBracket: + calcRoundBracket( style, leftLineBracket, parentSize, mySize ); + setWidth( getWidth()/2 ); + break; + case RightLineBracket: + calcRoundBracket( style, rightLineBracket, parentSize, mySize ); + setWidth( getWidth()/2 ); + break; + case SlashBracket: + if ( calcCMDelimiterSize( style, cmex_SlashBracket, + mySize, parentSize ) ) { + return; + } + calcLargest( style, cmex_SlashBracket, mySize ); + break; + case BackSlashBracket: + if ( calcCMDelimiterSize( style, cmex_BackSlashBracket, + mySize, parentSize ) ) { + return; + } + calcLargest( style, cmex_BackSlashBracket, mySize ); + break; + case LeftCornerBracket: + if ( calcCMDelimiterSize( style, cmex_LeftCornerBracket, + mySize, parentSize ) ) { + return; + } + calcLargest( style, cmex_LeftCornerBracket, mySize ); + break; + case RightCornerBracket: + if ( calcCMDelimiterSize( style, cmex_RightCornerBracket, + mySize, parentSize ) ) { + return; + } + calcLargest( style, cmex_RightCornerBracket, mySize ); + break; + case LeftRoundBracket: + if ( calcCMDelimiterSize( style, cmex_LeftRoundBracket, + mySize, parentSize ) ) { + return; + } + calcRoundBracket( style, leftRoundBracket, parentSize, mySize ); + break; + case RightRoundBracket: + if ( calcCMDelimiterSize( style, cmex_RightRoundBracket, + mySize, parentSize ) ) { + return; + } + calcRoundBracket( style, rightRoundBracket, parentSize, mySize ); + break; + case EmptyBracket: + setHeight(parentSize); + //setWidth(style.getEmptyRectWidth()); + setWidth(0); + break; + case LeftCurlyBracket: + if ( calcCMDelimiterSize( style, cmex_LeftCurlyBracket, + mySize, parentSize ) ) { + return; + } + calcCurlyBracket( style, leftCurlyBracket, parentSize, mySize ); + break; + case RightCurlyBracket: + if ( calcCMDelimiterSize( style, cmex_RightCurlyBracket, + mySize, parentSize ) ) { + return; + } + calcCurlyBracket( style, rightCurlyBracket, parentSize, mySize ); + break; + case Integral: + calcCharSize( style, style.getBracketFont(), mySize, cmex_Int ); + break; + case Sum: + calcCharSize( style, style.getBracketFont(), mySize, cmex_Sum ); + break; + case Product: + calcCharSize( style, style.getBracketFont(), mySize, cmex_Prod ); + break; + } +} + +void Artwork::calcSizes( const ContextStyle& style, + ContextStyle::TextStyle tstyle, + double factor ) +{ + luPt mySize = style.getAdjustedSize( tstyle, factor ); + switch (type) { + case LeftSquareBracket: + calcCharSize(style, mySize, leftSquareBracketChar); + break; + case RightSquareBracket: + calcCharSize(style, mySize, rightSquareBracketChar); + break; + case LeftLineBracket: + case RightLineBracket: + calcCharSize(style, mySize, verticalLineChar); + break; + case SlashBracket: + calcCharSize(style, mySize, slashChar); + break; + case BackSlashBracket: + calcCharSize(style, mySize, backSlashChar); + break; + case LeftCornerBracket: + calcCharSize(style, mySize, leftAngleBracketChar); + break; + case RightCornerBracket: + calcCharSize(style, mySize, rightAngleBracketChar); + break; + case LeftRoundBracket: + calcCharSize(style, mySize, leftParenthesisChar); + break; + case RightRoundBracket: + calcCharSize(style, mySize, rightParenthesisChar); + break; + case EmptyBracket: + //calcCharSize(style, mySize, spaceChar); + setHeight(0); + //setWidth(style.getEmptyRectWidth()); + setWidth(0); + break; + case LeftCurlyBracket: + calcCharSize(style, mySize, leftCurlyBracketChar); + break; + case RightCurlyBracket: + calcCharSize(style, mySize, rightCurlyBracketChar); + break; + case Integral: + case Sum: + case Product: + break; + } +} + + +void Artwork::draw(TQPainter& painter, const LuPixelRect& /*r*/, + const ContextStyle& context, ContextStyle::TextStyle tstyle, + StyleAttributes& style, const LuPixelPoint& parentOrigin) +{ + luPt mySize = context.getAdjustedSize( tstyle, style.sizeFactor() ); + luPixel myX = parentOrigin.x() + getX(); + luPixel myY = parentOrigin.y() + getY(); + /* + if ( !LuPixelRect( myX, myY, getWidth(), getHeight() ).intersects( r ) ) + return; + */ + + painter.setPen(context.getDefaultColor()); + + switch (type) { + case LeftSquareBracket: + drawCharacter(painter, context, myX, myY, mySize, leftSquareBracketChar); + break; + case RightSquareBracket: + drawCharacter(painter, context, myX, myY, mySize, rightSquareBracketChar); + break; + case LeftCurlyBracket: + drawCharacter(painter, context, myX, myY, mySize, leftCurlyBracketChar); + break; + case RightCurlyBracket: + drawCharacter(painter, context, myX, myY, mySize, rightCurlyBracketChar); + break; + case LeftLineBracket: + case RightLineBracket: + drawCharacter(painter, context, myX, myY, mySize, verticalLineChar); + break; + case SlashBracket: + drawCharacter(painter, context, myX, myY, mySize, slashChar); + break; + case BackSlashBracket: + drawCharacter(painter, context, myX, myY, mySize, backSlashChar); + break; + case LeftCornerBracket: + drawCharacter(painter, context, myX, myY, mySize, leftAngleBracketChar); + break; + case RightCornerBracket: + drawCharacter(painter, context, myX, myY, mySize, rightAngleBracketChar); + break; + case LeftRoundBracket: + drawCharacter(painter, context, myX, myY, mySize, leftParenthesisChar); + break; + case RightRoundBracket: + drawCharacter(painter, context, myX, myY, mySize, rightParenthesisChar); + break; + case EmptyBracket: + break; + case Integral: + case Sum: + case Product: + break; + } +} + +void Artwork::draw(TQPainter& painter, const LuPixelRect& , + const ContextStyle& context, ContextStyle::TextStyle tstyle, + StyleAttributes& style, luPt , const LuPixelPoint& origin) +{ + luPt mySize = context.getAdjustedSize( tstyle, style.sizeFactor() ); + luPixel myX = origin.x() + getX(); + luPixel myY = origin.y() + getY(); + /* + if ( !LuPixelRect( myX, myY, getWidth(), getHeight() ).intersects( r ) ) + return; + */ + + painter.setPen(context.getDefaultColor()); + + switch (getType()) { + case LeftSquareBracket: + if ( cmChar != -1 ) { + drawCMDelimiter( painter, context, myX, myY, mySize ); + } + else { + drawBigRoundBracket( painter, context, leftSquareBracket, myX, myY, mySize ); + } + break; + case RightSquareBracket: + if ( cmChar != -1 ) { + drawCMDelimiter( painter, context, myX, myY, mySize ); + } + else { + drawBigRoundBracket( painter, context, rightSquareBracket, myX, myY, mySize ); + } + break; + case LeftCurlyBracket: + if ( cmChar != -1 ) { + drawCMDelimiter( painter, context, myX, myY, mySize ); + } + else { + drawBigCurlyBracket( painter, context, leftCurlyBracket, myX, myY, mySize ); + } + break; + case RightCurlyBracket: + if ( cmChar != -1 ) { + drawCMDelimiter( painter, context, myX, myY, mySize ); + } + else { + drawBigCurlyBracket( painter, context, rightCurlyBracket, myX, myY, mySize ); + } + break; + case LeftLineBracket: { + luPixel halfWidth = getWidth()/2; + drawBigRoundBracket( painter, context, leftLineBracket, + myX-halfWidth, myY, mySize ); + } + break; + case RightLineBracket: { + luPixel halfWidth = getWidth()/2; + drawBigRoundBracket( painter, context, rightLineBracket, + myX-halfWidth, myY, mySize ); + } + break; + case SlashBracket: + if ( cmChar != -1 ) { + drawCMDelimiter( painter, context, myX, myY, mySize ); + } + break; + case BackSlashBracket: + if ( cmChar != -1 ) { + drawCMDelimiter( painter, context, myX, myY, mySize ); + } + break; + case LeftCornerBracket: + if ( cmChar != -1 ) { + drawCMDelimiter( painter, context, myX, myY, mySize ); + } + else drawCharacter(painter, context, myX, myY, mySize, leftAngleBracketChar); + break; + case RightCornerBracket: + if ( cmChar != -1 ) { + drawCMDelimiter( painter, context, myX, myY, mySize ); + } + else drawCharacter(painter, context, myX, myY, mySize, rightAngleBracketChar); + break; + case LeftRoundBracket: + if ( cmChar != -1 ) { + drawCMDelimiter( painter, context, myX, myY, mySize ); + } + else { + drawBigRoundBracket( painter, context, leftRoundBracket, myX, myY, mySize ); + } + break; + case RightRoundBracket: + if ( cmChar != -1 ) { + drawCMDelimiter( painter, context, myX, myY, mySize ); + } + else { + drawBigRoundBracket( painter, context, rightRoundBracket, myX, myY, mySize ); + } + break; + case EmptyBracket: + break; + case Integral: + drawCharacter(painter, context, TQFont( "cmex10" ), myX, myY, mySize, cmex_Int); + break; + case Sum: + drawCharacter(painter, context, TQFont( "cmex10" ), myX, myY, mySize, cmex_Sum); + break; + case Product: + drawCharacter(painter, context, TQFont( "cmex10" ), myX, myY, mySize, cmex_Prod); + break; + } + + // debug +// painter.setBrush(TQt::NoBrush); +// painter.setPen(TQt::green); +// painter.drawRect( context.layoutUnitToPixelX( myX ), +// context.layoutUnitToPixelY( myY ), +// context.layoutUnitToPixelX( getWidth() ), +// context.layoutUnitToPixelY( getHeight() ) ); +} + +void Artwork::calcCharSize( const ContextStyle& style, luPt height, TQChar ch ) +{ + calcCharSize( style, style.getMathFont(), height, ch ); +} + + +void Artwork::drawCharacter( TQPainter& painter, const ContextStyle& style, + luPixel x, luPixel y, + luPt height, TQChar ch ) +{ + drawCharacter( painter, style, style.getMathFont(), x, y, height, ch ); +} + + +void Artwork::calcCharSize( const ContextStyle& style, TQFont f, + luPt height, TQChar c ) +{ + f.setPointSizeFloat( style.layoutUnitPtToPt( height ) ); + //f.setPointSize( height ); + TQFontMetrics fm(f); + setWidth( style.ptToLayoutUnitPt( fm.width( c ) ) ); + LuPixelRect bound = fm.boundingRect( c ); + setHeight( style.ptToLayoutUnitPt( bound.height() ) ); + setBaseline( style.ptToLayoutUnitPt( -bound.top() ) ); +} + + +void Artwork::drawCharacter( TQPainter& painter, const ContextStyle& style, + TQFont f, + luPixel x, luPixel y, luPt height, uchar c ) +{ + f.setPointSizeFloat( style.layoutUnitToFontSize( height, false ) ); + + painter.setFont( f ); + painter.drawText( style.layoutUnitToPixelX( x ), + style.layoutUnitToPixelY( y+getBaseline() ), + TQString( TQChar( c ) ) ); +} + + +void Artwork::calcRoundBracket( const ContextStyle& style, const TQChar chars[], + luPt height, luPt charHeight ) +{ + uchar uppercorner = chars[0]; + uchar lowercorner = chars[1]; + //uchar line = style.symbolTable().character( chars[2] ); + + TQFont f = style.getBracketFont(); + f.setPointSizeFloat( style.layoutUnitPtToPt( charHeight ) ); + TQFontMetrics fm( f ); + LuPtRect upperBound = fm.boundingRect( uppercorner ); + LuPtRect lowerBound = fm.boundingRect( lowercorner ); + //LuPtRect lineBound = fm.boundingRect( line ); + + setWidth( style.ptToLayoutUnitPt( fm.width( TQChar( uppercorner ) ) ) ); + luPt edgeHeight = style.ptToLayoutUnitPt( upperBound.height()+lowerBound.height() ); + //luPt lineHeight = style.ptToLayoutUnitPt( lineBound.height() ); + + //setHeight( edgeHeight + ( ( height-edgeHeight-1 ) / lineHeight + 1 ) * lineHeight ); + setHeight( TQMAX( edgeHeight, height ) ); +} + +void Artwork::drawBigRoundBracket( TQPainter& p, const ContextStyle& style, const TQChar chars[], + luPixel x, luPixel y, luPt charHeight ) +{ + uchar uppercorner = chars[0]; + uchar lowercorner = chars[1]; + uchar line = chars[2]; + + TQFont f = style.getBracketFont(); + f.setPointSizeFloat( style.layoutUnitToFontSize( charHeight, false ) ); + p.setFont(f); + + TQFontMetrics fm(f); + TQRect upperBound = fm.boundingRect(uppercorner); + TQRect lowerBound = fm.boundingRect(lowercorner); + TQRect lineBound = fm.boundingRect(line); + + pixel ptX = style.layoutUnitToPixelX( x ); + pixel ptY = style.layoutUnitToPixelY( y ); + pixel height = style.layoutUnitToPixelY( getHeight() ); + +// p.setPen( TQt::red ); +// //p.drawRect( ptX, ptY, upperBound.width(), upperBound.height() + lowerBound.height() ); +// p.drawRect( ptX, ptY, style.layoutUnitToPixelX( getWidth() ), +// style.layoutUnitToPixelY( getHeight() ) ); + +// p.setPen( TQt::black ); + p.drawText( ptX, ptY-upperBound.top(), TQString( TQChar( uppercorner ) ) ); + p.drawText( ptX, ptY+height-lowerBound.top()-lowerBound.height(), + TQString( TQChar( lowercorner ) ) ); + + // for printing + //pt safety = lineBound.height() / 10.0; + pixel safety = 0; + + pixel gap = height - upperBound.height() - lowerBound.height(); + pixel lineHeight = lineBound.height() - safety; + int lineCount = tqRound( static_cast( gap ) / lineHeight ); + pixel start = upperBound.height()-lineBound.top() - safety; + + for (int i = 0; i < lineCount; i++) { + p.drawText( ptX, ptY+start+i*lineHeight, TQString(TQChar(line))); + } + pixel remaining = gap - lineCount*lineHeight; + pixel dist = ( lineHeight - remaining ) / 2; + p.drawText( ptX, ptY+height-upperBound.height()+dist-lineBound.height()-lineBound.top(), + TQString( TQChar( line ) ) ); +} + +void Artwork::calcCurlyBracket( const ContextStyle& style, const TQChar chars[], + luPt height, luPt charHeight ) +{ + uchar uppercorner = chars[0]; + uchar lowercorner = chars[1]; + //uchar line = style.symbolTable().character( chars[2] ); + uchar middle = chars[3]; + + TQFont f = style.getBracketFont(); + f.setPointSizeFloat( style.layoutUnitPtToPt( charHeight ) ); + TQFontMetrics fm( f ); + LuPtRect upperBound = fm.boundingRect( uppercorner ); + LuPtRect lowerBound = fm.boundingRect( lowercorner ); + //LuPtRect lineBound = fm.boundingRect( line ); + LuPtRect middleBound = fm.boundingRect( middle ); + + setWidth( style.ptToLayoutUnitPt( fm.width( TQChar( uppercorner ) ) ) ); + luPt edgeHeight = style.ptToLayoutUnitPt( upperBound.height()+ + lowerBound.height()+ + middleBound.height() ); + //luPt lineHeight = style.ptToLayoutUnitPt( lineBound.height() ); + + //setHeight( edgeHeight + ( ( height-edgeHeight-1 ) / lineHeight + 1 ) * lineHeight ); + setHeight( TQMAX( edgeHeight, height ) ); +} + +void Artwork::drawBigCurlyBracket( TQPainter& p, const ContextStyle& style, const TQChar chars[], + luPixel x, luPixel y, luPt charHeight ) +{ + //TQFont f = style.getSymbolFont(); + TQFont f = style.getBracketFont(); + f.setPointSizeFloat( style.layoutUnitToFontSize( charHeight, false ) ); + p.setFont(f); + + uchar uppercorner = chars[0]; + uchar lowercorner = chars[1]; + uchar line = chars[2]; + uchar middle = chars[3]; + + TQFontMetrics fm(p.fontMetrics()); + TQRect upperBound = fm.boundingRect(uppercorner); + TQRect lowerBound = fm.boundingRect(lowercorner); + TQRect middleBound = fm.boundingRect(middle); + TQRect lineBound = fm.boundingRect(line); + + pixel ptX = style.layoutUnitToPixelX( x ); + pixel ptY = style.layoutUnitToPixelY( y ); + pixel height = style.layoutUnitToPixelY( getHeight() ); + + //p.setPen(TQt::gray); + //p.drawRect(x, y, upperBound.width() + offset, height); + + p.drawText( ptX, ptY-upperBound.top(), TQString( TQChar( uppercorner ) ) ); + p.drawText( ptX, ptY+(height-middleBound.height())/2-middleBound.top(), + TQString( TQChar( middle ) ) ); + p.drawText( ptX, ptY+height-lowerBound.top()-lowerBound.height(), + TQString( TQChar( lowercorner ) ) ); + + // for printing + // If the world was perfect and the urw-symbol font correct + // this could be 0. + //lu safety = lineBound.height() / 10; + pixel safety = 0; + + pixel lineHeight = lineBound.height() - safety; + pixel gap = height/2 - upperBound.height() - middleBound.height() / 2; + + if (gap > 0) { + TQString ch = TQString(TQChar(line)); + int lineCount = tqRound( gap / lineHeight ) + 1; + + pixel start = (height - middleBound.height()) / 2 + safety; + for (int i = 0; i < lineCount; i++) { + p.drawText( ptX, ptY-lineBound.top()+TQMAX( start-(i+1)*lineHeight, + upperBound.width() ), + ch ); + } + + start = (height + middleBound.height()) / 2 - safety; + for (int i = 0; i < lineCount; i++) { + p.drawText( ptX, ptY-lineBound.top()+TQMIN( start+i*lineHeight, + height-upperBound.width()-lineBound.height() ), + ch ); + } + } +} + +KFORMULA_NAMESPACE_END diff --git a/lib/kformula/formulacursor.cc b/lib/kformula/formulacursor.cc deleted file mode 100644 index 53d02b1f..00000000 --- a/lib/kformula/formulacursor.cc +++ /dev/null @@ -1,746 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2001 Andrea Rizzi - Ulrich Kuettler - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - -#include - -#include -#include - -#include "formulacursor.h" -#include "formulaelement.h" -#include "indexelement.h" -#include "matrixelement.h" -#include "rootelement.h" -#include "sequenceelement.h" -#include "symbolelement.h" -#include "textelement.h" - -KFORMULA_NAMESPACE_BEGIN - -FormulaCursor::FormulaCursor(FormulaElement* element) - : selectionFlag(false), linearMovement(false), - hasChangedFlag(true), readOnly(false) -{ - //setTo(element, 0); - element->goInside( this ); -} - -void FormulaCursor::setTo(BasicElement* element, uint cursor, int mark) -{ - hasChangedFlag = true; - current = element; - cursorPos = cursor; - if ((mark == -1) && selectionFlag) { - return; - } - if (mark != -1) { - setSelection(true); - } - markPos = mark; -} - - -void FormulaCursor::setPos(uint pos) -{ - hasChangedFlag = true; - cursorPos = pos; -} - -void FormulaCursor::setMark(int mark) -{ - hasChangedFlag = true; - markPos = mark; -} - -void FormulaCursor::calcCursorSize( const ContextStyle& context, bool smallCursor ) -{ - // We only draw the cursor if its normalized. - SequenceElement* sequence = dynamic_cast(current); - - if (sequence != 0) { - sequence->calcCursorSize( context, this, smallCursor ); - } -} - -void FormulaCursor::draw( TQPainter& painter, const ContextStyle& context, - StyleAttributes& style, bool smallCursor, bool activeCursor ) -{ - //if (readOnly && !isSelection()) - //return; - - // We only draw the cursor if its normalized. - SequenceElement* sequence = dynamic_cast(current); - - if (sequence != 0) { - sequence->drawCursor( painter, context, style, this, smallCursor, activeCursor ); - } -} - - -void FormulaCursor::handleSelectState(int flag) -{ - if (flag & SelectMovement) { - if (!isSelection()) { - setMark(getPos()); - setSelection(true); - } - } - else { - setSelection(false); - } -} - -void FormulaCursor::moveLeft(int flag) -{ - BasicElement* element = getElement(); - handleSelectState(flag); - if (flag & WordMovement) { - SequenceElement* sequence = dynamic_cast(current); - if (sequence != 0) { - sequence->moveWordLeft(this); - } - else { - element->moveHome(this); - } - } - else { - element->moveLeft(this, element); - } -} - -void FormulaCursor::moveRight(int flag) -{ - BasicElement* element = getElement(); - handleSelectState(flag); - if (flag & WordMovement) { - SequenceElement* sequence = dynamic_cast(current); - if (sequence != 0) { - sequence->moveWordRight(this); - } - else { - element->moveEnd(this); - } - } - else { - element->moveRight(this, element); - } -} - -void FormulaCursor::moveUp(int flag) -{ - BasicElement* element = getElement(); - handleSelectState(flag); - element->moveUp(this, element); -} - -void FormulaCursor::moveDown(int flag) -{ - BasicElement* element = getElement(); - handleSelectState(flag); - element->moveDown(this, element); -} - -void FormulaCursor::moveHome(int flag) -{ - BasicElement* element = getElement(); - handleSelectState(flag); - if (flag & WordMovement) { - element->formula()->moveHome(this); - } - else { - element->moveHome(this); - } -} - -void FormulaCursor::moveEnd(int flag) -{ - BasicElement* element = getElement(); - handleSelectState(flag); - if (flag & WordMovement) { - element->formula()->moveEnd(this); - } - else { - element->moveEnd(this); - } -} - -bool FormulaCursor::isHome() const -{ - return ( getElement() == getElement()->formula() ) && ( getPos() == 0 ); -} - -bool FormulaCursor::isEnd() const -{ - return ( getElement() == getElement()->formula() ) && - ( getPos() == normal()->countChildren() ); -} - -void FormulaCursor::mousePress( const LuPixelPoint& pos, int flag ) -{ - FormulaElement* formula = getElement()->formula(); - formula->goToPos( this, pos ); - if (flag & SelectMovement) { - setSelection(true); - if (getMark() == -1) { - setMark(getPos()); - } - } - else { - setSelection(false); - setMark(getPos()); - } -} - -void FormulaCursor::mouseMove( const LuPixelPoint& point, int ) -{ - setSelection(true); - BasicElement* element = getElement(); - int mark = getMark(); - - FormulaElement* formula = getElement()->formula(); - formula->goToPos( this, point ); - BasicElement* newElement = getElement(); - int pos = getPos(); - - BasicElement* posChild = 0; - BasicElement* markChild = 0; - while (element != newElement) { - posChild = newElement; - newElement = newElement->getParent(); - if (newElement == 0) { - posChild = 0; - newElement = getElement(); - markChild = element; - element = element->getParent(); - } - } - - if (dynamic_cast(element) == 0) { - element = element->getParent(); - element->selectChild(this, newElement); - } - else { - if (posChild != 0) { - element->selectChild(this, posChild); - pos = getPos(); - } - if (markChild != 0) { - element->selectChild(this, markChild); - mark = getMark(); - } - if (pos == mark) { - if ((posChild == 0) && (markChild != 0)) { - mark++; - } - else if ((posChild != 0) && (markChild == 0)) { - mark--; - } - } - else if (pos < mark) { - if (posChild != 0) { - pos--; - } - } - setTo(element, pos, mark); - } -} - -void FormulaCursor::mouseRelease( const LuPixelPoint&, int ) -{ - //mouseSelectionFlag = false; -} - - -/** - * Moves the cursor inside the element. Selection is turned off. - */ -void FormulaCursor::goInsideElement(BasicElement* element) -{ - element->goInside(this); -} - - -/** - * Moves the cursor to a normal position. That is somewhere - * inside a SequenceElement. - * You need to call this after each removal because the cursor - * might point to some non existing place. - */ -void FormulaCursor::normalize(Direction direction) -{ - BasicElement* element = getElement(); - element->normalize(this, direction); -} - - -/** - * Inserts the child at the current position. - * Ignores the selection. - */ -void FormulaCursor::insert(BasicElement* child, Direction direction) -{ - TQPtrList list; - list.append(child); - insert(list, direction); -} - -void FormulaCursor::insert(TQPtrList& children, - Direction direction) -{ - assert( !isReadOnly() ); - BasicElement* element = getElement(); - element->insert(this, children, direction); -} - - -/** - * Removes the current selected children and returns them. - * The cursor needs to be normal (that is be inside a SequenceElement) - * for this to have any effect. - */ -void FormulaCursor::remove(TQPtrList& children, - Direction direction) -{ - assert( !isReadOnly() ); - SequenceElement* sequence = normal(); - if (sequence != 0) { - - // If there is no child to remove in the sequence - // remove the sequence instead. - if (sequence->countChildren() == 0) { - BasicElement* parent = sequence->getParent(); - if (parent != 0) { - parent->selectChild(this, sequence); - parent->remove(this, children, direction); - return; - } - } - else { - sequence->remove(this, children, direction); - } - } -} - - -/** - * Replaces the current selection with the supplied element. - * The replaced elements become the new element's main child's content. - */ -void FormulaCursor::replaceSelectionWith(BasicElement* element, - Direction direction) -{ - assert( !isReadOnly() ); - TQPtrList list; - // we suppres deletion here to get an error if something - // was left in the list. - //list.setAutoDelete(true); - - //remove(list, direction); - if (isSelection()) { - getElement()->remove(this, list, direction); - } - - insert(element, direction); - SequenceElement* mainChild = element->getMainChild(); - if (mainChild != 0) { - mainChild->goInside(this); - insert(list); - /* - BasicElement* parent = element->getParent(); - if (direction == beforeCursor) { - parent->moveRight(this, element); - } - else { - parent->moveLeft(this, element); - } - */ - element->selectChild(this, mainChild); - } -} - - -/** - * Replaces the element the cursor points to with its main child's - * content. - */ -BasicElement* FormulaCursor::replaceByMainChildContent(Direction direction) -{ - assert( !isReadOnly() ); - TQPtrList childrenList; - TQPtrList list; - BasicElement* element = getElement(); - SequenceElement* mainChild = element->getMainChild(); - if ((mainChild != 0) && (mainChild->countChildren() > 0)) { - mainChild->selectAllChildren(this); - remove(childrenList); - } - element->getParent()->selectChild(this, element); - setSelection(false); - remove(list); - insert(childrenList, direction); - if (list.count() > 0) { - return list.take(0); - } - return 0; -} - - -/** - * Trys to find the element we are the main child of and replace - * it with our content. - * - * This is simply another form of replaceByMainChildContent. You - * use this one if the cursor is normalized and inside the main child. - */ -BasicElement* FormulaCursor::removeEnclosingElement(Direction direction) -{ - assert( !isReadOnly() ); - BasicElement* parent = getElement()->getParent(); - if (parent != 0) { - if (getElement() == parent->getMainChild()) { - parent->selectChild(this, getElement()); - return replaceByMainChildContent(direction); - } - } - return 0; -} - - -/** - * Returns wether the element the cursor points to should be replaced. - * Elements are senseless as soon as they only contain a main child. - */ -bool FormulaCursor::elementIsSenseless() -{ - BasicElement* element = getElement(); - return element->isSenseless(); -} - - -/** - * Returns the child the cursor points to. Depending on the - * direction this might be the child before or after the - * cursor. - * - * Might be 0 is there is no such child. - */ -BasicElement* FormulaCursor::getActiveChild(Direction direction) -{ - return getElement()->getChild(this, direction); -} - -BasicElement* FormulaCursor::getSelectedChild() -{ - if (isSelection()) { - if ((getSelectionEnd() - getSelectionStart()) > 1) { - return 0; - } - return getActiveChild((getPos() > getMark()) ? - beforeCursor : - afterCursor); - } - else { - return getActiveChild(beforeCursor); - } -} - - -void FormulaCursor::selectActiveElement() -{ - if ( !isSelection() && getPos() > 0 ) { - setSelection( true ); - setMark( getPos() - 1 ); - } -} - - -/** - * Tells whether we currently point to the given elements - * main child and to the place behind its last child. - */ -bool FormulaCursor::pointsAfterMainChild(BasicElement* element) -{ - if (element != 0) { - SequenceElement* mainChild = element->getMainChild(); - return (getElement() == mainChild) && - ((mainChild->countChildren() == getPos()) || (0 == getPos())); - } - return false; -} - - -/** - * Returns the IndexElement the cursor is on or 0 - * if there is non. - */ -IndexElement* FormulaCursor::getActiveIndexElement() -{ - IndexElement* element = dynamic_cast(getSelectedChild()); - - if ((element == 0) && !isSelection()) { - element = dynamic_cast(getElement()->getParent()); - if (!pointsAfterMainChild(element)) { - return 0; - } - } - return element; -} - - -/** - * Returns the RootElement the cursor is on or 0 - * if there is non. - */ -RootElement* FormulaCursor::getActiveRootElement() -{ - RootElement* element = dynamic_cast(getSelectedChild()); - - if ((element == 0) && !isSelection()) { - element = dynamic_cast(getElement()->getParent()); - if (!pointsAfterMainChild(element)) { - return 0; - } - } - return element; -} - - -/** - * @returns the SymbolElement the cursor is on or 0 - * if there is non. - */ -SymbolElement* FormulaCursor::getActiveSymbolElement() -{ - SymbolElement* element = dynamic_cast(getSelectedChild()); - - if ((element == 0) && !isSelection()) { - element = dynamic_cast(getElement()->getParent()); - if (!pointsAfterMainChild(element)) { - return 0; - } - } - return element; -} - -/** - * @returns the NameSequence the cursor is on or 0 - * if there is non. - */ -NameSequence* FormulaCursor::getActiveNameSequence() -{ - NameSequence* element = dynamic_cast( getSelectedChild() ); - - if ( ( element == 0 ) && !isSelection() ) { - element = dynamic_cast( getElement() ); - if ( !pointsAfterMainChild( element ) ) { - return 0; - } - } - return element; -} - -/** - * @returns the TextElement the cursor is on or 0. - */ -TextElement* FormulaCursor::getActiveTextElement() -{ - return dynamic_cast(getSelectedChild()); -} - - -MatrixElement* FormulaCursor::getActiveMatrixElement() -{ - MatrixElement* element = dynamic_cast(getSelectedChild()); - - if ( ( element != 0 ) && !isSelection() ) { - normal()->selectChild( this, element ); - } -// if ((element == 0) && !isSelection()) { -// element = dynamic_cast(getElement()->getParent()); -// if (!pointsAfterMainChild(element)) { -// return 0; -// } -// } - return element; -} - -/** - * The element is going to leave the formula with and all its children. - */ -void FormulaCursor::elementWillVanish(BasicElement* element) -{ - BasicElement* child = getElement(); - if (element && child == element->getParent()) { - child->childWillVanish(this, element); - return; - } - while (child != 0) { - if (child == element) { - // This is meant to catch all cursors that did not - // cause the deletion. - child->getParent()->moveLeft(this, child); - setSelection(false); - hasChangedFlag = true; - return; - } - child = child->getParent(); - } -} - - -/** - * A new formula has been loaded. Our current element has to change. - */ -void FormulaCursor::formulaLoaded(FormulaElement* rootElement) -{ - //current = rootElement; - //setPos(0); - rootElement->goInside( this ); - setMark(-1); - setSelection(false); -} - - -bool FormulaCursor::isReadOnly() const -{ - if ( readOnly ) { - return true; - } - const SequenceElement* sequence = normal(); - if ( sequence != 0 ) { - bool ro = sequence->readOnly( this ); - //kdDebug() << k_funcinfo << "readOnly=" << ro << endl; - return ro; - } - return false; -} - - -/** - * Stores the currently selected elements inside a dom. - */ -void FormulaCursor::copy( TQDomDocument& doc ) -{ - if (isSelection()) { - SequenceElement* sequence = normal(); - if (sequence != 0) { - TQDomElement root = doc.createElementNS( "http://www.w3.org/1998/Math/MathML", - "math" ); - doc.appendChild( root ); - TQDomElement de = doc.createElement( "mrow" ); - root.appendChild( de ); - sequence->getChildrenMathMLDom(doc, de, getSelectionStart(), getSelectionEnd()); - } - else { - // This must never happen. - tqFatal("A not normalized cursor is selecting."); - } - } -} - -/** - * Inserts the elements that could be read from the dom into - * the list. Returns true on success. - */ -bool FormulaCursor::buildElementsFromDom( TQDomElement root, TQPtrList& list ) -{ - assert( !isReadOnly() ); - SequenceElement* sequence = normal(); - if (sequence != 0) { - TQDomElement e = root.firstChild().toElement(); - if (sequence->buildChildrenFromDom(list, e.firstChild())) { - return true; - } - } - return false; -} - -/** - * Inserts the elements that could be read from the MathML dom into - * the list. Returns true on success. - */ -bool FormulaCursor::buildElementsFromMathMLDom( TQDomElement root, TQPtrList& list ) -{ - assert( !isReadOnly() ); - SequenceElement* sequence = normal(); - if (sequence != 0) { - TQDomElement e = root.firstChild().toElement(); - if (sequence->buildChildrenFromMathMLDom(list, e.firstChild())) { - return true; - } - } - return false; -} - -/** - * Creates a new CursorData object that describes the cursor. - * It's up to the caller to delete this object. - */ -FormulaCursor::CursorData* FormulaCursor::getCursorData() -{ - return new CursorData(current, cursorPos, markPos, - selectionFlag, linearMovement, readOnly); -} - - -// Keep in sync with 'setCursorData' -FormulaCursor& FormulaCursor::operator= (const FormulaCursor& other) -{ - current = other.current; - cursorPos = other.cursorPos; - markPos = other.markPos; - selectionFlag = other.selectionFlag; - linearMovement = other.linearMovement; - readOnly = other.readOnly; - hasChangedFlag = true; - return *this; -} - - -/** - * Sets the cursor to where the CursorData points to. No checking is done - * so you better make sure the point exists. - */ -void FormulaCursor::setCursorData(FormulaCursor::CursorData* data) -{ - current = data->current; - cursorPos = data->cursorPos; - markPos = data->markPos; - selectionFlag = data->selectionFlag; - linearMovement = data->linearMovement; - readOnly = data->readOnly; - hasChangedFlag = true; -} - - -/** - * Returns the sequence the cursor is in if we are normal. If not returns 0. - */ -SequenceElement* FormulaCursor::normal() -{ - return dynamic_cast(current); -} - -const SequenceElement* FormulaCursor::normal() const -{ - return dynamic_cast(current); -} - -KFORMULA_NAMESPACE_END diff --git a/lib/kformula/formulacursor.cpp b/lib/kformula/formulacursor.cpp new file mode 100644 index 00000000..53d02b1f --- /dev/null +++ b/lib/kformula/formulacursor.cpp @@ -0,0 +1,746 @@ +/* This file is part of the KDE project + Copyright (C) 2001 Andrea Rizzi + Ulrich Kuettler + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include + +#include +#include + +#include "formulacursor.h" +#include "formulaelement.h" +#include "indexelement.h" +#include "matrixelement.h" +#include "rootelement.h" +#include "sequenceelement.h" +#include "symbolelement.h" +#include "textelement.h" + +KFORMULA_NAMESPACE_BEGIN + +FormulaCursor::FormulaCursor(FormulaElement* element) + : selectionFlag(false), linearMovement(false), + hasChangedFlag(true), readOnly(false) +{ + //setTo(element, 0); + element->goInside( this ); +} + +void FormulaCursor::setTo(BasicElement* element, uint cursor, int mark) +{ + hasChangedFlag = true; + current = element; + cursorPos = cursor; + if ((mark == -1) && selectionFlag) { + return; + } + if (mark != -1) { + setSelection(true); + } + markPos = mark; +} + + +void FormulaCursor::setPos(uint pos) +{ + hasChangedFlag = true; + cursorPos = pos; +} + +void FormulaCursor::setMark(int mark) +{ + hasChangedFlag = true; + markPos = mark; +} + +void FormulaCursor::calcCursorSize( const ContextStyle& context, bool smallCursor ) +{ + // We only draw the cursor if its normalized. + SequenceElement* sequence = dynamic_cast(current); + + if (sequence != 0) { + sequence->calcCursorSize( context, this, smallCursor ); + } +} + +void FormulaCursor::draw( TQPainter& painter, const ContextStyle& context, + StyleAttributes& style, bool smallCursor, bool activeCursor ) +{ + //if (readOnly && !isSelection()) + //return; + + // We only draw the cursor if its normalized. + SequenceElement* sequence = dynamic_cast(current); + + if (sequence != 0) { + sequence->drawCursor( painter, context, style, this, smallCursor, activeCursor ); + } +} + + +void FormulaCursor::handleSelectState(int flag) +{ + if (flag & SelectMovement) { + if (!isSelection()) { + setMark(getPos()); + setSelection(true); + } + } + else { + setSelection(false); + } +} + +void FormulaCursor::moveLeft(int flag) +{ + BasicElement* element = getElement(); + handleSelectState(flag); + if (flag & WordMovement) { + SequenceElement* sequence = dynamic_cast(current); + if (sequence != 0) { + sequence->moveWordLeft(this); + } + else { + element->moveHome(this); + } + } + else { + element->moveLeft(this, element); + } +} + +void FormulaCursor::moveRight(int flag) +{ + BasicElement* element = getElement(); + handleSelectState(flag); + if (flag & WordMovement) { + SequenceElement* sequence = dynamic_cast(current); + if (sequence != 0) { + sequence->moveWordRight(this); + } + else { + element->moveEnd(this); + } + } + else { + element->moveRight(this, element); + } +} + +void FormulaCursor::moveUp(int flag) +{ + BasicElement* element = getElement(); + handleSelectState(flag); + element->moveUp(this, element); +} + +void FormulaCursor::moveDown(int flag) +{ + BasicElement* element = getElement(); + handleSelectState(flag); + element->moveDown(this, element); +} + +void FormulaCursor::moveHome(int flag) +{ + BasicElement* element = getElement(); + handleSelectState(flag); + if (flag & WordMovement) { + element->formula()->moveHome(this); + } + else { + element->moveHome(this); + } +} + +void FormulaCursor::moveEnd(int flag) +{ + BasicElement* element = getElement(); + handleSelectState(flag); + if (flag & WordMovement) { + element->formula()->moveEnd(this); + } + else { + element->moveEnd(this); + } +} + +bool FormulaCursor::isHome() const +{ + return ( getElement() == getElement()->formula() ) && ( getPos() == 0 ); +} + +bool FormulaCursor::isEnd() const +{ + return ( getElement() == getElement()->formula() ) && + ( getPos() == normal()->countChildren() ); +} + +void FormulaCursor::mousePress( const LuPixelPoint& pos, int flag ) +{ + FormulaElement* formula = getElement()->formula(); + formula->goToPos( this, pos ); + if (flag & SelectMovement) { + setSelection(true); + if (getMark() == -1) { + setMark(getPos()); + } + } + else { + setSelection(false); + setMark(getPos()); + } +} + +void FormulaCursor::mouseMove( const LuPixelPoint& point, int ) +{ + setSelection(true); + BasicElement* element = getElement(); + int mark = getMark(); + + FormulaElement* formula = getElement()->formula(); + formula->goToPos( this, point ); + BasicElement* newElement = getElement(); + int pos = getPos(); + + BasicElement* posChild = 0; + BasicElement* markChild = 0; + while (element != newElement) { + posChild = newElement; + newElement = newElement->getParent(); + if (newElement == 0) { + posChild = 0; + newElement = getElement(); + markChild = element; + element = element->getParent(); + } + } + + if (dynamic_cast(element) == 0) { + element = element->getParent(); + element->selectChild(this, newElement); + } + else { + if (posChild != 0) { + element->selectChild(this, posChild); + pos = getPos(); + } + if (markChild != 0) { + element->selectChild(this, markChild); + mark = getMark(); + } + if (pos == mark) { + if ((posChild == 0) && (markChild != 0)) { + mark++; + } + else if ((posChild != 0) && (markChild == 0)) { + mark--; + } + } + else if (pos < mark) { + if (posChild != 0) { + pos--; + } + } + setTo(element, pos, mark); + } +} + +void FormulaCursor::mouseRelease( const LuPixelPoint&, int ) +{ + //mouseSelectionFlag = false; +} + + +/** + * Moves the cursor inside the element. Selection is turned off. + */ +void FormulaCursor::goInsideElement(BasicElement* element) +{ + element->goInside(this); +} + + +/** + * Moves the cursor to a normal position. That is somewhere + * inside a SequenceElement. + * You need to call this after each removal because the cursor + * might point to some non existing place. + */ +void FormulaCursor::normalize(Direction direction) +{ + BasicElement* element = getElement(); + element->normalize(this, direction); +} + + +/** + * Inserts the child at the current position. + * Ignores the selection. + */ +void FormulaCursor::insert(BasicElement* child, Direction direction) +{ + TQPtrList list; + list.append(child); + insert(list, direction); +} + +void FormulaCursor::insert(TQPtrList& children, + Direction direction) +{ + assert( !isReadOnly() ); + BasicElement* element = getElement(); + element->insert(this, children, direction); +} + + +/** + * Removes the current selected children and returns them. + * The cursor needs to be normal (that is be inside a SequenceElement) + * for this to have any effect. + */ +void FormulaCursor::remove(TQPtrList& children, + Direction direction) +{ + assert( !isReadOnly() ); + SequenceElement* sequence = normal(); + if (sequence != 0) { + + // If there is no child to remove in the sequence + // remove the sequence instead. + if (sequence->countChildren() == 0) { + BasicElement* parent = sequence->getParent(); + if (parent != 0) { + parent->selectChild(this, sequence); + parent->remove(this, children, direction); + return; + } + } + else { + sequence->remove(this, children, direction); + } + } +} + + +/** + * Replaces the current selection with the supplied element. + * The replaced elements become the new element's main child's content. + */ +void FormulaCursor::replaceSelectionWith(BasicElement* element, + Direction direction) +{ + assert( !isReadOnly() ); + TQPtrList list; + // we suppres deletion here to get an error if something + // was left in the list. + //list.setAutoDelete(true); + + //remove(list, direction); + if (isSelection()) { + getElement()->remove(this, list, direction); + } + + insert(element, direction); + SequenceElement* mainChild = element->getMainChild(); + if (mainChild != 0) { + mainChild->goInside(this); + insert(list); + /* + BasicElement* parent = element->getParent(); + if (direction == beforeCursor) { + parent->moveRight(this, element); + } + else { + parent->moveLeft(this, element); + } + */ + element->selectChild(this, mainChild); + } +} + + +/** + * Replaces the element the cursor points to with its main child's + * content. + */ +BasicElement* FormulaCursor::replaceByMainChildContent(Direction direction) +{ + assert( !isReadOnly() ); + TQPtrList childrenList; + TQPtrList list; + BasicElement* element = getElement(); + SequenceElement* mainChild = element->getMainChild(); + if ((mainChild != 0) && (mainChild->countChildren() > 0)) { + mainChild->selectAllChildren(this); + remove(childrenList); + } + element->getParent()->selectChild(this, element); + setSelection(false); + remove(list); + insert(childrenList, direction); + if (list.count() > 0) { + return list.take(0); + } + return 0; +} + + +/** + * Trys to find the element we are the main child of and replace + * it with our content. + * + * This is simply another form of replaceByMainChildContent. You + * use this one if the cursor is normalized and inside the main child. + */ +BasicElement* FormulaCursor::removeEnclosingElement(Direction direction) +{ + assert( !isReadOnly() ); + BasicElement* parent = getElement()->getParent(); + if (parent != 0) { + if (getElement() == parent->getMainChild()) { + parent->selectChild(this, getElement()); + return replaceByMainChildContent(direction); + } + } + return 0; +} + + +/** + * Returns wether the element the cursor points to should be replaced. + * Elements are senseless as soon as they only contain a main child. + */ +bool FormulaCursor::elementIsSenseless() +{ + BasicElement* element = getElement(); + return element->isSenseless(); +} + + +/** + * Returns the child the cursor points to. Depending on the + * direction this might be the child before or after the + * cursor. + * + * Might be 0 is there is no such child. + */ +BasicElement* FormulaCursor::getActiveChild(Direction direction) +{ + return getElement()->getChild(this, direction); +} + +BasicElement* FormulaCursor::getSelectedChild() +{ + if (isSelection()) { + if ((getSelectionEnd() - getSelectionStart()) > 1) { + return 0; + } + return getActiveChild((getPos() > getMark()) ? + beforeCursor : + afterCursor); + } + else { + return getActiveChild(beforeCursor); + } +} + + +void FormulaCursor::selectActiveElement() +{ + if ( !isSelection() && getPos() > 0 ) { + setSelection( true ); + setMark( getPos() - 1 ); + } +} + + +/** + * Tells whether we currently point to the given elements + * main child and to the place behind its last child. + */ +bool FormulaCursor::pointsAfterMainChild(BasicElement* element) +{ + if (element != 0) { + SequenceElement* mainChild = element->getMainChild(); + return (getElement() == mainChild) && + ((mainChild->countChildren() == getPos()) || (0 == getPos())); + } + return false; +} + + +/** + * Returns the IndexElement the cursor is on or 0 + * if there is non. + */ +IndexElement* FormulaCursor::getActiveIndexElement() +{ + IndexElement* element = dynamic_cast(getSelectedChild()); + + if ((element == 0) && !isSelection()) { + element = dynamic_cast(getElement()->getParent()); + if (!pointsAfterMainChild(element)) { + return 0; + } + } + return element; +} + + +/** + * Returns the RootElement the cursor is on or 0 + * if there is non. + */ +RootElement* FormulaCursor::getActiveRootElement() +{ + RootElement* element = dynamic_cast(getSelectedChild()); + + if ((element == 0) && !isSelection()) { + element = dynamic_cast(getElement()->getParent()); + if (!pointsAfterMainChild(element)) { + return 0; + } + } + return element; +} + + +/** + * @returns the SymbolElement the cursor is on or 0 + * if there is non. + */ +SymbolElement* FormulaCursor::getActiveSymbolElement() +{ + SymbolElement* element = dynamic_cast(getSelectedChild()); + + if ((element == 0) && !isSelection()) { + element = dynamic_cast(getElement()->getParent()); + if (!pointsAfterMainChild(element)) { + return 0; + } + } + return element; +} + +/** + * @returns the NameSequence the cursor is on or 0 + * if there is non. + */ +NameSequence* FormulaCursor::getActiveNameSequence() +{ + NameSequence* element = dynamic_cast( getSelectedChild() ); + + if ( ( element == 0 ) && !isSelection() ) { + element = dynamic_cast( getElement() ); + if ( !pointsAfterMainChild( element ) ) { + return 0; + } + } + return element; +} + +/** + * @returns the TextElement the cursor is on or 0. + */ +TextElement* FormulaCursor::getActiveTextElement() +{ + return dynamic_cast(getSelectedChild()); +} + + +MatrixElement* FormulaCursor::getActiveMatrixElement() +{ + MatrixElement* element = dynamic_cast(getSelectedChild()); + + if ( ( element != 0 ) && !isSelection() ) { + normal()->selectChild( this, element ); + } +// if ((element == 0) && !isSelection()) { +// element = dynamic_cast(getElement()->getParent()); +// if (!pointsAfterMainChild(element)) { +// return 0; +// } +// } + return element; +} + +/** + * The element is going to leave the formula with and all its children. + */ +void FormulaCursor::elementWillVanish(BasicElement* element) +{ + BasicElement* child = getElement(); + if (element && child == element->getParent()) { + child->childWillVanish(this, element); + return; + } + while (child != 0) { + if (child == element) { + // This is meant to catch all cursors that did not + // cause the deletion. + child->getParent()->moveLeft(this, child); + setSelection(false); + hasChangedFlag = true; + return; + } + child = child->getParent(); + } +} + + +/** + * A new formula has been loaded. Our current element has to change. + */ +void FormulaCursor::formulaLoaded(FormulaElement* rootElement) +{ + //current = rootElement; + //setPos(0); + rootElement->goInside( this ); + setMark(-1); + setSelection(false); +} + + +bool FormulaCursor::isReadOnly() const +{ + if ( readOnly ) { + return true; + } + const SequenceElement* sequence = normal(); + if ( sequence != 0 ) { + bool ro = sequence->readOnly( this ); + //kdDebug() << k_funcinfo << "readOnly=" << ro << endl; + return ro; + } + return false; +} + + +/** + * Stores the currently selected elements inside a dom. + */ +void FormulaCursor::copy( TQDomDocument& doc ) +{ + if (isSelection()) { + SequenceElement* sequence = normal(); + if (sequence != 0) { + TQDomElement root = doc.createElementNS( "http://www.w3.org/1998/Math/MathML", + "math" ); + doc.appendChild( root ); + TQDomElement de = doc.createElement( "mrow" ); + root.appendChild( de ); + sequence->getChildrenMathMLDom(doc, de, getSelectionStart(), getSelectionEnd()); + } + else { + // This must never happen. + tqFatal("A not normalized cursor is selecting."); + } + } +} + +/** + * Inserts the elements that could be read from the dom into + * the list. Returns true on success. + */ +bool FormulaCursor::buildElementsFromDom( TQDomElement root, TQPtrList& list ) +{ + assert( !isReadOnly() ); + SequenceElement* sequence = normal(); + if (sequence != 0) { + TQDomElement e = root.firstChild().toElement(); + if (sequence->buildChildrenFromDom(list, e.firstChild())) { + return true; + } + } + return false; +} + +/** + * Inserts the elements that could be read from the MathML dom into + * the list. Returns true on success. + */ +bool FormulaCursor::buildElementsFromMathMLDom( TQDomElement root, TQPtrList& list ) +{ + assert( !isReadOnly() ); + SequenceElement* sequence = normal(); + if (sequence != 0) { + TQDomElement e = root.firstChild().toElement(); + if (sequence->buildChildrenFromMathMLDom(list, e.firstChild())) { + return true; + } + } + return false; +} + +/** + * Creates a new CursorData object that describes the cursor. + * It's up to the caller to delete this object. + */ +FormulaCursor::CursorData* FormulaCursor::getCursorData() +{ + return new CursorData(current, cursorPos, markPos, + selectionFlag, linearMovement, readOnly); +} + + +// Keep in sync with 'setCursorData' +FormulaCursor& FormulaCursor::operator= (const FormulaCursor& other) +{ + current = other.current; + cursorPos = other.cursorPos; + markPos = other.markPos; + selectionFlag = other.selectionFlag; + linearMovement = other.linearMovement; + readOnly = other.readOnly; + hasChangedFlag = true; + return *this; +} + + +/** + * Sets the cursor to where the CursorData points to. No checking is done + * so you better make sure the point exists. + */ +void FormulaCursor::setCursorData(FormulaCursor::CursorData* data) +{ + current = data->current; + cursorPos = data->cursorPos; + markPos = data->markPos; + selectionFlag = data->selectionFlag; + linearMovement = data->linearMovement; + readOnly = data->readOnly; + hasChangedFlag = true; +} + + +/** + * Returns the sequence the cursor is in if we are normal. If not returns 0. + */ +SequenceElement* FormulaCursor::normal() +{ + return dynamic_cast(current); +} + +const SequenceElement* FormulaCursor::normal() const +{ + return dynamic_cast(current); +} + +KFORMULA_NAMESPACE_END diff --git a/lib/kformula/formulaelement.cc b/lib/kformula/formulaelement.cc deleted file mode 100644 index 946e595d..00000000 --- a/lib/kformula/formulaelement.cc +++ /dev/null @@ -1,336 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2001 Andrea Rizzi - Ulrich Kuettler - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - -#include -#include - -#include - -#include "contextstyle.h" -#include "formulacursor.h" -#include "formulaelement.h" -#include "kformulacontainer.h" -#include "kformuladocument.h" - -KFORMULA_NAMESPACE_BEGIN - -FormulaElement::FormulaElement(FormulaDocument* container) - : document( container ), baseSize( 20 ), ownBaseSize( false ) -{ -} - - -void FormulaElement::setBaseSize( int size ) -{ - if ( size > 0 ) { - baseSize = size; - ownBaseSize = true; - } - else { - ownBaseSize = false; - } - document->baseSizeChanged( size, ownBaseSize ); -} - - -/** - * Returns the element the point is in. - */ -BasicElement* FormulaElement::goToPos( FormulaCursor* cursor, const LuPixelPoint& point ) -{ - bool handled = false; - BasicElement* element = inherited::goToPos(cursor, handled, point, LuPixelPoint()); - if (element == 0) { - //if ((point.x() > getWidth()) || (point.y() > getHeight())) { - cursor->setTo(this, countChildren()); - //} - return this; - } - return element; -} - -void FormulaElement::elementRemoval(BasicElement* child) -{ - document->elementRemoval(child); -} - -void FormulaElement::changed() -{ - document->changed(); -} - -void FormulaElement::cursorHasMoved( FormulaCursor* cursor ) -{ - document->cursorHasMoved( cursor ); -} - -void FormulaElement::moveOutLeft( FormulaCursor* cursor ) -{ - document->moveOutLeft( cursor ); -} - -void FormulaElement::moveOutRight( FormulaCursor* cursor ) -{ - document->moveOutRight( cursor ); -} - -void FormulaElement::moveOutBelow( FormulaCursor* cursor ) -{ - document->moveOutBelow( cursor ); -} - -void FormulaElement::moveOutAbove( FormulaCursor* cursor ) -{ - document->moveOutAbove( cursor ); -} - -void FormulaElement::tell( const TQString& msg ) -{ - document->tell( msg ); -} - -void FormulaElement::removeFormula( FormulaCursor* cursor ) -{ - document->removeFormula( cursor ); -} - -void FormulaElement::insertFormula( FormulaCursor* cursor ) -{ - document->insertFormula( cursor ); -} - -void FormulaElement::calcSizes( const ContextStyle& context, - ContextStyle::TextStyle tstyle, - ContextStyle::IndexStyle istyle, - StyleAttributes& style ) -{ - inherited::calcSizes( context, tstyle, istyle, style ); -} - - -void FormulaElement::draw( TQPainter& painter, const LuPixelRect& r, - const ContextStyle& context, - ContextStyle::TextStyle tstyle, - ContextStyle::IndexStyle istyle, - StyleAttributes& style, - const LuPixelPoint& parentOrigin ) -{ - inherited::draw( painter, r, context, tstyle, istyle, style, parentOrigin ); -} - - -/** - * Calculates the formulas sizes and positions. - */ -void FormulaElement::calcSizes( ContextStyle& context ) -{ - //kdDebug( DEBUGID ) << "FormulaElement::calcSizes" << endl; - if ( ownBaseSize ) { - context.setSizeFactor( static_cast( getBaseSize() )/context.baseSize() ); - } - else { - context.setSizeFactor( 1 ); - } - StyleAttributes style; - calcSizes( context, context.getBaseTextStyle(), ContextStyle::normal, style ); -} - -/** - * Draws the whole thing. - */ -void FormulaElement::draw( TQPainter& painter, const LuPixelRect& r, - ContextStyle& context ) -{ - //kdDebug( DEBUGID ) << "FormulaElement::draw" << endl; - if ( ownBaseSize ) { - context.setSizeFactor( static_cast( getBaseSize() )/context.baseSize() ); - } - else { - context.setSizeFactor( 1 ); - } - StyleAttributes style; - draw( painter, r, context, context.getBaseTextStyle(), - ContextStyle::normal, style, LuPixelPoint() ); -} - -KCommand* FormulaElement::buildCommand( Container* container, Request* request ) -{ - switch ( *request ) { - case req_compactExpression: - return 0; - default: - break; - } - return inherited::buildCommand( container, request ); -} - -const SymbolTable& FormulaElement::getSymbolTable() const -{ - return document->getSymbolTable(); -} - - -TQDomElement FormulaElement::emptyFormulaElement( TQDomDocument& doc ) -{ - TQDomElement element = doc.createElement( getTagName() ); - /* - element.setAttribute( "VERSION", "6" ); - if ( ownBaseSize ) { - element.setAttribute( "BASESIZE", baseSize ); - } - */ - return element; -} - -KCommand* FormulaElement::input( Container* container, TQKeyEvent* event ) -{ - TQChar ch = event->text().at( 0 ); - if ( !ch.isPrint() ) { - int action = event->key(); - //int state = event->state(); - //MoveFlag flag = movementFlag(state); - - switch ( action ) { - case TQt::Key_Return: - case TQt::Key_Enter: { - FormulaCursor* cursor = container->activeCursor(); - insertFormula( cursor ); - return 0; - } - } - } - return inherited::input( container, event ); -} - -/** - * Appends our attributes to the dom element. - */ -void FormulaElement::writeDom(TQDomElement element) -{ - inherited::writeDom(element); - element.setAttribute( "VERSION", "6" ); - if ( ownBaseSize ) { - element.setAttribute( "BASESIZE", baseSize ); - } -} - -/** - * Reads our attributes from the element. - * Returns false if it failed. - */ -bool FormulaElement::readAttributesFromDom(TQDomElement element) -{ - if (!inherited::readAttributesFromDom(element)) { - return false; - } - int version = -1; - TQString versionStr = element.attribute( "VERSION" ); - if ( !versionStr.isNull() ) { - version = versionStr.toInt(); - } - if ( version > -1 ) { - // Version 6 added the MultilineElement (TabMarker) - // Version 5 added under- and overlines - if ( version < 4 ) { - convertNames( element ); - } - } - TQString baseSizeStr = element.attribute( "BASESIZE" ); - if ( !baseSizeStr.isNull() ) { - ownBaseSize = true; - baseSize = baseSizeStr.toInt(); - } - else { - ownBaseSize = false; - } - return true; -} - -/** - * Reads our content from the node. Sets the node to the next node - * that needs to be read. - * Returns false if it failed. - */ -bool FormulaElement::readContentFromDom(TQDomNode& node) -{ - return inherited::readContentFromDom(node); -} - -void FormulaElement::convertNames( TQDomNode node ) -{ - if ( node.isElement() && ( node.nodeName().upper() == "TEXT" ) ) { - TQDomNamedNodeMap attr = node.attributes(); - TQDomAttr ch = attr.namedItem( "CHAR" ).toAttr(); - if ( ch.value() == "\\" ) { - TQDomNode sequence = node.parentNode(); - TQDomDocument doc = sequence.ownerDocument(); - TQDomElement nameseq = doc.createElement( "NAMESEQUENCE" ); - sequence.replaceChild( nameseq, node ); - - bool inName = true; - while ( inName ) { - inName = false; - TQDomNode n = nameseq.nextSibling(); - if ( n.isElement() && ( n.nodeName().upper() == "TEXT" ) ) { - attr = n.attributes(); - ch = attr.namedItem( "CHAR" ).toAttr(); - if ( ch.value().at( 0 ).isLetter() ) { - nameseq.appendChild( sequence.removeChild( n ) ); - inName = true; - } - } - } - } - } - if ( node.hasChildNodes() ) { - TQDomNode n = node.firstChild(); - while ( !n.isNull() ) { - convertNames( n ); - n = n.nextSibling(); - } - } -} - -TQString FormulaElement::toLatex() -{ - return inherited::toLatex(); //Consider $$ sorround -} - -void FormulaElement::writeMathML( TQDomDocument& doc, TQDomNode& parent, bool oasisFormat ) const -{ - TQDomElement de; - if ( !oasisFormat ) { - de = doc.createElementNS( "http://www.w3.org/1998/Math/MathML", - "math" ); - parent.appendChild( de ); - } - else { - TQDomElement element = doc.createElement( "math:semantics" ); - de = doc.createElement( "math:mrow" ); - parent.appendChild( element ); - element.appendChild( de ); - } - for ( uint i = 0; i < countChildren(); ++i ) { - const BasicElement* e = getChild( i ); - e->writeMathML( doc, de, oasisFormat ); - } -} - -KFORMULA_NAMESPACE_END diff --git a/lib/kformula/formulaelement.cpp b/lib/kformula/formulaelement.cpp new file mode 100644 index 00000000..946e595d --- /dev/null +++ b/lib/kformula/formulaelement.cpp @@ -0,0 +1,336 @@ +/* This file is part of the KDE project + Copyright (C) 2001 Andrea Rizzi + Ulrich Kuettler + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include + +#include + +#include "contextstyle.h" +#include "formulacursor.h" +#include "formulaelement.h" +#include "kformulacontainer.h" +#include "kformuladocument.h" + +KFORMULA_NAMESPACE_BEGIN + +FormulaElement::FormulaElement(FormulaDocument* container) + : document( container ), baseSize( 20 ), ownBaseSize( false ) +{ +} + + +void FormulaElement::setBaseSize( int size ) +{ + if ( size > 0 ) { + baseSize = size; + ownBaseSize = true; + } + else { + ownBaseSize = false; + } + document->baseSizeChanged( size, ownBaseSize ); +} + + +/** + * Returns the element the point is in. + */ +BasicElement* FormulaElement::goToPos( FormulaCursor* cursor, const LuPixelPoint& point ) +{ + bool handled = false; + BasicElement* element = inherited::goToPos(cursor, handled, point, LuPixelPoint()); + if (element == 0) { + //if ((point.x() > getWidth()) || (point.y() > getHeight())) { + cursor->setTo(this, countChildren()); + //} + return this; + } + return element; +} + +void FormulaElement::elementRemoval(BasicElement* child) +{ + document->elementRemoval(child); +} + +void FormulaElement::changed() +{ + document->changed(); +} + +void FormulaElement::cursorHasMoved( FormulaCursor* cursor ) +{ + document->cursorHasMoved( cursor ); +} + +void FormulaElement::moveOutLeft( FormulaCursor* cursor ) +{ + document->moveOutLeft( cursor ); +} + +void FormulaElement::moveOutRight( FormulaCursor* cursor ) +{ + document->moveOutRight( cursor ); +} + +void FormulaElement::moveOutBelow( FormulaCursor* cursor ) +{ + document->moveOutBelow( cursor ); +} + +void FormulaElement::moveOutAbove( FormulaCursor* cursor ) +{ + document->moveOutAbove( cursor ); +} + +void FormulaElement::tell( const TQString& msg ) +{ + document->tell( msg ); +} + +void FormulaElement::removeFormula( FormulaCursor* cursor ) +{ + document->removeFormula( cursor ); +} + +void FormulaElement::insertFormula( FormulaCursor* cursor ) +{ + document->insertFormula( cursor ); +} + +void FormulaElement::calcSizes( const ContextStyle& context, + ContextStyle::TextStyle tstyle, + ContextStyle::IndexStyle istyle, + StyleAttributes& style ) +{ + inherited::calcSizes( context, tstyle, istyle, style ); +} + + +void FormulaElement::draw( TQPainter& painter, const LuPixelRect& r, + const ContextStyle& context, + ContextStyle::TextStyle tstyle, + ContextStyle::IndexStyle istyle, + StyleAttributes& style, + const LuPixelPoint& parentOrigin ) +{ + inherited::draw( painter, r, context, tstyle, istyle, style, parentOrigin ); +} + + +/** + * Calculates the formulas sizes and positions. + */ +void FormulaElement::calcSizes( ContextStyle& context ) +{ + //kdDebug( DEBUGID ) << "FormulaElement::calcSizes" << endl; + if ( ownBaseSize ) { + context.setSizeFactor( static_cast( getBaseSize() )/context.baseSize() ); + } + else { + context.setSizeFactor( 1 ); + } + StyleAttributes style; + calcSizes( context, context.getBaseTextStyle(), ContextStyle::normal, style ); +} + +/** + * Draws the whole thing. + */ +void FormulaElement::draw( TQPainter& painter, const LuPixelRect& r, + ContextStyle& context ) +{ + //kdDebug( DEBUGID ) << "FormulaElement::draw" << endl; + if ( ownBaseSize ) { + context.setSizeFactor( static_cast( getBaseSize() )/context.baseSize() ); + } + else { + context.setSizeFactor( 1 ); + } + StyleAttributes style; + draw( painter, r, context, context.getBaseTextStyle(), + ContextStyle::normal, style, LuPixelPoint() ); +} + +KCommand* FormulaElement::buildCommand( Container* container, Request* request ) +{ + switch ( *request ) { + case req_compactExpression: + return 0; + default: + break; + } + return inherited::buildCommand( container, request ); +} + +const SymbolTable& FormulaElement::getSymbolTable() const +{ + return document->getSymbolTable(); +} + + +TQDomElement FormulaElement::emptyFormulaElement( TQDomDocument& doc ) +{ + TQDomElement element = doc.createElement( getTagName() ); + /* + element.setAttribute( "VERSION", "6" ); + if ( ownBaseSize ) { + element.setAttribute( "BASESIZE", baseSize ); + } + */ + return element; +} + +KCommand* FormulaElement::input( Container* container, TQKeyEvent* event ) +{ + TQChar ch = event->text().at( 0 ); + if ( !ch.isPrint() ) { + int action = event->key(); + //int state = event->state(); + //MoveFlag flag = movementFlag(state); + + switch ( action ) { + case TQt::Key_Return: + case TQt::Key_Enter: { + FormulaCursor* cursor = container->activeCursor(); + insertFormula( cursor ); + return 0; + } + } + } + return inherited::input( container, event ); +} + +/** + * Appends our attributes to the dom element. + */ +void FormulaElement::writeDom(TQDomElement element) +{ + inherited::writeDom(element); + element.setAttribute( "VERSION", "6" ); + if ( ownBaseSize ) { + element.setAttribute( "BASESIZE", baseSize ); + } +} + +/** + * Reads our attributes from the element. + * Returns false if it failed. + */ +bool FormulaElement::readAttributesFromDom(TQDomElement element) +{ + if (!inherited::readAttributesFromDom(element)) { + return false; + } + int version = -1; + TQString versionStr = element.attribute( "VERSION" ); + if ( !versionStr.isNull() ) { + version = versionStr.toInt(); + } + if ( version > -1 ) { + // Version 6 added the MultilineElement (TabMarker) + // Version 5 added under- and overlines + if ( version < 4 ) { + convertNames( element ); + } + } + TQString baseSizeStr = element.attribute( "BASESIZE" ); + if ( !baseSizeStr.isNull() ) { + ownBaseSize = true; + baseSize = baseSizeStr.toInt(); + } + else { + ownBaseSize = false; + } + return true; +} + +/** + * Reads our content from the node. Sets the node to the next node + * that needs to be read. + * Returns false if it failed. + */ +bool FormulaElement::readContentFromDom(TQDomNode& node) +{ + return inherited::readContentFromDom(node); +} + +void FormulaElement::convertNames( TQDomNode node ) +{ + if ( node.isElement() && ( node.nodeName().upper() == "TEXT" ) ) { + TQDomNamedNodeMap attr = node.attributes(); + TQDomAttr ch = attr.namedItem( "CHAR" ).toAttr(); + if ( ch.value() == "\\" ) { + TQDomNode sequence = node.parentNode(); + TQDomDocument doc = sequence.ownerDocument(); + TQDomElement nameseq = doc.createElement( "NAMESEQUENCE" ); + sequence.replaceChild( nameseq, node ); + + bool inName = true; + while ( inName ) { + inName = false; + TQDomNode n = nameseq.nextSibling(); + if ( n.isElement() && ( n.nodeName().upper() == "TEXT" ) ) { + attr = n.attributes(); + ch = attr.namedItem( "CHAR" ).toAttr(); + if ( ch.value().at( 0 ).isLetter() ) { + nameseq.appendChild( sequence.removeChild( n ) ); + inName = true; + } + } + } + } + } + if ( node.hasChildNodes() ) { + TQDomNode n = node.firstChild(); + while ( !n.isNull() ) { + convertNames( n ); + n = n.nextSibling(); + } + } +} + +TQString FormulaElement::toLatex() +{ + return inherited::toLatex(); //Consider $$ sorround +} + +void FormulaElement::writeMathML( TQDomDocument& doc, TQDomNode& parent, bool oasisFormat ) const +{ + TQDomElement de; + if ( !oasisFormat ) { + de = doc.createElementNS( "http://www.w3.org/1998/Math/MathML", + "math" ); + parent.appendChild( de ); + } + else { + TQDomElement element = doc.createElement( "math:semantics" ); + de = doc.createElement( "math:mrow" ); + parent.appendChild( element ); + element.appendChild( de ); + } + for ( uint i = 0; i < countChildren(); ++i ) { + const BasicElement* e = getChild( i ); + e->writeMathML( doc, de, oasisFormat ); + } +} + +KFORMULA_NAMESPACE_END diff --git a/lib/kformula/fractionelement.cc b/lib/kformula/fractionelement.cc deleted file mode 100644 index 9f1125e1..00000000 --- a/lib/kformula/fractionelement.cc +++ /dev/null @@ -1,657 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2001 Andrea Rizzi - Ulrich Kuettler - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - -#include - -#include -#include - -#include "elementvisitor.h" -#include "formulaelement.h" -#include "formulacursor.h" -#include "fractionelement.h" -#include "sequenceelement.h" - -KFORMULA_NAMESPACE_BEGIN -using namespace std; - -FractionElement::FractionElement(BasicElement* parent) : BasicElement(parent), - m_lineThicknessType( NoSize ), - m_numAlign( NoHorizontalAlign ), - m_denomAlign( NoHorizontalAlign ), - m_customBevelled( false ) -{ - numerator = new SequenceElement(this); - denominator = new SequenceElement(this); -} - -FractionElement::~FractionElement() -{ - delete denominator; - delete numerator; -} - -FractionElement::FractionElement( const FractionElement& other ) - : BasicElement( other ), - m_lineThicknessType( other.m_lineThicknessType ), - m_lineThickness( other.m_lineThickness ), - m_numAlign( other.m_numAlign ), - m_denomAlign( other.m_denomAlign ), - m_customBevelled( other.m_customBevelled ), - m_bevelled( other.m_bevelled ) -{ - numerator = new SequenceElement( *( other.numerator ) ); - denominator = new SequenceElement( *( other.denominator ) ); - numerator->setParent( this ); - denominator->setParent( this ); -} - - -bool FractionElement::accept( ElementVisitor* visitor ) -{ - return visitor->visit( this ); -} - -void FractionElement::entered( SequenceElement* child ) -{ - if ( child == numerator ) { - formula()->tell( i18n( "Numerator" ) ); - } - else { - formula()->tell( i18n( "Denominator" ) ); - } -} - - -BasicElement* FractionElement::goToPos( FormulaCursor* cursor, bool& handled, - const LuPixelPoint& point, const LuPixelPoint& parentOrigin ) -{ - BasicElement* e = BasicElement::goToPos(cursor, handled, point, parentOrigin); - if (e != 0) { - LuPixelPoint myPos(parentOrigin.x() + getX(), - parentOrigin.y() + getY()); - e = numerator->goToPos(cursor, handled, point, myPos); - if (e != 0) { - return e; - } - e = denominator->goToPos(cursor, handled, point, myPos); - if (e != 0) { - return e; - } - - luPixel dx = point.x() - myPos.x(); - luPixel dy = point.y() - myPos.y(); - - // the positions after the numerator / denominator - if ((dx > numerator->getX()) && - (dy < numerator->getHeight())) { - numerator->moveLeft(cursor, this); - handled = true; - return numerator; - } - else if ((dx > denominator->getX()) && - (dy > denominator->getY())) { - denominator->moveLeft(cursor, this); - handled = true; - return denominator; - } - - return this; - } - return 0; -} - - -/** - * Calculates our width and height and - * our children's parentPosition. - */ -void FractionElement::calcSizes( const ContextStyle& context, - ContextStyle::TextStyle tstyle, - ContextStyle::IndexStyle istyle, - StyleAttributes& style ) -{ - ContextStyle::TextStyle i_tstyle = context.convertTextStyleFraction( tstyle ); - ContextStyle::IndexStyle u_istyle = context.convertIndexStyleUpper( istyle ); - ContextStyle::IndexStyle l_istyle = context.convertIndexStyleLower( istyle ); - double factor = style.sizeFactor(); - - numerator->calcSizes( context, i_tstyle, u_istyle, style ); - denominator->calcSizes( context, i_tstyle, l_istyle, style ); - - luPixel distY = context.ptToPixelY( context.getThinSpace( tstyle, factor ) ); - - double linethickness = lineThickness( context, factor ); - - setWidth( TQMAX( numerator->getWidth(), denominator->getWidth() ) ); - setHeight( numerator->getHeight() + denominator->getHeight() + - 2*distY + linethickness ); - setBaseline( tqRound( numerator->getHeight() + distY + .5*linethickness - + context.axisHeight( tstyle, factor ) ) ); - - numerator->setX( ( getWidth() - numerator->getWidth() ) / 2 ); - denominator->setX( ( getWidth() - denominator->getWidth() ) / 2 ); - - numerator->setY( 0 ); - denominator->setY( getHeight() - denominator->getHeight() ); -} - - -/** - * Draws the whole element including its children. - * The `parentOrigin' is the point this element's parent starts. - * We can use our parentPosition to get our own origin then. - */ -void FractionElement::draw( TQPainter& painter, const LuPixelRect& r, - const ContextStyle& context, - ContextStyle::TextStyle tstyle, - ContextStyle::IndexStyle istyle, - StyleAttributes& style, - const LuPixelPoint& parentOrigin ) -{ - LuPixelPoint myPos( parentOrigin.x()+getX(), parentOrigin.y()+getY() ); - //if ( !LuPixelRect( myPos.x(), myPos.y(), getWidth(), getHeight() ).intersects( r ) ) - // return; - - numerator->draw( painter, r, context, - context.convertTextStyleFraction( tstyle ), - context.convertIndexStyleUpper( istyle ), style, myPos); - if (denominator) { // Can be temporarily 0 see FractionElement::remove - denominator->draw( painter, r, context, - context.convertTextStyleFraction( tstyle ), - context.convertIndexStyleLower( istyle ), style, - myPos); - } - - if ( withLine() ) { - // TODO: thickness - double factor = style.sizeFactor(); - double linethickness = lineThickness( context, factor ); - painter.setPen( TQPen( style.color(), - context.layoutUnitToPixelY( linethickness ) ) ); - painter.drawLine( context.layoutUnitToPixelX( myPos.x() ), - context.layoutUnitToPixelY( myPos.y() + axis( context, tstyle, factor ) ), - context.layoutUnitToPixelX( myPos.x() + getWidth() ), - context.layoutUnitToPixelY( myPos.y() + axis( context, tstyle, factor ) ) ); - } -} - - -void FractionElement::dispatchFontCommand( FontCommand* cmd ) -{ - numerator->dispatchFontCommand( cmd ); - denominator->dispatchFontCommand( cmd ); -} - -/** - * Enters this element while moving to the left starting inside - * the element `from'. Searches for a cursor position inside - * this element or to the left of it. - */ -void FractionElement::moveLeft(FormulaCursor* cursor, BasicElement* from) -{ - if (cursor->isSelectionMode()) { - getParent()->moveLeft(cursor, this); - } - else { - bool linear = cursor->getLinearMovement(); - if (from == getParent()) { - if (linear) { - denominator->moveLeft(cursor, this); - } - else { - numerator->moveLeft(cursor, this); - } - } - else if (from == denominator) { - numerator->moveLeft(cursor, this); - } - else { - getParent()->moveLeft(cursor, this); - } - } -} - - -/** - * Enters this element while moving to the right starting inside - * the element `from'. Searches for a cursor position inside - * this element or to the right of it. - */ -void FractionElement::moveRight(FormulaCursor* cursor, BasicElement* from) -{ - if (cursor->isSelectionMode()) { - getParent()->moveRight(cursor, this); - } - else { - bool linear = cursor->getLinearMovement(); - if (from == getParent()) { - numerator->moveRight(cursor, this); - } - else if (from == numerator) { - if (linear) { - denominator->moveRight(cursor, this); - } - else { - getParent()->moveRight(cursor, this); - } - } - else { - getParent()->moveRight(cursor, this); - } - } -} - - -/** - * Enters this element while moving up starting inside - * the element `from'. Searches for a cursor position inside - * this element or above it. - */ -void FractionElement::moveUp(FormulaCursor* cursor, BasicElement* from) -{ - if (cursor->isSelectionMode()) { - getParent()->moveUp(cursor, this); - } - else { - if (from == getParent()) { - denominator->moveRight(cursor, this); - } - else if (from == denominator) { - numerator->moveRight(cursor, this); - } - else { - getParent()->moveUp(cursor, this); - } - } -} - - -/** - * Enters this element while moving down starting inside - * the element `from'. Searches for a cursor position inside - * this element or below it. - */ -void FractionElement::moveDown(FormulaCursor* cursor, BasicElement* from) -{ - if (cursor->isSelectionMode()) { - getParent()->moveDown(cursor, this); - } - else { - if (from == getParent()) { - numerator->moveRight(cursor, this); - } - else if (from == numerator) { - denominator->moveRight(cursor, this); - } - else { - getParent()->moveDown(cursor, this); - } - } -} - - -/** - * Reinserts the denominator if it has been removed. - */ -void FractionElement::insert(FormulaCursor* cursor, - TQPtrList& newChildren, - Direction direction) -{ - if (cursor->getPos() == denominatorPos) { - denominator = static_cast(newChildren.take(0)); - denominator->setParent(this); - - if (direction == beforeCursor) { - denominator->moveLeft(cursor, this); - } - else { - denominator->moveRight(cursor, this); - } - cursor->setSelection(false); - formula()->changed(); - } -} - - -/** - * Removes all selected children and returns them. Places the - * cursor to where the children have been. - * - * We remove ourselve if we are requested to remove our numerator. - * - * It is possible to remove the denominator. But after this we - * are senseless and the caller is required to replace us. - */ -void FractionElement::remove(FormulaCursor* cursor, - TQPtrList& removedChildren, - Direction direction) -{ - switch (cursor->getPos()) { - case numeratorPos: - getParent()->selectChild(cursor, this); - getParent()->remove(cursor, removedChildren, direction); - break; - case denominatorPos: - removedChildren.append(denominator); - formula()->elementRemoval(denominator); - denominator = 0; - cursor->setTo(this, denominatorPos); - formula()->changed(); - break; - } -} - - -/** - * Returns wether the element has no more useful - * children (except its main child) and should therefore - * be replaced by its main child's content. - */ -bool FractionElement::isSenseless() -{ - return denominator == 0; -} - - -// main child -// -// If an element has children one has to become the main one. - -SequenceElement* FractionElement::getMainChild() -{ - return numerator; -} - -// void FractionElement::setMainChild(SequenceElement* child) -// { -// formula()->elementRemoval(numerator); -// numerator = child; -// numerator->setParent(this); -// formula()->changed(); -// } - - -/** - * Sets the cursor to select the child. The mark is placed before, - * the position behind it. - */ -void FractionElement::selectChild(FormulaCursor* cursor, BasicElement* child) -{ - if (child == numerator) { - cursor->setTo(this, numeratorPos); - } - else if (child == denominator) { - cursor->setTo(this, denominatorPos); - } -} - - -/** - * Appends our attributes to the dom element. - */ -void FractionElement::writeDom(TQDomElement element) -{ - BasicElement::writeDom(element); - - TQDomDocument doc = element.ownerDocument(); - if (!withLine()) element.setAttribute("NOLINE", 1); - - TQDomElement num = doc.createElement("NUMERATOR"); - num.appendChild(numerator->getElementDom(doc)); - element.appendChild(num); - - TQDomElement den = doc.createElement("DENOMINATOR"); - den.appendChild(denominator->getElementDom(doc)); - element.appendChild(den); -} - -/** - * Reads our attributes from the element. - * Returns false if it failed. - */ -bool FractionElement::readAttributesFromDom(TQDomElement element) -{ - if (!BasicElement::readAttributesFromDom(element)) { - return false; - } - TQString lineStr = element.attribute("NOLINE"); - if(!lineStr.isNull()) { - m_lineThicknessType = RelativeSize; - m_lineThickness = lineStr.toInt(); - } - return true; -} - -/** - * Reads our attributes from the MathML element. - * Returns false if it failed. - */ -bool FractionElement::readAttributesFromMathMLDom(const TQDomElement& element) -{ - if ( ! BasicElement::readAttributesFromMathMLDom( element ) ) { - return false; - } - TQString linethicknessStr = element.attribute( "linethickness" ).lower(); - if ( ! linethicknessStr.isNull() ) { - if ( linethicknessStr == "thin" ) { - m_lineThicknessType = RelativeSize; - m_lineThickness = 0.5; // ### Arbitrary size - } - else if ( linethicknessStr == "medium" ) { - m_lineThicknessType = RelativeSize; - m_lineThickness = 1.0; - } - else if ( linethicknessStr == "thick" ) { - m_lineThicknessType = RelativeSize; - m_lineThickness = 2.0; // ### Arbitrary size - } - else { - m_lineThickness = getSize( linethicknessStr, &m_lineThicknessType ); - } - } - TQString numalignStr = element.attribute( "numalign" ).lower(); - if ( ! numalignStr.isNull() ) { - if ( numalignStr == "left" ) { - m_numAlign = LeftHorizontalAlign; - } - else if ( numalignStr == "center" ) { - m_numAlign = CenterHorizontalAlign; - } - else if ( numalignStr == "right" ) { - m_numAlign = RightHorizontalAlign; - } - } - TQString denomalignStr = element.attribute( "denomalign" ).lower(); - if ( ! denomalignStr.isNull() ) { - if ( denomalignStr == "left" ) { - m_denomAlign = LeftHorizontalAlign; - } - else if ( denomalignStr == "center" ) { - m_denomAlign = CenterHorizontalAlign; - } - else if ( denomalignStr == "right" ) { - m_denomAlign = RightHorizontalAlign; - } - } - TQString bevelledStr = element.attribute( "bevelled" ).lower(); - if ( ! bevelledStr.isNull() ) { - m_customBevelled = true; - if ( bevelledStr == "true" ) { - m_bevelled = true; - } - else { - m_bevelled = false; - } - } - - return true; -} - -/** - * Reads our content from the node. Sets the node to the next node - * that needs to be read. - * Returns false if it failed. - */ -bool FractionElement::readContentFromDom(TQDomNode& node) -{ - if (!BasicElement::readContentFromDom(node)) { - return false; - } - - if ( !buildChild( numerator, node, "NUMERATOR" ) ) { - kdWarning( DEBUGID ) << "Empty numerator in FractionElement." << endl; - return false; - } - node = node.nextSibling(); - - if ( !buildChild( denominator, node, "DENOMINATOR" ) ) { - kdWarning( DEBUGID ) << "Empty denominator in FractionElement." << endl; - return false; - } - node = node.nextSibling(); - - return true; -} - -/** - * Reads our content from the MathML node. Sets the node to the next node - * that needs to be read. - * Returns false if it failed. - */ -int FractionElement::readContentFromMathMLDom(TQDomNode& node) -{ - if ( BasicElement::readContentFromMathMLDom( node ) == -1 ) { - return -1; - } - - int numeratorNumber = numerator->buildMathMLChild( node ); - if ( numeratorNumber == -1 ) { - kdWarning( DEBUGID ) << "Empty numerator in FractionElement." << endl; - return -1; - } - for (int i = 0; i < numeratorNumber; i++ ) { - if ( node.isNull() ) { - return -1; - } - node = node.nextSibling(); - } - - if ( denominator->buildMathMLChild( node ) == -1 ) { - kdWarning( DEBUGID ) << "Empty denominator in FractionElement." << endl; - return -1; - } - - return 1; -} - -TQString FractionElement::toLatex() -{ - if ( withLine() ) { - return "\\frac{" + numerator->toLatex() +"}{" + denominator->toLatex() + "}"; - } - else { - return "{" + numerator->toLatex() + "\\atop " + denominator->toLatex() + "}"; - } -} - -TQString FractionElement::formulaString() -{ - return "(" + numerator->formulaString() + ")/(" + denominator->formulaString() + ")"; -} - -void FractionElement::writeMathMLAttributes( TQDomElement& element ) const -{ - switch ( m_lineThicknessType ) { - case AbsoluteSize: - element.setAttribute( "linethickness", TQString( "%1pt" ).arg( m_lineThickness ) ); - break; - case RelativeSize: - element.setAttribute( "linethickness", TQString( "%1%" ).arg( m_lineThickness * 100.0 ) ); - break; - case PixelSize: - element.setAttribute( "linethickness", TQString( "%1px" ).arg( m_lineThickness ) ); - break; - default: - break; - } - - switch ( m_numAlign ) { - case LeftHorizontalAlign: - element.setAttribute( "numalign", "left" ); - break; - case CenterHorizontalAlign: - element.setAttribute( "numalign", "center" ); - break; - case RightHorizontalAlign: - element.setAttribute( "numalign", "right" ); - break; - default: - break; - } - - switch ( m_denomAlign ) { - case LeftHorizontalAlign: - element.setAttribute( "denomalign", "left" ); - break; - case CenterHorizontalAlign: - element.setAttribute( "denomalign", "center" ); - break; - case RightHorizontalAlign: - element.setAttribute( "denomalign", "right" ); - break; - default: - break; - } - - if ( m_customBevelled ) { - element.setAttribute( "bevelled", m_bevelled ? "true" : "false" ); - } -} - -void FractionElement::writeMathMLContent( TQDomDocument& doc, - TQDomElement& element, - bool oasisFormat ) const -{ - numerator->writeMathML( doc, element, oasisFormat ); - denominator->writeMathML( doc, element, oasisFormat ); -} - -double FractionElement::lineThickness( const ContextStyle& context, double factor ) -{ - double linethickness = context.getLineWidth( factor ); - switch ( m_lineThicknessType ) { - case AbsoluteSize: - linethickness = context.ptToLayoutUnitPixX( m_lineThickness ); - break; - case RelativeSize: - linethickness *= m_lineThickness; - break; - case PixelSize: - linethickness = m_lineThickness; - break; - default: - break; - } - return linethickness; -} - - -KFORMULA_NAMESPACE_END diff --git a/lib/kformula/fractionelement.cpp b/lib/kformula/fractionelement.cpp new file mode 100644 index 00000000..9f1125e1 --- /dev/null +++ b/lib/kformula/fractionelement.cpp @@ -0,0 +1,657 @@ +/* This file is part of the KDE project + Copyright (C) 2001 Andrea Rizzi + Ulrich Kuettler + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include + +#include +#include + +#include "elementvisitor.h" +#include "formulaelement.h" +#include "formulacursor.h" +#include "fractionelement.h" +#include "sequenceelement.h" + +KFORMULA_NAMESPACE_BEGIN +using namespace std; + +FractionElement::FractionElement(BasicElement* parent) : BasicElement(parent), + m_lineThicknessType( NoSize ), + m_numAlign( NoHorizontalAlign ), + m_denomAlign( NoHorizontalAlign ), + m_customBevelled( false ) +{ + numerator = new SequenceElement(this); + denominator = new SequenceElement(this); +} + +FractionElement::~FractionElement() +{ + delete denominator; + delete numerator; +} + +FractionElement::FractionElement( const FractionElement& other ) + : BasicElement( other ), + m_lineThicknessType( other.m_lineThicknessType ), + m_lineThickness( other.m_lineThickness ), + m_numAlign( other.m_numAlign ), + m_denomAlign( other.m_denomAlign ), + m_customBevelled( other.m_customBevelled ), + m_bevelled( other.m_bevelled ) +{ + numerator = new SequenceElement( *( other.numerator ) ); + denominator = new SequenceElement( *( other.denominator ) ); + numerator->setParent( this ); + denominator->setParent( this ); +} + + +bool FractionElement::accept( ElementVisitor* visitor ) +{ + return visitor->visit( this ); +} + +void FractionElement::entered( SequenceElement* child ) +{ + if ( child == numerator ) { + formula()->tell( i18n( "Numerator" ) ); + } + else { + formula()->tell( i18n( "Denominator" ) ); + } +} + + +BasicElement* FractionElement::goToPos( FormulaCursor* cursor, bool& handled, + const LuPixelPoint& point, const LuPixelPoint& parentOrigin ) +{ + BasicElement* e = BasicElement::goToPos(cursor, handled, point, parentOrigin); + if (e != 0) { + LuPixelPoint myPos(parentOrigin.x() + getX(), + parentOrigin.y() + getY()); + e = numerator->goToPos(cursor, handled, point, myPos); + if (e != 0) { + return e; + } + e = denominator->goToPos(cursor, handled, point, myPos); + if (e != 0) { + return e; + } + + luPixel dx = point.x() - myPos.x(); + luPixel dy = point.y() - myPos.y(); + + // the positions after the numerator / denominator + if ((dx > numerator->getX()) && + (dy < numerator->getHeight())) { + numerator->moveLeft(cursor, this); + handled = true; + return numerator; + } + else if ((dx > denominator->getX()) && + (dy > denominator->getY())) { + denominator->moveLeft(cursor, this); + handled = true; + return denominator; + } + + return this; + } + return 0; +} + + +/** + * Calculates our width and height and + * our children's parentPosition. + */ +void FractionElement::calcSizes( const ContextStyle& context, + ContextStyle::TextStyle tstyle, + ContextStyle::IndexStyle istyle, + StyleAttributes& style ) +{ + ContextStyle::TextStyle i_tstyle = context.convertTextStyleFraction( tstyle ); + ContextStyle::IndexStyle u_istyle = context.convertIndexStyleUpper( istyle ); + ContextStyle::IndexStyle l_istyle = context.convertIndexStyleLower( istyle ); + double factor = style.sizeFactor(); + + numerator->calcSizes( context, i_tstyle, u_istyle, style ); + denominator->calcSizes( context, i_tstyle, l_istyle, style ); + + luPixel distY = context.ptToPixelY( context.getThinSpace( tstyle, factor ) ); + + double linethickness = lineThickness( context, factor ); + + setWidth( TQMAX( numerator->getWidth(), denominator->getWidth() ) ); + setHeight( numerator->getHeight() + denominator->getHeight() + + 2*distY + linethickness ); + setBaseline( tqRound( numerator->getHeight() + distY + .5*linethickness + + context.axisHeight( tstyle, factor ) ) ); + + numerator->setX( ( getWidth() - numerator->getWidth() ) / 2 ); + denominator->setX( ( getWidth() - denominator->getWidth() ) / 2 ); + + numerator->setY( 0 ); + denominator->setY( getHeight() - denominator->getHeight() ); +} + + +/** + * Draws the whole element including its children. + * The `parentOrigin' is the point this element's parent starts. + * We can use our parentPosition to get our own origin then. + */ +void FractionElement::draw( TQPainter& painter, const LuPixelRect& r, + const ContextStyle& context, + ContextStyle::TextStyle tstyle, + ContextStyle::IndexStyle istyle, + StyleAttributes& style, + const LuPixelPoint& parentOrigin ) +{ + LuPixelPoint myPos( parentOrigin.x()+getX(), parentOrigin.y()+getY() ); + //if ( !LuPixelRect( myPos.x(), myPos.y(), getWidth(), getHeight() ).intersects( r ) ) + // return; + + numerator->draw( painter, r, context, + context.convertTextStyleFraction( tstyle ), + context.convertIndexStyleUpper( istyle ), style, myPos); + if (denominator) { // Can be temporarily 0 see FractionElement::remove + denominator->draw( painter, r, context, + context.convertTextStyleFraction( tstyle ), + context.convertIndexStyleLower( istyle ), style, + myPos); + } + + if ( withLine() ) { + // TODO: thickness + double factor = style.sizeFactor(); + double linethickness = lineThickness( context, factor ); + painter.setPen( TQPen( style.color(), + context.layoutUnitToPixelY( linethickness ) ) ); + painter.drawLine( context.layoutUnitToPixelX( myPos.x() ), + context.layoutUnitToPixelY( myPos.y() + axis( context, tstyle, factor ) ), + context.layoutUnitToPixelX( myPos.x() + getWidth() ), + context.layoutUnitToPixelY( myPos.y() + axis( context, tstyle, factor ) ) ); + } +} + + +void FractionElement::dispatchFontCommand( FontCommand* cmd ) +{ + numerator->dispatchFontCommand( cmd ); + denominator->dispatchFontCommand( cmd ); +} + +/** + * Enters this element while moving to the left starting inside + * the element `from'. Searches for a cursor position inside + * this element or to the left of it. + */ +void FractionElement::moveLeft(FormulaCursor* cursor, BasicElement* from) +{ + if (cursor->isSelectionMode()) { + getParent()->moveLeft(cursor, this); + } + else { + bool linear = cursor->getLinearMovement(); + if (from == getParent()) { + if (linear) { + denominator->moveLeft(cursor, this); + } + else { + numerator->moveLeft(cursor, this); + } + } + else if (from == denominator) { + numerator->moveLeft(cursor, this); + } + else { + getParent()->moveLeft(cursor, this); + } + } +} + + +/** + * Enters this element while moving to the right starting inside + * the element `from'. Searches for a cursor position inside + * this element or to the right of it. + */ +void FractionElement::moveRight(FormulaCursor* cursor, BasicElement* from) +{ + if (cursor->isSelectionMode()) { + getParent()->moveRight(cursor, this); + } + else { + bool linear = cursor->getLinearMovement(); + if (from == getParent()) { + numerator->moveRight(cursor, this); + } + else if (from == numerator) { + if (linear) { + denominator->moveRight(cursor, this); + } + else { + getParent()->moveRight(cursor, this); + } + } + else { + getParent()->moveRight(cursor, this); + } + } +} + + +/** + * Enters this element while moving up starting inside + * the element `from'. Searches for a cursor position inside + * this element or above it. + */ +void FractionElement::moveUp(FormulaCursor* cursor, BasicElement* from) +{ + if (cursor->isSelectionMode()) { + getParent()->moveUp(cursor, this); + } + else { + if (from == getParent()) { + denominator->moveRight(cursor, this); + } + else if (from == denominator) { + numerator->moveRight(cursor, this); + } + else { + getParent()->moveUp(cursor, this); + } + } +} + + +/** + * Enters this element while moving down starting inside + * the element `from'. Searches for a cursor position inside + * this element or below it. + */ +void FractionElement::moveDown(FormulaCursor* cursor, BasicElement* from) +{ + if (cursor->isSelectionMode()) { + getParent()->moveDown(cursor, this); + } + else { + if (from == getParent()) { + numerator->moveRight(cursor, this); + } + else if (from == numerator) { + denominator->moveRight(cursor, this); + } + else { + getParent()->moveDown(cursor, this); + } + } +} + + +/** + * Reinserts the denominator if it has been removed. + */ +void FractionElement::insert(FormulaCursor* cursor, + TQPtrList& newChildren, + Direction direction) +{ + if (cursor->getPos() == denominatorPos) { + denominator = static_cast(newChildren.take(0)); + denominator->setParent(this); + + if (direction == beforeCursor) { + denominator->moveLeft(cursor, this); + } + else { + denominator->moveRight(cursor, this); + } + cursor->setSelection(false); + formula()->changed(); + } +} + + +/** + * Removes all selected children and returns them. Places the + * cursor to where the children have been. + * + * We remove ourselve if we are requested to remove our numerator. + * + * It is possible to remove the denominator. But after this we + * are senseless and the caller is required to replace us. + */ +void FractionElement::remove(FormulaCursor* cursor, + TQPtrList& removedChildren, + Direction direction) +{ + switch (cursor->getPos()) { + case numeratorPos: + getParent()->selectChild(cursor, this); + getParent()->remove(cursor, removedChildren, direction); + break; + case denominatorPos: + removedChildren.append(denominator); + formula()->elementRemoval(denominator); + denominator = 0; + cursor->setTo(this, denominatorPos); + formula()->changed(); + break; + } +} + + +/** + * Returns wether the element has no more useful + * children (except its main child) and should therefore + * be replaced by its main child's content. + */ +bool FractionElement::isSenseless() +{ + return denominator == 0; +} + + +// main child +// +// If an element has children one has to become the main one. + +SequenceElement* FractionElement::getMainChild() +{ + return numerator; +} + +// void FractionElement::setMainChild(SequenceElement* child) +// { +// formula()->elementRemoval(numerator); +// numerator = child; +// numerator->setParent(this); +// formula()->changed(); +// } + + +/** + * Sets the cursor to select the child. The mark is placed before, + * the position behind it. + */ +void FractionElement::selectChild(FormulaCursor* cursor, BasicElement* child) +{ + if (child == numerator) { + cursor->setTo(this, numeratorPos); + } + else if (child == denominator) { + cursor->setTo(this, denominatorPos); + } +} + + +/** + * Appends our attributes to the dom element. + */ +void FractionElement::writeDom(TQDomElement element) +{ + BasicElement::writeDom(element); + + TQDomDocument doc = element.ownerDocument(); + if (!withLine()) element.setAttribute("NOLINE", 1); + + TQDomElement num = doc.createElement("NUMERATOR"); + num.appendChild(numerator->getElementDom(doc)); + element.appendChild(num); + + TQDomElement den = doc.createElement("DENOMINATOR"); + den.appendChild(denominator->getElementDom(doc)); + element.appendChild(den); +} + +/** + * Reads our attributes from the element. + * Returns false if it failed. + */ +bool FractionElement::readAttributesFromDom(TQDomElement element) +{ + if (!BasicElement::readAttributesFromDom(element)) { + return false; + } + TQString lineStr = element.attribute("NOLINE"); + if(!lineStr.isNull()) { + m_lineThicknessType = RelativeSize; + m_lineThickness = lineStr.toInt(); + } + return true; +} + +/** + * Reads our attributes from the MathML element. + * Returns false if it failed. + */ +bool FractionElement::readAttributesFromMathMLDom(const TQDomElement& element) +{ + if ( ! BasicElement::readAttributesFromMathMLDom( element ) ) { + return false; + } + TQString linethicknessStr = element.attribute( "linethickness" ).lower(); + if ( ! linethicknessStr.isNull() ) { + if ( linethicknessStr == "thin" ) { + m_lineThicknessType = RelativeSize; + m_lineThickness = 0.5; // ### Arbitrary size + } + else if ( linethicknessStr == "medium" ) { + m_lineThicknessType = RelativeSize; + m_lineThickness = 1.0; + } + else if ( linethicknessStr == "thick" ) { + m_lineThicknessType = RelativeSize; + m_lineThickness = 2.0; // ### Arbitrary size + } + else { + m_lineThickness = getSize( linethicknessStr, &m_lineThicknessType ); + } + } + TQString numalignStr = element.attribute( "numalign" ).lower(); + if ( ! numalignStr.isNull() ) { + if ( numalignStr == "left" ) { + m_numAlign = LeftHorizontalAlign; + } + else if ( numalignStr == "center" ) { + m_numAlign = CenterHorizontalAlign; + } + else if ( numalignStr == "right" ) { + m_numAlign = RightHorizontalAlign; + } + } + TQString denomalignStr = element.attribute( "denomalign" ).lower(); + if ( ! denomalignStr.isNull() ) { + if ( denomalignStr == "left" ) { + m_denomAlign = LeftHorizontalAlign; + } + else if ( denomalignStr == "center" ) { + m_denomAlign = CenterHorizontalAlign; + } + else if ( denomalignStr == "right" ) { + m_denomAlign = RightHorizontalAlign; + } + } + TQString bevelledStr = element.attribute( "bevelled" ).lower(); + if ( ! bevelledStr.isNull() ) { + m_customBevelled = true; + if ( bevelledStr == "true" ) { + m_bevelled = true; + } + else { + m_bevelled = false; + } + } + + return true; +} + +/** + * Reads our content from the node. Sets the node to the next node + * that needs to be read. + * Returns false if it failed. + */ +bool FractionElement::readContentFromDom(TQDomNode& node) +{ + if (!BasicElement::readContentFromDom(node)) { + return false; + } + + if ( !buildChild( numerator, node, "NUMERATOR" ) ) { + kdWarning( DEBUGID ) << "Empty numerator in FractionElement." << endl; + return false; + } + node = node.nextSibling(); + + if ( !buildChild( denominator, node, "DENOMINATOR" ) ) { + kdWarning( DEBUGID ) << "Empty denominator in FractionElement." << endl; + return false; + } + node = node.nextSibling(); + + return true; +} + +/** + * Reads our content from the MathML node. Sets the node to the next node + * that needs to be read. + * Returns false if it failed. + */ +int FractionElement::readContentFromMathMLDom(TQDomNode& node) +{ + if ( BasicElement::readContentFromMathMLDom( node ) == -1 ) { + return -1; + } + + int numeratorNumber = numerator->buildMathMLChild( node ); + if ( numeratorNumber == -1 ) { + kdWarning( DEBUGID ) << "Empty numerator in FractionElement." << endl; + return -1; + } + for (int i = 0; i < numeratorNumber; i++ ) { + if ( node.isNull() ) { + return -1; + } + node = node.nextSibling(); + } + + if ( denominator->buildMathMLChild( node ) == -1 ) { + kdWarning( DEBUGID ) << "Empty denominator in FractionElement." << endl; + return -1; + } + + return 1; +} + +TQString FractionElement::toLatex() +{ + if ( withLine() ) { + return "\\frac{" + numerator->toLatex() +"}{" + denominator->toLatex() + "}"; + } + else { + return "{" + numerator->toLatex() + "\\atop " + denominator->toLatex() + "}"; + } +} + +TQString FractionElement::formulaString() +{ + return "(" + numerator->formulaString() + ")/(" + denominator->formulaString() + ")"; +} + +void FractionElement::writeMathMLAttributes( TQDomElement& element ) const +{ + switch ( m_lineThicknessType ) { + case AbsoluteSize: + element.setAttribute( "linethickness", TQString( "%1pt" ).arg( m_lineThickness ) ); + break; + case RelativeSize: + element.setAttribute( "linethickness", TQString( "%1%" ).arg( m_lineThickness * 100.0 ) ); + break; + case PixelSize: + element.setAttribute( "linethickness", TQString( "%1px" ).arg( m_lineThickness ) ); + break; + default: + break; + } + + switch ( m_numAlign ) { + case LeftHorizontalAlign: + element.setAttribute( "numalign", "left" ); + break; + case CenterHorizontalAlign: + element.setAttribute( "numalign", "center" ); + break; + case RightHorizontalAlign: + element.setAttribute( "numalign", "right" ); + break; + default: + break; + } + + switch ( m_denomAlign ) { + case LeftHorizontalAlign: + element.setAttribute( "denomalign", "left" ); + break; + case CenterHorizontalAlign: + element.setAttribute( "denomalign", "center" ); + break; + case RightHorizontalAlign: + element.setAttribute( "denomalign", "right" ); + break; + default: + break; + } + + if ( m_customBevelled ) { + element.setAttribute( "bevelled", m_bevelled ? "true" : "false" ); + } +} + +void FractionElement::writeMathMLContent( TQDomDocument& doc, + TQDomElement& element, + bool oasisFormat ) const +{ + numerator->writeMathML( doc, element, oasisFormat ); + denominator->writeMathML( doc, element, oasisFormat ); +} + +double FractionElement::lineThickness( const ContextStyle& context, double factor ) +{ + double linethickness = context.getLineWidth( factor ); + switch ( m_lineThicknessType ) { + case AbsoluteSize: + linethickness = context.ptToLayoutUnitPixX( m_lineThickness ); + break; + case RelativeSize: + linethickness *= m_lineThickness; + break; + case PixelSize: + linethickness = m_lineThickness; + break; + default: + break; + } + return linethickness; +} + + +KFORMULA_NAMESPACE_END diff --git a/lib/kformula/glyphelement.cc b/lib/kformula/glyphelement.cc deleted file mode 100644 index 709609cf..00000000 --- a/lib/kformula/glyphelement.cc +++ /dev/null @@ -1,159 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2006 Alfredo Beaumont Sainz - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - -#include -#include - -#include "fontstyle.h" -#include "glyphelement.h" - -KFORMULA_NAMESPACE_BEGIN - -GlyphElement::GlyphElement( BasicElement* parent ) : TextElement( ' ', false, parent ) { -} - -bool GlyphElement::readAttributesFromMathMLDom( const TQDomElement& element ) -{ - if ( !BasicElement::readAttributesFromMathMLDom( element ) ) { - return false; - } - - // MathML Section 3.2.9.2 - m_fontFamily = element.attribute( "fontfamily" ); - if ( m_fontFamily.isNull() ) { - kdWarning( DEBUGID ) << "Required attribute fontfamily not found in glyph element\n"; - return false; - } - TQString indexStr = element.attribute( "index" ); - if ( indexStr.isNull() ) { - kdWarning( DEBUGID ) << "Required attribute index not found in glyph element\n"; - return false; - } - bool ok; - ushort index = indexStr.toUShort( &ok ); - if ( ! ok ) { - kdWarning( DEBUGID ) << "Invalid index value in glyph element\n"; - return false; - } - m_char = TQChar( index ); - - m_alt = element.attribute( "alt" ); - if ( m_alt.isNull() ) { - kdWarning( DEBUGID ) << "Required attribute alt not found in glyph element\n"; - return false; - } - - TQStringList missing; - FontStyle::testFont( missing, m_fontFamily.lower() ); - m_hasFont = missing.isEmpty(); - - return true; -} - - -/** - * Calculates our width and height and - * our children's parentPosition. - */ -void GlyphElement::calcSizes( const ContextStyle& context, - ContextStyle::TextStyle tstyle, - ContextStyle::IndexStyle /*istyle*/, - StyleAttributes& style ) -{ - double factor = style.sizeFactor(); - luPt mySize = context.getAdjustedSize( tstyle, factor ); - TQRect bound; - - if ( m_hasFont ) { - TQFont font( m_fontFamily ); - font.setPointSizeFloat( context.layoutUnitPtToPt( mySize ) ); - TQFontMetrics fm ( font ); - bound = fm.boundingRect( m_char ); - setWidth( context.ptToLayoutUnitPt( fm.width( m_char ) ) ); - } - else { - TQFont font( context.getDefaultFont() ); - font.setPointSizeFloat( context.layoutUnitPtToPt( mySize ) ); - TQFontMetrics fm ( font ); - bound = fm.boundingRect( m_alt ); - setWidth( context.ptToLayoutUnitPt( fm.width( m_alt ) ) ); - } - setHeight( context.ptToLayoutUnitPt( bound.height() ) ); - setBaseline( context.ptToLayoutUnitPt( -bound.top() ) ); - - // There are some glyphs in TeX that have - // baseline==0. (\int, \sum, \prod) - if ( getBaseline() == 0 ) { - setBaseline( -1 ); - } -} - -/** - * Draws the whole element including its children. - * The `parentOrigin' is the point this element's parent starts. - * We can use our parentPosition to get our own origin then. - */ -void GlyphElement::draw( TQPainter& painter, const LuPixelRect& /*r*/, - const ContextStyle& context, - ContextStyle::TextStyle tstyle, - ContextStyle::IndexStyle /*istyle*/, - StyleAttributes& style, - const LuPixelPoint& parentOrigin ) -{ - LuPixelPoint myPos( parentOrigin.x()+getX(), parentOrigin.y()+getY() ); - //if ( !LuPixelRect( myPos.x(), myPos.y(), getWidth(), getHeight() ).intersects( r ) ) - // return; - - double factor = style.sizeFactor(); - luPt mySize = context.getAdjustedSize( tstyle, factor ); - TQFont font; - TQString text; - - if ( m_hasFont ) { - painter.setPen( style.color() ); - setCharStyle( style.charStyle() ); - setCharFamily( style.charFamily() ); - font = TQFont( m_fontFamily ); - text = m_char; - painter.fillRect( context.layoutUnitToPixelX( myPos.x() ), - context.layoutUnitToPixelY( myPos.y() ), - context.layoutUnitToPixelX( getWidth() ), - context.layoutUnitToPixelY( getHeight() ), - style.background() ); - } - else { - painter.setPen( context.getErrorColor() ); - font = context.getDefaultFont(); - text = m_alt; - } - font.setPointSizeFloat( context.layoutUnitToFontSize( mySize, false ) ); - painter.setFont( font ); - painter.drawText( context.layoutUnitToPixelX( myPos.x() ), - context.layoutUnitToPixelY( myPos.y()+getBaseline() ), - text ); -} - -void GlyphElement::writeMathMLAttributes( TQDomElement& element ) const -{ - element.setAttribute( "fontfamily", m_fontFamily ); - element.setAttribute( "index", m_char.unicode() ); - element.setAttribute( "alt", m_alt ); -} - -KFORMULA_NAMESPACE_END diff --git a/lib/kformula/glyphelement.cpp b/lib/kformula/glyphelement.cpp new file mode 100644 index 00000000..709609cf --- /dev/null +++ b/lib/kformula/glyphelement.cpp @@ -0,0 +1,159 @@ +/* This file is part of the KDE project + Copyright (C) 2006 Alfredo Beaumont Sainz + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include + +#include "fontstyle.h" +#include "glyphelement.h" + +KFORMULA_NAMESPACE_BEGIN + +GlyphElement::GlyphElement( BasicElement* parent ) : TextElement( ' ', false, parent ) { +} + +bool GlyphElement::readAttributesFromMathMLDom( const TQDomElement& element ) +{ + if ( !BasicElement::readAttributesFromMathMLDom( element ) ) { + return false; + } + + // MathML Section 3.2.9.2 + m_fontFamily = element.attribute( "fontfamily" ); + if ( m_fontFamily.isNull() ) { + kdWarning( DEBUGID ) << "Required attribute fontfamily not found in glyph element\n"; + return false; + } + TQString indexStr = element.attribute( "index" ); + if ( indexStr.isNull() ) { + kdWarning( DEBUGID ) << "Required attribute index not found in glyph element\n"; + return false; + } + bool ok; + ushort index = indexStr.toUShort( &ok ); + if ( ! ok ) { + kdWarning( DEBUGID ) << "Invalid index value in glyph element\n"; + return false; + } + m_char = TQChar( index ); + + m_alt = element.attribute( "alt" ); + if ( m_alt.isNull() ) { + kdWarning( DEBUGID ) << "Required attribute alt not found in glyph element\n"; + return false; + } + + TQStringList missing; + FontStyle::testFont( missing, m_fontFamily.lower() ); + m_hasFont = missing.isEmpty(); + + return true; +} + + +/** + * Calculates our width and height and + * our children's parentPosition. + */ +void GlyphElement::calcSizes( const ContextStyle& context, + ContextStyle::TextStyle tstyle, + ContextStyle::IndexStyle /*istyle*/, + StyleAttributes& style ) +{ + double factor = style.sizeFactor(); + luPt mySize = context.getAdjustedSize( tstyle, factor ); + TQRect bound; + + if ( m_hasFont ) { + TQFont font( m_fontFamily ); + font.setPointSizeFloat( context.layoutUnitPtToPt( mySize ) ); + TQFontMetrics fm ( font ); + bound = fm.boundingRect( m_char ); + setWidth( context.ptToLayoutUnitPt( fm.width( m_char ) ) ); + } + else { + TQFont font( context.getDefaultFont() ); + font.setPointSizeFloat( context.layoutUnitPtToPt( mySize ) ); + TQFontMetrics fm ( font ); + bound = fm.boundingRect( m_alt ); + setWidth( context.ptToLayoutUnitPt( fm.width( m_alt ) ) ); + } + setHeight( context.ptToLayoutUnitPt( bound.height() ) ); + setBaseline( context.ptToLayoutUnitPt( -bound.top() ) ); + + // There are some glyphs in TeX that have + // baseline==0. (\int, \sum, \prod) + if ( getBaseline() == 0 ) { + setBaseline( -1 ); + } +} + +/** + * Draws the whole element including its children. + * The `parentOrigin' is the point this element's parent starts. + * We can use our parentPosition to get our own origin then. + */ +void GlyphElement::draw( TQPainter& painter, const LuPixelRect& /*r*/, + const ContextStyle& context, + ContextStyle::TextStyle tstyle, + ContextStyle::IndexStyle /*istyle*/, + StyleAttributes& style, + const LuPixelPoint& parentOrigin ) +{ + LuPixelPoint myPos( parentOrigin.x()+getX(), parentOrigin.y()+getY() ); + //if ( !LuPixelRect( myPos.x(), myPos.y(), getWidth(), getHeight() ).intersects( r ) ) + // return; + + double factor = style.sizeFactor(); + luPt mySize = context.getAdjustedSize( tstyle, factor ); + TQFont font; + TQString text; + + if ( m_hasFont ) { + painter.setPen( style.color() ); + setCharStyle( style.charStyle() ); + setCharFamily( style.charFamily() ); + font = TQFont( m_fontFamily ); + text = m_char; + painter.fillRect( context.layoutUnitToPixelX( myPos.x() ), + context.layoutUnitToPixelY( myPos.y() ), + context.layoutUnitToPixelX( getWidth() ), + context.layoutUnitToPixelY( getHeight() ), + style.background() ); + } + else { + painter.setPen( context.getErrorColor() ); + font = context.getDefaultFont(); + text = m_alt; + } + font.setPointSizeFloat( context.layoutUnitToFontSize( mySize, false ) ); + painter.setFont( font ); + painter.drawText( context.layoutUnitToPixelX( myPos.x() ), + context.layoutUnitToPixelY( myPos.y()+getBaseline() ), + text ); +} + +void GlyphElement::writeMathMLAttributes( TQDomElement& element ) const +{ + element.setAttribute( "fontfamily", m_fontFamily ); + element.setAttribute( "index", m_char.unicode() ); + element.setAttribute( "alt", m_alt ); +} + +KFORMULA_NAMESPACE_END diff --git a/lib/kformula/identifierelement.cc b/lib/kformula/identifierelement.cc deleted file mode 100644 index 63275e1c..00000000 --- a/lib/kformula/identifierelement.cc +++ /dev/null @@ -1,206 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2006 Alfredo Beaumont Sainz - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - -#include - -#include "kformuladefs.h" -#include "textelement.h" -#include "identifierelement.h" -#include "operatorelement.h" -#include "numberelement.h" -#include "kformulacommand.h" -#include "kformulacontainer.h" -#include "kformuladocument.h" -#include "formulaelement.h" -#include "creationstrategy.h" - -KFORMULA_NAMESPACE_BEGIN - -IdentifierElement::IdentifierElement( BasicElement* parent ) : TokenElement( parent ) {} - -/* - * Token elements' content has to be of homogeneous type. Every token element - * must (TODO: check this) appear inside a non-token sequence, and thus, if - * the command asks for a different content, a new element has to be created in - * parent sequence. - */ -KCommand* IdentifierElement::buildCommand( Container* container, Request* request ) -{ - FormulaCursor* cursor = container->activeCursor(); - if ( cursor->isReadOnly() ) { - formula()->tell( i18n( "write protection" ) ); - return 0; - } - - if ( *request == req_addText ) { - KFCReplace* command = new KFCReplace( i18n("Add Text"), container ); - TextRequest* tr = static_cast( request ); - for ( uint i = 0; i < tr->text().length(); i++ ) { - TextElement* element = creationStrategy->createTextElement( tr->text()[i] ); - command->addElement( element ); - } - return command; - } - - else if ( *request == req_addTextChar ) { - KFCReplace* command = new KFCReplace( i18n("Add Text"), container ); - TextCharRequest* tr = static_cast( request ); - TextElement* element = creationStrategy->createTextElement( tr->ch(), tr->isSymbol() ); - command->addElement( element ); - return command; - } - - if ( countChildren() == 0 || cursor->getPos() == countChildren() ) { - // We are in the last position, so it's easy, call the parent to - // create a new child - SequenceElement* parent = static_cast( getParent() ); - if ( parent ) { - uint pos = parent->childPos( this ); - cursor->setTo( parent, pos + 1); - return parent->buildCommand( container, request ); - } - } - if ( cursor->getPos() == 0 ) { - SequenceElement* parent = static_cast( getParent() ); - if ( parent ) { - uint pos = parent->childPos( this ); - cursor->setTo( parent, pos ); - return parent->buildCommand( container, request ); - } - } - - // We are in the middle of a token, so: - // a) Cut from mark to the end - // b) Create a new token and add an element from key pressed - // c) Create a new token and add elements cut previously - // d) Move cursor to parent so that it command execution works fine - - switch( *request ) { - case req_addOperator: { - KFCSplitToken* command = new KFCSplitToken( i18n("Add Operator"), container ); - OperatorRequest* opr = static_cast( request ); - OperatorElement* op = creationStrategy->createOperatorElement(); - TextElement* text = creationStrategy->createTextElement( opr->ch() ); - command->addCursor( cursor ); - command->addToken( op ); - command->addContent( op, text ); - SequenceElement* parent = static_cast< SequenceElement* >( getParent() ); - if ( parent ) { - cursor->setTo( parent, parent->childPos( this ) + 1 ); - } - return command; - } - case req_addNumber: { - KFCSplitToken* command = new KFCSplitToken( i18n("Add Number"), container ); - NumberRequest* nr = static_cast( request ); - NumberElement* num = creationStrategy->createNumberElement(); - TextElement* text = creationStrategy->createTextElement( nr->ch() ); - command->addCursor( cursor ); - command->addToken( num ); - command->addContent( num, text ); - SequenceElement* parent = static_cast< SequenceElement* >( getParent() ); - if ( parent ) { - cursor->setTo( parent, parent->childPos( this ) + 1 ); - } - return command; - } - case req_addEmptyBox: - case req_addNameSequence: - case req_addBracket: - case req_addSpace: - case req_addFraction: - case req_addRoot: - case req_addSymbol: - case req_addOneByTwoMatrix: - case req_addMatrix: { - uint pos = static_cast(getParent())->childPos( this ); - cursor->setTo( getParent(), pos + 1); - return getParent()->buildCommand( container, request ); - } - default: - return SequenceElement::buildCommand( container, request ); - } - return 0; -} - -void IdentifierElement::setStyleVariant( StyleAttributes& style ) -{ - if ( customMathVariant() ) { - style.setCustomMathVariant ( true ); - style.setCustomFontWeight( false ); - style.setCustomFontStyle( false ); - style.setCustomFont( false ); - if ( customMathVariant() ) { - style.setCharFamily ( charFamily() ); - style.setCharStyle( charStyle() ); - } - else { - style.setCharFamily( style.charFamily() ); - style.setCharStyle( style.charStyle() ); - } - } - else { - style.setCustomMathVariant( false ); - if ( customFontFamily() ) { - style.setCustomFont( true ); - style.setFont( TQFont(fontFamily()) ); - } - - bool fontweight = false; - if ( customFontWeight() || style.customFontWeight() ) { - style.setCustomFontWeight( true ); - if ( customFontWeight() ) { - fontweight = fontWeight(); - } - else { - fontweight = style.customFontWeight(); - } - style.setFontWeight( fontweight ); - } - else { - style.setCustomFontWeight( false ); - } - - bool fontstyle; - if ( customFontStyle() ) { - fontstyle = fontStyle(); - } - else if ( countChildren() == 1 ) { - fontstyle = true; - } - else { - fontstyle = false; - } - - if ( fontweight && fontstyle ) { - style.setCharStyle( boldItalicChar ); - } - else if ( fontweight && ! fontstyle ) { - style.setCharStyle( boldChar ); - } - else if ( ! fontweight && fontstyle ) { - style.setCharStyle( italicChar ); - } - else { - style.setCharStyle( normalChar ); - } - } -} - -KFORMULA_NAMESPACE_END diff --git a/lib/kformula/identifierelement.cpp b/lib/kformula/identifierelement.cpp new file mode 100644 index 00000000..63275e1c --- /dev/null +++ b/lib/kformula/identifierelement.cpp @@ -0,0 +1,206 @@ +/* This file is part of the KDE project + Copyright (C) 2006 Alfredo Beaumont Sainz + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include + +#include "kformuladefs.h" +#include "textelement.h" +#include "identifierelement.h" +#include "operatorelement.h" +#include "numberelement.h" +#include "kformulacommand.h" +#include "kformulacontainer.h" +#include "kformuladocument.h" +#include "formulaelement.h" +#include "creationstrategy.h" + +KFORMULA_NAMESPACE_BEGIN + +IdentifierElement::IdentifierElement( BasicElement* parent ) : TokenElement( parent ) {} + +/* + * Token elements' content has to be of homogeneous type. Every token element + * must (TODO: check this) appear inside a non-token sequence, and thus, if + * the command asks for a different content, a new element has to be created in + * parent sequence. + */ +KCommand* IdentifierElement::buildCommand( Container* container, Request* request ) +{ + FormulaCursor* cursor = container->activeCursor(); + if ( cursor->isReadOnly() ) { + formula()->tell( i18n( "write protection" ) ); + return 0; + } + + if ( *request == req_addText ) { + KFCReplace* command = new KFCReplace( i18n("Add Text"), container ); + TextRequest* tr = static_cast( request ); + for ( uint i = 0; i < tr->text().length(); i++ ) { + TextElement* element = creationStrategy->createTextElement( tr->text()[i] ); + command->addElement( element ); + } + return command; + } + + else if ( *request == req_addTextChar ) { + KFCReplace* command = new KFCReplace( i18n("Add Text"), container ); + TextCharRequest* tr = static_cast( request ); + TextElement* element = creationStrategy->createTextElement( tr->ch(), tr->isSymbol() ); + command->addElement( element ); + return command; + } + + if ( countChildren() == 0 || cursor->getPos() == countChildren() ) { + // We are in the last position, so it's easy, call the parent to + // create a new child + SequenceElement* parent = static_cast( getParent() ); + if ( parent ) { + uint pos = parent->childPos( this ); + cursor->setTo( parent, pos + 1); + return parent->buildCommand( container, request ); + } + } + if ( cursor->getPos() == 0 ) { + SequenceElement* parent = static_cast( getParent() ); + if ( parent ) { + uint pos = parent->childPos( this ); + cursor->setTo( parent, pos ); + return parent->buildCommand( container, request ); + } + } + + // We are in the middle of a token, so: + // a) Cut from mark to the end + // b) Create a new token and add an element from key pressed + // c) Create a new token and add elements cut previously + // d) Move cursor to parent so that it command execution works fine + + switch( *request ) { + case req_addOperator: { + KFCSplitToken* command = new KFCSplitToken( i18n("Add Operator"), container ); + OperatorRequest* opr = static_cast( request ); + OperatorElement* op = creationStrategy->createOperatorElement(); + TextElement* text = creationStrategy->createTextElement( opr->ch() ); + command->addCursor( cursor ); + command->addToken( op ); + command->addContent( op, text ); + SequenceElement* parent = static_cast< SequenceElement* >( getParent() ); + if ( parent ) { + cursor->setTo( parent, parent->childPos( this ) + 1 ); + } + return command; + } + case req_addNumber: { + KFCSplitToken* command = new KFCSplitToken( i18n("Add Number"), container ); + NumberRequest* nr = static_cast( request ); + NumberElement* num = creationStrategy->createNumberElement(); + TextElement* text = creationStrategy->createTextElement( nr->ch() ); + command->addCursor( cursor ); + command->addToken( num ); + command->addContent( num, text ); + SequenceElement* parent = static_cast< SequenceElement* >( getParent() ); + if ( parent ) { + cursor->setTo( parent, parent->childPos( this ) + 1 ); + } + return command; + } + case req_addEmptyBox: + case req_addNameSequence: + case req_addBracket: + case req_addSpace: + case req_addFraction: + case req_addRoot: + case req_addSymbol: + case req_addOneByTwoMatrix: + case req_addMatrix: { + uint pos = static_cast(getParent())->childPos( this ); + cursor->setTo( getParent(), pos + 1); + return getParent()->buildCommand( container, request ); + } + default: + return SequenceElement::buildCommand( container, request ); + } + return 0; +} + +void IdentifierElement::setStyleVariant( StyleAttributes& style ) +{ + if ( customMathVariant() ) { + style.setCustomMathVariant ( true ); + style.setCustomFontWeight( false ); + style.setCustomFontStyle( false ); + style.setCustomFont( false ); + if ( customMathVariant() ) { + style.setCharFamily ( charFamily() ); + style.setCharStyle( charStyle() ); + } + else { + style.setCharFamily( style.charFamily() ); + style.setCharStyle( style.charStyle() ); + } + } + else { + style.setCustomMathVariant( false ); + if ( customFontFamily() ) { + style.setCustomFont( true ); + style.setFont( TQFont(fontFamily()) ); + } + + bool fontweight = false; + if ( customFontWeight() || style.customFontWeight() ) { + style.setCustomFontWeight( true ); + if ( customFontWeight() ) { + fontweight = fontWeight(); + } + else { + fontweight = style.customFontWeight(); + } + style.setFontWeight( fontweight ); + } + else { + style.setCustomFontWeight( false ); + } + + bool fontstyle; + if ( customFontStyle() ) { + fontstyle = fontStyle(); + } + else if ( countChildren() == 1 ) { + fontstyle = true; + } + else { + fontstyle = false; + } + + if ( fontweight && fontstyle ) { + style.setCharStyle( boldItalicChar ); + } + else if ( fontweight && ! fontstyle ) { + style.setCharStyle( boldChar ); + } + else if ( ! fontweight && fontstyle ) { + style.setCharStyle( italicChar ); + } + else { + style.setCharStyle( normalChar ); + } + } +} + +KFORMULA_NAMESPACE_END diff --git a/lib/kformula/indexelement.cc b/lib/kformula/indexelement.cc deleted file mode 100644 index 6f2f6d1d..00000000 --- a/lib/kformula/indexelement.cc +++ /dev/null @@ -1,1763 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2001 Andrea Rizzi - Ulrich Kuettler - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - -#include - -#include -#include - -#include "elementvisitor.h" -#include "indexelement.h" -#include "formulacursor.h" -#include "formulaelement.h" -#include "kformulacommand.h" -#include "sequenceelement.h" - - -KFORMULA_NAMESPACE_BEGIN - - -class IndexSequenceElement : public SequenceElement { - typedef SequenceElement inherited; -public: - - IndexSequenceElement( BasicElement* parent = 0 ) : SequenceElement( parent ) {} - virtual IndexSequenceElement* clone() { - return new IndexSequenceElement( *this ); - } - - /** - * This is called by the container to get a command depending on - * the current cursor position (this is how the element gets chosen) - * and the request. - * - * @returns the command that performs the requested action with - * the containers active cursor. - */ - virtual KCommand* buildCommand( Container*, Request* ); -}; - - -KCommand* IndexSequenceElement::buildCommand( Container* container, Request* request ) -{ - FormulaCursor* cursor = container->activeCursor(); - if ( cursor->isReadOnly() ) { - return 0; - } - - switch ( *request ) { - case req_addIndex: { - FormulaCursor* cursor = container->activeCursor(); - if ( cursor->isSelection() || - ( cursor->getPos() > 0 && cursor->getPos() < countChildren() ) ) { - break; - } - IndexElement* element = static_cast( getParent() ); - IndexRequest* ir = static_cast( request ); - ElementIndexPtr index = element->getIndex( ir->index() ); - if ( !index->hasIndex() ) { - KFCAddGenericIndex* command = new KFCAddGenericIndex( container, index ); - return command; - } - else { - index->moveToIndex( cursor, afterCursor ); - cursor->setSelection( false ); - formula()->cursorHasMoved( cursor ); - return 0; - } - } - default: - break; - } - return inherited::buildCommand( container, request ); -} - - -IndexElement::IndexElement(BasicElement* parent) - : BasicElement(parent), - m_subScriptShiftType( NoSize ), - m_superScriptShiftType( NoSize ), - m_customAccentUnder( false ), - m_customAccent ( false ) -{ - content = new IndexSequenceElement( this ); - - upperLeft = 0; - upperMiddle = 0; - upperRight = 0; - lowerLeft = 0; - lowerMiddle = 0; - lowerRight = 0; -} - -IndexElement::~IndexElement() -{ - delete content; - delete upperLeft; - delete upperMiddle; - delete upperRight; - delete lowerLeft; - delete lowerMiddle; - delete lowerRight; -} - - -IndexElement::IndexElement( const IndexElement& other ) - : BasicElement( other ), - m_subScriptShiftType( other.m_subScriptShiftType ), - m_subScriptShift( other.m_subScriptShift ), - m_superScriptShiftType( other.m_superScriptShiftType ), - m_superScriptShift( other.m_superScriptShift ), - m_customAccentUnder( other.m_customAccentUnder ), - m_accentUnder( other.m_accentUnder ), - m_customAccent ( other.m_customAccent ), - m_accent( other.m_accent ) -{ - content = new IndexSequenceElement( *dynamic_cast( other.content ) ); - - if ( other.upperLeft ) { - upperLeft = new SequenceElement( *( other.upperLeft ) ); - upperLeft->setParent( this ); - } - else { - upperLeft = 0; - } - if ( other.upperMiddle ) { - upperMiddle = new SequenceElement( *( other.upperMiddle ) ); - upperMiddle->setParent( this ); - } - else { - upperMiddle = 0; - } - if ( other.upperRight ) { - upperRight = new SequenceElement( *( other.upperRight ) ); - upperRight->setParent( this ); - } - else { - upperRight = 0; - } - - if ( other.lowerLeft ) { - lowerLeft = new SequenceElement( *( other.lowerLeft ) ); - lowerLeft->setParent( this ); - } - else { - lowerLeft = 0; - } - if ( other.lowerMiddle ) { - lowerMiddle = new SequenceElement( *( other.lowerMiddle ) ); - lowerMiddle->setParent( this ); - } - else { - lowerMiddle = 0; - } - if ( other.lowerRight ) { - lowerRight = new SequenceElement( *( other.lowerRight ) ); - lowerRight->setParent( this ); - } - else { - lowerRight = 0; - } -} - - -bool IndexElement::accept( ElementVisitor* visitor ) -{ - return visitor->visit( this ); -} - - -TQChar IndexElement::getCharacter() const -{ - if ( !content->isTextOnly() ) { - return TQChar::null; - } - - if ( hasUpperRight() && !upperRight->isTextOnly() ) { - return TQChar::null; - } - if ( hasUpperMiddle() && !upperMiddle->isTextOnly() ) { - return TQChar::null; - } - if ( hasUpperLeft() && !upperLeft->isTextOnly() ) { - return TQChar::null; - } - if ( hasLowerRight() && !lowerRight->isTextOnly() ) { - return TQChar::null; - } - if ( hasLowerMiddle() && !lowerMiddle->isTextOnly() ) { - return TQChar::null; - } - if ( hasLowerLeft() && !lowerLeft->isTextOnly() ) { - return TQChar::null; - } - - return ' '; -} - -void IndexElement::entered( SequenceElement* child ) -{ - if ( child == content ) { - formula()->tell( i18n( "Indexed list" ) ); - } - else { - formula()->tell( i18n( "Index" ) ); - } -} - - -/** - * Returns the element the point is in. - */ -BasicElement* IndexElement::goToPos( FormulaCursor* cursor, bool& handled, - const LuPixelPoint& point, const LuPixelPoint& parentOrigin ) -{ - BasicElement* e = BasicElement::goToPos(cursor, handled, point, parentOrigin); - if (e != 0) { - LuPixelPoint myPos(parentOrigin.x()+getX(), parentOrigin.y()+getY()); - e = content->goToPos(cursor, handled, point, myPos); - if (e != 0) return e; - - if (hasUpperRight()) { - e = upperRight->goToPos(cursor, handled, point, myPos); - if (e != 0) return e; - } - if (hasUpperMiddle()) { - e = upperMiddle->goToPos(cursor, handled, point, myPos); - if (e != 0) return e; - } - if (hasUpperLeft()) { - e = upperLeft->goToPos(cursor, handled, point, myPos); - if (e != 0) return e; - } - if (hasLowerRight()) { - e = lowerRight->goToPos(cursor, handled, point, myPos); - if (e != 0) return e; - } - if (hasLowerMiddle()) { - e = lowerMiddle->goToPos(cursor, handled, point, myPos); - if (e != 0) return e; - } - if (hasLowerLeft()) { - e = lowerLeft->goToPos(cursor, handled, point, myPos); - if (e != 0) return e; - } - - luPixel dx = point.x() - myPos.x(); - luPixel dy = point.y() - myPos.y(); - - // the positions after the left indexes - if (dx < content->getX()+content->getWidth()) { - if (dy < content->getY()) { - if (hasUpperMiddle() && (dx > upperMiddle->getX())) { - upperMiddle->moveLeft(cursor, this); - handled = true; - return upperMiddle; - } - if (hasUpperLeft() && (dx > upperLeft->getX())) { - upperLeft->moveLeft(cursor, this); - handled = true; - return upperLeft; - } - } - else if (dy > content->getY()+content->getHeight()) { - if (hasLowerMiddle() && (dx > lowerMiddle->getX())) { - lowerMiddle->moveLeft(cursor, this); - handled = true; - return lowerMiddle; - } - if (hasLowerLeft() && (dx > lowerLeft->getX())) { - lowerLeft->moveLeft(cursor, this); - handled = true; - return lowerLeft; - } - } - } - // the positions after the left indexes - else { - if (dy < content->getY()) { - if (hasUpperRight()) { - upperRight->moveLeft(cursor, this); - handled = true; - return upperRight; - } - } - else if (dy > content->getY()+content->getHeight()) { - if (hasLowerRight()) { - lowerRight->moveLeft(cursor, this); - handled = true; - return lowerRight; - } - } - else { - content->moveLeft(cursor, this); - handled = true; - return content; - } - } - - return this; - } - return 0; -} - - -// drawing -// -// Drawing depends on a context which knows the required properties like -// fonts, spaces and such. -// It is essential to calculate elements size with the same context -// before you draw. - - -void IndexElement::setMiddleX(int xOffset, int middleWidth) -{ - content->setX(xOffset + (middleWidth - content->getWidth()) / 2); - if (hasUpperMiddle()) { - upperMiddle->setX(xOffset + (middleWidth - upperMiddle->getWidth()) / 2); - } - if (hasLowerMiddle()) { - lowerMiddle->setX(xOffset + (middleWidth - lowerMiddle->getWidth()) / 2); - } -} - - -/** - * Calculates our width and height and - * our children's parentPosition. - */ -void IndexElement::calcSizes(const ContextStyle& context, - ContextStyle::TextStyle tstyle, - ContextStyle::IndexStyle istyle, - StyleAttributes& style ) -{ - double factor = style.sizeFactor(); - luPixel distY = context.ptToPixelY( context.getThinSpace( tstyle, factor ) ); - - ContextStyle::TextStyle i_tstyle = context.convertTextStyleIndex(tstyle); - ContextStyle::IndexStyle u_istyle = context.convertIndexStyleUpper( istyle ); - ContextStyle::IndexStyle l_istyle = context.convertIndexStyleLower( istyle ); - - // get the indexes size - luPixel ulWidth = 0, ulHeight = 0, ulMidline = 0; - if (hasUpperLeft()) { - upperLeft->calcSizes( context, i_tstyle, u_istyle, style ); - ulWidth = upperLeft->getWidth(); - ulHeight = upperLeft->getHeight(); - ulMidline = upperLeft->axis( context, i_tstyle, factor ); - } - - luPixel umWidth = 0, umHeight = 0, umMidline = 0; - if (hasUpperMiddle()) { - upperMiddle->calcSizes( context, i_tstyle, u_istyle, style ); - umWidth = upperMiddle->getWidth(); - umHeight = upperMiddle->getHeight() + distY; - umMidline = upperMiddle->axis( context, i_tstyle, factor ); - } - - luPixel urWidth = 0, urHeight = 0, urMidline = 0; - if (hasUpperRight()) { - upperRight->calcSizes( context, i_tstyle, u_istyle, style ); - urWidth = upperRight->getWidth(); - urHeight = upperRight->getHeight(); - urMidline = upperRight->axis( context, i_tstyle, factor ); - } - - luPixel llWidth = 0, llHeight = 0, llMidline = 0; - if (hasLowerLeft()) { - lowerLeft->calcSizes( context, i_tstyle, l_istyle, style ); - llWidth = lowerLeft->getWidth(); - llHeight = lowerLeft->getHeight(); - llMidline = lowerLeft->axis( context, i_tstyle, factor ); - } - - luPixel lmWidth = 0, lmHeight = 0, lmMidline = 0; - if (hasLowerMiddle()) { - lowerMiddle->calcSizes( context, i_tstyle, l_istyle, style ); - lmWidth = lowerMiddle->getWidth(); - lmHeight = lowerMiddle->getHeight() + distY; - lmMidline = lowerMiddle->axis( context, i_tstyle, factor ); - } - - luPixel lrWidth = 0, lrHeight = 0, lrMidline = 0; - if (hasLowerRight()) { - lowerRight->calcSizes( context, i_tstyle, l_istyle, style ); - lrWidth = lowerRight->getWidth(); - lrHeight = lowerRight->getHeight(); - lrMidline = lowerRight->axis( context, i_tstyle, factor ); - } - - // get the contents size - content->calcSizes( context, tstyle, istyle, style ); - luPixel width = TQMAX(content->getWidth(), TQMAX(umWidth, lmWidth)); - luPixel toMidline = content->axis( context, tstyle, factor ); - luPixel fromMidline = content->getHeight() - toMidline; - - // calculate the x offsets - if (ulWidth > llWidth) { - upperLeft->setX(0); - if (hasLowerLeft()) { - lowerLeft->setX(ulWidth - llWidth); - } - setMiddleX(ulWidth, width); - width += ulWidth; - } - else { - if (hasUpperLeft()) { - upperLeft->setX(llWidth - ulWidth); - } - if (hasLowerLeft()) { - lowerLeft->setX(0); - } - setMiddleX(llWidth, width); - width += llWidth; - } - - if (hasUpperRight()) { - upperRight->setX(width); - } - if (hasLowerRight()) { - lowerRight->setX(width); - } - width += TQMAX(urWidth, lrWidth); - - // calculate the y offsets - luPixel ulOffset = 0; - luPixel urOffset = 0; - luPixel llOffset = 0; - luPixel lrOffset = 0; - if (content->isTextOnly()) { - luPt mySize = context.getAdjustedSize( tstyle, factor ); - TQFont font = context.getDefaultFont(); - font.setPointSizeFloat( context.layoutUnitPtToPt( mySize ) ); - - TQFontMetrics fm(font); - LuPixelRect bound = fm.boundingRect('x'); - - luPixel exBaseline = context.ptToLayoutUnitPt( -bound.top() ); - - // the upper half - ulOffset = ulHeight + exBaseline - content->getBaseline(); - urOffset = urHeight + exBaseline - content->getBaseline(); - - // the lower half - llOffset = lrOffset = content->getBaseline(); - } - else { - - // the upper half - ulOffset = TQMAX(ulMidline, ulHeight-toMidline); - urOffset = TQMAX(urMidline, urHeight-toMidline); - - // the lower half - llOffset = TQMAX(content->getHeight()-llMidline, toMidline); - lrOffset = TQMAX(content->getHeight()-lrMidline, toMidline); - } - - // Add more offset if defined in attributes - switch ( m_superScriptShiftType ) { - case AbsoluteSize: - urOffset += context.ptToLayoutUnitPt( m_superScriptShift ); - break; - case RelativeSize: - urOffset += urOffset * m_superScriptShift; - break; - case PixelSize: - urOffset += context.pixelToLayoutUnitY( m_superScriptShift ); - break; - default: - break; - } - - switch ( m_subScriptShiftType ) { - case AbsoluteSize: - lrOffset += context.ptToLayoutUnitPt( m_subScriptShift ); - break; - case RelativeSize: - lrOffset += lrOffset * m_subScriptShift; - break; - case PixelSize: - lrOffset += context.pixelToLayoutUnitY( m_subScriptShift ); - break; - default: - break; - } - - luPixel height = TQMAX(umHeight, TQMAX(ulOffset, urOffset)); - - // the upper half - content->setY(height); - toMidline += height; - if (hasUpperLeft()) { - upperLeft->setY(height-ulOffset); - } - if (hasUpperMiddle()) { - upperMiddle->setY(height-umHeight); - } - if (hasUpperRight()) { - upperRight->setY( height - urOffset ); - } - - // the lower half - if (hasLowerLeft()) { - lowerLeft->setY(height+llOffset); - } - if (hasLowerMiddle()) { - lowerMiddle->setY(height+content->getHeight()+distY); - } - if (hasLowerRight()) { - lowerRight->setY( height + lrOffset ); - } - - fromMidline += TQMAX(TQMAX(llHeight+llOffset, lrHeight+lrOffset) - content->getHeight(), lmHeight); - - // set the result - setWidth(width); - setHeight(toMidline+fromMidline); - if (content->isTextOnly()) { - setBaseline(content->getY() + content->getBaseline()); - //setMidline(content->getY() + content->getMidline()); - } - else { - //setMidline(toMidline); - setBaseline(content->getBaseline() + content->getY()); - } -} - -/** - * Draws the whole element including its children. - * The `parentOrigin' is the point this element's parent starts. - * We can use our parentPosition to get our own origin then. - */ -void IndexElement::draw( TQPainter& painter, const LuPixelRect& r, - const ContextStyle& context, - ContextStyle::TextStyle tstyle, - ContextStyle::IndexStyle istyle, - StyleAttributes& style, - const LuPixelPoint& parentOrigin ) -{ - LuPixelPoint myPos( parentOrigin.x()+getX(), parentOrigin.y()+getY() ); - //if ( !LuPixelRect( myPos.x(), myPos.y(), getWidth(), getHeight() ).intersects( r ) ) - // return; - - ContextStyle::TextStyle i_tstyle = context.convertTextStyleIndex(tstyle); - ContextStyle::IndexStyle u_istyle = context.convertIndexStyleUpper( istyle ); - ContextStyle::IndexStyle l_istyle = context.convertIndexStyleLower( istyle ); - - content->draw(painter, r, context, tstyle, istyle, style, myPos); - if (hasUpperLeft()) { - upperLeft->draw(painter, r, context, i_tstyle, u_istyle, style, myPos); - } - if (hasUpperMiddle()) { - upperMiddle->draw(painter, r, context, i_tstyle, u_istyle, style, myPos); - } - if (hasUpperRight()) { - upperRight->draw(painter, r, context, i_tstyle, u_istyle, style, myPos); - } - if (hasLowerLeft()) { - lowerLeft->draw(painter, r, context, i_tstyle, l_istyle, style, myPos); - } - if (hasLowerMiddle()) { - lowerMiddle->draw(painter, r, context, i_tstyle, l_istyle, style, myPos); - } - if (hasLowerRight()) { - lowerRight->draw(painter, r, context, i_tstyle, l_istyle, style, myPos); - } - - // Debug - //painter.setBrush(TQt::NoBrush); - //painter.setPen(TQt::red); - //painter.drawRect(myPos.x(), myPos.y(), getWidth(), getHeight()); - //painter.drawLine(myPos.x(), myPos.y()+getMidline(), - // myPos.x()+getWidth(), myPos.y()+getMidline()); -} - - -void IndexElement::dispatchFontCommand( FontCommand* cmd ) -{ - content->dispatchFontCommand( cmd ); - if (hasUpperLeft()) { - upperLeft->dispatchFontCommand( cmd ); - } - if (hasUpperMiddle()) { - upperMiddle->dispatchFontCommand( cmd ); - } - if (hasUpperRight()) { - upperRight->dispatchFontCommand( cmd ); - } - if (hasLowerLeft()) { - lowerLeft->dispatchFontCommand( cmd ); - } - if (hasLowerMiddle()) { - lowerMiddle->dispatchFontCommand( cmd ); - } - if (hasLowerRight()) { - lowerRight->dispatchFontCommand( cmd ); - } -} - - -// navigation -// -// The elements are responsible to handle cursor movement themselves. -// To do this they need to know the direction the cursor moves and -// the element it comes from. -// -// The cursor might be in normal or in selection mode. - -int IndexElement::getFromPos(BasicElement* from) -{ - if (from == lowerRight) { - return lowerRightPos; - } - else if (from == upperRight) { - return upperRightPos; - } - else if (from == lowerMiddle) { - return lowerMiddlePos; - } - else if (from == content) { - return contentPos; - } - else if (from == upperMiddle) { - return upperMiddlePos; - } - else if (from == lowerLeft) { - return lowerLeftPos; - } - else if (from == upperLeft) { - return upperLeftPos; - } - return parentPos; -} - -/** - * Enters this element while moving to the left starting inside - * the element `from'. Searches for a cursor position inside - * this element or to the left of it. - */ -void IndexElement::moveLeft(FormulaCursor* cursor, BasicElement* from) -{ - if (cursor->isSelectionMode()) { - getParent()->moveLeft(cursor, this); - } - else { - bool linear = cursor->getLinearMovement(); - int fromPos = getFromPos(from); - if (!linear) { - if ((fromPos == lowerRightPos) && hasLowerMiddle()) { - lowerMiddle->moveLeft(cursor, this); - return; - } - else if ((fromPos == upperRightPos) && hasUpperMiddle()) { - upperMiddle->moveLeft(cursor, this); - return; - } - else if ((fromPos == lowerMiddlePos) && hasLowerLeft()) { - lowerLeft->moveLeft(cursor, this); - return; - } - else if ((fromPos == upperMiddlePos) && hasUpperLeft()) { - upperLeft->moveLeft(cursor, this); - return; - } - } - switch (fromPos) { - case parentPos: - if (hasLowerRight() && linear) { - lowerRight->moveLeft(cursor, this); - break; - } - case lowerRightPos: - if (hasUpperRight() && linear) { - upperRight->moveLeft(cursor, this); - break; - } - case upperRightPos: - if (hasLowerMiddle() && linear) { - lowerMiddle->moveLeft(cursor, this); - break; - } - case lowerMiddlePos: - content->moveLeft(cursor, this); - break; - case contentPos: - if (hasUpperMiddle() && linear) { - upperMiddle->moveLeft(cursor, this); - break; - } - case upperMiddlePos: - if (hasLowerLeft() && linear) { - lowerLeft->moveLeft(cursor, this); - break; - } - case lowerLeftPos: - if (hasUpperLeft() && linear) { - upperLeft->moveLeft(cursor, this); - break; - } - case upperLeftPos: - getParent()->moveLeft(cursor, this); - } - } -} - -/** - * Enters this element while moving to the right starting inside - * the element `from'. Searches for a cursor position inside - * this element or to the right of it. - */ -void IndexElement::moveRight(FormulaCursor* cursor, BasicElement* from) -{ - if (cursor->isSelectionMode()) { - getParent()->moveRight(cursor, this); - } - else { - bool linear = cursor->getLinearMovement(); - int fromPos = getFromPos(from); - if (!linear) { - if ((fromPos == lowerLeftPos) && hasLowerMiddle()) { - lowerMiddle->moveRight(cursor, this); - return; - } - else if ((fromPos == upperLeftPos) && hasUpperMiddle()) { - upperMiddle->moveRight(cursor, this); - return; - } - else if ((fromPos == lowerMiddlePos) && hasLowerRight()) { - lowerRight->moveRight(cursor, this); - return; - } - else if ((fromPos == upperMiddlePos) && hasUpperRight()) { - upperRight->moveRight(cursor, this); - return; - } - } - switch (fromPos) { - case parentPos: - if (hasUpperLeft() && linear) { - upperLeft->moveRight(cursor, this); - break; - } - case upperLeftPos: - if (hasLowerLeft() && linear) { - lowerLeft->moveRight(cursor, this); - break; - } - case lowerLeftPos: - if (hasUpperMiddle() && linear) { - upperMiddle->moveRight(cursor, this); - break; - } - case upperMiddlePos: - content->moveRight(cursor, this); - break; - case contentPos: - if (hasLowerMiddle() && linear) { - lowerMiddle->moveRight(cursor, this); - break; - } - case lowerMiddlePos: - if (hasUpperRight() && linear) { - upperRight->moveRight(cursor, this); - break; - } - case upperRightPos: - if (hasLowerRight() && linear) { - lowerRight->moveRight(cursor, this); - break; - } - case lowerRightPos: - getParent()->moveRight(cursor, this); - } - } -} - -/** - * Enters this element while moving up starting inside - * the element `from'. Searches for a cursor position inside - * this element or above it. - */ -void IndexElement::moveUp(FormulaCursor* cursor, BasicElement* from) -{ - if (cursor->isSelectionMode()) { - getParent()->moveUp(cursor, this); - } - else { - if (from == content) { - if ((cursor->getPos() == 0) && (cursor->getElement() == from)) { - if (hasUpperLeft()) { - upperLeft->moveLeft(cursor, this); - return; - } - else if (hasUpperMiddle()) { - upperMiddle->moveRight(cursor, this); - return; - } - } - if (hasUpperRight()) { - upperRight->moveRight(cursor, this); - } - else if (hasUpperMiddle()) { - upperMiddle->moveLeft(cursor, this); - } - else if (hasUpperLeft()) { - upperLeft->moveLeft(cursor, this); - } - else { - getParent()->moveUp(cursor, this); - } - } - else if ((from == upperLeft) || (from == upperMiddle) || (from == upperRight)) { - getParent()->moveUp(cursor, this); - } - else if ((from == getParent()) || (from == lowerLeft) || (from == lowerMiddle)) { - content->moveRight(cursor, this); - } - else if (from == lowerRight) { - content->moveLeft(cursor, this); - } - } -} - -/** - * Enters this element while moving down starting inside - * the element `from'. Searches for a cursor position inside - * this element or below it. - */ -void IndexElement::moveDown(FormulaCursor* cursor, BasicElement* from) -{ - if (cursor->isSelectionMode()) { - getParent()->moveDown(cursor, this); - } - else { - if (from == content) { - if ((cursor->getPos() == 0) && (cursor->getElement() == from)) { - if (hasLowerLeft()) { - lowerLeft->moveLeft(cursor, this); - return; - } - else if (hasLowerMiddle()) { - lowerMiddle->moveRight(cursor, this); - return; - } - } - if (hasLowerRight()) { - lowerRight->moveRight(cursor, this); - } - else if (hasLowerMiddle()) { - lowerMiddle->moveLeft(cursor, this); - } - else if (hasLowerLeft()) { - lowerLeft->moveLeft(cursor, this); - } - else { - getParent()->moveDown(cursor, this); - } - } - else if ((from == lowerLeft) || (from == lowerMiddle) || (from == lowerRight)) { - getParent()->moveDown(cursor, this); - } - else if ((from == getParent()) || (from == upperLeft) || (from == upperMiddle)) { - content->moveRight(cursor, this); - } - if (from == upperRight) { - content->moveLeft(cursor, this); - } - } -} - - -// children - - -// main child -// -// If an element has children one has to become the main one. - -// void IndexElement::setMainChild(SequenceElement* child) -// { -// formula()->elementRemoval(content); -// content = child; -// content->setParent(this); -// formula()->changed(); -// } - - -/** - * Inserts all new children at the cursor position. Places the - * cursor according to the direction. - * - * You only can insert one index at a time. So the list must contain - * exactly on SequenceElement. And the index you want to insert - * must not exist already. - * - * The list will be emptied but stays the property of the caller. - */ -void IndexElement::insert(FormulaCursor* cursor, - TQPtrList& newChildren, - Direction direction) -{ - SequenceElement* index = static_cast(newChildren.take(0)); - index->setParent(this); - - switch (cursor->getPos()) { - case upperLeftPos: - upperLeft = index; - break; - case lowerLeftPos: - lowerLeft = index; - break; - case upperMiddlePos: - upperMiddle = index; - break; - case lowerMiddlePos: - lowerMiddle = index; - break; - case upperRightPos: - upperRight = index; - break; - case lowerRightPos: - lowerRight = index; - break; - default: - // this is an error! - return; - } - - if (direction == beforeCursor) { - index->moveLeft(cursor, this); - } - else { - index->moveRight(cursor, this); - } - cursor->setSelection(false); - formula()->changed(); -} - - -/** - * Removes all selected children and returns them. Places the - * cursor to where the children have been. - * - * The cursor has to be inside one of our indexes which is supposed - * to be empty. The index will be removed and the cursor will - * be placed to the removed index so it can be inserted again. - * This methode is called by SequenceElement::remove only. - * - * The ownership of the list is passed to the caller. - */ -void IndexElement::remove(FormulaCursor* cursor, - TQPtrList& removedChildren, - Direction direction) -{ - int pos = cursor->getPos(); - switch (pos) { - case upperLeftPos: - removedChildren.append(upperLeft); - formula()->elementRemoval(upperLeft); - upperLeft = 0; - setToUpperLeft(cursor); - break; - case lowerLeftPos: - removedChildren.append(lowerLeft); - formula()->elementRemoval(lowerLeft); - lowerLeft = 0; - setToLowerLeft(cursor); - break; - case contentPos: { - BasicElement* parent = getParent(); - parent->selectChild(cursor, this); - parent->remove(cursor, removedChildren, direction); - break; - } - case upperMiddlePos: - removedChildren.append(upperMiddle); - formula()->elementRemoval(upperMiddle); - upperMiddle = 0; - setToUpperMiddle(cursor); - break; - case lowerMiddlePos: - removedChildren.append(lowerMiddle); - formula()->elementRemoval(lowerMiddle); - lowerMiddle = 0; - setToLowerMiddle(cursor); - break; - case upperRightPos: - removedChildren.append(upperRight); - formula()->elementRemoval(upperRight); - upperRight = 0; - setToUpperRight(cursor); - break; - case lowerRightPos: - removedChildren.append(lowerRight); - formula()->elementRemoval(lowerRight); - lowerRight = 0; - setToLowerRight(cursor); - break; - } - formula()->changed(); -} - -/** - * Moves the cursor to a normal place where new elements - * might be inserted. - */ -void IndexElement::normalize(FormulaCursor* cursor, Direction direction) -{ - if (direction == beforeCursor) { - content->moveLeft(cursor, this); - } - else { - content->moveRight(cursor, this); - } -} - -/** - * Returns wether the element has no more useful - * children (except its main child) and should therefore - * be replaced by its main child's content. - */ -bool IndexElement::isSenseless() -{ - return !hasUpperLeft() && !hasUpperRight() && !hasUpperMiddle() && - !hasLowerLeft() && !hasLowerRight() && !hasLowerMiddle(); -} - - -/** - * Returns the child at the cursor. - */ -BasicElement* IndexElement::getChild(FormulaCursor* cursor, Direction) -{ - int pos = cursor->getPos(); - /* - It makes no sense to care for the direction. - if (direction == beforeCursor) { - pos -= 1; - } - */ - switch (pos) { - case contentPos: - return content; - case upperLeftPos: - return upperLeft; - case lowerLeftPos: - return lowerLeft; - case upperMiddlePos: - return upperMiddle; - case lowerMiddlePos: - return lowerMiddle; - case upperRightPos: - return upperRight; - case lowerRightPos: - return lowerRight; - } - return 0; -} - - -/** - * Sets the cursor to select the child. The mark is placed before, - * the position behind it. - */ -void IndexElement::selectChild(FormulaCursor* cursor, BasicElement* child) -{ - if (child == content) { - setToContent(cursor); - } - else if (child == upperLeft) { - setToUpperLeft(cursor); - } - else if (child == lowerLeft) { - setToLowerLeft(cursor); - } - else if (child == upperMiddle) { - setToUpperMiddle(cursor); - } - else if (child == lowerMiddle) { - setToLowerMiddle(cursor); - } - else if (child == upperRight) { - setToUpperRight(cursor); - } - else if (child == lowerRight) { - setToLowerRight(cursor); - } -} - - -/** - * Sets the cursor to point to the place where the content is. - * There always is a content so this is not a useful place. - * No insertion or removal will succeed as long as the cursor is - * there. - */ -void IndexElement::setToContent(FormulaCursor* cursor) -{ - cursor->setTo(this, contentPos); -} - -// point the cursor to a gap where an index is to be inserted. -// this makes no sense if there is such an index already. - -void IndexElement::setToUpperLeft(FormulaCursor* cursor) -{ - cursor->setTo(this, upperLeftPos); -} - -void IndexElement::setToUpperMiddle(FormulaCursor* cursor) -{ - cursor->setTo(this, upperMiddlePos); -} - -void IndexElement::setToUpperRight(FormulaCursor* cursor) -{ - cursor->setTo(this, upperRightPos); -} - -void IndexElement::setToLowerLeft(FormulaCursor* cursor) -{ - cursor->setTo(this, lowerLeftPos); -} - -void IndexElement::setToLowerMiddle(FormulaCursor* cursor) -{ - cursor->setTo(this, lowerMiddlePos); -} - -void IndexElement::setToLowerRight(FormulaCursor* cursor) -{ - cursor->setTo(this, lowerRightPos); -} - - -// move inside an index that exists already. - -void IndexElement::moveToUpperLeft(FormulaCursor* cursor, Direction direction) -{ - if (hasUpperLeft()) { - if (direction == beforeCursor) { - upperLeft->moveLeft(cursor, this); - } - else { - upperLeft->moveRight(cursor, this); - } - } -} - -void IndexElement::moveToUpperMiddle(FormulaCursor* cursor, Direction direction) -{ - if (hasUpperMiddle()) { - if (direction == beforeCursor) { - upperMiddle->moveLeft(cursor, this); - } - else { - upperMiddle->moveRight(cursor, this); - } - } -} - -void IndexElement::moveToUpperRight(FormulaCursor* cursor, Direction direction) -{ - if (hasUpperRight()) { - if (direction == beforeCursor) { - upperRight->moveLeft(cursor, this); - } - else { - upperRight->moveRight(cursor, this); - } - } -} - -void IndexElement::moveToLowerLeft(FormulaCursor* cursor, Direction direction) -{ - if (hasLowerLeft()) { - if (direction == beforeCursor) { - lowerLeft->moveLeft(cursor, this); - } - else { - lowerLeft->moveRight(cursor, this); - } - } -} - -void IndexElement::moveToLowerMiddle(FormulaCursor* cursor, Direction direction) -{ - if (hasLowerMiddle()) { - if (direction == beforeCursor) { - lowerMiddle->moveLeft(cursor, this); - } - else { - lowerMiddle->moveRight(cursor, this); - } - } -} - -void IndexElement::moveToLowerRight(FormulaCursor* cursor, Direction direction) -{ - if (hasLowerRight()) { - if (direction == beforeCursor) { - lowerRight->moveLeft(cursor, this); - } - else { - lowerRight->moveRight(cursor, this); - } - } -} - - -/** - * Appends our attributes to the dom element. - */ -void IndexElement::writeDom(TQDomElement element) -{ - BasicElement::writeDom(element); - - TQDomDocument doc = element.ownerDocument(); - - TQDomElement cont = doc.createElement("CONTENT"); - cont.appendChild(content->getElementDom(doc)); - element.appendChild(cont); - - if (hasUpperLeft()) { - TQDomElement ind = doc.createElement("UPPERLEFT"); - ind.appendChild(upperLeft->getElementDom(doc)); - element.appendChild(ind); - } - if (hasUpperMiddle()) { - TQDomElement ind = doc.createElement("UPPERMIDDLE"); - ind.appendChild(upperMiddle->getElementDom(doc)); - element.appendChild(ind); - } - if (hasUpperRight()) { - TQDomElement ind = doc.createElement("UPPERRIGHT"); - ind.appendChild(upperRight->getElementDom(doc)); - element.appendChild(ind); - } - if (hasLowerLeft()) { - TQDomElement ind = doc.createElement("LOWERLEFT"); - ind.appendChild(lowerLeft->getElementDom(doc)); - element.appendChild(ind); - } - if (hasLowerMiddle()) { - TQDomElement ind = doc.createElement("LOWERMIDDLE"); - ind.appendChild(lowerMiddle->getElementDom(doc)); - element.appendChild(ind); - } - if (hasLowerRight()) { - TQDomElement ind = doc.createElement("LOWERRIGHT"); - ind.appendChild(lowerRight->getElementDom(doc)); - element.appendChild(ind); - } -} - -/** - * Reads our attributes from the element. - * Returns false if it failed. - */ -bool IndexElement::readAttributesFromDom(TQDomElement element) -{ - if (!BasicElement::readAttributesFromDom(element)) { - return false; - } - return true; -} - -/** - * Reads our content from the node. Sets the node to the next node - * that needs to be read. - * Returns false if it failed. - */ -bool IndexElement::readContentFromDom(TQDomNode& node) -{ - if (!BasicElement::readContentFromDom(node)) { - return false; - } - - if ( !buildChild( content, node, "CONTENT" ) ) { - kdWarning( DEBUGID ) << "Empty content in IndexElement." << endl; - return false; - } - node = node.nextSibling(); - - bool upperLeftRead = false; - bool upperMiddleRead = false; - bool upperRightRead = false; - bool lowerLeftRead = false; - bool lowerMiddleRead = false; - bool lowerRightRead = false; - - while (!node.isNull() && - !(upperLeftRead && upperMiddleRead && upperRightRead && - lowerLeftRead && lowerMiddleRead && lowerRightRead)) { - - if (!upperLeftRead && (node.nodeName().upper() == "UPPERLEFT")) { - upperLeftRead = buildChild( upperLeft=new SequenceElement( this ), node, "UPPERLEFT" ); - if ( !upperLeftRead ) return false; - } - - if (!upperMiddleRead && (node.nodeName().upper() == "UPPERMIDDLE")) { - upperMiddleRead = buildChild( upperMiddle=new SequenceElement( this ), node, "UPPERMIDDLE" ); - if ( !upperMiddleRead ) return false; - } - - if (!upperRightRead && (node.nodeName().upper() == "UPPERRIGHT")) { - upperRightRead = buildChild( upperRight=new SequenceElement( this ), node, "UPPERRIGHT" ); - if ( !upperRightRead ) return false; - } - - if (!lowerLeftRead && (node.nodeName().upper() == "LOWERLEFT")) { - lowerLeftRead = buildChild( lowerLeft=new SequenceElement( this ), node, "LOWERLEFT" ); - if ( !lowerLeftRead ) return false; - } - - if (!lowerMiddleRead && (node.nodeName().upper() == "LOWERMIDDLE")) { - lowerMiddleRead = buildChild( lowerMiddle=new SequenceElement( this ), node, "LOWERMIDDLE" ); - if ( !lowerMiddleRead ) return false; - } - - if (!lowerRightRead && (node.nodeName().upper() == "LOWERRIGHT")) { - lowerRightRead = buildChild( lowerRight=new SequenceElement( this ), node, "LOWERRIGHT" ); - if ( !lowerRightRead ) return false; - } - - node = node.nextSibling(); - } - return upperLeftRead || upperMiddleRead || upperRightRead || - lowerLeftRead || lowerMiddleRead || lowerRightRead; -} - -bool IndexElement::readAttributesFromMathMLDom( const TQDomElement& element ) -{ - if ( !BasicElement::readAttributesFromMathMLDom( element ) ) { - return false; - } - - TQString tag = element.tagName().stripWhiteSpace().lower(); - if ( tag == "msub" || tag == "msubsup" ) { - TQString subscriptshiftStr = element.attribute( "subscriptshift" ).stripWhiteSpace().lower(); - if ( ! subscriptshiftStr.isNull() ) { - m_subScriptShift = getSize( subscriptshiftStr, &m_subScriptShiftType ); - } - } - if ( tag == "msup" || tag == "msubsup" ) { - TQString superscriptshiftStr = element.attribute( "superscriptshift" ).stripWhiteSpace().lower(); - if ( ! superscriptshiftStr.isNull() ) { - m_superScriptShift = getSize( superscriptshiftStr, &m_superScriptShiftType ); - } - } - - if ( tag == "munder" || tag == "munderover" ) { - TQString accentunderStr = element.attribute( "accentunder" ).stripWhiteSpace().lower(); - if ( ! accentunderStr.isNull() ) { - if ( accentunderStr == "true" ) { - m_customAccentUnder = true; - m_accentUnder = true; - } - else if ( accentunderStr == "false" ) { - m_customAccentUnder = true; - m_accentUnder = false; - } - else { - kdWarning( DEBUGID ) << "Invalid value for attribute `accentunder': " - << accentunderStr << endl; - } - } - } - if ( tag == "mover" || tag == "munderover" ) { - TQString accentStr = element.attribute( "accent" ).stripWhiteSpace().lower(); - if ( ! accentStr.isNull() ) { - if ( accentStr == "true" ) { - m_customAccent = true; - m_accent = true; - } - else if ( accentStr == "false" ) { - m_customAccent = true; - m_accent = false; - } - else { - kdWarning( DEBUGID ) << "Invalid value for attribute `accent': " - << accentStr << endl; - } - } - } - return true; -} - -/** - * Reads our content from the MathML node. Sets the node to the next node - * that needs to be read. It is sometimes needed to read more than one node - * (e. g. for fence operators). - * Returns the number of nodes processed or -1 if it failed. - */ -int IndexElement::readContentFromMathMLDom( TQDomNode& node ) -{ - if ( BasicElement::readContentFromMathMLDom( node ) == -1 ) { - return -1; - } - - int contentNumber = content->buildMathMLChild( node ); - if ( contentNumber == -1 ) { - kdWarning( DEBUGID ) << "Empty base in Script" << endl; - return -1; - } - for (int i = 0; i < contentNumber; i++ ) { - if ( node.isNull() ) { - return -1; - } - node = node.nextSibling(); - } - - TQString indexType = node.parentNode().toElement().tagName().lower(); - if ( indexType == "msub" ) { - lowerRight = new SequenceElement( this ); - int lowerRightNumber = lowerRight->buildMathMLChild( node ); - if ( lowerRightNumber == -1 ) { - kdWarning( DEBUGID ) << "Empty subscript in Script" << endl; - return -1; - } - for (int i = 0; i < lowerRightNumber; i++ ) { - if ( node.isNull() ) { - return -1; - } - node = node.nextSibling(); - } - - return 1; - } - - if ( indexType == "msup" ) { - upperRight = new SequenceElement( this ); - int upperRightNumber = upperRight->buildMathMLChild( node ); - if ( upperRightNumber == -1 ) { - kdWarning( DEBUGID ) << "Empty superscript in Script" << endl; - return -1; - } - for (int i = 0; i < upperRightNumber; i++ ) { - if ( node.isNull() ) { - return -1; - } - node = node.nextSibling(); - } - - return 1; - } - - if ( indexType == "msubsup" ) { - lowerRight = new SequenceElement( this ); - int lowerRightNumber = lowerRight->buildMathMLChild( node ); - if ( lowerRightNumber == -1 ) { - kdWarning( DEBUGID ) << "Empty subscript in Script" << endl; - return -1; - } - for (int i = 0; i < lowerRightNumber; i++ ) { - if ( node.isNull() ) { - return -1; - } - node = node.nextSibling(); - } - - upperRight = new SequenceElement( this ); - int upperRightNumber = upperRight->buildMathMLChild( node ); - if ( upperRightNumber == -1 ) { - kdWarning( DEBUGID ) << "Empty superscript in Script" << endl; - return -1; - } - for (int i = 0; i < upperRightNumber; i++ ) { - if ( node.isNull() ) { - return -1; - } - node = node.nextSibling(); - } - - return 1; - } - if ( indexType == "munder" ) { - lowerMiddle = new SequenceElement( this ); - int lowerMiddleNumber = lowerMiddle->buildMathMLChild( node ); - if ( lowerMiddleNumber == -1 ) { - kdWarning( DEBUGID ) << "Empty underscript in Script" << endl; - return -1; - } - for (int i = 0; i < lowerMiddleNumber; i++ ) { - if ( node.isNull() ) { - return -1; - } - node = node.nextSibling(); - } - - return 1; - } - - if ( indexType == "mover" ) { - upperMiddle = new SequenceElement( this ); - int upperMiddleNumber = upperMiddle->buildMathMLChild( node ); - if ( upperMiddleNumber == -1 ) { - kdWarning( DEBUGID ) << "Empty overscript in Script" << endl; - return -1; - } - for (int i = 0; i < upperMiddleNumber; i++ ) { - if ( node.isNull() ) { - return -1; - } - node = node.nextSibling(); - } - - return 1; - } - - if ( indexType == "munderover" ) { - lowerMiddle = new SequenceElement( this ); - int lowerMiddleNumber = lowerMiddle->buildMathMLChild( node ); - if ( lowerMiddleNumber == -1 ) { - kdWarning( DEBUGID ) << "Empty underscript in Script" << endl; - return -1; - } - for (int i = 0; i < lowerMiddleNumber; i++ ) { - if ( node.isNull() ) { - return -1; - } - node = node.nextSibling(); - } - - - upperMiddle = new SequenceElement( this ); - int upperMiddleNumber = upperMiddle->buildMathMLChild( node ); - if ( upperMiddleNumber == -1 ) { - kdWarning( DEBUGID ) << "Empty overscript in Script" << endl; - return -1; - } - for (int i = 0; i < upperMiddleNumber; i++ ) { - if ( node.isNull() ) { - return -1; - } - node = node.nextSibling(); - } - - return 1; - } - // TODO: mmultiscripts, section 3.4.7 - return 1; -} - - -ElementIndexPtr IndexElement::getIndex( int position ) -{ - switch (position) { - case upperRightPos: - return getUpperRight(); - case lowerRightPos: - return getLowerRight(); - case lowerMiddlePos: - return getLowerMiddle(); - case upperMiddlePos: - return getUpperMiddle(); - case lowerLeftPos: - return getLowerLeft(); - case upperLeftPos: - return getUpperLeft(); - } - return getUpperRight(); -} - - - -TQString IndexElement::toLatex() -{ - TQString index; - - if ( hasUpperMiddle() ) { - index += "\\overset{" + upperMiddle->toLatex() + "}{"; - } - - if ( hasLowerMiddle() ) { - index += "\\underset{" + lowerMiddle->toLatex() + "}{"; - } - - if ( hasUpperLeft() || hasUpperRight() ) { //Not sure that this is possible in Latex! - /*index += "{}"; - if ( hasUpperLeft() ) - index += "^" + upperLeft->toLatex(); - if ( hasLowerLeft() ) - index += "_" + lowerLeft->toLatex(); - */ - } - - index += content->toLatex(); - - if ( hasUpperRight() || hasLowerRight() ) { - if ( hasUpperRight() ) - index += "^{" + upperRight->toLatex() + "}"; - if ( hasLowerRight() ) - index += "_{" + lowerRight->toLatex() + "}"; - index += " "; - } - - if ( hasLowerMiddle() ) { - index += "}"; - } - - if ( hasUpperMiddle() ) { - index += "}"; - } - - return index; -} - -TQString IndexElement::formulaString() -{ - TQString index = "(" + content->formulaString() + ")"; - if ( hasLowerRight() ) { - index += "_(" + lowerRight->formulaString() + ")"; - } - if ( hasUpperRight() ) { - index += "**(" + upperRight->formulaString() + ")"; - } - return index; -} - -TQString IndexElement::getElementName() const -{ - if ( hasUpperMiddle() && hasLowerMiddle() ) - return "munderover"; - if ( hasUpperMiddle() ) - return "mover"; - if ( hasLowerMiddle() ) - return "munder"; - if ( hasLowerLeft() || hasUpperLeft() ) - return "mmultiscripts"; - if ( hasLowerRight() || hasUpperRight() ) { - if ( ! hasUpperRight() ) - return "msub"; - if ( ! hasLowerRight() ) - return "msup"; - } - return "msubsup"; -} - -void IndexElement::writeMathMLAttributes( TQDomElement& element ) const -{ - TQString tag = getElementName(); - if ( tag == "msub" || tag == "msubsup" ) { - switch ( m_subScriptShiftType ) { - case AbsoluteSize: - element.setAttribute( "subscriptshift", TQString( "%1pt" ).arg( m_subScriptShift ) ); - break; - case RelativeSize: - element.setAttribute( "subscriptshift", TQString( "%1%" ).arg( m_subScriptShift * 100.0 ) ); - break; - case PixelSize: - element.setAttribute( "subscriptshift", TQString( "%1px" ).arg( m_subScriptShift ) ); - break; - default: - break; - } - } - if ( tag == "msup" || tag == "msubsup" ) { - switch ( m_superScriptShiftType ) { - case AbsoluteSize: - element.setAttribute( "superscriptshift", TQString( "%1pt" ).arg( m_superScriptShift ) ); - break; - case RelativeSize: - element.setAttribute( "superscriptshift", TQString( "%1%" ).arg( m_superScriptShift * 100.0 ) ); - break; - case PixelSize: - element.setAttribute( "superscriptshift", TQString( "%1px" ).arg( m_superScriptShift ) ); - break; - default: - break; - } - } - if ( tag == "munder" || tag == "munderover" ) { - if ( m_customAccentUnder ) { - element.setAttribute( "accentunder", m_accentUnder ? "true" : "false" ); - } - } - if ( tag == "mover" || tag == "munderover" ) { - if ( m_customAccent ) { - element.setAttribute( "accent", m_accent ? "true" : "false" ); - } - } -} - - -void IndexElement::writeMathMLContent( TQDomDocument& doc, - TQDomElement& element, - bool oasisFormat ) const -{ - TQDomElement de; - - content->writeMathML( doc, element, oasisFormat ); // base - if ( hasUpperMiddle() && hasLowerMiddle() ) - { - lowerMiddle->writeMathML( doc, element, oasisFormat ); - upperMiddle->writeMathML( doc, element,oasisFormat ); - } - else if ( hasUpperMiddle() ) - { - upperMiddle->writeMathML( doc, element,oasisFormat ); - } - else if ( hasLowerMiddle() ) - { - lowerMiddle->writeMathML( doc, element,oasisFormat ); - } - - if ( hasLowerLeft() || hasUpperLeft() ) - { - if ( hasLowerRight() ) - lowerRight->writeMathML( doc, element, oasisFormat ); - else - element.appendChild( doc.createElement( "none" ) ); - - if ( hasUpperRight() ) - upperRight->writeMathML( doc, element, oasisFormat ); - else - element.appendChild( doc.createElement( "none" ) ); - - element.appendChild( doc.createElement( "mprescripts" ) ); - - if ( hasLowerLeft() ) - lowerLeft->writeMathML( doc, element, oasisFormat ); - else - element.appendChild( doc.createElement( "none" ) ); - - if ( hasUpperLeft() ) - upperLeft->writeMathML( doc, element, oasisFormat ); - else - element.appendChild( doc.createElement( "none" ) ); - } - else if ( hasLowerRight() || hasUpperRight() ) - { - if ( !hasUpperRight() ) { - lowerRight->writeMathML( doc, element, oasisFormat ); - } - else if ( !hasLowerRight() ) { - upperRight->writeMathML( doc, element, oasisFormat ); - } - else // both - { - lowerRight->writeMathML( doc, element, oasisFormat ); - upperRight->writeMathML( doc, element,oasisFormat ); - } - } -} - -KFORMULA_NAMESPACE_END diff --git a/lib/kformula/indexelement.cpp b/lib/kformula/indexelement.cpp new file mode 100644 index 00000000..6f2f6d1d --- /dev/null +++ b/lib/kformula/indexelement.cpp @@ -0,0 +1,1763 @@ +/* This file is part of the KDE project + Copyright (C) 2001 Andrea Rizzi + Ulrich Kuettler + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include + +#include +#include + +#include "elementvisitor.h" +#include "indexelement.h" +#include "formulacursor.h" +#include "formulaelement.h" +#include "kformulacommand.h" +#include "sequenceelement.h" + + +KFORMULA_NAMESPACE_BEGIN + + +class IndexSequenceElement : public SequenceElement { + typedef SequenceElement inherited; +public: + + IndexSequenceElement( BasicElement* parent = 0 ) : SequenceElement( parent ) {} + virtual IndexSequenceElement* clone() { + return new IndexSequenceElement( *this ); + } + + /** + * This is called by the container to get a command depending on + * the current cursor position (this is how the element gets chosen) + * and the request. + * + * @returns the command that performs the requested action with + * the containers active cursor. + */ + virtual KCommand* buildCommand( Container*, Request* ); +}; + + +KCommand* IndexSequenceElement::buildCommand( Container* container, Request* request ) +{ + FormulaCursor* cursor = container->activeCursor(); + if ( cursor->isReadOnly() ) { + return 0; + } + + switch ( *request ) { + case req_addIndex: { + FormulaCursor* cursor = container->activeCursor(); + if ( cursor->isSelection() || + ( cursor->getPos() > 0 && cursor->getPos() < countChildren() ) ) { + break; + } + IndexElement* element = static_cast( getParent() ); + IndexRequest* ir = static_cast( request ); + ElementIndexPtr index = element->getIndex( ir->index() ); + if ( !index->hasIndex() ) { + KFCAddGenericIndex* command = new KFCAddGenericIndex( container, index ); + return command; + } + else { + index->moveToIndex( cursor, afterCursor ); + cursor->setSelection( false ); + formula()->cursorHasMoved( cursor ); + return 0; + } + } + default: + break; + } + return inherited::buildCommand( container, request ); +} + + +IndexElement::IndexElement(BasicElement* parent) + : BasicElement(parent), + m_subScriptShiftType( NoSize ), + m_superScriptShiftType( NoSize ), + m_customAccentUnder( false ), + m_customAccent ( false ) +{ + content = new IndexSequenceElement( this ); + + upperLeft = 0; + upperMiddle = 0; + upperRight = 0; + lowerLeft = 0; + lowerMiddle = 0; + lowerRight = 0; +} + +IndexElement::~IndexElement() +{ + delete content; + delete upperLeft; + delete upperMiddle; + delete upperRight; + delete lowerLeft; + delete lowerMiddle; + delete lowerRight; +} + + +IndexElement::IndexElement( const IndexElement& other ) + : BasicElement( other ), + m_subScriptShiftType( other.m_subScriptShiftType ), + m_subScriptShift( other.m_subScriptShift ), + m_superScriptShiftType( other.m_superScriptShiftType ), + m_superScriptShift( other.m_superScriptShift ), + m_customAccentUnder( other.m_customAccentUnder ), + m_accentUnder( other.m_accentUnder ), + m_customAccent ( other.m_customAccent ), + m_accent( other.m_accent ) +{ + content = new IndexSequenceElement( *dynamic_cast( other.content ) ); + + if ( other.upperLeft ) { + upperLeft = new SequenceElement( *( other.upperLeft ) ); + upperLeft->setParent( this ); + } + else { + upperLeft = 0; + } + if ( other.upperMiddle ) { + upperMiddle = new SequenceElement( *( other.upperMiddle ) ); + upperMiddle->setParent( this ); + } + else { + upperMiddle = 0; + } + if ( other.upperRight ) { + upperRight = new SequenceElement( *( other.upperRight ) ); + upperRight->setParent( this ); + } + else { + upperRight = 0; + } + + if ( other.lowerLeft ) { + lowerLeft = new SequenceElement( *( other.lowerLeft ) ); + lowerLeft->setParent( this ); + } + else { + lowerLeft = 0; + } + if ( other.lowerMiddle ) { + lowerMiddle = new SequenceElement( *( other.lowerMiddle ) ); + lowerMiddle->setParent( this ); + } + else { + lowerMiddle = 0; + } + if ( other.lowerRight ) { + lowerRight = new SequenceElement( *( other.lowerRight ) ); + lowerRight->setParent( this ); + } + else { + lowerRight = 0; + } +} + + +bool IndexElement::accept( ElementVisitor* visitor ) +{ + return visitor->visit( this ); +} + + +TQChar IndexElement::getCharacter() const +{ + if ( !content->isTextOnly() ) { + return TQChar::null; + } + + if ( hasUpperRight() && !upperRight->isTextOnly() ) { + return TQChar::null; + } + if ( hasUpperMiddle() && !upperMiddle->isTextOnly() ) { + return TQChar::null; + } + if ( hasUpperLeft() && !upperLeft->isTextOnly() ) { + return TQChar::null; + } + if ( hasLowerRight() && !lowerRight->isTextOnly() ) { + return TQChar::null; + } + if ( hasLowerMiddle() && !lowerMiddle->isTextOnly() ) { + return TQChar::null; + } + if ( hasLowerLeft() && !lowerLeft->isTextOnly() ) { + return TQChar::null; + } + + return ' '; +} + +void IndexElement::entered( SequenceElement* child ) +{ + if ( child == content ) { + formula()->tell( i18n( "Indexed list" ) ); + } + else { + formula()->tell( i18n( "Index" ) ); + } +} + + +/** + * Returns the element the point is in. + */ +BasicElement* IndexElement::goToPos( FormulaCursor* cursor, bool& handled, + const LuPixelPoint& point, const LuPixelPoint& parentOrigin ) +{ + BasicElement* e = BasicElement::goToPos(cursor, handled, point, parentOrigin); + if (e != 0) { + LuPixelPoint myPos(parentOrigin.x()+getX(), parentOrigin.y()+getY()); + e = content->goToPos(cursor, handled, point, myPos); + if (e != 0) return e; + + if (hasUpperRight()) { + e = upperRight->goToPos(cursor, handled, point, myPos); + if (e != 0) return e; + } + if (hasUpperMiddle()) { + e = upperMiddle->goToPos(cursor, handled, point, myPos); + if (e != 0) return e; + } + if (hasUpperLeft()) { + e = upperLeft->goToPos(cursor, handled, point, myPos); + if (e != 0) return e; + } + if (hasLowerRight()) { + e = lowerRight->goToPos(cursor, handled, point, myPos); + if (e != 0) return e; + } + if (hasLowerMiddle()) { + e = lowerMiddle->goToPos(cursor, handled, point, myPos); + if (e != 0) return e; + } + if (hasLowerLeft()) { + e = lowerLeft->goToPos(cursor, handled, point, myPos); + if (e != 0) return e; + } + + luPixel dx = point.x() - myPos.x(); + luPixel dy = point.y() - myPos.y(); + + // the positions after the left indexes + if (dx < content->getX()+content->getWidth()) { + if (dy < content->getY()) { + if (hasUpperMiddle() && (dx > upperMiddle->getX())) { + upperMiddle->moveLeft(cursor, this); + handled = true; + return upperMiddle; + } + if (hasUpperLeft() && (dx > upperLeft->getX())) { + upperLeft->moveLeft(cursor, this); + handled = true; + return upperLeft; + } + } + else if (dy > content->getY()+content->getHeight()) { + if (hasLowerMiddle() && (dx > lowerMiddle->getX())) { + lowerMiddle->moveLeft(cursor, this); + handled = true; + return lowerMiddle; + } + if (hasLowerLeft() && (dx > lowerLeft->getX())) { + lowerLeft->moveLeft(cursor, this); + handled = true; + return lowerLeft; + } + } + } + // the positions after the left indexes + else { + if (dy < content->getY()) { + if (hasUpperRight()) { + upperRight->moveLeft(cursor, this); + handled = true; + return upperRight; + } + } + else if (dy > content->getY()+content->getHeight()) { + if (hasLowerRight()) { + lowerRight->moveLeft(cursor, this); + handled = true; + return lowerRight; + } + } + else { + content->moveLeft(cursor, this); + handled = true; + return content; + } + } + + return this; + } + return 0; +} + + +// drawing +// +// Drawing depends on a context which knows the required properties like +// fonts, spaces and such. +// It is essential to calculate elements size with the same context +// before you draw. + + +void IndexElement::setMiddleX(int xOffset, int middleWidth) +{ + content->setX(xOffset + (middleWidth - content->getWidth()) / 2); + if (hasUpperMiddle()) { + upperMiddle->setX(xOffset + (middleWidth - upperMiddle->getWidth()) / 2); + } + if (hasLowerMiddle()) { + lowerMiddle->setX(xOffset + (middleWidth - lowerMiddle->getWidth()) / 2); + } +} + + +/** + * Calculates our width and height and + * our children's parentPosition. + */ +void IndexElement::calcSizes(const ContextStyle& context, + ContextStyle::TextStyle tstyle, + ContextStyle::IndexStyle istyle, + StyleAttributes& style ) +{ + double factor = style.sizeFactor(); + luPixel distY = context.ptToPixelY( context.getThinSpace( tstyle, factor ) ); + + ContextStyle::TextStyle i_tstyle = context.convertTextStyleIndex(tstyle); + ContextStyle::IndexStyle u_istyle = context.convertIndexStyleUpper( istyle ); + ContextStyle::IndexStyle l_istyle = context.convertIndexStyleLower( istyle ); + + // get the indexes size + luPixel ulWidth = 0, ulHeight = 0, ulMidline = 0; + if (hasUpperLeft()) { + upperLeft->calcSizes( context, i_tstyle, u_istyle, style ); + ulWidth = upperLeft->getWidth(); + ulHeight = upperLeft->getHeight(); + ulMidline = upperLeft->axis( context, i_tstyle, factor ); + } + + luPixel umWidth = 0, umHeight = 0, umMidline = 0; + if (hasUpperMiddle()) { + upperMiddle->calcSizes( context, i_tstyle, u_istyle, style ); + umWidth = upperMiddle->getWidth(); + umHeight = upperMiddle->getHeight() + distY; + umMidline = upperMiddle->axis( context, i_tstyle, factor ); + } + + luPixel urWidth = 0, urHeight = 0, urMidline = 0; + if (hasUpperRight()) { + upperRight->calcSizes( context, i_tstyle, u_istyle, style ); + urWidth = upperRight->getWidth(); + urHeight = upperRight->getHeight(); + urMidline = upperRight->axis( context, i_tstyle, factor ); + } + + luPixel llWidth = 0, llHeight = 0, llMidline = 0; + if (hasLowerLeft()) { + lowerLeft->calcSizes( context, i_tstyle, l_istyle, style ); + llWidth = lowerLeft->getWidth(); + llHeight = lowerLeft->getHeight(); + llMidline = lowerLeft->axis( context, i_tstyle, factor ); + } + + luPixel lmWidth = 0, lmHeight = 0, lmMidline = 0; + if (hasLowerMiddle()) { + lowerMiddle->calcSizes( context, i_tstyle, l_istyle, style ); + lmWidth = lowerMiddle->getWidth(); + lmHeight = lowerMiddle->getHeight() + distY; + lmMidline = lowerMiddle->axis( context, i_tstyle, factor ); + } + + luPixel lrWidth = 0, lrHeight = 0, lrMidline = 0; + if (hasLowerRight()) { + lowerRight->calcSizes( context, i_tstyle, l_istyle, style ); + lrWidth = lowerRight->getWidth(); + lrHeight = lowerRight->getHeight(); + lrMidline = lowerRight->axis( context, i_tstyle, factor ); + } + + // get the contents size + content->calcSizes( context, tstyle, istyle, style ); + luPixel width = TQMAX(content->getWidth(), TQMAX(umWidth, lmWidth)); + luPixel toMidline = content->axis( context, tstyle, factor ); + luPixel fromMidline = content->getHeight() - toMidline; + + // calculate the x offsets + if (ulWidth > llWidth) { + upperLeft->setX(0); + if (hasLowerLeft()) { + lowerLeft->setX(ulWidth - llWidth); + } + setMiddleX(ulWidth, width); + width += ulWidth; + } + else { + if (hasUpperLeft()) { + upperLeft->setX(llWidth - ulWidth); + } + if (hasLowerLeft()) { + lowerLeft->setX(0); + } + setMiddleX(llWidth, width); + width += llWidth; + } + + if (hasUpperRight()) { + upperRight->setX(width); + } + if (hasLowerRight()) { + lowerRight->setX(width); + } + width += TQMAX(urWidth, lrWidth); + + // calculate the y offsets + luPixel ulOffset = 0; + luPixel urOffset = 0; + luPixel llOffset = 0; + luPixel lrOffset = 0; + if (content->isTextOnly()) { + luPt mySize = context.getAdjustedSize( tstyle, factor ); + TQFont font = context.getDefaultFont(); + font.setPointSizeFloat( context.layoutUnitPtToPt( mySize ) ); + + TQFontMetrics fm(font); + LuPixelRect bound = fm.boundingRect('x'); + + luPixel exBaseline = context.ptToLayoutUnitPt( -bound.top() ); + + // the upper half + ulOffset = ulHeight + exBaseline - content->getBaseline(); + urOffset = urHeight + exBaseline - content->getBaseline(); + + // the lower half + llOffset = lrOffset = content->getBaseline(); + } + else { + + // the upper half + ulOffset = TQMAX(ulMidline, ulHeight-toMidline); + urOffset = TQMAX(urMidline, urHeight-toMidline); + + // the lower half + llOffset = TQMAX(content->getHeight()-llMidline, toMidline); + lrOffset = TQMAX(content->getHeight()-lrMidline, toMidline); + } + + // Add more offset if defined in attributes + switch ( m_superScriptShiftType ) { + case AbsoluteSize: + urOffset += context.ptToLayoutUnitPt( m_superScriptShift ); + break; + case RelativeSize: + urOffset += urOffset * m_superScriptShift; + break; + case PixelSize: + urOffset += context.pixelToLayoutUnitY( m_superScriptShift ); + break; + default: + break; + } + + switch ( m_subScriptShiftType ) { + case AbsoluteSize: + lrOffset += context.ptToLayoutUnitPt( m_subScriptShift ); + break; + case RelativeSize: + lrOffset += lrOffset * m_subScriptShift; + break; + case PixelSize: + lrOffset += context.pixelToLayoutUnitY( m_subScriptShift ); + break; + default: + break; + } + + luPixel height = TQMAX(umHeight, TQMAX(ulOffset, urOffset)); + + // the upper half + content->setY(height); + toMidline += height; + if (hasUpperLeft()) { + upperLeft->setY(height-ulOffset); + } + if (hasUpperMiddle()) { + upperMiddle->setY(height-umHeight); + } + if (hasUpperRight()) { + upperRight->setY( height - urOffset ); + } + + // the lower half + if (hasLowerLeft()) { + lowerLeft->setY(height+llOffset); + } + if (hasLowerMiddle()) { + lowerMiddle->setY(height+content->getHeight()+distY); + } + if (hasLowerRight()) { + lowerRight->setY( height + lrOffset ); + } + + fromMidline += TQMAX(TQMAX(llHeight+llOffset, lrHeight+lrOffset) - content->getHeight(), lmHeight); + + // set the result + setWidth(width); + setHeight(toMidline+fromMidline); + if (content->isTextOnly()) { + setBaseline(content->getY() + content->getBaseline()); + //setMidline(content->getY() + content->getMidline()); + } + else { + //setMidline(toMidline); + setBaseline(content->getBaseline() + content->getY()); + } +} + +/** + * Draws the whole element including its children. + * The `parentOrigin' is the point this element's parent starts. + * We can use our parentPosition to get our own origin then. + */ +void IndexElement::draw( TQPainter& painter, const LuPixelRect& r, + const ContextStyle& context, + ContextStyle::TextStyle tstyle, + ContextStyle::IndexStyle istyle, + StyleAttributes& style, + const LuPixelPoint& parentOrigin ) +{ + LuPixelPoint myPos( parentOrigin.x()+getX(), parentOrigin.y()+getY() ); + //if ( !LuPixelRect( myPos.x(), myPos.y(), getWidth(), getHeight() ).intersects( r ) ) + // return; + + ContextStyle::TextStyle i_tstyle = context.convertTextStyleIndex(tstyle); + ContextStyle::IndexStyle u_istyle = context.convertIndexStyleUpper( istyle ); + ContextStyle::IndexStyle l_istyle = context.convertIndexStyleLower( istyle ); + + content->draw(painter, r, context, tstyle, istyle, style, myPos); + if (hasUpperLeft()) { + upperLeft->draw(painter, r, context, i_tstyle, u_istyle, style, myPos); + } + if (hasUpperMiddle()) { + upperMiddle->draw(painter, r, context, i_tstyle, u_istyle, style, myPos); + } + if (hasUpperRight()) { + upperRight->draw(painter, r, context, i_tstyle, u_istyle, style, myPos); + } + if (hasLowerLeft()) { + lowerLeft->draw(painter, r, context, i_tstyle, l_istyle, style, myPos); + } + if (hasLowerMiddle()) { + lowerMiddle->draw(painter, r, context, i_tstyle, l_istyle, style, myPos); + } + if (hasLowerRight()) { + lowerRight->draw(painter, r, context, i_tstyle, l_istyle, style, myPos); + } + + // Debug + //painter.setBrush(TQt::NoBrush); + //painter.setPen(TQt::red); + //painter.drawRect(myPos.x(), myPos.y(), getWidth(), getHeight()); + //painter.drawLine(myPos.x(), myPos.y()+getMidline(), + // myPos.x()+getWidth(), myPos.y()+getMidline()); +} + + +void IndexElement::dispatchFontCommand( FontCommand* cmd ) +{ + content->dispatchFontCommand( cmd ); + if (hasUpperLeft()) { + upperLeft->dispatchFontCommand( cmd ); + } + if (hasUpperMiddle()) { + upperMiddle->dispatchFontCommand( cmd ); + } + if (hasUpperRight()) { + upperRight->dispatchFontCommand( cmd ); + } + if (hasLowerLeft()) { + lowerLeft->dispatchFontCommand( cmd ); + } + if (hasLowerMiddle()) { + lowerMiddle->dispatchFontCommand( cmd ); + } + if (hasLowerRight()) { + lowerRight->dispatchFontCommand( cmd ); + } +} + + +// navigation +// +// The elements are responsible to handle cursor movement themselves. +// To do this they need to know the direction the cursor moves and +// the element it comes from. +// +// The cursor might be in normal or in selection mode. + +int IndexElement::getFromPos(BasicElement* from) +{ + if (from == lowerRight) { + return lowerRightPos; + } + else if (from == upperRight) { + return upperRightPos; + } + else if (from == lowerMiddle) { + return lowerMiddlePos; + } + else if (from == content) { + return contentPos; + } + else if (from == upperMiddle) { + return upperMiddlePos; + } + else if (from == lowerLeft) { + return lowerLeftPos; + } + else if (from == upperLeft) { + return upperLeftPos; + } + return parentPos; +} + +/** + * Enters this element while moving to the left starting inside + * the element `from'. Searches for a cursor position inside + * this element or to the left of it. + */ +void IndexElement::moveLeft(FormulaCursor* cursor, BasicElement* from) +{ + if (cursor->isSelectionMode()) { + getParent()->moveLeft(cursor, this); + } + else { + bool linear = cursor->getLinearMovement(); + int fromPos = getFromPos(from); + if (!linear) { + if ((fromPos == lowerRightPos) && hasLowerMiddle()) { + lowerMiddle->moveLeft(cursor, this); + return; + } + else if ((fromPos == upperRightPos) && hasUpperMiddle()) { + upperMiddle->moveLeft(cursor, this); + return; + } + else if ((fromPos == lowerMiddlePos) && hasLowerLeft()) { + lowerLeft->moveLeft(cursor, this); + return; + } + else if ((fromPos == upperMiddlePos) && hasUpperLeft()) { + upperLeft->moveLeft(cursor, this); + return; + } + } + switch (fromPos) { + case parentPos: + if (hasLowerRight() && linear) { + lowerRight->moveLeft(cursor, this); + break; + } + case lowerRightPos: + if (hasUpperRight() && linear) { + upperRight->moveLeft(cursor, this); + break; + } + case upperRightPos: + if (hasLowerMiddle() && linear) { + lowerMiddle->moveLeft(cursor, this); + break; + } + case lowerMiddlePos: + content->moveLeft(cursor, this); + break; + case contentPos: + if (hasUpperMiddle() && linear) { + upperMiddle->moveLeft(cursor, this); + break; + } + case upperMiddlePos: + if (hasLowerLeft() && linear) { + lowerLeft->moveLeft(cursor, this); + break; + } + case lowerLeftPos: + if (hasUpperLeft() && linear) { + upperLeft->moveLeft(cursor, this); + break; + } + case upperLeftPos: + getParent()->moveLeft(cursor, this); + } + } +} + +/** + * Enters this element while moving to the right starting inside + * the element `from'. Searches for a cursor position inside + * this element or to the right of it. + */ +void IndexElement::moveRight(FormulaCursor* cursor, BasicElement* from) +{ + if (cursor->isSelectionMode()) { + getParent()->moveRight(cursor, this); + } + else { + bool linear = cursor->getLinearMovement(); + int fromPos = getFromPos(from); + if (!linear) { + if ((fromPos == lowerLeftPos) && hasLowerMiddle()) { + lowerMiddle->moveRight(cursor, this); + return; + } + else if ((fromPos == upperLeftPos) && hasUpperMiddle()) { + upperMiddle->moveRight(cursor, this); + return; + } + else if ((fromPos == lowerMiddlePos) && hasLowerRight()) { + lowerRight->moveRight(cursor, this); + return; + } + else if ((fromPos == upperMiddlePos) && hasUpperRight()) { + upperRight->moveRight(cursor, this); + return; + } + } + switch (fromPos) { + case parentPos: + if (hasUpperLeft() && linear) { + upperLeft->moveRight(cursor, this); + break; + } + case upperLeftPos: + if (hasLowerLeft() && linear) { + lowerLeft->moveRight(cursor, this); + break; + } + case lowerLeftPos: + if (hasUpperMiddle() && linear) { + upperMiddle->moveRight(cursor, this); + break; + } + case upperMiddlePos: + content->moveRight(cursor, this); + break; + case contentPos: + if (hasLowerMiddle() && linear) { + lowerMiddle->moveRight(cursor, this); + break; + } + case lowerMiddlePos: + if (hasUpperRight() && linear) { + upperRight->moveRight(cursor, this); + break; + } + case upperRightPos: + if (hasLowerRight() && linear) { + lowerRight->moveRight(cursor, this); + break; + } + case lowerRightPos: + getParent()->moveRight(cursor, this); + } + } +} + +/** + * Enters this element while moving up starting inside + * the element `from'. Searches for a cursor position inside + * this element or above it. + */ +void IndexElement::moveUp(FormulaCursor* cursor, BasicElement* from) +{ + if (cursor->isSelectionMode()) { + getParent()->moveUp(cursor, this); + } + else { + if (from == content) { + if ((cursor->getPos() == 0) && (cursor->getElement() == from)) { + if (hasUpperLeft()) { + upperLeft->moveLeft(cursor, this); + return; + } + else if (hasUpperMiddle()) { + upperMiddle->moveRight(cursor, this); + return; + } + } + if (hasUpperRight()) { + upperRight->moveRight(cursor, this); + } + else if (hasUpperMiddle()) { + upperMiddle->moveLeft(cursor, this); + } + else if (hasUpperLeft()) { + upperLeft->moveLeft(cursor, this); + } + else { + getParent()->moveUp(cursor, this); + } + } + else if ((from == upperLeft) || (from == upperMiddle) || (from == upperRight)) { + getParent()->moveUp(cursor, this); + } + else if ((from == getParent()) || (from == lowerLeft) || (from == lowerMiddle)) { + content->moveRight(cursor, this); + } + else if (from == lowerRight) { + content->moveLeft(cursor, this); + } + } +} + +/** + * Enters this element while moving down starting inside + * the element `from'. Searches for a cursor position inside + * this element or below it. + */ +void IndexElement::moveDown(FormulaCursor* cursor, BasicElement* from) +{ + if (cursor->isSelectionMode()) { + getParent()->moveDown(cursor, this); + } + else { + if (from == content) { + if ((cursor->getPos() == 0) && (cursor->getElement() == from)) { + if (hasLowerLeft()) { + lowerLeft->moveLeft(cursor, this); + return; + } + else if (hasLowerMiddle()) { + lowerMiddle->moveRight(cursor, this); + return; + } + } + if (hasLowerRight()) { + lowerRight->moveRight(cursor, this); + } + else if (hasLowerMiddle()) { + lowerMiddle->moveLeft(cursor, this); + } + else if (hasLowerLeft()) { + lowerLeft->moveLeft(cursor, this); + } + else { + getParent()->moveDown(cursor, this); + } + } + else if ((from == lowerLeft) || (from == lowerMiddle) || (from == lowerRight)) { + getParent()->moveDown(cursor, this); + } + else if ((from == getParent()) || (from == upperLeft) || (from == upperMiddle)) { + content->moveRight(cursor, this); + } + if (from == upperRight) { + content->moveLeft(cursor, this); + } + } +} + + +// children + + +// main child +// +// If an element has children one has to become the main one. + +// void IndexElement::setMainChild(SequenceElement* child) +// { +// formula()->elementRemoval(content); +// content = child; +// content->setParent(this); +// formula()->changed(); +// } + + +/** + * Inserts all new children at the cursor position. Places the + * cursor according to the direction. + * + * You only can insert one index at a time. So the list must contain + * exactly on SequenceElement. And the index you want to insert + * must not exist already. + * + * The list will be emptied but stays the property of the caller. + */ +void IndexElement::insert(FormulaCursor* cursor, + TQPtrList& newChildren, + Direction direction) +{ + SequenceElement* index = static_cast(newChildren.take(0)); + index->setParent(this); + + switch (cursor->getPos()) { + case upperLeftPos: + upperLeft = index; + break; + case lowerLeftPos: + lowerLeft = index; + break; + case upperMiddlePos: + upperMiddle = index; + break; + case lowerMiddlePos: + lowerMiddle = index; + break; + case upperRightPos: + upperRight = index; + break; + case lowerRightPos: + lowerRight = index; + break; + default: + // this is an error! + return; + } + + if (direction == beforeCursor) { + index->moveLeft(cursor, this); + } + else { + index->moveRight(cursor, this); + } + cursor->setSelection(false); + formula()->changed(); +} + + +/** + * Removes all selected children and returns them. Places the + * cursor to where the children have been. + * + * The cursor has to be inside one of our indexes which is supposed + * to be empty. The index will be removed and the cursor will + * be placed to the removed index so it can be inserted again. + * This methode is called by SequenceElement::remove only. + * + * The ownership of the list is passed to the caller. + */ +void IndexElement::remove(FormulaCursor* cursor, + TQPtrList& removedChildren, + Direction direction) +{ + int pos = cursor->getPos(); + switch (pos) { + case upperLeftPos: + removedChildren.append(upperLeft); + formula()->elementRemoval(upperLeft); + upperLeft = 0; + setToUpperLeft(cursor); + break; + case lowerLeftPos: + removedChildren.append(lowerLeft); + formula()->elementRemoval(lowerLeft); + lowerLeft = 0; + setToLowerLeft(cursor); + break; + case contentPos: { + BasicElement* parent = getParent(); + parent->selectChild(cursor, this); + parent->remove(cursor, removedChildren, direction); + break; + } + case upperMiddlePos: + removedChildren.append(upperMiddle); + formula()->elementRemoval(upperMiddle); + upperMiddle = 0; + setToUpperMiddle(cursor); + break; + case lowerMiddlePos: + removedChildren.append(lowerMiddle); + formula()->elementRemoval(lowerMiddle); + lowerMiddle = 0; + setToLowerMiddle(cursor); + break; + case upperRightPos: + removedChildren.append(upperRight); + formula()->elementRemoval(upperRight); + upperRight = 0; + setToUpperRight(cursor); + break; + case lowerRightPos: + removedChildren.append(lowerRight); + formula()->elementRemoval(lowerRight); + lowerRight = 0; + setToLowerRight(cursor); + break; + } + formula()->changed(); +} + +/** + * Moves the cursor to a normal place where new elements + * might be inserted. + */ +void IndexElement::normalize(FormulaCursor* cursor, Direction direction) +{ + if (direction == beforeCursor) { + content->moveLeft(cursor, this); + } + else { + content->moveRight(cursor, this); + } +} + +/** + * Returns wether the element has no more useful + * children (except its main child) and should therefore + * be replaced by its main child's content. + */ +bool IndexElement::isSenseless() +{ + return !hasUpperLeft() && !hasUpperRight() && !hasUpperMiddle() && + !hasLowerLeft() && !hasLowerRight() && !hasLowerMiddle(); +} + + +/** + * Returns the child at the cursor. + */ +BasicElement* IndexElement::getChild(FormulaCursor* cursor, Direction) +{ + int pos = cursor->getPos(); + /* + It makes no sense to care for the direction. + if (direction == beforeCursor) { + pos -= 1; + } + */ + switch (pos) { + case contentPos: + return content; + case upperLeftPos: + return upperLeft; + case lowerLeftPos: + return lowerLeft; + case upperMiddlePos: + return upperMiddle; + case lowerMiddlePos: + return lowerMiddle; + case upperRightPos: + return upperRight; + case lowerRightPos: + return lowerRight; + } + return 0; +} + + +/** + * Sets the cursor to select the child. The mark is placed before, + * the position behind it. + */ +void IndexElement::selectChild(FormulaCursor* cursor, BasicElement* child) +{ + if (child == content) { + setToContent(cursor); + } + else if (child == upperLeft) { + setToUpperLeft(cursor); + } + else if (child == lowerLeft) { + setToLowerLeft(cursor); + } + else if (child == upperMiddle) { + setToUpperMiddle(cursor); + } + else if (child == lowerMiddle) { + setToLowerMiddle(cursor); + } + else if (child == upperRight) { + setToUpperRight(cursor); + } + else if (child == lowerRight) { + setToLowerRight(cursor); + } +} + + +/** + * Sets the cursor to point to the place where the content is. + * There always is a content so this is not a useful place. + * No insertion or removal will succeed as long as the cursor is + * there. + */ +void IndexElement::setToContent(FormulaCursor* cursor) +{ + cursor->setTo(this, contentPos); +} + +// point the cursor to a gap where an index is to be inserted. +// this makes no sense if there is such an index already. + +void IndexElement::setToUpperLeft(FormulaCursor* cursor) +{ + cursor->setTo(this, upperLeftPos); +} + +void IndexElement::setToUpperMiddle(FormulaCursor* cursor) +{ + cursor->setTo(this, upperMiddlePos); +} + +void IndexElement::setToUpperRight(FormulaCursor* cursor) +{ + cursor->setTo(this, upperRightPos); +} + +void IndexElement::setToLowerLeft(FormulaCursor* cursor) +{ + cursor->setTo(this, lowerLeftPos); +} + +void IndexElement::setToLowerMiddle(FormulaCursor* cursor) +{ + cursor->setTo(this, lowerMiddlePos); +} + +void IndexElement::setToLowerRight(FormulaCursor* cursor) +{ + cursor->setTo(this, lowerRightPos); +} + + +// move inside an index that exists already. + +void IndexElement::moveToUpperLeft(FormulaCursor* cursor, Direction direction) +{ + if (hasUpperLeft()) { + if (direction == beforeCursor) { + upperLeft->moveLeft(cursor, this); + } + else { + upperLeft->moveRight(cursor, this); + } + } +} + +void IndexElement::moveToUpperMiddle(FormulaCursor* cursor, Direction direction) +{ + if (hasUpperMiddle()) { + if (direction == beforeCursor) { + upperMiddle->moveLeft(cursor, this); + } + else { + upperMiddle->moveRight(cursor, this); + } + } +} + +void IndexElement::moveToUpperRight(FormulaCursor* cursor, Direction direction) +{ + if (hasUpperRight()) { + if (direction == beforeCursor) { + upperRight->moveLeft(cursor, this); + } + else { + upperRight->moveRight(cursor, this); + } + } +} + +void IndexElement::moveToLowerLeft(FormulaCursor* cursor, Direction direction) +{ + if (hasLowerLeft()) { + if (direction == beforeCursor) { + lowerLeft->moveLeft(cursor, this); + } + else { + lowerLeft->moveRight(cursor, this); + } + } +} + +void IndexElement::moveToLowerMiddle(FormulaCursor* cursor, Direction direction) +{ + if (hasLowerMiddle()) { + if (direction == beforeCursor) { + lowerMiddle->moveLeft(cursor, this); + } + else { + lowerMiddle->moveRight(cursor, this); + } + } +} + +void IndexElement::moveToLowerRight(FormulaCursor* cursor, Direction direction) +{ + if (hasLowerRight()) { + if (direction == beforeCursor) { + lowerRight->moveLeft(cursor, this); + } + else { + lowerRight->moveRight(cursor, this); + } + } +} + + +/** + * Appends our attributes to the dom element. + */ +void IndexElement::writeDom(TQDomElement element) +{ + BasicElement::writeDom(element); + + TQDomDocument doc = element.ownerDocument(); + + TQDomElement cont = doc.createElement("CONTENT"); + cont.appendChild(content->getElementDom(doc)); + element.appendChild(cont); + + if (hasUpperLeft()) { + TQDomElement ind = doc.createElement("UPPERLEFT"); + ind.appendChild(upperLeft->getElementDom(doc)); + element.appendChild(ind); + } + if (hasUpperMiddle()) { + TQDomElement ind = doc.createElement("UPPERMIDDLE"); + ind.appendChild(upperMiddle->getElementDom(doc)); + element.appendChild(ind); + } + if (hasUpperRight()) { + TQDomElement ind = doc.createElement("UPPERRIGHT"); + ind.appendChild(upperRight->getElementDom(doc)); + element.appendChild(ind); + } + if (hasLowerLeft()) { + TQDomElement ind = doc.createElement("LOWERLEFT"); + ind.appendChild(lowerLeft->getElementDom(doc)); + element.appendChild(ind); + } + if (hasLowerMiddle()) { + TQDomElement ind = doc.createElement("LOWERMIDDLE"); + ind.appendChild(lowerMiddle->getElementDom(doc)); + element.appendChild(ind); + } + if (hasLowerRight()) { + TQDomElement ind = doc.createElement("LOWERRIGHT"); + ind.appendChild(lowerRight->getElementDom(doc)); + element.appendChild(ind); + } +} + +/** + * Reads our attributes from the element. + * Returns false if it failed. + */ +bool IndexElement::readAttributesFromDom(TQDomElement element) +{ + if (!BasicElement::readAttributesFromDom(element)) { + return false; + } + return true; +} + +/** + * Reads our content from the node. Sets the node to the next node + * that needs to be read. + * Returns false if it failed. + */ +bool IndexElement::readContentFromDom(TQDomNode& node) +{ + if (!BasicElement::readContentFromDom(node)) { + return false; + } + + if ( !buildChild( content, node, "CONTENT" ) ) { + kdWarning( DEBUGID ) << "Empty content in IndexElement." << endl; + return false; + } + node = node.nextSibling(); + + bool upperLeftRead = false; + bool upperMiddleRead = false; + bool upperRightRead = false; + bool lowerLeftRead = false; + bool lowerMiddleRead = false; + bool lowerRightRead = false; + + while (!node.isNull() && + !(upperLeftRead && upperMiddleRead && upperRightRead && + lowerLeftRead && lowerMiddleRead && lowerRightRead)) { + + if (!upperLeftRead && (node.nodeName().upper() == "UPPERLEFT")) { + upperLeftRead = buildChild( upperLeft=new SequenceElement( this ), node, "UPPERLEFT" ); + if ( !upperLeftRead ) return false; + } + + if (!upperMiddleRead && (node.nodeName().upper() == "UPPERMIDDLE")) { + upperMiddleRead = buildChild( upperMiddle=new SequenceElement( this ), node, "UPPERMIDDLE" ); + if ( !upperMiddleRead ) return false; + } + + if (!upperRightRead && (node.nodeName().upper() == "UPPERRIGHT")) { + upperRightRead = buildChild( upperRight=new SequenceElement( this ), node, "UPPERRIGHT" ); + if ( !upperRightRead ) return false; + } + + if (!lowerLeftRead && (node.nodeName().upper() == "LOWERLEFT")) { + lowerLeftRead = buildChild( lowerLeft=new SequenceElement( this ), node, "LOWERLEFT" ); + if ( !lowerLeftRead ) return false; + } + + if (!lowerMiddleRead && (node.nodeName().upper() == "LOWERMIDDLE")) { + lowerMiddleRead = buildChild( lowerMiddle=new SequenceElement( this ), node, "LOWERMIDDLE" ); + if ( !lowerMiddleRead ) return false; + } + + if (!lowerRightRead && (node.nodeName().upper() == "LOWERRIGHT")) { + lowerRightRead = buildChild( lowerRight=new SequenceElement( this ), node, "LOWERRIGHT" ); + if ( !lowerRightRead ) return false; + } + + node = node.nextSibling(); + } + return upperLeftRead || upperMiddleRead || upperRightRead || + lowerLeftRead || lowerMiddleRead || lowerRightRead; +} + +bool IndexElement::readAttributesFromMathMLDom( const TQDomElement& element ) +{ + if ( !BasicElement::readAttributesFromMathMLDom( element ) ) { + return false; + } + + TQString tag = element.tagName().stripWhiteSpace().lower(); + if ( tag == "msub" || tag == "msubsup" ) { + TQString subscriptshiftStr = element.attribute( "subscriptshift" ).stripWhiteSpace().lower(); + if ( ! subscriptshiftStr.isNull() ) { + m_subScriptShift = getSize( subscriptshiftStr, &m_subScriptShiftType ); + } + } + if ( tag == "msup" || tag == "msubsup" ) { + TQString superscriptshiftStr = element.attribute( "superscriptshift" ).stripWhiteSpace().lower(); + if ( ! superscriptshiftStr.isNull() ) { + m_superScriptShift = getSize( superscriptshiftStr, &m_superScriptShiftType ); + } + } + + if ( tag == "munder" || tag == "munderover" ) { + TQString accentunderStr = element.attribute( "accentunder" ).stripWhiteSpace().lower(); + if ( ! accentunderStr.isNull() ) { + if ( accentunderStr == "true" ) { + m_customAccentUnder = true; + m_accentUnder = true; + } + else if ( accentunderStr == "false" ) { + m_customAccentUnder = true; + m_accentUnder = false; + } + else { + kdWarning( DEBUGID ) << "Invalid value for attribute `accentunder': " + << accentunderStr << endl; + } + } + } + if ( tag == "mover" || tag == "munderover" ) { + TQString accentStr = element.attribute( "accent" ).stripWhiteSpace().lower(); + if ( ! accentStr.isNull() ) { + if ( accentStr == "true" ) { + m_customAccent = true; + m_accent = true; + } + else if ( accentStr == "false" ) { + m_customAccent = true; + m_accent = false; + } + else { + kdWarning( DEBUGID ) << "Invalid value for attribute `accent': " + << accentStr << endl; + } + } + } + return true; +} + +/** + * Reads our content from the MathML node. Sets the node to the next node + * that needs to be read. It is sometimes needed to read more than one node + * (e. g. for fence operators). + * Returns the number of nodes processed or -1 if it failed. + */ +int IndexElement::readContentFromMathMLDom( TQDomNode& node ) +{ + if ( BasicElement::readContentFromMathMLDom( node ) == -1 ) { + return -1; + } + + int contentNumber = content->buildMathMLChild( node ); + if ( contentNumber == -1 ) { + kdWarning( DEBUGID ) << "Empty base in Script" << endl; + return -1; + } + for (int i = 0; i < contentNumber; i++ ) { + if ( node.isNull() ) { + return -1; + } + node = node.nextSibling(); + } + + TQString indexType = node.parentNode().toElement().tagName().lower(); + if ( indexType == "msub" ) { + lowerRight = new SequenceElement( this ); + int lowerRightNumber = lowerRight->buildMathMLChild( node ); + if ( lowerRightNumber == -1 ) { + kdWarning( DEBUGID ) << "Empty subscript in Script" << endl; + return -1; + } + for (int i = 0; i < lowerRightNumber; i++ ) { + if ( node.isNull() ) { + return -1; + } + node = node.nextSibling(); + } + + return 1; + } + + if ( indexType == "msup" ) { + upperRight = new SequenceElement( this ); + int upperRightNumber = upperRight->buildMathMLChild( node ); + if ( upperRightNumber == -1 ) { + kdWarning( DEBUGID ) << "Empty superscript in Script" << endl; + return -1; + } + for (int i = 0; i < upperRightNumber; i++ ) { + if ( node.isNull() ) { + return -1; + } + node = node.nextSibling(); + } + + return 1; + } + + if ( indexType == "msubsup" ) { + lowerRight = new SequenceElement( this ); + int lowerRightNumber = lowerRight->buildMathMLChild( node ); + if ( lowerRightNumber == -1 ) { + kdWarning( DEBUGID ) << "Empty subscript in Script" << endl; + return -1; + } + for (int i = 0; i < lowerRightNumber; i++ ) { + if ( node.isNull() ) { + return -1; + } + node = node.nextSibling(); + } + + upperRight = new SequenceElement( this ); + int upperRightNumber = upperRight->buildMathMLChild( node ); + if ( upperRightNumber == -1 ) { + kdWarning( DEBUGID ) << "Empty superscript in Script" << endl; + return -1; + } + for (int i = 0; i < upperRightNumber; i++ ) { + if ( node.isNull() ) { + return -1; + } + node = node.nextSibling(); + } + + return 1; + } + if ( indexType == "munder" ) { + lowerMiddle = new SequenceElement( this ); + int lowerMiddleNumber = lowerMiddle->buildMathMLChild( node ); + if ( lowerMiddleNumber == -1 ) { + kdWarning( DEBUGID ) << "Empty underscript in Script" << endl; + return -1; + } + for (int i = 0; i < lowerMiddleNumber; i++ ) { + if ( node.isNull() ) { + return -1; + } + node = node.nextSibling(); + } + + return 1; + } + + if ( indexType == "mover" ) { + upperMiddle = new SequenceElement( this ); + int upperMiddleNumber = upperMiddle->buildMathMLChild( node ); + if ( upperMiddleNumber == -1 ) { + kdWarning( DEBUGID ) << "Empty overscript in Script" << endl; + return -1; + } + for (int i = 0; i < upperMiddleNumber; i++ ) { + if ( node.isNull() ) { + return -1; + } + node = node.nextSibling(); + } + + return 1; + } + + if ( indexType == "munderover" ) { + lowerMiddle = new SequenceElement( this ); + int lowerMiddleNumber = lowerMiddle->buildMathMLChild( node ); + if ( lowerMiddleNumber == -1 ) { + kdWarning( DEBUGID ) << "Empty underscript in Script" << endl; + return -1; + } + for (int i = 0; i < lowerMiddleNumber; i++ ) { + if ( node.isNull() ) { + return -1; + } + node = node.nextSibling(); + } + + + upperMiddle = new SequenceElement( this ); + int upperMiddleNumber = upperMiddle->buildMathMLChild( node ); + if ( upperMiddleNumber == -1 ) { + kdWarning( DEBUGID ) << "Empty overscript in Script" << endl; + return -1; + } + for (int i = 0; i < upperMiddleNumber; i++ ) { + if ( node.isNull() ) { + return -1; + } + node = node.nextSibling(); + } + + return 1; + } + // TODO: mmultiscripts, section 3.4.7 + return 1; +} + + +ElementIndexPtr IndexElement::getIndex( int position ) +{ + switch (position) { + case upperRightPos: + return getUpperRight(); + case lowerRightPos: + return getLowerRight(); + case lowerMiddlePos: + return getLowerMiddle(); + case upperMiddlePos: + return getUpperMiddle(); + case lowerLeftPos: + return getLowerLeft(); + case upperLeftPos: + return getUpperLeft(); + } + return getUpperRight(); +} + + + +TQString IndexElement::toLatex() +{ + TQString index; + + if ( hasUpperMiddle() ) { + index += "\\overset{" + upperMiddle->toLatex() + "}{"; + } + + if ( hasLowerMiddle() ) { + index += "\\underset{" + lowerMiddle->toLatex() + "}{"; + } + + if ( hasUpperLeft() || hasUpperRight() ) { //Not sure that this is possible in Latex! + /*index += "{}"; + if ( hasUpperLeft() ) + index += "^" + upperLeft->toLatex(); + if ( hasLowerLeft() ) + index += "_" + lowerLeft->toLatex(); + */ + } + + index += content->toLatex(); + + if ( hasUpperRight() || hasLowerRight() ) { + if ( hasUpperRight() ) + index += "^{" + upperRight->toLatex() + "}"; + if ( hasLowerRight() ) + index += "_{" + lowerRight->toLatex() + "}"; + index += " "; + } + + if ( hasLowerMiddle() ) { + index += "}"; + } + + if ( hasUpperMiddle() ) { + index += "}"; + } + + return index; +} + +TQString IndexElement::formulaString() +{ + TQString index = "(" + content->formulaString() + ")"; + if ( hasLowerRight() ) { + index += "_(" + lowerRight->formulaString() + ")"; + } + if ( hasUpperRight() ) { + index += "**(" + upperRight->formulaString() + ")"; + } + return index; +} + +TQString IndexElement::getElementName() const +{ + if ( hasUpperMiddle() && hasLowerMiddle() ) + return "munderover"; + if ( hasUpperMiddle() ) + return "mover"; + if ( hasLowerMiddle() ) + return "munder"; + if ( hasLowerLeft() || hasUpperLeft() ) + return "mmultiscripts"; + if ( hasLowerRight() || hasUpperRight() ) { + if ( ! hasUpperRight() ) + return "msub"; + if ( ! hasLowerRight() ) + return "msup"; + } + return "msubsup"; +} + +void IndexElement::writeMathMLAttributes( TQDomElement& element ) const +{ + TQString tag = getElementName(); + if ( tag == "msub" || tag == "msubsup" ) { + switch ( m_subScriptShiftType ) { + case AbsoluteSize: + element.setAttribute( "subscriptshift", TQString( "%1pt" ).arg( m_subScriptShift ) ); + break; + case RelativeSize: + element.setAttribute( "subscriptshift", TQString( "%1%" ).arg( m_subScriptShift * 100.0 ) ); + break; + case PixelSize: + element.setAttribute( "subscriptshift", TQString( "%1px" ).arg( m_subScriptShift ) ); + break; + default: + break; + } + } + if ( tag == "msup" || tag == "msubsup" ) { + switch ( m_superScriptShiftType ) { + case AbsoluteSize: + element.setAttribute( "superscriptshift", TQString( "%1pt" ).arg( m_superScriptShift ) ); + break; + case RelativeSize: + element.setAttribute( "superscriptshift", TQString( "%1%" ).arg( m_superScriptShift * 100.0 ) ); + break; + case PixelSize: + element.setAttribute( "superscriptshift", TQString( "%1px" ).arg( m_superScriptShift ) ); + break; + default: + break; + } + } + if ( tag == "munder" || tag == "munderover" ) { + if ( m_customAccentUnder ) { + element.setAttribute( "accentunder", m_accentUnder ? "true" : "false" ); + } + } + if ( tag == "mover" || tag == "munderover" ) { + if ( m_customAccent ) { + element.setAttribute( "accent", m_accent ? "true" : "false" ); + } + } +} + + +void IndexElement::writeMathMLContent( TQDomDocument& doc, + TQDomElement& element, + bool oasisFormat ) const +{ + TQDomElement de; + + content->writeMathML( doc, element, oasisFormat ); // base + if ( hasUpperMiddle() && hasLowerMiddle() ) + { + lowerMiddle->writeMathML( doc, element, oasisFormat ); + upperMiddle->writeMathML( doc, element,oasisFormat ); + } + else if ( hasUpperMiddle() ) + { + upperMiddle->writeMathML( doc, element,oasisFormat ); + } + else if ( hasLowerMiddle() ) + { + lowerMiddle->writeMathML( doc, element,oasisFormat ); + } + + if ( hasLowerLeft() || hasUpperLeft() ) + { + if ( hasLowerRight() ) + lowerRight->writeMathML( doc, element, oasisFormat ); + else + element.appendChild( doc.createElement( "none" ) ); + + if ( hasUpperRight() ) + upperRight->writeMathML( doc, element, oasisFormat ); + else + element.appendChild( doc.createElement( "none" ) ); + + element.appendChild( doc.createElement( "mprescripts" ) ); + + if ( hasLowerLeft() ) + lowerLeft->writeMathML( doc, element, oasisFormat ); + else + element.appendChild( doc.createElement( "none" ) ); + + if ( hasUpperLeft() ) + upperLeft->writeMathML( doc, element, oasisFormat ); + else + element.appendChild( doc.createElement( "none" ) ); + } + else if ( hasLowerRight() || hasUpperRight() ) + { + if ( !hasUpperRight() ) { + lowerRight->writeMathML( doc, element, oasisFormat ); + } + else if ( !hasLowerRight() ) { + upperRight->writeMathML( doc, element, oasisFormat ); + } + else // both + { + lowerRight->writeMathML( doc, element, oasisFormat ); + upperRight->writeMathML( doc, element,oasisFormat ); + } + } +} + +KFORMULA_NAMESPACE_END diff --git a/lib/kformula/kformulacommand.cc b/lib/kformula/kformulacommand.cc deleted file mode 100644 index 4aa31161..00000000 --- a/lib/kformula/kformulacommand.cc +++ /dev/null @@ -1,625 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2001 Andrea Rizzi - Ulrich Kuettler - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - -#include //This is for undo descriptions - -#include - -#include "formulacursor.h" -#include "formulaelement.h" -#include "indexelement.h" -#include "kformulacommand.h" -#include "matrixelement.h" -#include "sequenceelement.h" -#include "textelement.h" -#include "tokenelement.h" - - -KFORMULA_NAMESPACE_BEGIN - -int PlainCommand::evilDestructionCount = 0; - -PlainCommand::PlainCommand( const TQString& name ) - : KNamedCommand(name) -{ - evilDestructionCount++; -} - -PlainCommand::~PlainCommand() -{ - evilDestructionCount--; -} - -Command::Command(const TQString &name, Container* document) - : PlainCommand(name), cursordata(0), undocursor(0), doc(document) -{ -} - -Command::~Command() -{ - delete undocursor; - delete cursordata; -} - -FormulaCursor* Command::getExecuteCursor() -{ - FormulaCursor* cursor = getActiveCursor(); - if (cursordata == 0) { - setExecuteCursor(getActiveCursor()); - } - else { - cursor->setCursorData(cursordata); - } - return cursor; -} - -void Command::setExecuteCursor(FormulaCursor* cursor) -{ - // assert(cursordata == 0); - cursordata = cursor->getCursorData(); -} - -FormulaCursor* Command::getUnexecuteCursor() -{ - FormulaCursor* cursor = getActiveCursor(); - cursor->setCursorData(undocursor); - destroyUndoCursor(); - return cursor; -} - -void Command::setUnexecuteCursor(FormulaCursor* cursor) -{ - // assert(undocursor == 0); - undocursor = cursor->getCursorData(); -} - - -// ****** Generic Add command - -KFCAdd::KFCAdd(const TQString &name, Container *document) - : Command(name, document) -{ - addList.setAutoDelete( true ); -} - - -void KFCAdd::execute() -{ - FormulaCursor* cursor = getExecuteCursor(); - cursor->insert(addList, beforeCursor); - setUnexecuteCursor(cursor); - cursor->setSelection(false); - testDirty(); -} - - -void KFCAdd::unexecute() -{ - FormulaCursor* cursor = getUnexecuteCursor(); - cursor->remove(addList, beforeCursor); - //cursor->setSelection(false); - cursor->normalize(); - testDirty(); -} - - -// ****** Remove selection command - -KFCRemoveSelection::KFCRemoveSelection(Container *document, - Direction direction) - : Command(i18n("Remove Selected Text"), document), - dir(direction) -{ - removedList.setAutoDelete( true ); -} - -void KFCRemoveSelection::execute() -{ - FormulaCursor* cursor = getExecuteCursor(); - cursor->remove(removedList, dir); - setUnexecuteCursor(cursor); - testDirty(); -} - -void KFCRemoveSelection::unexecute() -{ - FormulaCursor* cursor = getUnexecuteCursor(); - cursor->insert(removedList); - cursor->setSelection(false); - testDirty(); -} - - - -KFCReplace::KFCReplace(const TQString &name, Container* document) - : KFCAdd(name, document), removeSelection(0) -{ -} - -KFCReplace::~KFCReplace() -{ - delete removeSelection; -} - -void KFCReplace::execute() -{ - if (getActiveCursor()->isSelection() && (removeSelection == 0)) { - removeSelection = new KFCRemoveSelection(getDocument()); - } - if (removeSelection != 0) { - removeSelection->execute(); - } - KFCAdd::execute(); -} - -void KFCReplace::unexecute() -{ - KFCAdd::unexecute(); - if (removeSelection != 0) { - removeSelection->unexecute(); - } -} - - -// ****** Token Add command - -KFCAddToken::KFCAddToken(const TQString &name, Container *document) - : Command(name, document) -{ -} - -KFCAddToken::~KFCAddToken() -{ - TQPtrDictIterator< TQPtrList< BasicElement > > it( contentList ); - TQPtrList< BasicElement >* list; - while ( ( list = it.current() ) != 0 ) { - delete list; - ++it; - } -} - -void KFCAddToken::execute() -{ - kdDebug( DEBUGID ) << k_funcinfo << endl; - FormulaCursor* cursor = getExecuteCursor(); - TQPtrList tokenListTmp = tokenList; - cursor->insert( tokenList, beforeCursor ); - tokenList = tokenListTmp; - TQPtrListIterator< BasicElement > it( tokenList ); - BasicElement* element; - BasicElement* current = cursor->getElement(); - while ( (element = it.current()) != 0 ) { - element->goInside( cursor ); - cursor->insert( *contentList.find( element ), beforeCursor ); - ++it; - } - setUnexecuteCursor( cursor ); - cursor->setSelection(false); - testDirty(); -} - - -void KFCAddToken::unexecute() -{ - kdDebug( DEBUGID ) << k_funcinfo << endl; - FormulaCursor* cursor = getUnexecuteCursor(); - SequenceElement* parent = static_cast(cursor->getElement()->getParent()); - - for ( int i = 0; i < tokenList.count(); i++ ) { - SequenceElement* current = static_cast(cursor->getElement()); - TQPtrList< BasicElement > list; - for ( uint i = 0; i < current->countChildren(); ++i ) { - cursor->remove( list, beforeCursor ); - } - if ( parent ) { - int pos = parent->childPos( current ); - cursor->setTo( parent, pos + 1); - cursor->remove( list, beforeCursor ); - if ( pos > 0 ) { - BasicElement* element = parent->getChild( pos - 1 ); - if (element) - element->moveEnd( cursor ); - } - } - } - testDirty(); -} - -/** - * Collect all tokens that are to be added - */ -void KFCAddToken::addToken( BasicElement* element ) -{ - tokenList.append( element ); - contentList.insert( element, new TQPtrList< BasicElement > ); - contentList.find( element )->setAutoDelete( true ); -} - -KFCReplaceToken::KFCReplaceToken(const TQString &name, Container* document) - : KFCAddToken(name, document), removeSelection(0) -{ -} - -KFCReplaceToken::~KFCReplaceToken() -{ - delete removeSelection; -} - -void KFCReplaceToken::execute() -{ - kdDebug( DEBUGID ) << k_funcinfo << endl; - if (getActiveCursor()->isSelection() && (removeSelection == 0)) { - removeSelection = new KFCRemoveSelection(getDocument()); - } - if (removeSelection != 0) { - removeSelection->execute(); - } - KFCAddToken::execute(); -} - -void KFCReplaceToken::unexecute() -{ - kdDebug( DEBUGID ) << k_funcinfo << endl; - KFCAddToken::unexecute(); - if (removeSelection != 0) { - removeSelection->unexecute(); - } -} - - -KFCSplitToken::KFCSplitToken(const TQString &name, Container* document) - : KFCAddToken(name, document), removeSelection(0) -{ - splitList.setAutoDelete( true ); -} - -KFCSplitToken::~KFCSplitToken() -{ - delete splitCursor; - delete removeSelection; -} - -void KFCSplitToken::execute() -{ - FormulaCursor* cursor = getExecuteCursor(); - if (getActiveCursor()->isSelection() && (removeSelection == 0)) { - removeSelection = new KFCRemoveSelection(getDocument()); - } - if (removeSelection != 0) { - removeSelection->execute(); - } - splitCursor = cursor->getCursorData(); - SequenceElement* parent = static_cast( cursor->getElement() ); - if ( parent ) { - cursor->setMark( parent->countChildren() ); - cursor->setSelection( true ); - } - cursor->remove( splitList, afterCursor ); - TokenElement *token = new TokenElement();// TODO - addToken( token ); - TQPtrListIterator< BasicElement > it ( splitList ); - BasicElement* element; - while ( ( element = it.current() ) != 0 ) { - addContent( token, element ); - ++it; - } - KFCAddToken::execute(); - cursor = getExecuteCursor(); - if ( parent ) { - BasicElement* child = parent->getChild( cursor->getPos() ); - if ( child ) { - child->moveEnd( cursor ); - } - } -} - -void KFCSplitToken::unexecute() -{ - kdDebug( DEBUGID ) << k_funcinfo << endl; - KFCAddToken::unexecute(); - FormulaCursor *cursor = getUnexecuteCursor(); - cursor->setCursorData( splitCursor ); - cursor->insert( splitList, afterCursor ); - if (removeSelection != 0) { - removeSelection->unexecute(); - } - testDirty(); -} - - -KFCRemove::KFCRemove(Container *document, - Direction direction) - : Command(i18n("Remove Selected Text"), document), - element(0), simpleRemoveCursor(0), dir(direction) -{ - removedList.setAutoDelete( true ); -} - -KFCRemove::~KFCRemove() -{ - delete simpleRemoveCursor; - delete element; -} - -void KFCRemove::execute() -{ - FormulaCursor* cursor = getExecuteCursor(); - cursor->remove(removedList, dir); - if (cursor->elementIsSenseless()) { - simpleRemoveCursor = cursor->getCursorData(); - element = cursor->replaceByMainChildContent(); - } - setUnexecuteCursor(cursor); - cursor->normalize( dir ); - testDirty(); -} - -void KFCRemove::unexecute() -{ - FormulaCursor* cursor = getUnexecuteCursor(); - if (element != 0) { - cursor->replaceSelectionWith(element); - element = 0; - - cursor->setCursorData(simpleRemoveCursor); - delete simpleRemoveCursor; - simpleRemoveCursor = 0; - } - cursor->insert(removedList, dir); - cursor->setSelection(false); - testDirty(); -} - - -KFCRemoveEnclosing::KFCRemoveEnclosing(Container* document, - Direction dir) - : Command(i18n("Remove Enclosing Element"), document), - element(0), direction(dir) -{ -} - -KFCRemoveEnclosing::~KFCRemoveEnclosing() -{ - delete element; -} - -void KFCRemoveEnclosing::execute() -{ - FormulaCursor* cursor = getExecuteCursor(); - element = cursor->removeEnclosingElement(direction); - setUnexecuteCursor(cursor); - //cursor->normalize(); - cursor->setSelection(false); - testDirty(); -} - -void KFCRemoveEnclosing::unexecute() -{ - FormulaCursor* cursor = getUnexecuteCursor(); - if ( element ) { - cursor->replaceSelectionWith(element); - } - cursor->normalize(); - cursor->setSelection(false); - element = 0; - testDirty(); -} - - -// ****** Add root, bracket etc command - -KFCAddReplacing::KFCAddReplacing(const TQString &name, Container* document) - : Command(name, document), element(0) -{ -} - -KFCAddReplacing::~KFCAddReplacing() -{ - delete element; -} - - -void KFCAddReplacing::execute() -{ - FormulaCursor* cursor = getExecuteCursor(); - cursor->replaceSelectionWith(element); - setUnexecuteCursor(cursor); - cursor->goInsideElement(element); - element = 0; - testDirty(); -} - - -void KFCAddReplacing::unexecute() -{ - FormulaCursor* cursor = getUnexecuteCursor(); - element = cursor->replaceByMainChildContent(); - cursor->normalize(); - testDirty(); -} - - -// ****** Add index command - -KFCAddGenericIndex::KFCAddGenericIndex(Container* document, ElementIndexPtr _index) - : KFCAdd(i18n("Add Index"), document), index(_index) -{ - addElement(new SequenceElement()); -} - -void KFCAddGenericIndex::execute() -{ - index->setToIndex(getActiveCursor()); - KFCAdd::execute(); -} - - -KFCAddIndex::KFCAddIndex(Container* document, - IndexElement* element, ElementIndexPtr index) - : KFCAddReplacing(i18n("Add Index"), document), - addIndex(document, index) -{ - setElement(element); -} - -KFCAddIndex::~KFCAddIndex() -{ -} - -void KFCAddIndex::execute() -{ - KFCAddReplacing::execute(); - addIndex.execute(); -} - -void KFCAddIndex::unexecute() -{ - addIndex.unexecute(); - KFCAddReplacing::unexecute(); -} - - -KFCChangeBaseSize::KFCChangeBaseSize( const TQString& name, Container* document, - FormulaElement* formula, int size ) - : PlainCommand( name ), m_document( document ), m_formula( formula ), m_size( size ) -{ - m_oldSize = formula->getBaseSize(); -} - -void KFCChangeBaseSize::execute() -{ - m_formula->setBaseSize( m_size ); - m_document->recalc(); -} - -void KFCChangeBaseSize::unexecute() -{ - m_formula->setBaseSize( m_oldSize ); - m_document->recalc(); -} - - -FontCommand::FontCommand( const TQString& name, Container* document ) - : Command( name, document ) -{ - list.setAutoDelete( false ); - elementList.setAutoDelete( false ); -} - - -void FontCommand::collectChildren() -{ - list.clear(); - uint count = elementList.count(); - for ( uint i=0; idispatchFontCommand( this ); - } -} - - -void FontCommand::parseSequences( const TQMap& parents ) -{ - TQValueList sequences = parents.keys(); - for ( TQValueList::iterator i = sequences.begin(); - i != sequences.end(); - ++i ) { - ( *i )->parse(); - } -} - - -CharStyleCommand::CharStyleCommand( CharStyle cs, const TQString& name, Container* document ) - : FontCommand( name, document ), charStyle( cs ) -{ -} - -void CharStyleCommand::execute() -{ - collectChildren(); - TQMap parentCollector; - - styleList.clear(); - uint count = childrenList().count(); - styleList.reserve( count ); - for ( uint i=0; igetCharStyle(); - child->setCharStyle( charStyle ); - parentCollector[static_cast( child->getParent() )] = 1; - } - parseSequences( parentCollector ); - testDirty(); -} - -void CharStyleCommand::unexecute() -{ - TQMap parentCollector; - uint count = childrenList().count(); - //styleList.reserve( count ); - for ( uint i=0; isetCharStyle( styleList[i] ); - parentCollector[static_cast( child->getParent() )] = 1; - } - parseSequences( parentCollector ); - testDirty(); -} - - -CharFamilyCommand::CharFamilyCommand( CharFamily cf, const TQString& name, Container* document ) - : FontCommand( name, document ), charFamily( cf ) -{ -} - -void CharFamilyCommand::execute() -{ - collectChildren(); - - TQMap parentCollector; - - familyList.clear(); - uint count = childrenList().count(); - familyList.reserve( count ); - for ( uint i=0; igetCharFamily(); - child->setCharFamily( charFamily ); - parentCollector[static_cast( child->getParent() )] = 1; - } - parseSequences( parentCollector ); - testDirty(); -} - -void CharFamilyCommand::unexecute() -{ - TQMap parentCollector; - uint count = childrenList().count(); - //familyList.reserve( count ); - for ( uint i=0; isetCharFamily( familyList[i] ); - parentCollector[static_cast( child->getParent() )] = 1; - } - parseSequences( parentCollector ); - testDirty(); -} - - -KFORMULA_NAMESPACE_END diff --git a/lib/kformula/kformulacommand.cpp b/lib/kformula/kformulacommand.cpp new file mode 100644 index 00000000..4aa31161 --- /dev/null +++ b/lib/kformula/kformulacommand.cpp @@ -0,0 +1,625 @@ +/* This file is part of the KDE project + Copyright (C) 2001 Andrea Rizzi + Ulrich Kuettler + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include //This is for undo descriptions + +#include + +#include "formulacursor.h" +#include "formulaelement.h" +#include "indexelement.h" +#include "kformulacommand.h" +#include "matrixelement.h" +#include "sequenceelement.h" +#include "textelement.h" +#include "tokenelement.h" + + +KFORMULA_NAMESPACE_BEGIN + +int PlainCommand::evilDestructionCount = 0; + +PlainCommand::PlainCommand( const TQString& name ) + : KNamedCommand(name) +{ + evilDestructionCount++; +} + +PlainCommand::~PlainCommand() +{ + evilDestructionCount--; +} + +Command::Command(const TQString &name, Container* document) + : PlainCommand(name), cursordata(0), undocursor(0), doc(document) +{ +} + +Command::~Command() +{ + delete undocursor; + delete cursordata; +} + +FormulaCursor* Command::getExecuteCursor() +{ + FormulaCursor* cursor = getActiveCursor(); + if (cursordata == 0) { + setExecuteCursor(getActiveCursor()); + } + else { + cursor->setCursorData(cursordata); + } + return cursor; +} + +void Command::setExecuteCursor(FormulaCursor* cursor) +{ + // assert(cursordata == 0); + cursordata = cursor->getCursorData(); +} + +FormulaCursor* Command::getUnexecuteCursor() +{ + FormulaCursor* cursor = getActiveCursor(); + cursor->setCursorData(undocursor); + destroyUndoCursor(); + return cursor; +} + +void Command::setUnexecuteCursor(FormulaCursor* cursor) +{ + // assert(undocursor == 0); + undocursor = cursor->getCursorData(); +} + + +// ****** Generic Add command + +KFCAdd::KFCAdd(const TQString &name, Container *document) + : Command(name, document) +{ + addList.setAutoDelete( true ); +} + + +void KFCAdd::execute() +{ + FormulaCursor* cursor = getExecuteCursor(); + cursor->insert(addList, beforeCursor); + setUnexecuteCursor(cursor); + cursor->setSelection(false); + testDirty(); +} + + +void KFCAdd::unexecute() +{ + FormulaCursor* cursor = getUnexecuteCursor(); + cursor->remove(addList, beforeCursor); + //cursor->setSelection(false); + cursor->normalize(); + testDirty(); +} + + +// ****** Remove selection command + +KFCRemoveSelection::KFCRemoveSelection(Container *document, + Direction direction) + : Command(i18n("Remove Selected Text"), document), + dir(direction) +{ + removedList.setAutoDelete( true ); +} + +void KFCRemoveSelection::execute() +{ + FormulaCursor* cursor = getExecuteCursor(); + cursor->remove(removedList, dir); + setUnexecuteCursor(cursor); + testDirty(); +} + +void KFCRemoveSelection::unexecute() +{ + FormulaCursor* cursor = getUnexecuteCursor(); + cursor->insert(removedList); + cursor->setSelection(false); + testDirty(); +} + + + +KFCReplace::KFCReplace(const TQString &name, Container* document) + : KFCAdd(name, document), removeSelection(0) +{ +} + +KFCReplace::~KFCReplace() +{ + delete removeSelection; +} + +void KFCReplace::execute() +{ + if (getActiveCursor()->isSelection() && (removeSelection == 0)) { + removeSelection = new KFCRemoveSelection(getDocument()); + } + if (removeSelection != 0) { + removeSelection->execute(); + } + KFCAdd::execute(); +} + +void KFCReplace::unexecute() +{ + KFCAdd::unexecute(); + if (removeSelection != 0) { + removeSelection->unexecute(); + } +} + + +// ****** Token Add command + +KFCAddToken::KFCAddToken(const TQString &name, Container *document) + : Command(name, document) +{ +} + +KFCAddToken::~KFCAddToken() +{ + TQPtrDictIterator< TQPtrList< BasicElement > > it( contentList ); + TQPtrList< BasicElement >* list; + while ( ( list = it.current() ) != 0 ) { + delete list; + ++it; + } +} + +void KFCAddToken::execute() +{ + kdDebug( DEBUGID ) << k_funcinfo << endl; + FormulaCursor* cursor = getExecuteCursor(); + TQPtrList tokenListTmp = tokenList; + cursor->insert( tokenList, beforeCursor ); + tokenList = tokenListTmp; + TQPtrListIterator< BasicElement > it( tokenList ); + BasicElement* element; + BasicElement* current = cursor->getElement(); + while ( (element = it.current()) != 0 ) { + element->goInside( cursor ); + cursor->insert( *contentList.find( element ), beforeCursor ); + ++it; + } + setUnexecuteCursor( cursor ); + cursor->setSelection(false); + testDirty(); +} + + +void KFCAddToken::unexecute() +{ + kdDebug( DEBUGID ) << k_funcinfo << endl; + FormulaCursor* cursor = getUnexecuteCursor(); + SequenceElement* parent = static_cast(cursor->getElement()->getParent()); + + for ( int i = 0; i < tokenList.count(); i++ ) { + SequenceElement* current = static_cast(cursor->getElement()); + TQPtrList< BasicElement > list; + for ( uint i = 0; i < current->countChildren(); ++i ) { + cursor->remove( list, beforeCursor ); + } + if ( parent ) { + int pos = parent->childPos( current ); + cursor->setTo( parent, pos + 1); + cursor->remove( list, beforeCursor ); + if ( pos > 0 ) { + BasicElement* element = parent->getChild( pos - 1 ); + if (element) + element->moveEnd( cursor ); + } + } + } + testDirty(); +} + +/** + * Collect all tokens that are to be added + */ +void KFCAddToken::addToken( BasicElement* element ) +{ + tokenList.append( element ); + contentList.insert( element, new TQPtrList< BasicElement > ); + contentList.find( element )->setAutoDelete( true ); +} + +KFCReplaceToken::KFCReplaceToken(const TQString &name, Container* document) + : KFCAddToken(name, document), removeSelection(0) +{ +} + +KFCReplaceToken::~KFCReplaceToken() +{ + delete removeSelection; +} + +void KFCReplaceToken::execute() +{ + kdDebug( DEBUGID ) << k_funcinfo << endl; + if (getActiveCursor()->isSelection() && (removeSelection == 0)) { + removeSelection = new KFCRemoveSelection(getDocument()); + } + if (removeSelection != 0) { + removeSelection->execute(); + } + KFCAddToken::execute(); +} + +void KFCReplaceToken::unexecute() +{ + kdDebug( DEBUGID ) << k_funcinfo << endl; + KFCAddToken::unexecute(); + if (removeSelection != 0) { + removeSelection->unexecute(); + } +} + + +KFCSplitToken::KFCSplitToken(const TQString &name, Container* document) + : KFCAddToken(name, document), removeSelection(0) +{ + splitList.setAutoDelete( true ); +} + +KFCSplitToken::~KFCSplitToken() +{ + delete splitCursor; + delete removeSelection; +} + +void KFCSplitToken::execute() +{ + FormulaCursor* cursor = getExecuteCursor(); + if (getActiveCursor()->isSelection() && (removeSelection == 0)) { + removeSelection = new KFCRemoveSelection(getDocument()); + } + if (removeSelection != 0) { + removeSelection->execute(); + } + splitCursor = cursor->getCursorData(); + SequenceElement* parent = static_cast( cursor->getElement() ); + if ( parent ) { + cursor->setMark( parent->countChildren() ); + cursor->setSelection( true ); + } + cursor->remove( splitList, afterCursor ); + TokenElement *token = new TokenElement();// TODO + addToken( token ); + TQPtrListIterator< BasicElement > it ( splitList ); + BasicElement* element; + while ( ( element = it.current() ) != 0 ) { + addContent( token, element ); + ++it; + } + KFCAddToken::execute(); + cursor = getExecuteCursor(); + if ( parent ) { + BasicElement* child = parent->getChild( cursor->getPos() ); + if ( child ) { + child->moveEnd( cursor ); + } + } +} + +void KFCSplitToken::unexecute() +{ + kdDebug( DEBUGID ) << k_funcinfo << endl; + KFCAddToken::unexecute(); + FormulaCursor *cursor = getUnexecuteCursor(); + cursor->setCursorData( splitCursor ); + cursor->insert( splitList, afterCursor ); + if (removeSelection != 0) { + removeSelection->unexecute(); + } + testDirty(); +} + + +KFCRemove::KFCRemove(Container *document, + Direction direction) + : Command(i18n("Remove Selected Text"), document), + element(0), simpleRemoveCursor(0), dir(direction) +{ + removedList.setAutoDelete( true ); +} + +KFCRemove::~KFCRemove() +{ + delete simpleRemoveCursor; + delete element; +} + +void KFCRemove::execute() +{ + FormulaCursor* cursor = getExecuteCursor(); + cursor->remove(removedList, dir); + if (cursor->elementIsSenseless()) { + simpleRemoveCursor = cursor->getCursorData(); + element = cursor->replaceByMainChildContent(); + } + setUnexecuteCursor(cursor); + cursor->normalize( dir ); + testDirty(); +} + +void KFCRemove::unexecute() +{ + FormulaCursor* cursor = getUnexecuteCursor(); + if (element != 0) { + cursor->replaceSelectionWith(element); + element = 0; + + cursor->setCursorData(simpleRemoveCursor); + delete simpleRemoveCursor; + simpleRemoveCursor = 0; + } + cursor->insert(removedList, dir); + cursor->setSelection(false); + testDirty(); +} + + +KFCRemoveEnclosing::KFCRemoveEnclosing(Container* document, + Direction dir) + : Command(i18n("Remove Enclosing Element"), document), + element(0), direction(dir) +{ +} + +KFCRemoveEnclosing::~KFCRemoveEnclosing() +{ + delete element; +} + +void KFCRemoveEnclosing::execute() +{ + FormulaCursor* cursor = getExecuteCursor(); + element = cursor->removeEnclosingElement(direction); + setUnexecuteCursor(cursor); + //cursor->normalize(); + cursor->setSelection(false); + testDirty(); +} + +void KFCRemoveEnclosing::unexecute() +{ + FormulaCursor* cursor = getUnexecuteCursor(); + if ( element ) { + cursor->replaceSelectionWith(element); + } + cursor->normalize(); + cursor->setSelection(false); + element = 0; + testDirty(); +} + + +// ****** Add root, bracket etc command + +KFCAddReplacing::KFCAddReplacing(const TQString &name, Container* document) + : Command(name, document), element(0) +{ +} + +KFCAddReplacing::~KFCAddReplacing() +{ + delete element; +} + + +void KFCAddReplacing::execute() +{ + FormulaCursor* cursor = getExecuteCursor(); + cursor->replaceSelectionWith(element); + setUnexecuteCursor(cursor); + cursor->goInsideElement(element); + element = 0; + testDirty(); +} + + +void KFCAddReplacing::unexecute() +{ + FormulaCursor* cursor = getUnexecuteCursor(); + element = cursor->replaceByMainChildContent(); + cursor->normalize(); + testDirty(); +} + + +// ****** Add index command + +KFCAddGenericIndex::KFCAddGenericIndex(Container* document, ElementIndexPtr _index) + : KFCAdd(i18n("Add Index"), document), index(_index) +{ + addElement(new SequenceElement()); +} + +void KFCAddGenericIndex::execute() +{ + index->setToIndex(getActiveCursor()); + KFCAdd::execute(); +} + + +KFCAddIndex::KFCAddIndex(Container* document, + IndexElement* element, ElementIndexPtr index) + : KFCAddReplacing(i18n("Add Index"), document), + addIndex(document, index) +{ + setElement(element); +} + +KFCAddIndex::~KFCAddIndex() +{ +} + +void KFCAddIndex::execute() +{ + KFCAddReplacing::execute(); + addIndex.execute(); +} + +void KFCAddIndex::unexecute() +{ + addIndex.unexecute(); + KFCAddReplacing::unexecute(); +} + + +KFCChangeBaseSize::KFCChangeBaseSize( const TQString& name, Container* document, + FormulaElement* formula, int size ) + : PlainCommand( name ), m_document( document ), m_formula( formula ), m_size( size ) +{ + m_oldSize = formula->getBaseSize(); +} + +void KFCChangeBaseSize::execute() +{ + m_formula->setBaseSize( m_size ); + m_document->recalc(); +} + +void KFCChangeBaseSize::unexecute() +{ + m_formula->setBaseSize( m_oldSize ); + m_document->recalc(); +} + + +FontCommand::FontCommand( const TQString& name, Container* document ) + : Command( name, document ) +{ + list.setAutoDelete( false ); + elementList.setAutoDelete( false ); +} + + +void FontCommand::collectChildren() +{ + list.clear(); + uint count = elementList.count(); + for ( uint i=0; idispatchFontCommand( this ); + } +} + + +void FontCommand::parseSequences( const TQMap& parents ) +{ + TQValueList sequences = parents.keys(); + for ( TQValueList::iterator i = sequences.begin(); + i != sequences.end(); + ++i ) { + ( *i )->parse(); + } +} + + +CharStyleCommand::CharStyleCommand( CharStyle cs, const TQString& name, Container* document ) + : FontCommand( name, document ), charStyle( cs ) +{ +} + +void CharStyleCommand::execute() +{ + collectChildren(); + TQMap parentCollector; + + styleList.clear(); + uint count = childrenList().count(); + styleList.reserve( count ); + for ( uint i=0; igetCharStyle(); + child->setCharStyle( charStyle ); + parentCollector[static_cast( child->getParent() )] = 1; + } + parseSequences( parentCollector ); + testDirty(); +} + +void CharStyleCommand::unexecute() +{ + TQMap parentCollector; + uint count = childrenList().count(); + //styleList.reserve( count ); + for ( uint i=0; isetCharStyle( styleList[i] ); + parentCollector[static_cast( child->getParent() )] = 1; + } + parseSequences( parentCollector ); + testDirty(); +} + + +CharFamilyCommand::CharFamilyCommand( CharFamily cf, const TQString& name, Container* document ) + : FontCommand( name, document ), charFamily( cf ) +{ +} + +void CharFamilyCommand::execute() +{ + collectChildren(); + + TQMap parentCollector; + + familyList.clear(); + uint count = childrenList().count(); + familyList.reserve( count ); + for ( uint i=0; igetCharFamily(); + child->setCharFamily( charFamily ); + parentCollector[static_cast( child->getParent() )] = 1; + } + parseSequences( parentCollector ); + testDirty(); +} + +void CharFamilyCommand::unexecute() +{ + TQMap parentCollector; + uint count = childrenList().count(); + //familyList.reserve( count ); + for ( uint i=0; isetCharFamily( familyList[i] ); + parentCollector[static_cast( child->getParent() )] = 1; + } + parseSequences( parentCollector ); + testDirty(); +} + + +KFORMULA_NAMESPACE_END diff --git a/lib/kformula/kformulacompatibility.cc b/lib/kformula/kformulacompatibility.cc deleted file mode 100644 index f64bf9de..00000000 --- a/lib/kformula/kformulacompatibility.cc +++ /dev/null @@ -1,402 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2001 Ulrich Kuettler - - This file is based on the other kformula lib - Copyright (C) 1999 Ilya Baran (ibaran@mit.edu) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - -#include - -#include -#include "kformuladefs.h" -#include "kformulacompatibility.h" - -KFORMULA_NAMESPACE_BEGIN - -const int SYMBOL_ABOVE = 20000; -const int UNUSED_OFFSET = 1000; - -typedef int BoxType; - -//const BoxType PLUS = '+'; -//const BoxType MINUS = '-'; -//const BoxType TIMES = '*'; -const BoxType OF_DIVIDE = '\\' + UNUSED_OFFSET; -const BoxType OF_POWER = '^' + UNUSED_OFFSET; //just a test to see if it works -const BoxType OF_SQRT = '@' + UNUSED_OFFSET; -//const BoxType TEXT = 't'; -//const BoxType CAT = '#' + UNUSED_OFFSET; -const BoxType OF_SUB = '_' + UNUSED_OFFSET; -const BoxType OF_LSUP = '6' + UNUSED_OFFSET; -const BoxType OF_LSUB = '%' + UNUSED_OFFSET; -//const BoxType PAREN = '('; -//const BoxType EQUAL = '='; -//const BoxType MORE = '>'; -//const BoxType LESS = '<'; -//const BoxType ABS = '|'; -//const BoxType BRACKET = '['; -//const BoxType SLASH = '/'; -const BoxType OF_MATRIX = 'm' + UNUSED_OFFSET; -const BoxType OF_SEPARATOR = '&' + UNUSED_OFFSET; // separator for matrices -const BoxType OF_ABOVE = ')' + UNUSED_OFFSET; //something useless -const BoxType OF_BELOW = ']' + UNUSED_OFFSET; -const BoxType OF_SYMBOL = 's' + UNUSED_OFFSET; // whatever -// char for keeping track of cursor position in undo/redo: -//const BoxType CURSOR = 'c' + UNUSED_OFFSET; - -const int INTEGRAL = SYMBOL_ABOVE + 0; // symbols have values above that -const int SUM = SYMBOL_ABOVE + 1; -const int PRODUCT = SYMBOL_ABOVE + 2; -const int ARROW = SYMBOL_ABOVE + 3; -// elements of the symbol font are their own codes + SYMBOL_ABOVE - - -Compatibility::Compatibility() -{ -} - - -TQDomDocument Compatibility::buildDOM(TQString text) -{ - TQDomDocument doc("KFORMULA"); - pos = 0; - formulaString = text; - TQDomElement formula = readSequence(doc); - formula.setTagName("FORMULA"); - doc.appendChild(formula); - return doc; -} - - -void Compatibility::appendNextSequence(const TQDomDocument& doc, TQDomElement element) -{ - if (hasNext() && nextToken() == '{') { - element.appendChild(readSequence(doc)); - } - else { - pushback(); - element.appendChild(doc.createElement("SEQUENCE")); - } -} - - -TQDomElement Compatibility::getLastSequence(const TQDomDocument& doc, TQDomElement sequence) -{ - if (sequence.lastChild().nodeName() == "SEQUENCE") { - TQDomNode child = sequence.removeChild(sequence.lastChild()); - return child.toElement(); - } - else { - TQDomElement newSeq = doc.createElement("SEQUENCE"); - if (!sequence.lastChild().isNull()) { - TQDomNode child = sequence.removeChild(sequence.lastChild()); - newSeq.appendChild(child); - } - return newSeq; - } -} - - -TQDomElement Compatibility::findIndexNode(const TQDomDocument& doc, TQDomElement sequence) -{ - TQDomElement element; - if (sequence.lastChild().nodeName() == "INDEX") { - element = sequence.lastChild().toElement(); - } - else { - element = doc.createElement("INDEX"); - TQDomElement con = doc.createElement("CONTENT"); - element.appendChild(con); - con.appendChild(getLastSequence(doc, sequence)); - sequence.appendChild(element); - } - return element; -} - - -void Compatibility::appendToSequence(TQDomElement sequence, TQDomElement element, int leftIndexSeen) -{ - if (leftIndexSeen > 0) { - if (sequence.lastChild().nodeName() == "INDEX") { - TQDomElement index = sequence.lastChild().toElement(); - if ((index.firstChild().nodeName() == "CONTENT") && - (index.firstChild().firstChild().nodeName() == "SEQUENCE")) { - TQDomElement seq = index.firstChild().firstChild().toElement(); - if (element.nodeName() == "SEQUENCE") { - index.firstChild().replaceChild(element, seq); - } - else { - seq.appendChild(element); - } - return; - } - } - } - sequence.appendChild(element); -} - - -TQDomElement Compatibility::readMatrix(const TQDomDocument& doc) -{ - TQDomElement element = doc.createElement("MATRIX"); - - uint cols = nextToken(); - nextToken(); - uint rows = nextToken(); - - element.setAttribute("ROWS", rows); - element.setAttribute("COLUMNS", cols); - - if ((nextToken() == '}') && (nextToken() == OF_MATRIX) && (nextToken() == '{')) { - TQValueList matrix; - for (uint c = 0; c < cols; c++) { - for (uint r = 0; r < rows; r++) { - if (hasNext() && (nextToken() == '{')) { - TQDomElement tmp = readSequence(doc); - matrix.append(tmp); - } - if (hasNext() && (nextToken() != OF_SEPARATOR)) { - pushback(); - } - } - } - if (hasNext() && (nextToken() != '}')) { - pushback(); - } - - if (matrix.count() == rows*cols) { - for (uint r = 0; r < rows; r++) { - for (uint c = 0; c < cols; c++) { - element.appendChild(matrix[c*rows+r]); - } - } - } - } - else { - pushback(); - } - - return element; -} - - -TQDomElement Compatibility::readSequence(const TQDomDocument& doc) -{ - // matrizes start with something that isn't a sequence - if ((tokenLeft() > 6) && (lookAhead(1) == OF_SEPARATOR)) { - return readMatrix(doc); - } - - int leftIndexSeen = 0; - TQDomElement sequence = doc.createElement("SEQUENCE"); - - while (hasNext()) { - ushort ch = nextToken(); - - // Debug - //cout << "read: " << ch << " (" << static_cast(ch) << ')' << endl; - - if (leftIndexSeen > 0) leftIndexSeen--; - - switch (ch) { - case '{': - appendToSequence(sequence, readSequence(doc), leftIndexSeen); - break; - case '}': - return sequence; - case '(': - case '[': - case '|': { - // There is an empty sequence we have to remove - if (!sequence.lastChild().isNull()) { - sequence.removeChild(sequence.lastChild()); - } - - TQDomElement element = doc.createElement("BRACKET"); - appendToSequence(sequence, element, leftIndexSeen); - element.setAttribute("LEFT", ch); - element.setAttribute("RIGHT", (ch=='(') ? ')' : ((ch=='[') ? ']' : '|')); - - TQDomElement con = doc.createElement("CONTENT"); - element.appendChild(con); - appendNextSequence(doc, con); - break; - } - case OF_DIVIDE: { - TQDomElement element = doc.createElement("FRACTION"); - - TQDomElement num = doc.createElement("NUMERATOR"); - element.appendChild(num); - num.appendChild(getLastSequence(doc, sequence)); - - TQDomElement den = doc.createElement("DENOMINATOR"); - element.appendChild(den); - appendNextSequence(doc, den); - - appendToSequence(sequence, element, leftIndexSeen); - break; - } - case OF_SQRT: { - TQDomElement element = doc.createElement("ROOT"); - TQDomElement con = doc.createElement("CONTENT"); - element.appendChild(con); - appendNextSequence(doc, con); - - TQDomElement ind = doc.createElement("INDEX"); - element.appendChild(ind); - ind.appendChild(getLastSequence(doc, sequence)); - - appendToSequence(sequence, element, leftIndexSeen); - break; - } - case OF_POWER: { - TQDomElement element = findIndexNode(doc, sequence); - TQDomElement upperRight = doc.createElement("UPPERRIGHT"); - element.appendChild(upperRight); - appendNextSequence(doc, upperRight); - break; - } - case OF_SUB: { - TQDomElement element = findIndexNode(doc, sequence); - TQDomElement lowerRight = doc.createElement("LOWERRIGHT"); - element.appendChild(lowerRight); - appendNextSequence(doc, lowerRight); - break; - } - case OF_LSUP: { - TQDomElement upperLeft = doc.createElement("UPPERLEFT"); - upperLeft.appendChild(getLastSequence(doc, sequence)); - TQDomElement element; - if (sequence.lastChild().nodeName() == "INDEX") { - element = sequence.lastChild().toElement(); - } - else { - element = doc.createElement("INDEX"); - TQDomElement con = doc.createElement("CONTENT"); - element.appendChild(con); - TQDomElement seq = doc.createElement("SEQUENCE"); - con.appendChild(seq); - appendToSequence(sequence, element, leftIndexSeen); - } - element.appendChild(upperLeft); - leftIndexSeen = 2; - break; - } - case OF_LSUB: { - TQDomElement lowerLeft = doc.createElement("LOWERLEFT"); - lowerLeft.appendChild(getLastSequence(doc, sequence)); - TQDomElement element; - if (sequence.lastChild().nodeName() == "INDEX") { - element = sequence.lastChild().toElement(); - } - else { - element = doc.createElement("INDEX"); - TQDomElement con = doc.createElement("CONTENT"); - element.appendChild(con); - TQDomElement seq = doc.createElement("SEQUENCE"); - con.appendChild(seq); - appendToSequence(sequence, element, leftIndexSeen); - } - element.appendChild(lowerLeft); - leftIndexSeen = 2; - break; - } - case OF_ABOVE: { - if (sequence.lastChild().nodeName() == "SEQUENCE") { - TQDomElement seq = sequence.lastChild().toElement(); - if ((seq.childNodes().count() == 1) && - ((seq.lastChild().nodeName() == "SYMBOL") || - (seq.lastChild().nodeName() == "INDEX"))) { - sequence.removeChild(seq); - - TQDomElement element = seq.lastChild().toElement(); - TQDomElement upper = (element.nodeName() == "SYMBOL") ? - doc.createElement("UPPER") : - doc.createElement("UPPERMIDDLE"); - element.appendChild(upper); - appendNextSequence(doc, upper); - appendToSequence(sequence, element, leftIndexSeen); - break; - } - } - TQDomElement element = findIndexNode(doc, sequence); - TQDomElement upper = doc.createElement("UPPERMIDDLE"); - element.appendChild(upper); - appendNextSequence(doc, upper); - break; - } - case OF_BELOW: { - if (sequence.lastChild().nodeName() == "SEQUENCE") { - TQDomElement seq = sequence.lastChild().toElement(); - if ((seq.childNodes().count() == 1) && - ((seq.lastChild().nodeName() == "SYMBOL") || - (seq.lastChild().nodeName() == "INDEX"))) { - sequence.removeChild(seq); - - TQDomElement element = seq.lastChild().toElement(); - TQDomElement lower = (element.nodeName() == "SYMBOL") ? - doc.createElement("LOWER") : - doc.createElement("LOWERMIDDLE"); - element.appendChild(lower); - appendNextSequence(doc, lower); - appendToSequence(sequence, element, leftIndexSeen); - break; - } - } - TQDomElement element = findIndexNode(doc, sequence); - TQDomElement lower = doc.createElement("LOWERMIDDLE"); - element.appendChild(lower); - appendNextSequence(doc, lower); - break; - } - case OF_SYMBOL: - kdDebug() << "OF_SYMBOL" << endl; - break; - case INTEGRAL: - case SUM: - case PRODUCT: { - TQDomElement element = doc.createElement("SYMBOL"); - element.setAttribute("TYPE", - (ch==INTEGRAL) ? Integral : - ((ch==SUM) ? Sum : Product)); - - TQDomElement con = doc.createElement("CONTENT"); - element.appendChild(con); - con.appendChild(readSequence(doc)); - pushback(); - appendToSequence(sequence, element, leftIndexSeen); - break; - } - case ARROW: { - TQDomElement element = doc.createElement("TEXT"); - element.setAttribute("CHAR", TQString(TQChar(static_cast(174)))); - element.setAttribute("SYMBOL", "1"); - appendToSequence(sequence, element, leftIndexSeen); - break; - } - default: { - TQDomElement element = doc.createElement("TEXT"); - element.setAttribute("CHAR", TQString(formulaString[pos-1])); - appendToSequence(sequence, element, leftIndexSeen); - } - } - } - return sequence; -} - -KFORMULA_NAMESPACE_END diff --git a/lib/kformula/kformulacompatibility.cpp b/lib/kformula/kformulacompatibility.cpp new file mode 100644 index 00000000..f64bf9de --- /dev/null +++ b/lib/kformula/kformulacompatibility.cpp @@ -0,0 +1,402 @@ +/* This file is part of the KDE project + Copyright (C) 2001 Ulrich Kuettler + + This file is based on the other kformula lib + Copyright (C) 1999 Ilya Baran (ibaran@mit.edu) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include + +#include +#include "kformuladefs.h" +#include "kformulacompatibility.h" + +KFORMULA_NAMESPACE_BEGIN + +const int SYMBOL_ABOVE = 20000; +const int UNUSED_OFFSET = 1000; + +typedef int BoxType; + +//const BoxType PLUS = '+'; +//const BoxType MINUS = '-'; +//const BoxType TIMES = '*'; +const BoxType OF_DIVIDE = '\\' + UNUSED_OFFSET; +const BoxType OF_POWER = '^' + UNUSED_OFFSET; //just a test to see if it works +const BoxType OF_SQRT = '@' + UNUSED_OFFSET; +//const BoxType TEXT = 't'; +//const BoxType CAT = '#' + UNUSED_OFFSET; +const BoxType OF_SUB = '_' + UNUSED_OFFSET; +const BoxType OF_LSUP = '6' + UNUSED_OFFSET; +const BoxType OF_LSUB = '%' + UNUSED_OFFSET; +//const BoxType PAREN = '('; +//const BoxType EQUAL = '='; +//const BoxType MORE = '>'; +//const BoxType LESS = '<'; +//const BoxType ABS = '|'; +//const BoxType BRACKET = '['; +//const BoxType SLASH = '/'; +const BoxType OF_MATRIX = 'm' + UNUSED_OFFSET; +const BoxType OF_SEPARATOR = '&' + UNUSED_OFFSET; // separator for matrices +const BoxType OF_ABOVE = ')' + UNUSED_OFFSET; //something useless +const BoxType OF_BELOW = ']' + UNUSED_OFFSET; +const BoxType OF_SYMBOL = 's' + UNUSED_OFFSET; // whatever +// char for keeping track of cursor position in undo/redo: +//const BoxType CURSOR = 'c' + UNUSED_OFFSET; + +const int INTEGRAL = SYMBOL_ABOVE + 0; // symbols have values above that +const int SUM = SYMBOL_ABOVE + 1; +const int PRODUCT = SYMBOL_ABOVE + 2; +const int ARROW = SYMBOL_ABOVE + 3; +// elements of the symbol font are their own codes + SYMBOL_ABOVE + + +Compatibility::Compatibility() +{ +} + + +TQDomDocument Compatibility::buildDOM(TQString text) +{ + TQDomDocument doc("KFORMULA"); + pos = 0; + formulaString = text; + TQDomElement formula = readSequence(doc); + formula.setTagName("FORMULA"); + doc.appendChild(formula); + return doc; +} + + +void Compatibility::appendNextSequence(const TQDomDocument& doc, TQDomElement element) +{ + if (hasNext() && nextToken() == '{') { + element.appendChild(readSequence(doc)); + } + else { + pushback(); + element.appendChild(doc.createElement("SEQUENCE")); + } +} + + +TQDomElement Compatibility::getLastSequence(const TQDomDocument& doc, TQDomElement sequence) +{ + if (sequence.lastChild().nodeName() == "SEQUENCE") { + TQDomNode child = sequence.removeChild(sequence.lastChild()); + return child.toElement(); + } + else { + TQDomElement newSeq = doc.createElement("SEQUENCE"); + if (!sequence.lastChild().isNull()) { + TQDomNode child = sequence.removeChild(sequence.lastChild()); + newSeq.appendChild(child); + } + return newSeq; + } +} + + +TQDomElement Compatibility::findIndexNode(const TQDomDocument& doc, TQDomElement sequence) +{ + TQDomElement element; + if (sequence.lastChild().nodeName() == "INDEX") { + element = sequence.lastChild().toElement(); + } + else { + element = doc.createElement("INDEX"); + TQDomElement con = doc.createElement("CONTENT"); + element.appendChild(con); + con.appendChild(getLastSequence(doc, sequence)); + sequence.appendChild(element); + } + return element; +} + + +void Compatibility::appendToSequence(TQDomElement sequence, TQDomElement element, int leftIndexSeen) +{ + if (leftIndexSeen > 0) { + if (sequence.lastChild().nodeName() == "INDEX") { + TQDomElement index = sequence.lastChild().toElement(); + if ((index.firstChild().nodeName() == "CONTENT") && + (index.firstChild().firstChild().nodeName() == "SEQUENCE")) { + TQDomElement seq = index.firstChild().firstChild().toElement(); + if (element.nodeName() == "SEQUENCE") { + index.firstChild().replaceChild(element, seq); + } + else { + seq.appendChild(element); + } + return; + } + } + } + sequence.appendChild(element); +} + + +TQDomElement Compatibility::readMatrix(const TQDomDocument& doc) +{ + TQDomElement element = doc.createElement("MATRIX"); + + uint cols = nextToken(); + nextToken(); + uint rows = nextToken(); + + element.setAttribute("ROWS", rows); + element.setAttribute("COLUMNS", cols); + + if ((nextToken() == '}') && (nextToken() == OF_MATRIX) && (nextToken() == '{')) { + TQValueList matrix; + for (uint c = 0; c < cols; c++) { + for (uint r = 0; r < rows; r++) { + if (hasNext() && (nextToken() == '{')) { + TQDomElement tmp = readSequence(doc); + matrix.append(tmp); + } + if (hasNext() && (nextToken() != OF_SEPARATOR)) { + pushback(); + } + } + } + if (hasNext() && (nextToken() != '}')) { + pushback(); + } + + if (matrix.count() == rows*cols) { + for (uint r = 0; r < rows; r++) { + for (uint c = 0; c < cols; c++) { + element.appendChild(matrix[c*rows+r]); + } + } + } + } + else { + pushback(); + } + + return element; +} + + +TQDomElement Compatibility::readSequence(const TQDomDocument& doc) +{ + // matrizes start with something that isn't a sequence + if ((tokenLeft() > 6) && (lookAhead(1) == OF_SEPARATOR)) { + return readMatrix(doc); + } + + int leftIndexSeen = 0; + TQDomElement sequence = doc.createElement("SEQUENCE"); + + while (hasNext()) { + ushort ch = nextToken(); + + // Debug + //cout << "read: " << ch << " (" << static_cast(ch) << ')' << endl; + + if (leftIndexSeen > 0) leftIndexSeen--; + + switch (ch) { + case '{': + appendToSequence(sequence, readSequence(doc), leftIndexSeen); + break; + case '}': + return sequence; + case '(': + case '[': + case '|': { + // There is an empty sequence we have to remove + if (!sequence.lastChild().isNull()) { + sequence.removeChild(sequence.lastChild()); + } + + TQDomElement element = doc.createElement("BRACKET"); + appendToSequence(sequence, element, leftIndexSeen); + element.setAttribute("LEFT", ch); + element.setAttribute("RIGHT", (ch=='(') ? ')' : ((ch=='[') ? ']' : '|')); + + TQDomElement con = doc.createElement("CONTENT"); + element.appendChild(con); + appendNextSequence(doc, con); + break; + } + case OF_DIVIDE: { + TQDomElement element = doc.createElement("FRACTION"); + + TQDomElement num = doc.createElement("NUMERATOR"); + element.appendChild(num); + num.appendChild(getLastSequence(doc, sequence)); + + TQDomElement den = doc.createElement("DENOMINATOR"); + element.appendChild(den); + appendNextSequence(doc, den); + + appendToSequence(sequence, element, leftIndexSeen); + break; + } + case OF_SQRT: { + TQDomElement element = doc.createElement("ROOT"); + TQDomElement con = doc.createElement("CONTENT"); + element.appendChild(con); + appendNextSequence(doc, con); + + TQDomElement ind = doc.createElement("INDEX"); + element.appendChild(ind); + ind.appendChild(getLastSequence(doc, sequence)); + + appendToSequence(sequence, element, leftIndexSeen); + break; + } + case OF_POWER: { + TQDomElement element = findIndexNode(doc, sequence); + TQDomElement upperRight = doc.createElement("UPPERRIGHT"); + element.appendChild(upperRight); + appendNextSequence(doc, upperRight); + break; + } + case OF_SUB: { + TQDomElement element = findIndexNode(doc, sequence); + TQDomElement lowerRight = doc.createElement("LOWERRIGHT"); + element.appendChild(lowerRight); + appendNextSequence(doc, lowerRight); + break; + } + case OF_LSUP: { + TQDomElement upperLeft = doc.createElement("UPPERLEFT"); + upperLeft.appendChild(getLastSequence(doc, sequence)); + TQDomElement element; + if (sequence.lastChild().nodeName() == "INDEX") { + element = sequence.lastChild().toElement(); + } + else { + element = doc.createElement("INDEX"); + TQDomElement con = doc.createElement("CONTENT"); + element.appendChild(con); + TQDomElement seq = doc.createElement("SEQUENCE"); + con.appendChild(seq); + appendToSequence(sequence, element, leftIndexSeen); + } + element.appendChild(upperLeft); + leftIndexSeen = 2; + break; + } + case OF_LSUB: { + TQDomElement lowerLeft = doc.createElement("LOWERLEFT"); + lowerLeft.appendChild(getLastSequence(doc, sequence)); + TQDomElement element; + if (sequence.lastChild().nodeName() == "INDEX") { + element = sequence.lastChild().toElement(); + } + else { + element = doc.createElement("INDEX"); + TQDomElement con = doc.createElement("CONTENT"); + element.appendChild(con); + TQDomElement seq = doc.createElement("SEQUENCE"); + con.appendChild(seq); + appendToSequence(sequence, element, leftIndexSeen); + } + element.appendChild(lowerLeft); + leftIndexSeen = 2; + break; + } + case OF_ABOVE: { + if (sequence.lastChild().nodeName() == "SEQUENCE") { + TQDomElement seq = sequence.lastChild().toElement(); + if ((seq.childNodes().count() == 1) && + ((seq.lastChild().nodeName() == "SYMBOL") || + (seq.lastChild().nodeName() == "INDEX"))) { + sequence.removeChild(seq); + + TQDomElement element = seq.lastChild().toElement(); + TQDomElement upper = (element.nodeName() == "SYMBOL") ? + doc.createElement("UPPER") : + doc.createElement("UPPERMIDDLE"); + element.appendChild(upper); + appendNextSequence(doc, upper); + appendToSequence(sequence, element, leftIndexSeen); + break; + } + } + TQDomElement element = findIndexNode(doc, sequence); + TQDomElement upper = doc.createElement("UPPERMIDDLE"); + element.appendChild(upper); + appendNextSequence(doc, upper); + break; + } + case OF_BELOW: { + if (sequence.lastChild().nodeName() == "SEQUENCE") { + TQDomElement seq = sequence.lastChild().toElement(); + if ((seq.childNodes().count() == 1) && + ((seq.lastChild().nodeName() == "SYMBOL") || + (seq.lastChild().nodeName() == "INDEX"))) { + sequence.removeChild(seq); + + TQDomElement element = seq.lastChild().toElement(); + TQDomElement lower = (element.nodeName() == "SYMBOL") ? + doc.createElement("LOWER") : + doc.createElement("LOWERMIDDLE"); + element.appendChild(lower); + appendNextSequence(doc, lower); + appendToSequence(sequence, element, leftIndexSeen); + break; + } + } + TQDomElement element = findIndexNode(doc, sequence); + TQDomElement lower = doc.createElement("LOWERMIDDLE"); + element.appendChild(lower); + appendNextSequence(doc, lower); + break; + } + case OF_SYMBOL: + kdDebug() << "OF_SYMBOL" << endl; + break; + case INTEGRAL: + case SUM: + case PRODUCT: { + TQDomElement element = doc.createElement("SYMBOL"); + element.setAttribute("TYPE", + (ch==INTEGRAL) ? Integral : + ((ch==SUM) ? Sum : Product)); + + TQDomElement con = doc.createElement("CONTENT"); + element.appendChild(con); + con.appendChild(readSequence(doc)); + pushback(); + appendToSequence(sequence, element, leftIndexSeen); + break; + } + case ARROW: { + TQDomElement element = doc.createElement("TEXT"); + element.setAttribute("CHAR", TQString(TQChar(static_cast(174)))); + element.setAttribute("SYMBOL", "1"); + appendToSequence(sequence, element, leftIndexSeen); + break; + } + default: { + TQDomElement element = doc.createElement("TEXT"); + element.setAttribute("CHAR", TQString(formulaString[pos-1])); + appendToSequence(sequence, element, leftIndexSeen); + } + } + } + return sequence; +} + +KFORMULA_NAMESPACE_END diff --git a/lib/kformula/kformulaconfigpage.cc b/lib/kformula/kformulaconfigpage.cc deleted file mode 100644 index ce95c40c..00000000 --- a/lib/kformula/kformulaconfigpage.cc +++ /dev/null @@ -1,543 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2001 Andrea Rizzi - Ulrich Kuettler - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - -#include // first for gcc 2.7.2 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -//#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "contextstyle.h" -#include "kformulaconfigpage.h" -#include "kformuladocument.h" -#include "symboltable.h" - - -KFORMULA_NAMESPACE_BEGIN - - -ConfigurePage::ConfigurePage( Document* document, TQWidget* view, TDEConfig* config, TQVBox* box, char* name ) - : TQObject( box->parent(), name ), m_document( document ), m_view( view ), m_config( config ), m_changed( false ) -{ - const ContextStyle& contextStyle = document->getContextStyle( true ); - - // fonts - - TQGroupBox *gbox = new TQGroupBox( i18n( "Fonts" ), box ); - gbox->setColumnLayout( 0, Qt::Horizontal ); - - TQGridLayout* grid = new TQGridLayout( gbox->layout(), 5, 3 ); - grid->setSpacing( KDialog::spacingHint() ); - - grid->setColStretch(1, 1); - - defaultFont = contextStyle.getDefaultFont(); - nameFont = contextStyle.getNameFont(); - numberFont = contextStyle.getNumberFont(); - operatorFont = contextStyle.getOperatorFont(); - - connect( buildFontLine( gbox, grid, 0, defaultFont, - i18n( "Default font:" ), defaultFontName ), - TQT_SIGNAL( clicked() ), TQT_SLOT( selectNewDefaultFont() ) ); - - connect( buildFontLine( gbox, grid, 1, nameFont, - i18n( "Name font:" ), nameFontName ), - TQT_SIGNAL( clicked() ), TQT_SLOT( selectNewNameFont() ) ); - - connect( buildFontLine( gbox, grid, 2, numberFont, - i18n( "Number font:" ), numberFontName ), - TQT_SIGNAL( clicked() ), TQT_SLOT( selectNewNumberFont() ) ); - - connect( buildFontLine( gbox, grid, 3, operatorFont, - i18n( "Operator font:" ), operatorFontName ), - TQT_SIGNAL( clicked() ), TQT_SLOT( selectNewOperatorFont() ) ); - - TQLabel* sizeTitle = new TQLabel( i18n( "Default base size:" ), gbox ); - grid->addWidget( sizeTitle, 4, 0 ); - - sizeSpin = new KIntNumInput( contextStyle.baseSize(), gbox ); - sizeSpin->setRange( 8, 72, 1, true ); - - grid->addMultiCellWidget( sizeSpin, 4, 4, 1, 2 ); - - connect( sizeSpin, TQT_SIGNAL( valueChanged( int ) ), - TQT_SLOT( baseSizeChanged( int ) ) ); - - // syntax highlighting - - syntaxHighlighting = new TQCheckBox( i18n( "Use syntax highlighting" ),box ); - syntaxHighlighting->setChecked( contextStyle.syntaxHighlighting() ); - -// hlBox = new TQGroupBox( i18n( "Highlight Colors" ), box ); -// hlBox->setColumnLayout( 0, Qt::Horizontal ); - -// grid = new TQGridLayout( hlBox->layout(), 5, 2 ); -// grid->setSpacing( KDialog::spacingHint() ); - -// TQLabel* defaultLabel = new TQLabel( hlBox, "defaultLabel" ); -// defaultLabel->setText( i18n( "Default color:" ) ); -// grid->addWidget( defaultLabel, 0, 0 ); - -// defaultColorBtn = new KColorButton( hlBox, "defaultColor" ); -// defaultColorBtn->setColor( contextStyle.getDefaultColor() ); -// grid->addWidget( defaultColorBtn, 0, 1 ); - - -// TQLabel* numberLabel = new TQLabel( hlBox, "numberLabel" ); -// numberLabel->setText( i18n( "Number color:" ) ); -// grid->addWidget( numberLabel, 1, 0 ); - -// numberColorBtn = new KColorButton( hlBox, "numberColor" ); -// numberColorBtn->setColor( contextStyle.getNumberColorPlain() ); -// grid->addWidget( numberColorBtn, 1, 1 ); - - -// TQLabel* operatorLabel = new TQLabel( hlBox, "operatorLabel" ); -// operatorLabel->setText( i18n( "Operator color:" ) ); -// grid->addWidget( operatorLabel, 2, 0 ); - -// operatorColorBtn = new KColorButton( hlBox, "operatorColor" ); -// operatorColorBtn->setColor( contextStyle.getOperatorColorPlain() ); -// grid->addWidget( operatorColorBtn, 2, 1 ); - - -// TQLabel* emptyLabel = new TQLabel( hlBox, "emptyLabel" ); -// emptyLabel->setText( i18n( "Empty color:" ) ); -// grid->addWidget( emptyLabel, 3, 0 ); - -// emptyColorBtn = new KColorButton( hlBox, "emptyColor" ); -// emptyColorBtn->setColor( contextStyle.getEmptyColorPlain() ); -// grid->addWidget( emptyColorBtn, 3, 1 ); - - -// TQLabel* errorLabel = new TQLabel( hlBox, "errorLabel" ); -// errorLabel->setText( i18n( "Error color:" ) ); -// grid->addWidget( errorLabel, 4, 0 ); - -// errorColorBtn = new KColorButton( hlBox, "errorColor" ); -// errorColorBtn->setColor( contextStyle.getErrorColorPlain() ); -// grid->addWidget( errorColorBtn, 4, 1 ); - - connect( syntaxHighlighting, TQT_SIGNAL( clicked() ), - TQT_SLOT( syntaxHighlightingClicked() ) ); - - syntaxHighlightingClicked(); - - connect( syntaxHighlighting, TQT_SIGNAL( clicked() ), this, TQT_SLOT( slotChanged() ) ); - connect( sizeSpin, TQT_SIGNAL( valueChanged( int ) ), this, TQT_SLOT( slotChanged() ) ); - - Q_ASSERT( !m_changed ); -} - - -TQPushButton* ConfigurePage::buildFontLine( TQWidget* parent, - TQGridLayout* layout, int number, TQFont font, TQString name, - TQLabel*& fontName ) -{ - TQLabel* fontTitle = new TQLabel( name, parent ); - - TQString labelName = font.family() + ' ' + TQString::number( font.pointSize() ); - fontName = new TQLabel( labelName, parent ); - fontName->setFont( font ); - fontName->setFrameStyle(TQFrame::StyledPanel | TQFrame::Sunken); - - TQPushButton* chooseButton = new TQPushButton( i18n( "Choose..." ), parent ); - - layout->addWidget( fontTitle, number, 0 ); - layout->addWidget( fontName, number, 1 ); - layout->addWidget( chooseButton, number, 2 ); - - return chooseButton; -} - - -void ConfigurePage::apply() -{ - if ( !m_changed ) - return; - - ContextStyle& contextStyle = m_document->getContextStyle( true ); - - contextStyle.setDefaultFont( defaultFont ); - contextStyle.setNameFont( nameFont ); - contextStyle.setNumberFont( numberFont ); - contextStyle.setOperatorFont( operatorFont ); - contextStyle.setBaseSize( sizeSpin->value() ); - - contextStyle.setSyntaxHighlighting( syntaxHighlighting->isChecked() ); -// contextStyle.setDefaultColor( defaultColorBtn->color() ); -// contextStyle.setNumberColor( numberColorBtn->color() ); -// contextStyle.setOperatorColor( operatorColorBtn->color() ); -// contextStyle.setEmptyColor( emptyColorBtn->color() ); -// contextStyle.setErrorColor( errorColorBtn->color() ); - - m_config->setGroup( "kformula Font" ); - m_config->writeEntry( "defaultFont", TQString(defaultFont.toString()) ); - m_config->writeEntry( "nameFont", TQString(nameFont.toString()) ); - m_config->writeEntry( "numberFont", TQString(numberFont.toString()) ); - m_config->writeEntry( "operatorFont", TQString(operatorFont.toString()) ); - m_config->writeEntry( "baseSize", TQString::number( sizeSpin->value() ) ); - -// m_config->setGroup( "kformula Color" ); -// m_config->writeEntry( "syntaxHighlighting", syntaxHighlighting->isChecked() ); -// m_config->writeEntry( "defaultColor", defaultColorBtn->color() ); -// m_config->writeEntry( "numberColor", numberColorBtn->color() ); -// m_config->writeEntry( "operatorColor", operatorColorBtn->color() ); -// m_config->writeEntry( "emptyColor", emptyColorBtn->color() ); -// m_config->writeEntry( "errorColor", errorColorBtn->color() ); - - // notify!!! - m_document->updateConfig(); - m_changed = false; -} - -void ConfigurePage::slotDefault() -{ - defaultFont = TQFont( "Times", 12, TQFont::Normal, true ); - nameFont = TQFont( "Times" ); - numberFont = nameFont; - operatorFont = nameFont; - - sizeSpin->setValue( 20 ); - - updateFontLabel( defaultFont, defaultFontName ); - updateFontLabel( nameFont, nameFontName ); - updateFontLabel( numberFont, numberFontName ); - updateFontLabel( operatorFont, operatorFontName ); - - syntaxHighlighting->setChecked( true ); - syntaxHighlightingClicked(); - -// defaultColorBtn->setColor( TQt::black ); -// numberColorBtn->setColor( TQt::blue ); -// operatorColorBtn->setColor( TQt::darkGreen ); -// emptyColorBtn->setColor( TQt::blue ); -// errorColorBtn->setColor( TQt::darkRed ); - slotChanged(); -} - -void ConfigurePage::syntaxHighlightingClicked() -{ -// bool checked = syntaxHighlighting->isChecked(); -// hlBox->setEnabled( checked ); -} - -void ConfigurePage::selectNewDefaultFont() -{ - if ( selectFont( defaultFont ) ) - updateFontLabel( defaultFont, defaultFontName ); -} - -void ConfigurePage::selectNewNameFont() -{ - if ( selectFont( nameFont ) ) - updateFontLabel( nameFont, nameFontName ); -} - -void ConfigurePage::selectNewNumberFont() -{ - if ( selectFont( numberFont ) ) - updateFontLabel( numberFont, numberFontName ); -} - -void ConfigurePage::selectNewOperatorFont() -{ - if ( selectFont( operatorFont ) ) - updateFontLabel( operatorFont, operatorFontName ); -} - -bool ConfigurePage::selectFont( TQFont & font ) -{ - TQStringList list; - - TDEFontChooser::getFontList( list, TDEFontChooser::SmoothScalableFonts ); - - TDEFontDialog dlg( m_view, 0, false, true, list ); - dlg.setFont( font ); - - int result = dlg.exec(); - if ( KDialog::Accepted == result ) { - font = dlg.font(); - slotChanged(); - return true; - } - - return false; -} - -void ConfigurePage::baseSizeChanged( int /*value*/ ) -{ -} - -void ConfigurePage::updateFontLabel( TQFont font, TQLabel* label ) -{ - label->setText( font.family() + ' ' + TQString::number( font.pointSize() ) ); - label->setFont( font ); -} - -void ConfigurePage::slotChanged() -{ - m_changed = true; -} - -// class UsedFontItem : public TDEListViewItem { -// public: -// UsedFontItem( MathFontsConfigurePage* page, TQListView* parent, TQString font ) -// : TDEListViewItem( parent, font ), m_page( page ) {} - -// int compare( TQListViewItem* i, int col, bool ascending ) const; - -// private: -// MathFontsConfigurePage* m_page; -// }; - -// int UsedFontItem::compare( TQListViewItem* i, int, bool ) const -// { -// TQValueVector::iterator lhsIt = m_page->findUsedFont( text( 0 ) ); -// TQValueVector::iterator rhsIt = m_page->findUsedFont( i->text( 0 ) ); -// if ( lhsIt < rhsIt ) { -// return -1; -// } -// else if ( lhsIt > rhsIt ) { -// return 1; -// } -// return 0; -// } - -// MathFontsConfigurePage::MathFontsConfigurePage( Document* document, TQWidget* view, -// TDEConfig* config, TQVBox* box, char* name ) -// : TQObject( box->parent(), name ), m_document( document ), m_view( view ), m_config( config ) -// { -// TQWidget* fontWidget = new TQWidget( box ); -// TQGridLayout* fontLayout = new TQGridLayout( fontWidget, 1, 1, KDialog::marginHint(), KDialog::spacingHint() ); - -// TQHBoxLayout* hLayout = new TQHBoxLayout( 0, 0, 6 ); - -// availableFonts = new TDEListView( fontWidget ); -// availableFonts->addColumn( i18n( "Available Fonts" ) ); -// hLayout->addWidget( availableFonts ); - -// TQVBoxLayout* vLayout = new TQVBoxLayout( 0, 0, 6 ); -// TQSpacerItem* spacer1 = new TQSpacerItem( 20, 20, TQSizePolicy::Minimum, TQSizePolicy::Expanding ); -// vLayout->addItem( spacer1 ); - -// addFont = new KPushButton( fontWidget ); -// addFont->setText( "->" ); -// vLayout->addWidget( addFont ); - -// removeFont = new KPushButton( fontWidget ); -// removeFont->setText( "<-" ); -// vLayout->addWidget( removeFont ); - -// TQSpacerItem* spacer2 = new TQSpacerItem( 20, 20, TQSizePolicy::Minimum, TQSizePolicy::Expanding ); -// vLayout->addItem( spacer2 ); - -// hLayout->addLayout( vLayout ); - -// vLayout = new TQVBoxLayout( 0, 0, 6 ); - -// moveUp = new KPushButton( fontWidget ); -// moveUp->setText( i18n( "Up" ) ); -// vLayout->addWidget( moveUp ); - -// requestedFonts = new TDEListView( fontWidget ); -// requestedFonts->addColumn( i18n( "Used Fonts" ) ); -// vLayout->addWidget( requestedFonts ); - -// moveDown = new KPushButton( fontWidget ); -// moveDown->setText( i18n( "Down" ) ); -// vLayout->addWidget( moveDown ); - -// hLayout->addLayout( vLayout ); - -// fontLayout->addLayout( hLayout, 0, 0 ); - -// // connect( availableFonts, TQT_SIGNAL( executed( TQListViewItem* ) ), -// // this, TQT_SLOT( slotAddFont() ) ); -// // connect( requestedFonts, TQT_SIGNAL( executed( TQListViewItem* ) ), -// // this, TQT_SLOT( slotRemoveFont() ) ); -// connect( addFont, TQT_SIGNAL( clicked() ), this, TQT_SLOT( slotAddFont() ) ); -// connect( removeFont, TQT_SIGNAL( clicked() ), this, TQT_SLOT( slotRemoveFont() ) ); -// connect( moveUp, TQT_SIGNAL( clicked() ), this, TQT_SLOT( slotMoveUp() ) ); -// connect( moveDown, TQT_SIGNAL( clicked() ), this, TQT_SLOT( slotMoveDown() ) ); - -// const ContextStyle& contextStyle = document->getContextStyle( true ); -// const SymbolTable& symbolTable = contextStyle.symbolTable(); -// const TQStringList& usedFonts = contextStyle.requestedFonts(); - -// TQMap fontMap; -// // symbolTable.findAvailableFonts( &fontMap ); - -// setupLists( usedFonts ); -// } - -// void MathFontsConfigurePage::apply() -// { -// TQStringList strings; -// std::copy( usedFontList.begin(), usedFontList.end(), std::back_inserter( strings ) ); - -// m_config->setGroup( "kformula Font" ); -// m_config->writeEntry( "usedMathFonts", strings ); - -// ContextStyle& contextStyle = m_document->getContextStyle( true ); -// contextStyle.setRequestedFonts( strings ); -// } - -// void MathFontsConfigurePage::slotDefault() -// { -// TQStringList usedFonts; - -// usedFonts.push_back( "esstixone" ); -// usedFonts.push_back( "esstixtwo" ); -// usedFonts.push_back( "esstixthree" ); -// usedFonts.push_back( "esstixfour" ); -// usedFonts.push_back( "esstixfive" ); -// usedFonts.push_back( "esstixsix" ); -// usedFonts.push_back( "esstixseven" ); -// usedFonts.push_back( "esstixeight" ); -// usedFonts.push_back( "esstixnine" ); -// usedFonts.push_back( "esstixten" ); -// usedFonts.push_back( "esstixeleven" ); -// usedFonts.push_back( "esstixtwelve" ); -// usedFonts.push_back( "esstixthirteen" ); -// usedFonts.push_back( "esstixfourteen" ); -// usedFonts.push_back( "esstixfifteen" ); -// usedFonts.push_back( "esstixsixteen" ); -// usedFonts.push_back( "esstixseventeen" ); - -// usedFontList.clear(); -// requestedFonts->clear(); -// availableFonts->clear(); - -// setupLists( usedFonts ); -// } - -// TQValueVector::iterator MathFontsConfigurePage::findUsedFont( TQString name ) -// { -// return std::find( usedFontList.begin(), usedFontList.end(), name ); -// } - -// void MathFontsConfigurePage::setupLists( const TQStringList& usedFonts ) -// { -// const ContextStyle& contextStyle = m_document->getContextStyle( true ); -// const SymbolTable& symbolTable = contextStyle.symbolTable(); - -// TQMap fontMap; -// // symbolTable.findAvailableFonts( &fontMap ); - -// for ( TQStringList::const_iterator it = usedFonts.begin(); it != usedFonts.end(); ++it ) { -// TQMap::iterator font = fontMap.find( *it ); -// if ( font != fontMap.end() ) { -// fontMap.erase( font ); -// new UsedFontItem( this, requestedFonts, *it ); -// usedFontList.push_back( *it ); -// } -// } -// for ( TQMap::iterator it = fontMap.begin(); it != fontMap.end(); ++it ) { -// new TDEListViewItem( availableFonts, it.key() ); -// } -// } - -// void MathFontsConfigurePage::slotAddFont() -// { -// TQListViewItem* fontItem = availableFonts->selectedItem(); -// if ( fontItem ) { -// TQString fontName = fontItem->text( 0 ); -// //availableFonts->takeItem( fontItem ); -// delete fontItem; - -// new UsedFontItem( this, requestedFonts, fontName ); -// usedFontList.push_back( fontName ); -// } -// } - -// void MathFontsConfigurePage::slotRemoveFont() -// { -// TQListViewItem* fontItem = requestedFonts->selectedItem(); -// if ( fontItem ) { -// TQString fontName = fontItem->text( 0 ); -// TQValueVector::iterator it = std::find( usedFontList.begin(), usedFontList.end(), fontName ); -// if ( it != usedFontList.end() ) { -// usedFontList.erase( it ); -// } -// //requestedFonts->takeItem( fontItem ); -// delete fontItem; -// new TDEListViewItem( availableFonts, fontName ); -// } -// } - -// void MathFontsConfigurePage::slotMoveUp() -// { -// TQListViewItem* fontItem = requestedFonts->selectedItem(); -// if ( fontItem ) { -// TQString fontName = fontItem->text( 0 ); -// TQValueVector::iterator it = std::find( usedFontList.begin(), usedFontList.end(), fontName ); -// if ( it != usedFontList.end() ) { -// uint pos = it - usedFontList.begin(); -// if ( pos > 0 ) { -// TQValueVector::iterator before = it-1; -// std::swap( *it, *before ); -// requestedFonts->sort(); -// } -// } -// } -// } - -// void MathFontsConfigurePage::slotMoveDown() -// { -// TQListViewItem* fontItem = requestedFonts->selectedItem(); -// if ( fontItem ) { -// TQString fontName = fontItem->text( 0 ); -// TQValueVector::iterator it = std::find( usedFontList.begin(), usedFontList.end(), fontName ); -// if ( it != usedFontList.end() ) { -// uint pos = it - usedFontList.begin(); -// if ( pos < usedFontList.size()-1 ) { -// TQValueVector::iterator after = it+1; -// std::swap( *it, *after ); -// requestedFonts->sort(); -// } -// } -// } -// } - -KFORMULA_NAMESPACE_END - -using namespace KFormula; -#include "kformulaconfigpage.moc" diff --git a/lib/kformula/kformulaconfigpage.cpp b/lib/kformula/kformulaconfigpage.cpp new file mode 100644 index 00000000..ce95c40c --- /dev/null +++ b/lib/kformula/kformulaconfigpage.cpp @@ -0,0 +1,543 @@ +/* This file is part of the KDE project + Copyright (C) 2001 Andrea Rizzi + Ulrich Kuettler + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include // first for gcc 2.7.2 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "contextstyle.h" +#include "kformulaconfigpage.h" +#include "kformuladocument.h" +#include "symboltable.h" + + +KFORMULA_NAMESPACE_BEGIN + + +ConfigurePage::ConfigurePage( Document* document, TQWidget* view, TDEConfig* config, TQVBox* box, char* name ) + : TQObject( box->parent(), name ), m_document( document ), m_view( view ), m_config( config ), m_changed( false ) +{ + const ContextStyle& contextStyle = document->getContextStyle( true ); + + // fonts + + TQGroupBox *gbox = new TQGroupBox( i18n( "Fonts" ), box ); + gbox->setColumnLayout( 0, Qt::Horizontal ); + + TQGridLayout* grid = new TQGridLayout( gbox->layout(), 5, 3 ); + grid->setSpacing( KDialog::spacingHint() ); + + grid->setColStretch(1, 1); + + defaultFont = contextStyle.getDefaultFont(); + nameFont = contextStyle.getNameFont(); + numberFont = contextStyle.getNumberFont(); + operatorFont = contextStyle.getOperatorFont(); + + connect( buildFontLine( gbox, grid, 0, defaultFont, + i18n( "Default font:" ), defaultFontName ), + TQT_SIGNAL( clicked() ), TQT_SLOT( selectNewDefaultFont() ) ); + + connect( buildFontLine( gbox, grid, 1, nameFont, + i18n( "Name font:" ), nameFontName ), + TQT_SIGNAL( clicked() ), TQT_SLOT( selectNewNameFont() ) ); + + connect( buildFontLine( gbox, grid, 2, numberFont, + i18n( "Number font:" ), numberFontName ), + TQT_SIGNAL( clicked() ), TQT_SLOT( selectNewNumberFont() ) ); + + connect( buildFontLine( gbox, grid, 3, operatorFont, + i18n( "Operator font:" ), operatorFontName ), + TQT_SIGNAL( clicked() ), TQT_SLOT( selectNewOperatorFont() ) ); + + TQLabel* sizeTitle = new TQLabel( i18n( "Default base size:" ), gbox ); + grid->addWidget( sizeTitle, 4, 0 ); + + sizeSpin = new KIntNumInput( contextStyle.baseSize(), gbox ); + sizeSpin->setRange( 8, 72, 1, true ); + + grid->addMultiCellWidget( sizeSpin, 4, 4, 1, 2 ); + + connect( sizeSpin, TQT_SIGNAL( valueChanged( int ) ), + TQT_SLOT( baseSizeChanged( int ) ) ); + + // syntax highlighting + + syntaxHighlighting = new TQCheckBox( i18n( "Use syntax highlighting" ),box ); + syntaxHighlighting->setChecked( contextStyle.syntaxHighlighting() ); + +// hlBox = new TQGroupBox( i18n( "Highlight Colors" ), box ); +// hlBox->setColumnLayout( 0, Qt::Horizontal ); + +// grid = new TQGridLayout( hlBox->layout(), 5, 2 ); +// grid->setSpacing( KDialog::spacingHint() ); + +// TQLabel* defaultLabel = new TQLabel( hlBox, "defaultLabel" ); +// defaultLabel->setText( i18n( "Default color:" ) ); +// grid->addWidget( defaultLabel, 0, 0 ); + +// defaultColorBtn = new KColorButton( hlBox, "defaultColor" ); +// defaultColorBtn->setColor( contextStyle.getDefaultColor() ); +// grid->addWidget( defaultColorBtn, 0, 1 ); + + +// TQLabel* numberLabel = new TQLabel( hlBox, "numberLabel" ); +// numberLabel->setText( i18n( "Number color:" ) ); +// grid->addWidget( numberLabel, 1, 0 ); + +// numberColorBtn = new KColorButton( hlBox, "numberColor" ); +// numberColorBtn->setColor( contextStyle.getNumberColorPlain() ); +// grid->addWidget( numberColorBtn, 1, 1 ); + + +// TQLabel* operatorLabel = new TQLabel( hlBox, "operatorLabel" ); +// operatorLabel->setText( i18n( "Operator color:" ) ); +// grid->addWidget( operatorLabel, 2, 0 ); + +// operatorColorBtn = new KColorButton( hlBox, "operatorColor" ); +// operatorColorBtn->setColor( contextStyle.getOperatorColorPlain() ); +// grid->addWidget( operatorColorBtn, 2, 1 ); + + +// TQLabel* emptyLabel = new TQLabel( hlBox, "emptyLabel" ); +// emptyLabel->setText( i18n( "Empty color:" ) ); +// grid->addWidget( emptyLabel, 3, 0 ); + +// emptyColorBtn = new KColorButton( hlBox, "emptyColor" ); +// emptyColorBtn->setColor( contextStyle.getEmptyColorPlain() ); +// grid->addWidget( emptyColorBtn, 3, 1 ); + + +// TQLabel* errorLabel = new TQLabel( hlBox, "errorLabel" ); +// errorLabel->setText( i18n( "Error color:" ) ); +// grid->addWidget( errorLabel, 4, 0 ); + +// errorColorBtn = new KColorButton( hlBox, "errorColor" ); +// errorColorBtn->setColor( contextStyle.getErrorColorPlain() ); +// grid->addWidget( errorColorBtn, 4, 1 ); + + connect( syntaxHighlighting, TQT_SIGNAL( clicked() ), + TQT_SLOT( syntaxHighlightingClicked() ) ); + + syntaxHighlightingClicked(); + + connect( syntaxHighlighting, TQT_SIGNAL( clicked() ), this, TQT_SLOT( slotChanged() ) ); + connect( sizeSpin, TQT_SIGNAL( valueChanged( int ) ), this, TQT_SLOT( slotChanged() ) ); + + Q_ASSERT( !m_changed ); +} + + +TQPushButton* ConfigurePage::buildFontLine( TQWidget* parent, + TQGridLayout* layout, int number, TQFont font, TQString name, + TQLabel*& fontName ) +{ + TQLabel* fontTitle = new TQLabel( name, parent ); + + TQString labelName = font.family() + ' ' + TQString::number( font.pointSize() ); + fontName = new TQLabel( labelName, parent ); + fontName->setFont( font ); + fontName->setFrameStyle(TQFrame::StyledPanel | TQFrame::Sunken); + + TQPushButton* chooseButton = new TQPushButton( i18n( "Choose..." ), parent ); + + layout->addWidget( fontTitle, number, 0 ); + layout->addWidget( fontName, number, 1 ); + layout->addWidget( chooseButton, number, 2 ); + + return chooseButton; +} + + +void ConfigurePage::apply() +{ + if ( !m_changed ) + return; + + ContextStyle& contextStyle = m_document->getContextStyle( true ); + + contextStyle.setDefaultFont( defaultFont ); + contextStyle.setNameFont( nameFont ); + contextStyle.setNumberFont( numberFont ); + contextStyle.setOperatorFont( operatorFont ); + contextStyle.setBaseSize( sizeSpin->value() ); + + contextStyle.setSyntaxHighlighting( syntaxHighlighting->isChecked() ); +// contextStyle.setDefaultColor( defaultColorBtn->color() ); +// contextStyle.setNumberColor( numberColorBtn->color() ); +// contextStyle.setOperatorColor( operatorColorBtn->color() ); +// contextStyle.setEmptyColor( emptyColorBtn->color() ); +// contextStyle.setErrorColor( errorColorBtn->color() ); + + m_config->setGroup( "kformula Font" ); + m_config->writeEntry( "defaultFont", TQString(defaultFont.toString()) ); + m_config->writeEntry( "nameFont", TQString(nameFont.toString()) ); + m_config->writeEntry( "numberFont", TQString(numberFont.toString()) ); + m_config->writeEntry( "operatorFont", TQString(operatorFont.toString()) ); + m_config->writeEntry( "baseSize", TQString::number( sizeSpin->value() ) ); + +// m_config->setGroup( "kformula Color" ); +// m_config->writeEntry( "syntaxHighlighting", syntaxHighlighting->isChecked() ); +// m_config->writeEntry( "defaultColor", defaultColorBtn->color() ); +// m_config->writeEntry( "numberColor", numberColorBtn->color() ); +// m_config->writeEntry( "operatorColor", operatorColorBtn->color() ); +// m_config->writeEntry( "emptyColor", emptyColorBtn->color() ); +// m_config->writeEntry( "errorColor", errorColorBtn->color() ); + + // notify!!! + m_document->updateConfig(); + m_changed = false; +} + +void ConfigurePage::slotDefault() +{ + defaultFont = TQFont( "Times", 12, TQFont::Normal, true ); + nameFont = TQFont( "Times" ); + numberFont = nameFont; + operatorFont = nameFont; + + sizeSpin->setValue( 20 ); + + updateFontLabel( defaultFont, defaultFontName ); + updateFontLabel( nameFont, nameFontName ); + updateFontLabel( numberFont, numberFontName ); + updateFontLabel( operatorFont, operatorFontName ); + + syntaxHighlighting->setChecked( true ); + syntaxHighlightingClicked(); + +// defaultColorBtn->setColor( TQt::black ); +// numberColorBtn->setColor( TQt::blue ); +// operatorColorBtn->setColor( TQt::darkGreen ); +// emptyColorBtn->setColor( TQt::blue ); +// errorColorBtn->setColor( TQt::darkRed ); + slotChanged(); +} + +void ConfigurePage::syntaxHighlightingClicked() +{ +// bool checked = syntaxHighlighting->isChecked(); +// hlBox->setEnabled( checked ); +} + +void ConfigurePage::selectNewDefaultFont() +{ + if ( selectFont( defaultFont ) ) + updateFontLabel( defaultFont, defaultFontName ); +} + +void ConfigurePage::selectNewNameFont() +{ + if ( selectFont( nameFont ) ) + updateFontLabel( nameFont, nameFontName ); +} + +void ConfigurePage::selectNewNumberFont() +{ + if ( selectFont( numberFont ) ) + updateFontLabel( numberFont, numberFontName ); +} + +void ConfigurePage::selectNewOperatorFont() +{ + if ( selectFont( operatorFont ) ) + updateFontLabel( operatorFont, operatorFontName ); +} + +bool ConfigurePage::selectFont( TQFont & font ) +{ + TQStringList list; + + TDEFontChooser::getFontList( list, TDEFontChooser::SmoothScalableFonts ); + + TDEFontDialog dlg( m_view, 0, false, true, list ); + dlg.setFont( font ); + + int result = dlg.exec(); + if ( KDialog::Accepted == result ) { + font = dlg.font(); + slotChanged(); + return true; + } + + return false; +} + +void ConfigurePage::baseSizeChanged( int /*value*/ ) +{ +} + +void ConfigurePage::updateFontLabel( TQFont font, TQLabel* label ) +{ + label->setText( font.family() + ' ' + TQString::number( font.pointSize() ) ); + label->setFont( font ); +} + +void ConfigurePage::slotChanged() +{ + m_changed = true; +} + +// class UsedFontItem : public TDEListViewItem { +// public: +// UsedFontItem( MathFontsConfigurePage* page, TQListView* parent, TQString font ) +// : TDEListViewItem( parent, font ), m_page( page ) {} + +// int compare( TQListViewItem* i, int col, bool ascending ) const; + +// private: +// MathFontsConfigurePage* m_page; +// }; + +// int UsedFontItem::compare( TQListViewItem* i, int, bool ) const +// { +// TQValueVector::iterator lhsIt = m_page->findUsedFont( text( 0 ) ); +// TQValueVector::iterator rhsIt = m_page->findUsedFont( i->text( 0 ) ); +// if ( lhsIt < rhsIt ) { +// return -1; +// } +// else if ( lhsIt > rhsIt ) { +// return 1; +// } +// return 0; +// } + +// MathFontsConfigurePage::MathFontsConfigurePage( Document* document, TQWidget* view, +// TDEConfig* config, TQVBox* box, char* name ) +// : TQObject( box->parent(), name ), m_document( document ), m_view( view ), m_config( config ) +// { +// TQWidget* fontWidget = new TQWidget( box ); +// TQGridLayout* fontLayout = new TQGridLayout( fontWidget, 1, 1, KDialog::marginHint(), KDialog::spacingHint() ); + +// TQHBoxLayout* hLayout = new TQHBoxLayout( 0, 0, 6 ); + +// availableFonts = new TDEListView( fontWidget ); +// availableFonts->addColumn( i18n( "Available Fonts" ) ); +// hLayout->addWidget( availableFonts ); + +// TQVBoxLayout* vLayout = new TQVBoxLayout( 0, 0, 6 ); +// TQSpacerItem* spacer1 = new TQSpacerItem( 20, 20, TQSizePolicy::Minimum, TQSizePolicy::Expanding ); +// vLayout->addItem( spacer1 ); + +// addFont = new KPushButton( fontWidget ); +// addFont->setText( "->" ); +// vLayout->addWidget( addFont ); + +// removeFont = new KPushButton( fontWidget ); +// removeFont->setText( "<-" ); +// vLayout->addWidget( removeFont ); + +// TQSpacerItem* spacer2 = new TQSpacerItem( 20, 20, TQSizePolicy::Minimum, TQSizePolicy::Expanding ); +// vLayout->addItem( spacer2 ); + +// hLayout->addLayout( vLayout ); + +// vLayout = new TQVBoxLayout( 0, 0, 6 ); + +// moveUp = new KPushButton( fontWidget ); +// moveUp->setText( i18n( "Up" ) ); +// vLayout->addWidget( moveUp ); + +// requestedFonts = new TDEListView( fontWidget ); +// requestedFonts->addColumn( i18n( "Used Fonts" ) ); +// vLayout->addWidget( requestedFonts ); + +// moveDown = new KPushButton( fontWidget ); +// moveDown->setText( i18n( "Down" ) ); +// vLayout->addWidget( moveDown ); + +// hLayout->addLayout( vLayout ); + +// fontLayout->addLayout( hLayout, 0, 0 ); + +// // connect( availableFonts, TQT_SIGNAL( executed( TQListViewItem* ) ), +// // this, TQT_SLOT( slotAddFont() ) ); +// // connect( requestedFonts, TQT_SIGNAL( executed( TQListViewItem* ) ), +// // this, TQT_SLOT( slotRemoveFont() ) ); +// connect( addFont, TQT_SIGNAL( clicked() ), this, TQT_SLOT( slotAddFont() ) ); +// connect( removeFont, TQT_SIGNAL( clicked() ), this, TQT_SLOT( slotRemoveFont() ) ); +// connect( moveUp, TQT_SIGNAL( clicked() ), this, TQT_SLOT( slotMoveUp() ) ); +// connect( moveDown, TQT_SIGNAL( clicked() ), this, TQT_SLOT( slotMoveDown() ) ); + +// const ContextStyle& contextStyle = document->getContextStyle( true ); +// const SymbolTable& symbolTable = contextStyle.symbolTable(); +// const TQStringList& usedFonts = contextStyle.requestedFonts(); + +// TQMap fontMap; +// // symbolTable.findAvailableFonts( &fontMap ); + +// setupLists( usedFonts ); +// } + +// void MathFontsConfigurePage::apply() +// { +// TQStringList strings; +// std::copy( usedFontList.begin(), usedFontList.end(), std::back_inserter( strings ) ); + +// m_config->setGroup( "kformula Font" ); +// m_config->writeEntry( "usedMathFonts", strings ); + +// ContextStyle& contextStyle = m_document->getContextStyle( true ); +// contextStyle.setRequestedFonts( strings ); +// } + +// void MathFontsConfigurePage::slotDefault() +// { +// TQStringList usedFonts; + +// usedFonts.push_back( "esstixone" ); +// usedFonts.push_back( "esstixtwo" ); +// usedFonts.push_back( "esstixthree" ); +// usedFonts.push_back( "esstixfour" ); +// usedFonts.push_back( "esstixfive" ); +// usedFonts.push_back( "esstixsix" ); +// usedFonts.push_back( "esstixseven" ); +// usedFonts.push_back( "esstixeight" ); +// usedFonts.push_back( "esstixnine" ); +// usedFonts.push_back( "esstixten" ); +// usedFonts.push_back( "esstixeleven" ); +// usedFonts.push_back( "esstixtwelve" ); +// usedFonts.push_back( "esstixthirteen" ); +// usedFonts.push_back( "esstixfourteen" ); +// usedFonts.push_back( "esstixfifteen" ); +// usedFonts.push_back( "esstixsixteen" ); +// usedFonts.push_back( "esstixseventeen" ); + +// usedFontList.clear(); +// requestedFonts->clear(); +// availableFonts->clear(); + +// setupLists( usedFonts ); +// } + +// TQValueVector::iterator MathFontsConfigurePage::findUsedFont( TQString name ) +// { +// return std::find( usedFontList.begin(), usedFontList.end(), name ); +// } + +// void MathFontsConfigurePage::setupLists( const TQStringList& usedFonts ) +// { +// const ContextStyle& contextStyle = m_document->getContextStyle( true ); +// const SymbolTable& symbolTable = contextStyle.symbolTable(); + +// TQMap fontMap; +// // symbolTable.findAvailableFonts( &fontMap ); + +// for ( TQStringList::const_iterator it = usedFonts.begin(); it != usedFonts.end(); ++it ) { +// TQMap::iterator font = fontMap.find( *it ); +// if ( font != fontMap.end() ) { +// fontMap.erase( font ); +// new UsedFontItem( this, requestedFonts, *it ); +// usedFontList.push_back( *it ); +// } +// } +// for ( TQMap::iterator it = fontMap.begin(); it != fontMap.end(); ++it ) { +// new TDEListViewItem( availableFonts, it.key() ); +// } +// } + +// void MathFontsConfigurePage::slotAddFont() +// { +// TQListViewItem* fontItem = availableFonts->selectedItem(); +// if ( fontItem ) { +// TQString fontName = fontItem->text( 0 ); +// //availableFonts->takeItem( fontItem ); +// delete fontItem; + +// new UsedFontItem( this, requestedFonts, fontName ); +// usedFontList.push_back( fontName ); +// } +// } + +// void MathFontsConfigurePage::slotRemoveFont() +// { +// TQListViewItem* fontItem = requestedFonts->selectedItem(); +// if ( fontItem ) { +// TQString fontName = fontItem->text( 0 ); +// TQValueVector::iterator it = std::find( usedFontList.begin(), usedFontList.end(), fontName ); +// if ( it != usedFontList.end() ) { +// usedFontList.erase( it ); +// } +// //requestedFonts->takeItem( fontItem ); +// delete fontItem; +// new TDEListViewItem( availableFonts, fontName ); +// } +// } + +// void MathFontsConfigurePage::slotMoveUp() +// { +// TQListViewItem* fontItem = requestedFonts->selectedItem(); +// if ( fontItem ) { +// TQString fontName = fontItem->text( 0 ); +// TQValueVector::iterator it = std::find( usedFontList.begin(), usedFontList.end(), fontName ); +// if ( it != usedFontList.end() ) { +// uint pos = it - usedFontList.begin(); +// if ( pos > 0 ) { +// TQValueVector::iterator before = it-1; +// std::swap( *it, *before ); +// requestedFonts->sort(); +// } +// } +// } +// } + +// void MathFontsConfigurePage::slotMoveDown() +// { +// TQListViewItem* fontItem = requestedFonts->selectedItem(); +// if ( fontItem ) { +// TQString fontName = fontItem->text( 0 ); +// TQValueVector::iterator it = std::find( usedFontList.begin(), usedFontList.end(), fontName ); +// if ( it != usedFontList.end() ) { +// uint pos = it - usedFontList.begin(); +// if ( pos < usedFontList.size()-1 ) { +// TQValueVector::iterator after = it+1; +// std::swap( *it, *after ); +// requestedFonts->sort(); +// } +// } +// } +// } + +KFORMULA_NAMESPACE_END + +using namespace KFormula; +#include "kformulaconfigpage.moc" diff --git a/lib/kformula/kformulacontainer.cc b/lib/kformula/kformulacontainer.cc deleted file mode 100644 index a6123154..00000000 --- a/lib/kformula/kformulacontainer.cc +++ /dev/null @@ -1,643 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2001 Andrea Rizzi - Ulrich Kuettler - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "KoGlobal.h" -#include "bracketelement.h" -#include "contextstyle.h" -#include "formulacursor.h" -#include "formulaelement.h" -#include "fractionelement.h" -#include "indexelement.h" -#include "kformulacommand.h" -#include "kformulacompatibility.h" -#include "kformulacontainer.h" -#include "kformuladocument.h" -#include "kformulamathmlread.h" -#include "kformulamimesource.h" -#include "matrixelement.h" -#include "rootelement.h" -#include "sequenceelement.h" -#include "symbolelement.h" -#include "symboltable.h" -#include "spaceelement.h" -#include "textelement.h" - -#include - -KFORMULA_NAMESPACE_BEGIN -using namespace std; - - -struct Container::Container_Impl { - - Container_Impl( Document* doc ) - : dirty( true ), cursorMoved( false ), document( doc ) - { - } - - ~Container_Impl() - { - delete internCursor; - delete rootElement; - document = 0; - } - - /** - * If true we need to recalc the formula. - */ - bool dirty; - - /** - * Tells whether a request caused the cursor to move. - */ - bool cursorMoved; - - /** - * The element tree's root. - */ - FormulaElement* rootElement; - - /** - * The active cursor is the one that triggered the last command. - */ - FormulaCursor* activeCursor; - - /** - * The cursor that is used if there is no view. - */ - FormulaCursor* internCursor; - - /** - * The document we belong to. - */ - Document* document; -}; - - -FormulaElement* Container::rootElement() const { return impl->rootElement; } -Document* Container::document() const { return impl->document; } - -Container::Container( Document* doc, int pos, bool registerMe ) -{ - impl = new Container_Impl( doc ); - impl->rootElement = 0; - if ( registerMe ) { - registerFormula( pos ); - } -} - -Container::~Container() -{ - unregisterFormula(); - delete impl; - impl = 0; -} - - -void Container::initialize() -{ - assert( impl->rootElement == 0 ); - impl->rootElement = createMainSequence(); - impl->activeCursor = impl->internCursor = createCursor(); - recalc(); -} - - -FormulaElement* Container::createMainSequence() -{ - return new FormulaElement( this ); -} - - -FormulaCursor* Container::createCursor() -{ - return new FormulaCursor(rootElement()); -} - - -KoCommandHistory* Container::getHistory() const -{ - return document()->getHistory(); -} - - -/** - * Gets called just before the child is removed from - * the element tree. - */ -void Container::elementRemoval(BasicElement* child) -{ - emit elementWillVanish(child); -} - -/** - * Gets called whenever something changes and we need to - * recalc. - */ -void Container::changed() -{ - impl->dirty = true; -} - -void Container::cursorHasMoved( FormulaCursor* ) -{ - impl->cursorMoved = true; -} - -void Container::moveOutLeft( FormulaCursor* cursor ) -{ - emit leaveFormula( this, cursor, EXIT_LEFT ); -} - -void Container::moveOutRight( FormulaCursor* cursor ) -{ - emit leaveFormula( this, cursor, EXIT_RIGHT ); -} - -void Container::moveOutAbove( FormulaCursor* cursor ) -{ - emit leaveFormula( this, cursor, EXIT_ABOVE ); -} - -void Container::moveOutBelow( FormulaCursor* cursor ) -{ - emit leaveFormula( this, cursor, EXIT_BELOW ); -} - -void Container::tell( const TQString& msg ) -{ - emit statusMsg( msg ); -} - -void Container::removeFormula( FormulaCursor* cursor ) -{ - emit leaveFormula( this, cursor, REMOVE_FORMULA ); -} - - -void Container::registerFormula( int pos ) -{ - document()->registerFormula( this, pos ); -} - -void Container::unregisterFormula() -{ - document()->unregisterFormula( this ); -} - - -void Container::baseSizeChanged( int size, bool owned ) -{ - if ( owned ) { - emit baseSizeChanged( size ); - } - else { - const ContextStyle& context = document()->getContextStyle(); - emit baseSizeChanged( context.baseSize() ); - } -} - -FormulaCursor* Container::activeCursor() -{ - return impl->activeCursor; -} - -const FormulaCursor* Container::activeCursor() const -{ - return impl->activeCursor; -} - - -/** - * Tells the formula that a view got the focus and might want to - * edit the formula. - */ -void Container::setActiveCursor(FormulaCursor* cursor) -{ - document()->activate(this); - if (cursor != 0) { - impl->activeCursor = cursor; - } - else { - *(impl->internCursor) = *(impl->activeCursor); - impl->activeCursor = impl->internCursor; - } -} - - -bool Container::hasValidCursor() const -{ - return (impl->activeCursor != 0) && !impl->activeCursor->isReadOnly(); -} - -void Container::testDirty() -{ - if (impl->dirty) { - recalc(); - } -} - -void Container::recalc() -{ - impl->dirty = false; - ContextStyle& context = impl->document->getContextStyle(); - rootElement()->calcSizes( context ); - - emit formulaChanged( context.layoutUnitToPixelX( rootElement()->getWidth() ), - context.layoutUnitToPixelY( rootElement()->getHeight() ) ); - emit formulaChanged( context.layoutUnitPtToPt( context.pixelXToPt( rootElement()->getWidth() ) ), - context.layoutUnitPtToPt( context.pixelYToPt( rootElement()->getHeight() ) ) ); - emit cursorMoved( activeCursor() ); -} - -bool Container::isEmpty() -{ - return rootElement()->countChildren() == 0; -} - - -const SymbolTable& Container::getSymbolTable() const -{ - return document()->getSymbolTable(); -} - - -void Container::draw( TQPainter& painter, const TQRect& r, const TQColorGroup& cg, bool edit ) -{ - painter.fillRect( r, cg.base() ); - draw( painter, r, edit ); -} - - -void Container::draw( TQPainter& painter, const TQRect& r, bool edit ) -{ - //ContextStyle& context = document()->getContextStyle( painter.device()->devType() == TQInternal::Printer ); - ContextStyle& context = document()->getContextStyle( edit ); - rootElement()->draw( painter, context.pixelToLayoutUnit( r ), context ); -} - - -void Container::checkCursor() -{ - if ( impl->cursorMoved ) { - impl->cursorMoved = false; - emit cursorMoved( activeCursor() ); - } -} - -void Container::input( TQKeyEvent* event ) -{ - //if ( !hasValidCursor() ) - if ( impl->activeCursor == 0 ) { - return; - } - execute( activeCursor()->getElement()->input( this, event ) ); - checkCursor(); -} - - -void Container::performRequest( Request* request ) -{ - if ( !hasValidCursor() ) - return; - execute( activeCursor()->getElement()->buildCommand( this, request ) ); - checkCursor(); -} - - -void Container::paste() -{ - if (!hasValidCursor()) - return; - TQClipboard* clipboard = TQApplication::clipboard(); - const TQMimeSource* source = clipboard->data(); - if (source->provides( MimeSource::selectionMimeType() )) { - TQByteArray data = source->encodedData( MimeSource::selectionMimeType() ); - TQDomDocument formula; - formula.setContent(data); - paste( formula, i18n("Paste") ); - } -} - -void Container::paste( const TQDomDocument& document, TQString desc ) -{ - FormulaCursor* cursor = activeCursor(); - TQPtrList list; - list.setAutoDelete( true ); - if ( cursor->buildElementsFromMathMLDom( document.documentElement(), list ) ) { - uint count = list.count(); - // You must not execute an add command that adds nothing. - if (count > 0) { - KFCReplace* command = new KFCReplace( desc, this ); - for (uint i = 0; i < count; i++) { - command->addElement(list.take(0)); - } - execute(command); - } - } -} - -void Container::copy() -{ - // read-only cursors are fine for copying. - FormulaCursor* cursor = activeCursor(); - if (cursor != 0) { - TQDomDocument formula = document()->createMathMLDomDocument(); - cursor->copy( formula ); - TQClipboard* clipboard = TQApplication::clipboard(); - clipboard->setData(new MimeSource(document(), formula)); - } -} - -void Container::cut() -{ - if (!hasValidCursor()) - return; - FormulaCursor* cursor = activeCursor(); - if (cursor->isSelection()) { - copy(); - DirectedRemove r( req_remove, beforeCursor ); - performRequest( &r ); - } -} - - -void Container::emitErrorMsg( const TQString& msg ) -{ - emit errorMsg( msg ); -} - -void Container::execute(KCommand* command) -{ - if ( command != 0 ) { - getHistory()->addCommand(command); - } -} - - -TQRect Container::boundingRect() const -{ - const ContextStyle& context = document()->getContextStyle(); - return TQRect( context.layoutUnitToPixelX( rootElement()->getX() ), - context.layoutUnitToPixelY( rootElement()->getY() ), - context.layoutUnitToPixelX( rootElement()->getWidth() ), - context.layoutUnitToPixelY( rootElement()->getHeight() ) ); -} - -TQRect Container::coveredRect() -{ - if ( impl->activeCursor != 0 ) { - const ContextStyle& context = document()->getContextStyle(); - const LuPixelRect& cursorRect = impl->activeCursor->getCursorSize(); - return TQRect( context.layoutUnitToPixelX( rootElement()->getX() ), - context.layoutUnitToPixelY( rootElement()->getY() ), - context.layoutUnitToPixelX( rootElement()->getWidth() ), - context.layoutUnitToPixelY( rootElement()->getHeight() ) ) | - TQRect( context.layoutUnitToPixelX( cursorRect.x() ), - context.layoutUnitToPixelY( cursorRect.y() ), - context.layoutUnitToPixelX( cursorRect.width() ), - context.layoutUnitToPixelY( cursorRect.height() ) ); - } - return boundingRect(); -} - -double Container::width() const -{ - const ContextStyle& context = document()->getContextStyle(); - return context.layoutUnitPtToPt( context.pixelXToPt( rootElement()->getWidth() ) ); -} - -double Container::height() const -{ - const ContextStyle& context = document()->getContextStyle(); - return context.layoutUnitPtToPt( context.pixelYToPt( rootElement()->getHeight() ) ); -} - -double Container::baseline() const -{ - const ContextStyle& context = document()->getContextStyle(); - //return context.layoutUnitToPixelY( rootElement()->getBaseline() ); - return context.layoutUnitPtToPt( context.pixelYToPt( rootElement()->getBaseline() ) ); -} - -void Container::moveTo( int x, int y ) -{ - const ContextStyle& context = document()->getContextStyle(); - rootElement()->setX( context.pixelToLayoutUnitX( x ) ); - rootElement()->setY( context.pixelToLayoutUnitY( y ) ); -} - -int Container::fontSize() const -{ - if ( rootElement()->hasOwnBaseSize() ) { - return rootElement()->getBaseSize(); - } - else { - const ContextStyle& context = document()->getContextStyle(); - return tqRound( context.baseSize() ); - } -} - -void Container::setFontSize( int pointSize, bool /*forPrint*/ ) -{ - if ( rootElement()->getBaseSize() != pointSize ) { - execute( new KFCChangeBaseSize( i18n( "Base Size Change" ), this, rootElement(), pointSize ) ); - } -} - -void Container::setFontSizeDirect( int pointSize ) -{ - rootElement()->setBaseSize( pointSize ); - recalc(); -} - -void Container::updateMatrixActions() -{ - BasicElement *currentElement = activeCursor()->getElement(); - if ( ( currentElement = currentElement->getParent() ) != 0 ) - document()->wrapper()->enableMatrixActions( dynamic_cast(currentElement) ); - else - document()->wrapper()->enableMatrixActions( false ); -} - -void Container::save( TQDomElement &root ) -{ - TQDomDocument ownerDoc = root.ownerDocument(); - root.appendChild(rootElement()->getElementDom(ownerDoc)); -} - - -/** - * Loads a formula from the document. - */ -bool Container::load( const TQDomElement &fe ) -{ - if (!fe.isNull()) { - FormulaElement* root = createMainSequence(); - if (root->buildFromDom(fe)) { - delete impl->rootElement; - impl->rootElement = root; - emit formulaLoaded(rootElement()); - - recalc(); - return true; - } - else { - delete root; - kdWarning( DEBUGID ) << "Error constructing element tree." << endl; - } - } - else { - kdWarning( DEBUGID ) << "Empty element." << endl; - } - return false; -} - - -void Container::saveMathML( TQTextStream& stream, bool oasisFormat ) -{ - TQDomDocument doc; - if ( !oasisFormat ) { - doc = document()->createMathMLDomDocument(); - } - rootElement()->writeMathML( doc, doc, oasisFormat ); - stream << doc; -} - -bool Container::loadMathML( const TQDomDocument &doc, bool oasisFormat ) -{ - return loadMathML( doc.documentElement(), oasisFormat ); -} - -/* -bool Container::loadMathML( const TQDomElement &element, bool oasisFormat ) -{ - const ContextStyle& context = document()->getContextStyle(); - MathML2KFormula filter( element, context, oasisFormat ); - filter.startConversion(); - if (filter.m_error) { - return false; - } - - if ( load( filter.getKFormulaDom().documentElement() ) ) { - getHistory()->clear(); - return true; - } - return false; -} -*/ - -bool Container::loadMathML( const TQDomElement &fe, bool /*oasisFormat*/ ) -{ - kdDebug( DEBUGID ) << "loadMathML" << endl; - if (!fe.isNull()) { - FormulaElement* root = createMainSequence(); - if ( root->buildFromMathMLDom( fe ) != - 1) { - delete impl->rootElement; - impl->rootElement = root; - emit formulaLoaded(rootElement()); - - recalc(); - return true; - } - else { - delete root; - kdWarning( DEBUGID ) << "Error constructing element tree." << endl; - } - } - else { - kdWarning( DEBUGID ) << "Empty element." << endl; - } - return false; -} - - -void Container::print(KPrinter& printer) -{ - //printer.setFullPage(true); - TQPainter painter; - if (painter.begin(&printer)) { - rootElement()->draw( painter, LuPixelRect( rootElement()->getX(), - rootElement()->getY(), - rootElement()->getWidth(), - rootElement()->getHeight() ), - document()->getContextStyle( false ) ); - } -} - -TQImage Container::drawImage( int width, int height ) -{ - ContextStyle& context = document()->getContextStyle( false ); - TQRect rect(impl->rootElement->getX(), impl->rootElement->getY(), - impl->rootElement->getWidth(), impl->rootElement->getHeight()); - - int realWidth = context.layoutUnitToPixelX( impl->rootElement->getWidth() ); - int realHeight = context.layoutUnitToPixelY( impl->rootElement->getHeight() ); - - double f = TQMAX( static_cast( width )/static_cast( realWidth ), - static_cast( height )/static_cast( realHeight ) ); - - int oldZoom = context.zoom(); - context.setZoomAndResolution( tqRound( oldZoom*f ), KoGlobal::dpiX(), KoGlobal::dpiY() ); - - kdDebug( DEBUGID ) << "Container::drawImage " - << "(" << width << " " << height << ")" - << "(" << context.layoutUnitToPixelX( impl->rootElement->getWidth() ) - << " " << context.layoutUnitToPixelY( impl->rootElement->getHeight() ) << ")" - << endl; - - TQPixmap pm( context.layoutUnitToPixelX( impl->rootElement->getWidth() ), - context.layoutUnitToPixelY( impl->rootElement->getHeight() ) ); - pm.fill(); - TQPainter paint(&pm); - impl->rootElement->draw(paint, rect, context); - paint.end(); - context.setZoomAndResolution( oldZoom, KoGlobal::dpiX(), KoGlobal::dpiY() ); - //return pm.convertToImage().smoothScale( width, height ); - return pm.convertToImage(); -} - -TQString Container::texString() -{ - return rootElement()->toLatex(); -} - -TQString Container::formulaString() -{ - return rootElement()->formulaString(); -} - -KFORMULA_NAMESPACE_END - -using namespace KFormula; -#include "kformulacontainer.moc" diff --git a/lib/kformula/kformulacontainer.cpp b/lib/kformula/kformulacontainer.cpp new file mode 100644 index 00000000..a6123154 --- /dev/null +++ b/lib/kformula/kformulacontainer.cpp @@ -0,0 +1,643 @@ +/* This file is part of the KDE project + Copyright (C) 2001 Andrea Rizzi + Ulrich Kuettler + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "KoGlobal.h" +#include "bracketelement.h" +#include "contextstyle.h" +#include "formulacursor.h" +#include "formulaelement.h" +#include "fractionelement.h" +#include "indexelement.h" +#include "kformulacommand.h" +#include "kformulacompatibility.h" +#include "kformulacontainer.h" +#include "kformuladocument.h" +#include "kformulamathmlread.h" +#include "kformulamimesource.h" +#include "matrixelement.h" +#include "rootelement.h" +#include "sequenceelement.h" +#include "symbolelement.h" +#include "symboltable.h" +#include "spaceelement.h" +#include "textelement.h" + +#include + +KFORMULA_NAMESPACE_BEGIN +using namespace std; + + +struct Container::Container_Impl { + + Container_Impl( Document* doc ) + : dirty( true ), cursorMoved( false ), document( doc ) + { + } + + ~Container_Impl() + { + delete internCursor; + delete rootElement; + document = 0; + } + + /** + * If true we need to recalc the formula. + */ + bool dirty; + + /** + * Tells whether a request caused the cursor to move. + */ + bool cursorMoved; + + /** + * The element tree's root. + */ + FormulaElement* rootElement; + + /** + * The active cursor is the one that triggered the last command. + */ + FormulaCursor* activeCursor; + + /** + * The cursor that is used if there is no view. + */ + FormulaCursor* internCursor; + + /** + * The document we belong to. + */ + Document* document; +}; + + +FormulaElement* Container::rootElement() const { return impl->rootElement; } +Document* Container::document() const { return impl->document; } + +Container::Container( Document* doc, int pos, bool registerMe ) +{ + impl = new Container_Impl( doc ); + impl->rootElement = 0; + if ( registerMe ) { + registerFormula( pos ); + } +} + +Container::~Container() +{ + unregisterFormula(); + delete impl; + impl = 0; +} + + +void Container::initialize() +{ + assert( impl->rootElement == 0 ); + impl->rootElement = createMainSequence(); + impl->activeCursor = impl->internCursor = createCursor(); + recalc(); +} + + +FormulaElement* Container::createMainSequence() +{ + return new FormulaElement( this ); +} + + +FormulaCursor* Container::createCursor() +{ + return new FormulaCursor(rootElement()); +} + + +KoCommandHistory* Container::getHistory() const +{ + return document()->getHistory(); +} + + +/** + * Gets called just before the child is removed from + * the element tree. + */ +void Container::elementRemoval(BasicElement* child) +{ + emit elementWillVanish(child); +} + +/** + * Gets called whenever something changes and we need to + * recalc. + */ +void Container::changed() +{ + impl->dirty = true; +} + +void Container::cursorHasMoved( FormulaCursor* ) +{ + impl->cursorMoved = true; +} + +void Container::moveOutLeft( FormulaCursor* cursor ) +{ + emit leaveFormula( this, cursor, EXIT_LEFT ); +} + +void Container::moveOutRight( FormulaCursor* cursor ) +{ + emit leaveFormula( this, cursor, EXIT_RIGHT ); +} + +void Container::moveOutAbove( FormulaCursor* cursor ) +{ + emit leaveFormula( this, cursor, EXIT_ABOVE ); +} + +void Container::moveOutBelow( FormulaCursor* cursor ) +{ + emit leaveFormula( this, cursor, EXIT_BELOW ); +} + +void Container::tell( const TQString& msg ) +{ + emit statusMsg( msg ); +} + +void Container::removeFormula( FormulaCursor* cursor ) +{ + emit leaveFormula( this, cursor, REMOVE_FORMULA ); +} + + +void Container::registerFormula( int pos ) +{ + document()->registerFormula( this, pos ); +} + +void Container::unregisterFormula() +{ + document()->unregisterFormula( this ); +} + + +void Container::baseSizeChanged( int size, bool owned ) +{ + if ( owned ) { + emit baseSizeChanged( size ); + } + else { + const ContextStyle& context = document()->getContextStyle(); + emit baseSizeChanged( context.baseSize() ); + } +} + +FormulaCursor* Container::activeCursor() +{ + return impl->activeCursor; +} + +const FormulaCursor* Container::activeCursor() const +{ + return impl->activeCursor; +} + + +/** + * Tells the formula that a view got the focus and might want to + * edit the formula. + */ +void Container::setActiveCursor(FormulaCursor* cursor) +{ + document()->activate(this); + if (cursor != 0) { + impl->activeCursor = cursor; + } + else { + *(impl->internCursor) = *(impl->activeCursor); + impl->activeCursor = impl->internCursor; + } +} + + +bool Container::hasValidCursor() const +{ + return (impl->activeCursor != 0) && !impl->activeCursor->isReadOnly(); +} + +void Container::testDirty() +{ + if (impl->dirty) { + recalc(); + } +} + +void Container::recalc() +{ + impl->dirty = false; + ContextStyle& context = impl->document->getContextStyle(); + rootElement()->calcSizes( context ); + + emit formulaChanged( context.layoutUnitToPixelX( rootElement()->getWidth() ), + context.layoutUnitToPixelY( rootElement()->getHeight() ) ); + emit formulaChanged( context.layoutUnitPtToPt( context.pixelXToPt( rootElement()->getWidth() ) ), + context.layoutUnitPtToPt( context.pixelYToPt( rootElement()->getHeight() ) ) ); + emit cursorMoved( activeCursor() ); +} + +bool Container::isEmpty() +{ + return rootElement()->countChildren() == 0; +} + + +const SymbolTable& Container::getSymbolTable() const +{ + return document()->getSymbolTable(); +} + + +void Container::draw( TQPainter& painter, const TQRect& r, const TQColorGroup& cg, bool edit ) +{ + painter.fillRect( r, cg.base() ); + draw( painter, r, edit ); +} + + +void Container::draw( TQPainter& painter, const TQRect& r, bool edit ) +{ + //ContextStyle& context = document()->getContextStyle( painter.device()->devType() == TQInternal::Printer ); + ContextStyle& context = document()->getContextStyle( edit ); + rootElement()->draw( painter, context.pixelToLayoutUnit( r ), context ); +} + + +void Container::checkCursor() +{ + if ( impl->cursorMoved ) { + impl->cursorMoved = false; + emit cursorMoved( activeCursor() ); + } +} + +void Container::input( TQKeyEvent* event ) +{ + //if ( !hasValidCursor() ) + if ( impl->activeCursor == 0 ) { + return; + } + execute( activeCursor()->getElement()->input( this, event ) ); + checkCursor(); +} + + +void Container::performRequest( Request* request ) +{ + if ( !hasValidCursor() ) + return; + execute( activeCursor()->getElement()->buildCommand( this, request ) ); + checkCursor(); +} + + +void Container::paste() +{ + if (!hasValidCursor()) + return; + TQClipboard* clipboard = TQApplication::clipboard(); + const TQMimeSource* source = clipboard->data(); + if (source->provides( MimeSource::selectionMimeType() )) { + TQByteArray data = source->encodedData( MimeSource::selectionMimeType() ); + TQDomDocument formula; + formula.setContent(data); + paste( formula, i18n("Paste") ); + } +} + +void Container::paste( const TQDomDocument& document, TQString desc ) +{ + FormulaCursor* cursor = activeCursor(); + TQPtrList list; + list.setAutoDelete( true ); + if ( cursor->buildElementsFromMathMLDom( document.documentElement(), list ) ) { + uint count = list.count(); + // You must not execute an add command that adds nothing. + if (count > 0) { + KFCReplace* command = new KFCReplace( desc, this ); + for (uint i = 0; i < count; i++) { + command->addElement(list.take(0)); + } + execute(command); + } + } +} + +void Container::copy() +{ + // read-only cursors are fine for copying. + FormulaCursor* cursor = activeCursor(); + if (cursor != 0) { + TQDomDocument formula = document()->createMathMLDomDocument(); + cursor->copy( formula ); + TQClipboard* clipboard = TQApplication::clipboard(); + clipboard->setData(new MimeSource(document(), formula)); + } +} + +void Container::cut() +{ + if (!hasValidCursor()) + return; + FormulaCursor* cursor = activeCursor(); + if (cursor->isSelection()) { + copy(); + DirectedRemove r( req_remove, beforeCursor ); + performRequest( &r ); + } +} + + +void Container::emitErrorMsg( const TQString& msg ) +{ + emit errorMsg( msg ); +} + +void Container::execute(KCommand* command) +{ + if ( command != 0 ) { + getHistory()->addCommand(command); + } +} + + +TQRect Container::boundingRect() const +{ + const ContextStyle& context = document()->getContextStyle(); + return TQRect( context.layoutUnitToPixelX( rootElement()->getX() ), + context.layoutUnitToPixelY( rootElement()->getY() ), + context.layoutUnitToPixelX( rootElement()->getWidth() ), + context.layoutUnitToPixelY( rootElement()->getHeight() ) ); +} + +TQRect Container::coveredRect() +{ + if ( impl->activeCursor != 0 ) { + const ContextStyle& context = document()->getContextStyle(); + const LuPixelRect& cursorRect = impl->activeCursor->getCursorSize(); + return TQRect( context.layoutUnitToPixelX( rootElement()->getX() ), + context.layoutUnitToPixelY( rootElement()->getY() ), + context.layoutUnitToPixelX( rootElement()->getWidth() ), + context.layoutUnitToPixelY( rootElement()->getHeight() ) ) | + TQRect( context.layoutUnitToPixelX( cursorRect.x() ), + context.layoutUnitToPixelY( cursorRect.y() ), + context.layoutUnitToPixelX( cursorRect.width() ), + context.layoutUnitToPixelY( cursorRect.height() ) ); + } + return boundingRect(); +} + +double Container::width() const +{ + const ContextStyle& context = document()->getContextStyle(); + return context.layoutUnitPtToPt( context.pixelXToPt( rootElement()->getWidth() ) ); +} + +double Container::height() const +{ + const ContextStyle& context = document()->getContextStyle(); + return context.layoutUnitPtToPt( context.pixelYToPt( rootElement()->getHeight() ) ); +} + +double Container::baseline() const +{ + const ContextStyle& context = document()->getContextStyle(); + //return context.layoutUnitToPixelY( rootElement()->getBaseline() ); + return context.layoutUnitPtToPt( context.pixelYToPt( rootElement()->getBaseline() ) ); +} + +void Container::moveTo( int x, int y ) +{ + const ContextStyle& context = document()->getContextStyle(); + rootElement()->setX( context.pixelToLayoutUnitX( x ) ); + rootElement()->setY( context.pixelToLayoutUnitY( y ) ); +} + +int Container::fontSize() const +{ + if ( rootElement()->hasOwnBaseSize() ) { + return rootElement()->getBaseSize(); + } + else { + const ContextStyle& context = document()->getContextStyle(); + return tqRound( context.baseSize() ); + } +} + +void Container::setFontSize( int pointSize, bool /*forPrint*/ ) +{ + if ( rootElement()->getBaseSize() != pointSize ) { + execute( new KFCChangeBaseSize( i18n( "Base Size Change" ), this, rootElement(), pointSize ) ); + } +} + +void Container::setFontSizeDirect( int pointSize ) +{ + rootElement()->setBaseSize( pointSize ); + recalc(); +} + +void Container::updateMatrixActions() +{ + BasicElement *currentElement = activeCursor()->getElement(); + if ( ( currentElement = currentElement->getParent() ) != 0 ) + document()->wrapper()->enableMatrixActions( dynamic_cast(currentElement) ); + else + document()->wrapper()->enableMatrixActions( false ); +} + +void Container::save( TQDomElement &root ) +{ + TQDomDocument ownerDoc = root.ownerDocument(); + root.appendChild(rootElement()->getElementDom(ownerDoc)); +} + + +/** + * Loads a formula from the document. + */ +bool Container::load( const TQDomElement &fe ) +{ + if (!fe.isNull()) { + FormulaElement* root = createMainSequence(); + if (root->buildFromDom(fe)) { + delete impl->rootElement; + impl->rootElement = root; + emit formulaLoaded(rootElement()); + + recalc(); + return true; + } + else { + delete root; + kdWarning( DEBUGID ) << "Error constructing element tree." << endl; + } + } + else { + kdWarning( DEBUGID ) << "Empty element." << endl; + } + return false; +} + + +void Container::saveMathML( TQTextStream& stream, bool oasisFormat ) +{ + TQDomDocument doc; + if ( !oasisFormat ) { + doc = document()->createMathMLDomDocument(); + } + rootElement()->writeMathML( doc, doc, oasisFormat ); + stream << doc; +} + +bool Container::loadMathML( const TQDomDocument &doc, bool oasisFormat ) +{ + return loadMathML( doc.documentElement(), oasisFormat ); +} + +/* +bool Container::loadMathML( const TQDomElement &element, bool oasisFormat ) +{ + const ContextStyle& context = document()->getContextStyle(); + MathML2KFormula filter( element, context, oasisFormat ); + filter.startConversion(); + if (filter.m_error) { + return false; + } + + if ( load( filter.getKFormulaDom().documentElement() ) ) { + getHistory()->clear(); + return true; + } + return false; +} +*/ + +bool Container::loadMathML( const TQDomElement &fe, bool /*oasisFormat*/ ) +{ + kdDebug( DEBUGID ) << "loadMathML" << endl; + if (!fe.isNull()) { + FormulaElement* root = createMainSequence(); + if ( root->buildFromMathMLDom( fe ) != - 1) { + delete impl->rootElement; + impl->rootElement = root; + emit formulaLoaded(rootElement()); + + recalc(); + return true; + } + else { + delete root; + kdWarning( DEBUGID ) << "Error constructing element tree." << endl; + } + } + else { + kdWarning( DEBUGID ) << "Empty element." << endl; + } + return false; +} + + +void Container::print(KPrinter& printer) +{ + //printer.setFullPage(true); + TQPainter painter; + if (painter.begin(&printer)) { + rootElement()->draw( painter, LuPixelRect( rootElement()->getX(), + rootElement()->getY(), + rootElement()->getWidth(), + rootElement()->getHeight() ), + document()->getContextStyle( false ) ); + } +} + +TQImage Container::drawImage( int width, int height ) +{ + ContextStyle& context = document()->getContextStyle( false ); + TQRect rect(impl->rootElement->getX(), impl->rootElement->getY(), + impl->rootElement->getWidth(), impl->rootElement->getHeight()); + + int realWidth = context.layoutUnitToPixelX( impl->rootElement->getWidth() ); + int realHeight = context.layoutUnitToPixelY( impl->rootElement->getHeight() ); + + double f = TQMAX( static_cast( width )/static_cast( realWidth ), + static_cast( height )/static_cast( realHeight ) ); + + int oldZoom = context.zoom(); + context.setZoomAndResolution( tqRound( oldZoom*f ), KoGlobal::dpiX(), KoGlobal::dpiY() ); + + kdDebug( DEBUGID ) << "Container::drawImage " + << "(" << width << " " << height << ")" + << "(" << context.layoutUnitToPixelX( impl->rootElement->getWidth() ) + << " " << context.layoutUnitToPixelY( impl->rootElement->getHeight() ) << ")" + << endl; + + TQPixmap pm( context.layoutUnitToPixelX( impl->rootElement->getWidth() ), + context.layoutUnitToPixelY( impl->rootElement->getHeight() ) ); + pm.fill(); + TQPainter paint(&pm); + impl->rootElement->draw(paint, rect, context); + paint.end(); + context.setZoomAndResolution( oldZoom, KoGlobal::dpiX(), KoGlobal::dpiY() ); + //return pm.convertToImage().smoothScale( width, height ); + return pm.convertToImage(); +} + +TQString Container::texString() +{ + return rootElement()->toLatex(); +} + +TQString Container::formulaString() +{ + return rootElement()->formulaString(); +} + +KFORMULA_NAMESPACE_END + +using namespace KFormula; +#include "kformulacontainer.moc" diff --git a/lib/kformula/kformuladocument.cc b/lib/kformula/kformuladocument.cc deleted file mode 100644 index c041232f..00000000 --- a/lib/kformula/kformuladocument.cc +++ /dev/null @@ -1,1299 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2001 Andrea Rizzi - Ulrich Kuettler - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -#include "contextstyle.h" -#include "creationstrategy.h" -#include "oasiscreationstrategy.h" -#include "kformulacontainer.h" -#include "kformuladocument.h" -#include "sequenceelement.h" -#include "symboltable.h" -#include "symbolaction.h" - -KFORMULA_NAMESPACE_BEGIN - -static const int CURRENT_SYNTAX_VERSION = 1; -// Make sure an appropriate DTD is available in www/koffice/DTD if changing this value -static const char * CURRENT_DTD_VERSION = "1.3"; - -int FormulaList::compareItems( TQPtrCollection::Item a, TQPtrCollection::Item b ) -{ - double ya = static_cast( a )->getDocumentY(); - double yb = static_cast( b )->getDocumentY(); - if ( fabs( ya-yb ) < 1e-4 ) { - double xa = static_cast( a )->getDocumentX(); - double xb = static_cast( b )->getDocumentX(); - if ( xa < xb ) return -1; - if ( xa > xb ) return 1; - return 0; - } - if ( ya < yb ) return -1; - return 1; -} - - -Document::Document( TQObject *parent, const char *name, - const TQStringList &/*args*/ ) - : TQObject( parent, name ), m_wrapper( 0 ), m_formula( 0 ), creationStrategy( 0 ) -{ - m_contextStyle = new ContextStyle; - setCreationStrategy( "Oasis" ); - formulae.setAutoDelete( false ); -} - - -Document::~Document() -{ - // Destroy remaining formulae. We do it backward because - // the formulae remove themselves from this document upon - // destruction. - int count = formulae.count(); - for ( int i=count-1; i>=0; --i ) { - delete formulae.at( i ); - } - delete m_contextStyle; -} - - -bool Document::hasFormula() -{ - return ( m_formula != 0 ) && ( m_formula->activeCursor() != 0 ); -} - - -Container* Document::createFormula( int pos, bool registerMe ) -{ - Container* formula = new Container( this, pos, registerMe ); - formula->initialize(); - return formula; -} - - -TQPtrListIterator Document::formulas() -{ - return TQPtrListIterator( formulae ); -} - - -int Document::formulaPos( Container* formula ) -{ - return formulae.find( formula ); -} - - -Container* Document::formulaAt( uint pos ) -{ - return formulae.at( pos ); -} - - -int Document::formulaCount() -{ - return formulae.count(); -} - - -bool Document::loadXML( const TQDomDocument& doc ) -{ - setCreationStrategy( "Ordinary" ); - - //clear(); - TQDomElement root = doc.documentElement(); - - // backward compatibility - if ( root.tagName() == "FORMULA" ) { - Container* formula = newFormula( 0 ); - return formula->load( root ); - } - - TQDomNode node = root.firstChild(); - if ( node.isElement() ) { - TQDomElement element = node.toElement(); - if ( element.tagName() == "FORMULASETTINGS" ) { - if ( !loadDocumentPart( element ) ) { - return false; - } - } - node = node.nextSibling(); - } - uint number = 0; - while ( !node.isNull() ) { - if ( node.isElement() ) { - TQDomElement element = node.toElement(); - Container* formula = newFormula( number ); - if ( !formula->load( element ) ) { - return false; - } - number += 1; - } - node = node.nextSibling(); - } - return formulae.count() > 0; -} - -bool Document::loadOasis( const TQDomDocument& doc ) -{ - // ### TODO: not finished! - setCreationStrategy( "Oasis" ); - KFormula::Container* formula = newFormula( 0 ); - return formula->loadMathML( doc, true ); -} - -bool Document::loadDocumentPart( TQDomElement /*node*/ ) -{ - return true; -} - -TQDomDocument Document::saveXML() -{ - TQDomDocument doc = createDomDocument(); - TQDomElement root = doc.documentElement(); - root.appendChild( saveDocumentPart( doc ) ); - uint count = formulae.count(); - for ( uint i=0; isave( root ); - } - return doc; -} - - -TQDomElement Document::saveDocumentPart( TQDomDocument& doc ) -{ - TQDomElement settings = doc.createElement( "FORMULASETTINGS" ); - return settings; -} - - -TQDomDocument Document::createDomDocument() -{ - return KoDocument::createDomDocument( "kformula", "KFORMULA", - CURRENT_DTD_VERSION ); -} - -/** - * Create a MathML Dom Document, deprecates KFO Dom Document for internal layout - * TODO: Shouldn't this go to KoDocument ? - */ -TQDomDocument Document::createMathMLDomDocument() -{ - TQDomDocumentType dt = - TQDomImplementation().createDocumentType( "math", - "-//W3C//DTD MathML 2.0//EN", - "http://www.w3.org/TR/MathML2/dtd/mathml2.dtd"); - TQDomDocument doc( dt ); - doc.insertBefore( doc.createProcessingInstruction( "xml", - "version=\"1.0\" encoding=\"UTF-8\"" ), - doc.documentElement() ); - return doc; -} - -/** - * Set formula creation strategy: old KFormula or MathML/ODF. - * This tells which tags are valid during formula constructions - * - * @param strategy -- "Ordinary" for old Kformula, "Oasis" for MathML/ODF - */ -void Document::setCreationStrategy( TQString strategy ) -{ - if ( !creationStrategy || creationStrategy->type() != strategy ) { - delete creationStrategy; - if ( strategy == "Ordinary" ) - creationStrategy = new OrdinaryCreationStrategy; - else - creationStrategy = new OasisCreationStrategy; - SequenceElement::setCreationStrategy( creationStrategy ); - } -} - -void Document::registerFormula( Container* f, int pos ) -{ - if ( ( pos > -1 ) && - ( static_cast( pos ) < formulae.count() ) ) { - formulae.insert( pos, f ); - //emit sigInsertFormula( f, pos ); - } - else { - formulae.append( f ); - //emit sigInsertFormula( f, formulae.count()-1 ); - } -} - -void Document::unregisterFormula( Container* f ) -{ - if ( m_formula == f ) { - m_formula = 0; - } - formulae.removeRef( f ); -} - -void Document::activate(Container* f) -{ - m_formula = f; -} - - -void Document::sortFormulaList() -{ - formulae.sort(); -} - - -Container* Document::newFormula( uint number ) -{ - if ( number < formulae.count() ) { - return formulae.at( number ); - } - return createFormula(); -} - - -double Document::getXResolution() const -{ - return m_contextStyle->zoomedResolutionX(); -} -double Document::getYResolution() const -{ - return m_contextStyle->zoomedResolutionY(); -} - -const SymbolTable& Document::getSymbolTable() const -{ - return m_contextStyle->symbolTable(); -} - -ContextStyle& Document::getContextStyle( bool edit ) -{ - m_contextStyle->setEdit( edit ); - return *m_contextStyle; -} - -void Document::setZoomAndResolution( int zoom, int dpiX, int dpiY ) -{ - m_contextStyle->setZoomAndResolution( zoom, dpiX, dpiY ); -} - -void Document::newZoomAndResolution( bool updateViews, bool /*forPrint*/ ) -{ - if ( updateViews ) { - recalc(); - } -} - -void Document::setZoomAndResolution( int zoom, - double zoomX, double zoomY, - bool updateViews, bool forPrint ) -{ - if ( getContextStyle( !forPrint ).setZoomAndResolution( zoom, zoomX, zoomY, updateViews, forPrint ) && updateViews ) { - recalc(); - } -} - - -SymbolType Document::leftBracketChar() -{ - return m_wrapper->leftBracketChar(); -} - -SymbolType Document::rightBracketChar() -{ - return m_wrapper->rightBracketChar(); -} - - -void Document::setEnabled( bool enabled ) -{ - m_wrapper->setEnabled( enabled ); -} - - -KoCommandHistory* Document::getHistory() const -{ - return m_wrapper->getHistory(); -} - - -void Document::recalc() -{ - for ( Container* f = formulae.first(); - f != 0; - f=formulae.next() ) { - f->recalc(); - } -} - - -void Document::updateConfig() -{ - m_wrapper->updateConfig(); - recalc(); -} - - -void Document::introduceWrapper( DocumentWrapper* wrapper, bool init ) -{ - m_wrapper = wrapper; - m_contextStyle->readConfig( wrapper->config(), init ); - m_contextStyle->init( init ); -} - - -////////////////////////////////////////////////////////////////////////////// - -DocumentWrapper::DocumentWrapper( TDEConfig* config, - TDEActionCollection* collection, - KoCommandHistory* history ) - : m_document( 0 ), - m_leftBracketChar( LeftRoundBracket ), - m_rightBracketChar( RightRoundBracket ), - m_config( config ), - m_hasActions( collection != 0 ) -{ - if ( m_hasActions ) { - createActions( collection ); - enableMatrixActions( false ); - } - setCommandStack( history ); -} - - -DocumentWrapper::~DocumentWrapper() -{ - delete m_document; - if ( m_ownHistory ) { - delete m_history; - } - - if ( m_hasActions ) - { - m_config->setGroup("General"); - m_config->writeEntry("syntaxHighlighting", m_syntaxHighlightingAction->isChecked() ); - } -} - - -void DocumentWrapper::document( Document* document, bool init ) -{ - m_document = document; - m_document->introduceWrapper( this, init ); - initSymbolNamesAction(); - m_config->setGroup("General"); - if ( m_hasActions ) - { - m_syntaxHighlightingAction->setChecked( m_config->readBoolEntry("syntaxHighlighting", true ) ); - if ( !m_syntaxHighlightingAction->isChecked() ) - toggleSyntaxHighlighting(); - } - else if ( m_config->readBoolEntry("syntaxHighlighting", true ) ) - { - m_document->m_contextStyle->setSyntaxHighlighting( true ); - // Only to notify all views. We don't expect to get new values. - m_document->recalc(); - } -} - - -void DocumentWrapper::setCommandStack( KoCommandHistory* history ) -{ - if ( history == 0 ) { - m_history = new KoCommandHistory; - m_ownHistory = true; - } - else { - m_history = history; - m_ownHistory = false; - } -} - - -void DocumentWrapper::createActions( TDEActionCollection* collection ) -{ - TDEGlobal::dirs()->addResourceType( "toolbar", - TDEStandardDirs::kde_default("data") + - "kformula/pics/" ); - - m_addNegThinSpaceAction = new TDEAction( i18n( "Add Negative Thin Space" ), - 0, - this, TQT_SLOT( addNegThinSpace() ), - collection, "formula_addnegthinspace") ; - m_addThinSpaceAction = new TDEAction( i18n( "Add Thin Space" ), - 0, - this, TQT_SLOT( addThinSpace() ), - collection, "formula_addthinspace") ; - m_addMediumSpaceAction = new TDEAction( i18n( "Add Medium Space" ), - 0, - this, TQT_SLOT( addMediumSpace() ), - collection, "formula_addmediumspace" ); - m_addThickSpaceAction = new TDEAction( i18n( "Add Thick Space" ), - 0, - this, TQT_SLOT( addThickSpace() ), - collection, "formula_addthickspace" ); - m_addQuadSpaceAction = new TDEAction( i18n( "Add Quad Space" ), - 0, - this, TQT_SLOT( addQuadSpace() ), - collection, "formula_addquadspace" ); - - m_addIntegralAction = new TDEAction(i18n("Add Integral"), - "int", - 0, - this, TQT_SLOT(addIntegral()), - collection, "formula_addintegral"); - m_addSumAction = new TDEAction(i18n("Add Sum"), - "sum", - 0, - this, TQT_SLOT(addSum()), - collection, "formula_addsum"); - m_addProductAction = new TDEAction(i18n("Add Product"), - "prod", - 0, - this, TQT_SLOT(addProduct()), - collection, "formula_addproduct"); - m_addRootAction = new TDEAction(i18n("Add Root"), - "sqrt", - 0, - this, TQT_SLOT(addRoot()), - collection, "formula_addroot"); - m_addFractionAction = new TDEAction(i18n("Add Fraction"), - "frac", - 0, - this, TQT_SLOT(addFraction()), - collection, "formula_addfrac"); - m_addBracketAction = new TDEAction(i18n("Add Bracket"), - "paren", - 0, - this, TQT_SLOT(addDefaultBracket()), - collection,"formula_addbra"); - m_addSBracketAction = new TDEAction(i18n("Add Square Bracket"), - "brackets", - 0, - this, TQT_SLOT(addSquareBracket()), - collection,"formula_addsqrbra"); - m_addCBracketAction = new TDEAction(i18n("Add Curly Bracket"), - "math_brace", - 0, - this, TQT_SLOT(addCurlyBracket()), - collection,"formula_addcurbra"); - m_addAbsAction = new TDEAction(i18n("Add Abs"), - "abs", - 0, - this, TQT_SLOT(addLineBracket()), - collection,"formula_addabsbra"); - - m_addMatrixAction = new TDEAction(i18n("Add Matrix..."), - "matrix", - 0, - this, TQT_SLOT(addMatrix()), - collection, "formula_addmatrix"); - - m_addOneByTwoMatrixAction = new TDEAction(i18n("Add 1x2 Matrix"), - "onetwomatrix", - 0, - this, TQT_SLOT(addOneByTwoMatrix()), - collection, "formula_add_one_by_two_matrix"); - - - m_addUpperLeftAction = new TDEAction(i18n("Add Upper Left Index"), - "lsup", - 0, - this, TQT_SLOT(addUpperLeftIndex()), - collection, "formula_addupperleft"); - m_addLowerLeftAction = new TDEAction(i18n("Add Lower Left Index"), - "lsub", - 0, - this, TQT_SLOT(addLowerLeftIndex()), - collection, "formula_addlowerleft"); - m_addUpperRightAction = new TDEAction(i18n("Add Upper Right Index"), - "rsup", - 0, - this, TQT_SLOT(addUpperRightIndex()), - collection, "formula_addupperright"); - m_addLowerRightAction = new TDEAction(i18n("Add Lower Right Index"), - "rsub", - 0, - this, TQT_SLOT(addLowerRightIndex()), - collection, "formula_addlowerright"); - - m_addGenericUpperAction = new TDEAction(i18n("Add Upper Index"), - "gsup", - /*CTRL + Key_U*/0, - this, TQT_SLOT(addGenericUpperIndex()), - collection, "formula_addupperindex"); - m_addGenericLowerAction = new TDEAction(i18n("Add Lower Index"), - "gsub", - 0, - this, TQT_SLOT(addGenericLowerIndex()), - collection, "formula_addlowerindex"); - - m_addOverlineAction = new TDEAction(i18n("Add Overline"), - "over", - 0, - this, TQT_SLOT(addOverline()), - collection, "formula_addoverline"); - m_addUnderlineAction = new TDEAction(i18n("Add Underline"), - "under", - 0, - this, TQT_SLOT(addUnderline()), - collection, "formula_addunderline"); - - m_addMultilineAction = new TDEAction(i18n("Add Multiline"), - "multiline", - 0, - this, TQT_SLOT(addMultiline()), - collection, "formula_addmultiline"); - - m_removeEnclosingAction = new TDEAction(i18n("Remove Enclosing Element"), - 0, - this, TQT_SLOT(removeEnclosing()), - collection, "formula_removeenclosing"); - - m_makeGreekAction = new TDEAction(i18n("Convert to Greek"), - 0, - this, TQT_SLOT(makeGreek()), - collection, "formula_makegreek"); - - m_appendColumnAction = new TDEAction( i18n( "Append Column" ), - "inscol", - 0, - this, TQT_SLOT( appendColumn() ), - collection, "formula_appendcolumn" ); - m_insertColumnAction = new TDEAction( i18n( "Insert Column" ), - "inscol", - 0, - this, TQT_SLOT( insertColumn() ), - collection, "formula_insertcolumn" ); - m_removeColumnAction = new TDEAction( i18n( "Remove Column" ), - "remcol", - 0, - this, TQT_SLOT( removeColumn() ), - collection, "formula_removecolumn" ); - m_appendRowAction = new TDEAction( i18n( "Append Row" ), - "insrow", - 0, - this, TQT_SLOT( appendRow() ), - collection, "formula_appendrow" ); - m_insertRowAction = new TDEAction( i18n( "Insert Row" ), - "insrow", - 0, - this, TQT_SLOT( insertRow() ), - collection, "formula_insertrow" ); - m_removeRowAction = new TDEAction( i18n( "Remove Row" ), - "remrow", - 0, - this, TQT_SLOT( removeRow() ), - collection, "formula_removerow" ); - - m_syntaxHighlightingAction = new TDEToggleAction(i18n("Syntax Highlighting"), - 0, - this, TQT_SLOT(toggleSyntaxHighlighting()), - collection, "formula_syntaxhighlighting"); - //m_syntaxHighlightingAction->setChecked( m_contextStyle->syntaxHighlighting() ); - - m_formatBoldAction = new TDEToggleAction( i18n( "&Bold" ), "format-text-bold", - 0, //CTRL + Key_B, - this, TQT_SLOT( textBold() ), - collection, "formula_format_bold" ); - m_formatItalicAction = new TDEToggleAction( i18n( "&Italic" ), "format-text-italic", - 0, //CTRL + Key_I, - this, TQT_SLOT( textItalic() ), - collection, "formula_format_italic" ); - m_formatBoldAction->setEnabled( false ); - m_formatItalicAction->setEnabled( false ); - - TQStringList delimiter; - delimiter.append(TQString("(")); - delimiter.append(TQString("[")); - delimiter.append(TQString("{")); - delimiter.append(TQString("<")); - delimiter.append(TQString("/")); - delimiter.append(TQString("\\")); - delimiter.append(TQString("|")); - delimiter.append(TQString(" ")); - delimiter.append(TQString(")")); - delimiter.append(TQString("]")); - delimiter.append(TQString("}")); - delimiter.append(TQString(">")); - m_leftBracket = new TDESelectAction(i18n("Left Delimiter"), - 0, this, TQT_SLOT(delimiterLeft()), - collection, "formula_typeleft"); - m_leftBracket->setItems(delimiter); - //leftBracket->setCurrentItem(0); - - delimiter.clear(); - delimiter.append(TQString(")")); - delimiter.append(TQString("]")); - delimiter.append(TQString("}")); - delimiter.append(TQString(">")); - delimiter.append(TQString("/")); - delimiter.append(TQString("\\")); - delimiter.append(TQString("|")); - delimiter.append(TQString(" ")); - delimiter.append(TQString("(")); - delimiter.append(TQString("[")); - delimiter.append(TQString("{")); - delimiter.append(TQString("<")); - m_rightBracket = new TDESelectAction(i18n("Right Delimiter"), - 0, this, TQT_SLOT(delimiterRight()), - collection, "formula_typeright"); - m_rightBracket->setItems(delimiter); - //rightBracket->setCurrentItem(0); - - m_insertSymbolAction = new TDEAction(i18n("Insert Symbol"), - "key_enter", - /*CTRL + Key_I*/0, - this, TQT_SLOT(insertSymbol()), - collection, "formula_insertsymbol"); - m_symbolNamesAction = new SymbolAction(i18n("Symbol Names"), - 0, this, TQT_SLOT(symbolNames()), - collection, "formula_symbolnames"); - - TQStringList ff; - ff.append( i18n( "Normal" ) ); - ff.append( i18n( "Script" ) ); - ff.append( i18n( "Fraktur" ) ); - ff.append( i18n( "Double Struck" ) ); - m_fontFamily = new TDESelectAction(i18n("Font Family"), - 0, this, TQT_SLOT(fontFamily()), - collection, "formula_fontfamily"); - m_fontFamily->setItems( ff ); - m_fontFamily->setEnabled( false ); - - TQStringList et; - et.append( i18n( "Identifier" ) ); - et.append( i18n( "Operator" ) ); - et.append( i18n( "Number" ) ); - et.append( i18n( "Text" ) ); - m_tokenElement = new TDESelectAction( i18n( "Token Type" ), - 0, this, TQT_SLOT( tokenElement() ), - collection, "formula_tokenelement" ); - m_tokenElement->setItems( et ); -// m_tokenElements->setEnabled( true ); -} - - -void DocumentWrapper::paste() -{ - if (hasFormula()) { - formula()->paste(); - } -} - -void DocumentWrapper::copy() -{ - if (hasFormula()) { - formula()->copy(); - } -} - -void DocumentWrapper::cut() -{ - if (hasFormula()) { - formula()->cut(); - } -} - -void DocumentWrapper::undo() -{ - m_history->undo(); -} - -void DocumentWrapper::redo() -{ - m_history->redo(); -} - -void DocumentWrapper::addNegThinSpace() -{ - if (hasFormula()) { - SpaceRequest r( NEGTHIN ); - formula()->performRequest( &r ); - } -} -void DocumentWrapper::addThinSpace() -{ - if (hasFormula()) { - SpaceRequest r( THIN ); - formula()->performRequest( &r ); - } -} -void DocumentWrapper::addMediumSpace() -{ - if (hasFormula()) { - SpaceRequest r( MEDIUM ); - formula()->performRequest( &r ); - } -} -void DocumentWrapper::addThickSpace() -{ - if (hasFormula()) { - SpaceRequest r( THICK ); - formula()->performRequest( &r ); - } -} -void DocumentWrapper::addQuadSpace() -{ - if (hasFormula()) { - SpaceRequest r( QUAD ); - formula()->performRequest( &r ); - } -} - -void DocumentWrapper::addDefaultBracket() -{ - if (hasFormula()) { - BracketRequest r( m_leftBracketChar, m_rightBracketChar ); - formula()->performRequest( &r ); - } -} - -void DocumentWrapper::addBracket( SymbolType left, SymbolType right ) -{ - if (hasFormula()) { - BracketRequest r( left, right ); - formula()->performRequest( &r ); - } -} - -void DocumentWrapper::addParenthesis() -{ - if (hasFormula()) { - BracketRequest r( LeftRoundBracket, RightRoundBracket ); - formula()->performRequest( &r ); - } -} - -void DocumentWrapper::addSquareBracket() -{ - if (hasFormula()) { - BracketRequest r( LeftSquareBracket, RightSquareBracket ); - formula()->performRequest( &r ); - } -} - -void DocumentWrapper::addCurlyBracket() -{ - if (hasFormula()) { - BracketRequest r( LeftCurlyBracket, RightCurlyBracket ); - formula()->performRequest( &r ); - } -} - -void DocumentWrapper::addLineBracket() -{ - if (hasFormula()) { - BracketRequest r( LeftLineBracket, RightLineBracket ); - formula()->performRequest( &r ); - } -} - -void DocumentWrapper::addFraction() -{ - if (hasFormula()) { - Request r( req_addFraction ); - formula()->performRequest( &r ); - } -} - -void DocumentWrapper::addRoot() -{ - if (hasFormula()) { - Request r( req_addRoot ); - formula()->performRequest( &r ); - } -} - -void DocumentWrapper::addIntegral() -{ - if (hasFormula()) { - SymbolRequest r( Integral ); - formula()->performRequest( &r ); - } -} - -void DocumentWrapper::addProduct() -{ - if (hasFormula()) { - SymbolRequest r( Product ); - formula()->performRequest( &r ); - } -} - -void DocumentWrapper::addSum() -{ - if (hasFormula()) { - SymbolRequest r( Sum ); - formula()->performRequest( &r ); - } -} - -void DocumentWrapper::addMatrix( uint rows, uint columns ) -{ - if (hasFormula()) { - MatrixRequest r( rows, columns ); - formula()->performRequest( &r ); - } -} - -void DocumentWrapper::addOneByTwoMatrix() -{ - if (hasFormula()) { - Request r( req_addOneByTwoMatrix ); - formula()->performRequest( &r ); - } -} - -void DocumentWrapper::addNameSequence() -{ - if (hasFormula()) { - Request r( req_addNameSequence ); - formula()->performRequest( &r ); - } -} - -void DocumentWrapper::addLowerLeftIndex() -{ - if (hasFormula()) { - IndexRequest r( lowerLeftPos ); - formula()->performRequest( &r ); - } -} - -void DocumentWrapper::addUpperLeftIndex() -{ - if (hasFormula()) { - IndexRequest r( upperLeftPos ); - formula()->performRequest( &r ); - } -} - -void DocumentWrapper::addLowerRightIndex() -{ - if (hasFormula()) { - IndexRequest r( lowerRightPos ); - formula()->performRequest( &r ); - } -} - -void DocumentWrapper::addUpperRightIndex() -{ - if (hasFormula()) { - IndexRequest r( upperRightPos ); - formula()->performRequest( &r ); - } -} - -void DocumentWrapper::addGenericLowerIndex() -{ - if (hasFormula()) { - IndexRequest r( lowerMiddlePos ); - formula()->performRequest( &r ); - } -} - -void DocumentWrapper::addGenericUpperIndex() -{ - if (hasFormula()) { - IndexRequest r( upperMiddlePos ); - formula()->performRequest( &r ); - } -} - -void DocumentWrapper::addOverline() -{ - if (hasFormula()) { - Request r( req_addOverline ); - formula()->performRequest( &r ); - } -} - -void DocumentWrapper::addUnderline() -{ - if (hasFormula()) { - Request r( req_addUnderline ); - formula()->performRequest( &r ); - } -} - -void DocumentWrapper::addMultiline() -{ - if (hasFormula()) { - Request r( req_addMultiline ); - formula()->performRequest( &r ); - } -} - -void DocumentWrapper::removeEnclosing() -{ - if (hasFormula()) { - DirectedRemove r( req_removeEnclosing, beforeCursor ); - formula()->performRequest( &r ); - } -} - -void DocumentWrapper::makeGreek() -{ - if (hasFormula()) { - Request r( req_makeGreek ); - formula()->performRequest( &r ); - } -} - -void DocumentWrapper::insertSymbol() -{ - if ( hasFormula() && - m_document->m_contextStyle->symbolTable().contains( m_selectedName ) ) { - TQChar ch = m_document->m_contextStyle->symbolTable().unicode( m_selectedName ); - if ( ch != TQChar::null ) { - TextCharRequest r( ch, true ); - formula()->performRequest( &r ); - } - else { - TextRequest r( m_selectedName ); - formula()->performRequest( &r ); - } - } -} - -void DocumentWrapper::insertSymbol( TQString name ) -{ - if ( hasFormula() ) { - if ( m_document->m_contextStyle->symbolTable().contains( name ) ) { - TQChar ch = m_document->m_contextStyle->symbolTable().unicode( name ); - if ( ch != TQChar::null ) { - TextCharRequest r( ch, true ); - formula()->performRequest( &r ); - return; - } - } - TextRequest r( name ); - formula()->performRequest( &r ); - } -} - -void DocumentWrapper::appendColumn() -{ - if ( hasFormula() ) { - Request r( req_appendColumn ); - formula()->performRequest( &r ); - } -} - -void DocumentWrapper::insertColumn() -{ - if ( hasFormula() ) { - Request r( req_insertColumn ); - formula()->performRequest( &r ); - } -} - -void DocumentWrapper::removeColumn() -{ - if ( hasFormula() ) { - Request r( req_removeColumn ); - formula()->performRequest( &r ); - } -} - -void DocumentWrapper::appendRow() -{ - if ( hasFormula() ) { - Request r( req_appendRow ); - formula()->performRequest( &r ); - } -} - -void DocumentWrapper::insertRow() -{ - if ( hasFormula() ) { - Request r( req_insertRow ); - formula()->performRequest( &r ); - } -} - -void DocumentWrapper::removeRow() -{ - if ( hasFormula() ) { - Request r( req_removeRow ); - formula()->performRequest( &r ); - } -} - -void DocumentWrapper::toggleSyntaxHighlighting() -{ - m_document->m_contextStyle->setSyntaxHighlighting( m_syntaxHighlightingAction->isChecked() ); - // Only to notify all views. We don't expect to get new values. - m_document->recalc(); -} - -void DocumentWrapper::textBold() -{ - if ( hasFormula() ) { - CharStyleRequest r( req_formatBold, - getFormatBoldAction()->isChecked(), - getFormatItalicAction()->isChecked() ); - formula()->performRequest( &r ); - } -} - -void DocumentWrapper::textItalic() -{ - if ( hasFormula() ) { - CharStyleRequest r( req_formatItalic, - getFormatBoldAction()->isChecked(), - getFormatItalicAction()->isChecked() ); - formula()->performRequest( &r ); - } -} - -void DocumentWrapper::delimiterLeft() -{ - TQString left = m_leftBracket->currentText(); - switch ( left.at(0).latin1() ) { - case '[': - case ']': - case '{': - case '}': - case '<': - case '>': - case '(': - case ')': - case '/': - case '\\': - m_leftBracketChar = static_cast( left.at(0).latin1() ); - break; - case '|': - m_leftBracketChar = LeftLineBracket; - break; - case ' ': - m_leftBracketChar = EmptyBracket; - break; - } -} - -void DocumentWrapper::delimiterRight() -{ - TQString right = m_rightBracket->currentText(); - switch ( right.at(0).latin1() ) { - case '[': - case ']': - case '{': - case '}': - case '<': - case '>': - case '(': - case ')': - case '/': - case '\\': - m_rightBracketChar = static_cast( right.at(0).latin1() ); - break; - case '|': - m_rightBracketChar = RightLineBracket; - break; - case ' ': - m_rightBracketChar = EmptyBracket; - break; - } -} - -void DocumentWrapper::symbolNames() -{ - m_selectedName = m_symbolNamesAction->currentText(); -} - - -void DocumentWrapper::fontFamily() -{ - if ( hasFormula() ) { - int i = m_fontFamily->currentItem(); - CharFamily cf = anyFamily; - switch( i ) { - case 0: cf = normalFamily; break; - case 1: cf = scriptFamily; break; - case 2: cf = frakturFamily; break; - case 3: cf = doubleStruckFamily; break; - } - CharFamilyRequest r( cf ); - formula()->performRequest( &r ); - } -} - - -void DocumentWrapper::tokenElement() -{ - if ( hasFormula() ) { - int i = m_tokenElement->currentItem(); - TokenElementType te = anyElement; - switch( i ) { - case 0: te = identifierElement; break; - case 1: te = operatorElement; break; - case 2: te = numberElement; break; - case 3: te = textElement; break; - } - TokenElementRequest r( te ); - formula()->performRequest( &r ); - } -} - - -void DocumentWrapper::initSymbolNamesAction() -{ - if ( m_hasActions ) { - const SymbolTable& st = m_document->m_contextStyle->symbolTable(); - TQStringList names = st.allNames(); - TQFont font( m_document->m_contextStyle->getFontStyle() ); - TQMemArray chars( names.count() ); - - uint i = 0; - for ( TQStringList::Iterator it = names.begin(); - it != names.end(); - ++it, ++i ) { - chars[ i ] = st.unicode( *it ); - } - m_symbolNamesAction->setSymbols( names, m_document->m_contextStyle->getMathFont(), chars ); - m_selectedName = names[0]; - } -} - - -void DocumentWrapper::setEnabled( bool enabled ) -{ - kdDebug( DEBUGID ) << "DocumentWrapper::setEnabled " << enabled << endl; - getAddNegThinSpaceAction()->setEnabled( enabled ); - getMakeGreekAction()->setEnabled( enabled ); - getAddGenericUpperAction()->setEnabled( enabled ); - getAddGenericLowerAction()->setEnabled( enabled ); - getAddOverlineAction()->setEnabled( enabled ); - getAddUnderlineAction()->setEnabled( enabled ); - getRemoveEnclosingAction()->setEnabled( enabled ); - getInsertSymbolAction()->setEnabled( enabled ); - getAddThinSpaceAction()->setEnabled( enabled ); - getAddMediumSpaceAction()->setEnabled( enabled ); - getAddThickSpaceAction()->setEnabled( enabled ); - getAddQuadSpaceAction()->setEnabled( enabled ); - getAddBracketAction()->setEnabled( enabled ); - getAddSBracketAction()->setEnabled( enabled ); - getAddCBracketAction()->setEnabled( enabled ); - getAddAbsAction()->setEnabled(enabled); - getAddFractionAction()->setEnabled( enabled ); - getAddRootAction()->setEnabled( enabled ); - getAddSumAction()->setEnabled( enabled ); - getAddProductAction()->setEnabled( enabled ); - getAddIntegralAction()->setEnabled( enabled ); - getAddMatrixAction()->setEnabled( enabled ); - getAddOneByTwoMatrixAction()->setEnabled( enabled ); - getAddUpperLeftAction()->setEnabled( enabled ); - getAddLowerLeftAction()->setEnabled( enabled ); - getAddUpperRightAction()->setEnabled( enabled ); - getAddLowerRightAction()->setEnabled( enabled ); - - getAddGenericUpperAction()->setEnabled( enabled ); - getAddGenericLowerAction()->setEnabled( enabled ); - - - if ( enabled ) { - getAddGenericUpperAction()-> - setShortcut( TDEShortcut( CTRL + Key_U ) ); - getAddGenericLowerAction()-> - setShortcut( TDEShortcut( CTRL + Key_L ) ); - getRemoveEnclosingAction()-> - setShortcut( TDEShortcut( CTRL + Key_R ) ); - getMakeGreekAction()-> - setShortcut( TDEShortcut( CTRL + Key_G ) ); - getInsertSymbolAction()-> - setShortcut( TDEShortcut( CTRL + Key_I ) ); - getAddOverlineAction()-> - setShortcut( TDEShortcut( CTRL + SHIFT + Key_O ) ); - getAddUnderlineAction()-> - setShortcut( TDEShortcut( CTRL + SHIFT + Key_U ) ); - getAddBracketAction()-> - setShortcut( TDEShortcut( CTRL + SHIFT + Key_B ) ); - getAddSBracketAction()-> - setShortcut( TDEShortcut( CTRL + SHIFT + Key_D ) ); - getAddCBracketAction()-> - setShortcut( TDEShortcut( CTRL + SHIFT + Key_C ) ); - getAddAbsAction()-> - setShortcut( TDEShortcut( CTRL + SHIFT + Key_A ) ); - getAddFractionAction()-> - setShortcut( TDEShortcut( CTRL + SHIFT + Key_F ) ); - getAddRootAction()-> - setShortcut( TDEShortcut( CTRL + SHIFT + Key_R ) ); - getAddSumAction()-> - setShortcut( TDEShortcut( CTRL + SHIFT + Key_S ) ); - getAddProductAction()-> - setShortcut( TDEShortcut( CTRL + SHIFT + Key_P ) ); - getAddIntegralAction()-> - setShortcut( TDEShortcut( CTRL + SHIFT + Key_I ) ); - getAddMatrixAction()-> - setShortcut( TDEShortcut( CTRL + SHIFT + Key_M ) ); - - } - else { - getAddGenericUpperAction()->setShortcut( TDEShortcut() ); - getAddGenericLowerAction()->setShortcut( TDEShortcut() ); - getRemoveEnclosingAction()->setShortcut( TDEShortcut() ); - getMakeGreekAction()->setShortcut( TDEShortcut() ); - getInsertSymbolAction()->setShortcut( TDEShortcut() ); - getAddOverlineAction()->setShortcut( TDEShortcut() ); - getAddUnderlineAction()->setShortcut( TDEShortcut() ); - getAddBracketAction()->setShortcut( TDEShortcut() ); - getAddSBracketAction()->setShortcut( TDEShortcut() ); - getAddCBracketAction()->setShortcut( TDEShortcut() ); - getAddAbsAction()->setShortcut( TDEShortcut() ); - getAddFractionAction()->setShortcut( TDEShortcut() ); - getAddRootAction()->setShortcut( TDEShortcut() ); - getAddSumAction()->setShortcut( TDEShortcut() ); - getAddProductAction()->setShortcut( TDEShortcut() ); - getAddIntegralAction()->setShortcut( TDEShortcut() ); - getAddMatrixAction()->setShortcut( TDEShortcut() ); - } -} - -void DocumentWrapper::enableMatrixActions( bool b) -{ - getAppendColumnAction()->setEnabled( b ); - getInsertColumnAction()->setEnabled( b ); - getRemoveColumnAction()->setEnabled( b ); - getAppendRowAction()->setEnabled( b ); - getInsertRowAction()->setEnabled( b ); - getRemoveRowAction()->setEnabled( b ); -} - -void DocumentWrapper::updateConfig() -{ - m_syntaxHighlightingAction-> - setChecked( m_document->m_contextStyle->syntaxHighlighting() ); - initSymbolNamesAction(); -} - - -KFORMULA_NAMESPACE_END - -using namespace KFormula; -#include "kformuladocument.moc" diff --git a/lib/kformula/kformuladocument.cpp b/lib/kformula/kformuladocument.cpp new file mode 100644 index 00000000..c041232f --- /dev/null +++ b/lib/kformula/kformuladocument.cpp @@ -0,0 +1,1299 @@ +/* This file is part of the KDE project + Copyright (C) 2001 Andrea Rizzi + Ulrich Kuettler + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "contextstyle.h" +#include "creationstrategy.h" +#include "oasiscreationstrategy.h" +#include "kformulacontainer.h" +#include "kformuladocument.h" +#include "sequenceelement.h" +#include "symboltable.h" +#include "symbolaction.h" + +KFORMULA_NAMESPACE_BEGIN + +static const int CURRENT_SYNTAX_VERSION = 1; +// Make sure an appropriate DTD is available in www/koffice/DTD if changing this value +static const char * CURRENT_DTD_VERSION = "1.3"; + +int FormulaList::compareItems( TQPtrCollection::Item a, TQPtrCollection::Item b ) +{ + double ya = static_cast( a )->getDocumentY(); + double yb = static_cast( b )->getDocumentY(); + if ( fabs( ya-yb ) < 1e-4 ) { + double xa = static_cast( a )->getDocumentX(); + double xb = static_cast( b )->getDocumentX(); + if ( xa < xb ) return -1; + if ( xa > xb ) return 1; + return 0; + } + if ( ya < yb ) return -1; + return 1; +} + + +Document::Document( TQObject *parent, const char *name, + const TQStringList &/*args*/ ) + : TQObject( parent, name ), m_wrapper( 0 ), m_formula( 0 ), creationStrategy( 0 ) +{ + m_contextStyle = new ContextStyle; + setCreationStrategy( "Oasis" ); + formulae.setAutoDelete( false ); +} + + +Document::~Document() +{ + // Destroy remaining formulae. We do it backward because + // the formulae remove themselves from this document upon + // destruction. + int count = formulae.count(); + for ( int i=count-1; i>=0; --i ) { + delete formulae.at( i ); + } + delete m_contextStyle; +} + + +bool Document::hasFormula() +{ + return ( m_formula != 0 ) && ( m_formula->activeCursor() != 0 ); +} + + +Container* Document::createFormula( int pos, bool registerMe ) +{ + Container* formula = new Container( this, pos, registerMe ); + formula->initialize(); + return formula; +} + + +TQPtrListIterator Document::formulas() +{ + return TQPtrListIterator( formulae ); +} + + +int Document::formulaPos( Container* formula ) +{ + return formulae.find( formula ); +} + + +Container* Document::formulaAt( uint pos ) +{ + return formulae.at( pos ); +} + + +int Document::formulaCount() +{ + return formulae.count(); +} + + +bool Document::loadXML( const TQDomDocument& doc ) +{ + setCreationStrategy( "Ordinary" ); + + //clear(); + TQDomElement root = doc.documentElement(); + + // backward compatibility + if ( root.tagName() == "FORMULA" ) { + Container* formula = newFormula( 0 ); + return formula->load( root ); + } + + TQDomNode node = root.firstChild(); + if ( node.isElement() ) { + TQDomElement element = node.toElement(); + if ( element.tagName() == "FORMULASETTINGS" ) { + if ( !loadDocumentPart( element ) ) { + return false; + } + } + node = node.nextSibling(); + } + uint number = 0; + while ( !node.isNull() ) { + if ( node.isElement() ) { + TQDomElement element = node.toElement(); + Container* formula = newFormula( number ); + if ( !formula->load( element ) ) { + return false; + } + number += 1; + } + node = node.nextSibling(); + } + return formulae.count() > 0; +} + +bool Document::loadOasis( const TQDomDocument& doc ) +{ + // ### TODO: not finished! + setCreationStrategy( "Oasis" ); + KFormula::Container* formula = newFormula( 0 ); + return formula->loadMathML( doc, true ); +} + +bool Document::loadDocumentPart( TQDomElement /*node*/ ) +{ + return true; +} + +TQDomDocument Document::saveXML() +{ + TQDomDocument doc = createDomDocument(); + TQDomElement root = doc.documentElement(); + root.appendChild( saveDocumentPart( doc ) ); + uint count = formulae.count(); + for ( uint i=0; isave( root ); + } + return doc; +} + + +TQDomElement Document::saveDocumentPart( TQDomDocument& doc ) +{ + TQDomElement settings = doc.createElement( "FORMULASETTINGS" ); + return settings; +} + + +TQDomDocument Document::createDomDocument() +{ + return KoDocument::createDomDocument( "kformula", "KFORMULA", + CURRENT_DTD_VERSION ); +} + +/** + * Create a MathML Dom Document, deprecates KFO Dom Document for internal layout + * TODO: Shouldn't this go to KoDocument ? + */ +TQDomDocument Document::createMathMLDomDocument() +{ + TQDomDocumentType dt = + TQDomImplementation().createDocumentType( "math", + "-//W3C//DTD MathML 2.0//EN", + "http://www.w3.org/TR/MathML2/dtd/mathml2.dtd"); + TQDomDocument doc( dt ); + doc.insertBefore( doc.createProcessingInstruction( "xml", + "version=\"1.0\" encoding=\"UTF-8\"" ), + doc.documentElement() ); + return doc; +} + +/** + * Set formula creation strategy: old KFormula or MathML/ODF. + * This tells which tags are valid during formula constructions + * + * @param strategy -- "Ordinary" for old Kformula, "Oasis" for MathML/ODF + */ +void Document::setCreationStrategy( TQString strategy ) +{ + if ( !creationStrategy || creationStrategy->type() != strategy ) { + delete creationStrategy; + if ( strategy == "Ordinary" ) + creationStrategy = new OrdinaryCreationStrategy; + else + creationStrategy = new OasisCreationStrategy; + SequenceElement::setCreationStrategy( creationStrategy ); + } +} + +void Document::registerFormula( Container* f, int pos ) +{ + if ( ( pos > -1 ) && + ( static_cast( pos ) < formulae.count() ) ) { + formulae.insert( pos, f ); + //emit sigInsertFormula( f, pos ); + } + else { + formulae.append( f ); + //emit sigInsertFormula( f, formulae.count()-1 ); + } +} + +void Document::unregisterFormula( Container* f ) +{ + if ( m_formula == f ) { + m_formula = 0; + } + formulae.removeRef( f ); +} + +void Document::activate(Container* f) +{ + m_formula = f; +} + + +void Document::sortFormulaList() +{ + formulae.sort(); +} + + +Container* Document::newFormula( uint number ) +{ + if ( number < formulae.count() ) { + return formulae.at( number ); + } + return createFormula(); +} + + +double Document::getXResolution() const +{ + return m_contextStyle->zoomedResolutionX(); +} +double Document::getYResolution() const +{ + return m_contextStyle->zoomedResolutionY(); +} + +const SymbolTable& Document::getSymbolTable() const +{ + return m_contextStyle->symbolTable(); +} + +ContextStyle& Document::getContextStyle( bool edit ) +{ + m_contextStyle->setEdit( edit ); + return *m_contextStyle; +} + +void Document::setZoomAndResolution( int zoom, int dpiX, int dpiY ) +{ + m_contextStyle->setZoomAndResolution( zoom, dpiX, dpiY ); +} + +void Document::newZoomAndResolution( bool updateViews, bool /*forPrint*/ ) +{ + if ( updateViews ) { + recalc(); + } +} + +void Document::setZoomAndResolution( int zoom, + double zoomX, double zoomY, + bool updateViews, bool forPrint ) +{ + if ( getContextStyle( !forPrint ).setZoomAndResolution( zoom, zoomX, zoomY, updateViews, forPrint ) && updateViews ) { + recalc(); + } +} + + +SymbolType Document::leftBracketChar() +{ + return m_wrapper->leftBracketChar(); +} + +SymbolType Document::rightBracketChar() +{ + return m_wrapper->rightBracketChar(); +} + + +void Document::setEnabled( bool enabled ) +{ + m_wrapper->setEnabled( enabled ); +} + + +KoCommandHistory* Document::getHistory() const +{ + return m_wrapper->getHistory(); +} + + +void Document::recalc() +{ + for ( Container* f = formulae.first(); + f != 0; + f=formulae.next() ) { + f->recalc(); + } +} + + +void Document::updateConfig() +{ + m_wrapper->updateConfig(); + recalc(); +} + + +void Document::introduceWrapper( DocumentWrapper* wrapper, bool init ) +{ + m_wrapper = wrapper; + m_contextStyle->readConfig( wrapper->config(), init ); + m_contextStyle->init( init ); +} + + +////////////////////////////////////////////////////////////////////////////// + +DocumentWrapper::DocumentWrapper( TDEConfig* config, + TDEActionCollection* collection, + KoCommandHistory* history ) + : m_document( 0 ), + m_leftBracketChar( LeftRoundBracket ), + m_rightBracketChar( RightRoundBracket ), + m_config( config ), + m_hasActions( collection != 0 ) +{ + if ( m_hasActions ) { + createActions( collection ); + enableMatrixActions( false ); + } + setCommandStack( history ); +} + + +DocumentWrapper::~DocumentWrapper() +{ + delete m_document; + if ( m_ownHistory ) { + delete m_history; + } + + if ( m_hasActions ) + { + m_config->setGroup("General"); + m_config->writeEntry("syntaxHighlighting", m_syntaxHighlightingAction->isChecked() ); + } +} + + +void DocumentWrapper::document( Document* document, bool init ) +{ + m_document = document; + m_document->introduceWrapper( this, init ); + initSymbolNamesAction(); + m_config->setGroup("General"); + if ( m_hasActions ) + { + m_syntaxHighlightingAction->setChecked( m_config->readBoolEntry("syntaxHighlighting", true ) ); + if ( !m_syntaxHighlightingAction->isChecked() ) + toggleSyntaxHighlighting(); + } + else if ( m_config->readBoolEntry("syntaxHighlighting", true ) ) + { + m_document->m_contextStyle->setSyntaxHighlighting( true ); + // Only to notify all views. We don't expect to get new values. + m_document->recalc(); + } +} + + +void DocumentWrapper::setCommandStack( KoCommandHistory* history ) +{ + if ( history == 0 ) { + m_history = new KoCommandHistory; + m_ownHistory = true; + } + else { + m_history = history; + m_ownHistory = false; + } +} + + +void DocumentWrapper::createActions( TDEActionCollection* collection ) +{ + TDEGlobal::dirs()->addResourceType( "toolbar", + TDEStandardDirs::kde_default("data") + + "kformula/pics/" ); + + m_addNegThinSpaceAction = new TDEAction( i18n( "Add Negative Thin Space" ), + 0, + this, TQT_SLOT( addNegThinSpace() ), + collection, "formula_addnegthinspace") ; + m_addThinSpaceAction = new TDEAction( i18n( "Add Thin Space" ), + 0, + this, TQT_SLOT( addThinSpace() ), + collection, "formula_addthinspace") ; + m_addMediumSpaceAction = new TDEAction( i18n( "Add Medium Space" ), + 0, + this, TQT_SLOT( addMediumSpace() ), + collection, "formula_addmediumspace" ); + m_addThickSpaceAction = new TDEAction( i18n( "Add Thick Space" ), + 0, + this, TQT_SLOT( addThickSpace() ), + collection, "formula_addthickspace" ); + m_addQuadSpaceAction = new TDEAction( i18n( "Add Quad Space" ), + 0, + this, TQT_SLOT( addQuadSpace() ), + collection, "formula_addquadspace" ); + + m_addIntegralAction = new TDEAction(i18n("Add Integral"), + "int", + 0, + this, TQT_SLOT(addIntegral()), + collection, "formula_addintegral"); + m_addSumAction = new TDEAction(i18n("Add Sum"), + "sum", + 0, + this, TQT_SLOT(addSum()), + collection, "formula_addsum"); + m_addProductAction = new TDEAction(i18n("Add Product"), + "prod", + 0, + this, TQT_SLOT(addProduct()), + collection, "formula_addproduct"); + m_addRootAction = new TDEAction(i18n("Add Root"), + "sqrt", + 0, + this, TQT_SLOT(addRoot()), + collection, "formula_addroot"); + m_addFractionAction = new TDEAction(i18n("Add Fraction"), + "frac", + 0, + this, TQT_SLOT(addFraction()), + collection, "formula_addfrac"); + m_addBracketAction = new TDEAction(i18n("Add Bracket"), + "paren", + 0, + this, TQT_SLOT(addDefaultBracket()), + collection,"formula_addbra"); + m_addSBracketAction = new TDEAction(i18n("Add Square Bracket"), + "brackets", + 0, + this, TQT_SLOT(addSquareBracket()), + collection,"formula_addsqrbra"); + m_addCBracketAction = new TDEAction(i18n("Add Curly Bracket"), + "math_brace", + 0, + this, TQT_SLOT(addCurlyBracket()), + collection,"formula_addcurbra"); + m_addAbsAction = new TDEAction(i18n("Add Abs"), + "abs", + 0, + this, TQT_SLOT(addLineBracket()), + collection,"formula_addabsbra"); + + m_addMatrixAction = new TDEAction(i18n("Add Matrix..."), + "matrix", + 0, + this, TQT_SLOT(addMatrix()), + collection, "formula_addmatrix"); + + m_addOneByTwoMatrixAction = new TDEAction(i18n("Add 1x2 Matrix"), + "onetwomatrix", + 0, + this, TQT_SLOT(addOneByTwoMatrix()), + collection, "formula_add_one_by_two_matrix"); + + + m_addUpperLeftAction = new TDEAction(i18n("Add Upper Left Index"), + "lsup", + 0, + this, TQT_SLOT(addUpperLeftIndex()), + collection, "formula_addupperleft"); + m_addLowerLeftAction = new TDEAction(i18n("Add Lower Left Index"), + "lsub", + 0, + this, TQT_SLOT(addLowerLeftIndex()), + collection, "formula_addlowerleft"); + m_addUpperRightAction = new TDEAction(i18n("Add Upper Right Index"), + "rsup", + 0, + this, TQT_SLOT(addUpperRightIndex()), + collection, "formula_addupperright"); + m_addLowerRightAction = new TDEAction(i18n("Add Lower Right Index"), + "rsub", + 0, + this, TQT_SLOT(addLowerRightIndex()), + collection, "formula_addlowerright"); + + m_addGenericUpperAction = new TDEAction(i18n("Add Upper Index"), + "gsup", + /*CTRL + Key_U*/0, + this, TQT_SLOT(addGenericUpperIndex()), + collection, "formula_addupperindex"); + m_addGenericLowerAction = new TDEAction(i18n("Add Lower Index"), + "gsub", + 0, + this, TQT_SLOT(addGenericLowerIndex()), + collection, "formula_addlowerindex"); + + m_addOverlineAction = new TDEAction(i18n("Add Overline"), + "over", + 0, + this, TQT_SLOT(addOverline()), + collection, "formula_addoverline"); + m_addUnderlineAction = new TDEAction(i18n("Add Underline"), + "under", + 0, + this, TQT_SLOT(addUnderline()), + collection, "formula_addunderline"); + + m_addMultilineAction = new TDEAction(i18n("Add Multiline"), + "multiline", + 0, + this, TQT_SLOT(addMultiline()), + collection, "formula_addmultiline"); + + m_removeEnclosingAction = new TDEAction(i18n("Remove Enclosing Element"), + 0, + this, TQT_SLOT(removeEnclosing()), + collection, "formula_removeenclosing"); + + m_makeGreekAction = new TDEAction(i18n("Convert to Greek"), + 0, + this, TQT_SLOT(makeGreek()), + collection, "formula_makegreek"); + + m_appendColumnAction = new TDEAction( i18n( "Append Column" ), + "inscol", + 0, + this, TQT_SLOT( appendColumn() ), + collection, "formula_appendcolumn" ); + m_insertColumnAction = new TDEAction( i18n( "Insert Column" ), + "inscol", + 0, + this, TQT_SLOT( insertColumn() ), + collection, "formula_insertcolumn" ); + m_removeColumnAction = new TDEAction( i18n( "Remove Column" ), + "remcol", + 0, + this, TQT_SLOT( removeColumn() ), + collection, "formula_removecolumn" ); + m_appendRowAction = new TDEAction( i18n( "Append Row" ), + "insrow", + 0, + this, TQT_SLOT( appendRow() ), + collection, "formula_appendrow" ); + m_insertRowAction = new TDEAction( i18n( "Insert Row" ), + "insrow", + 0, + this, TQT_SLOT( insertRow() ), + collection, "formula_insertrow" ); + m_removeRowAction = new TDEAction( i18n( "Remove Row" ), + "remrow", + 0, + this, TQT_SLOT( removeRow() ), + collection, "formula_removerow" ); + + m_syntaxHighlightingAction = new TDEToggleAction(i18n("Syntax Highlighting"), + 0, + this, TQT_SLOT(toggleSyntaxHighlighting()), + collection, "formula_syntaxhighlighting"); + //m_syntaxHighlightingAction->setChecked( m_contextStyle->syntaxHighlighting() ); + + m_formatBoldAction = new TDEToggleAction( i18n( "&Bold" ), "format-text-bold", + 0, //CTRL + Key_B, + this, TQT_SLOT( textBold() ), + collection, "formula_format_bold" ); + m_formatItalicAction = new TDEToggleAction( i18n( "&Italic" ), "format-text-italic", + 0, //CTRL + Key_I, + this, TQT_SLOT( textItalic() ), + collection, "formula_format_italic" ); + m_formatBoldAction->setEnabled( false ); + m_formatItalicAction->setEnabled( false ); + + TQStringList delimiter; + delimiter.append(TQString("(")); + delimiter.append(TQString("[")); + delimiter.append(TQString("{")); + delimiter.append(TQString("<")); + delimiter.append(TQString("/")); + delimiter.append(TQString("\\")); + delimiter.append(TQString("|")); + delimiter.append(TQString(" ")); + delimiter.append(TQString(")")); + delimiter.append(TQString("]")); + delimiter.append(TQString("}")); + delimiter.append(TQString(">")); + m_leftBracket = new TDESelectAction(i18n("Left Delimiter"), + 0, this, TQT_SLOT(delimiterLeft()), + collection, "formula_typeleft"); + m_leftBracket->setItems(delimiter); + //leftBracket->setCurrentItem(0); + + delimiter.clear(); + delimiter.append(TQString(")")); + delimiter.append(TQString("]")); + delimiter.append(TQString("}")); + delimiter.append(TQString(">")); + delimiter.append(TQString("/")); + delimiter.append(TQString("\\")); + delimiter.append(TQString("|")); + delimiter.append(TQString(" ")); + delimiter.append(TQString("(")); + delimiter.append(TQString("[")); + delimiter.append(TQString("{")); + delimiter.append(TQString("<")); + m_rightBracket = new TDESelectAction(i18n("Right Delimiter"), + 0, this, TQT_SLOT(delimiterRight()), + collection, "formula_typeright"); + m_rightBracket->setItems(delimiter); + //rightBracket->setCurrentItem(0); + + m_insertSymbolAction = new TDEAction(i18n("Insert Symbol"), + "key_enter", + /*CTRL + Key_I*/0, + this, TQT_SLOT(insertSymbol()), + collection, "formula_insertsymbol"); + m_symbolNamesAction = new SymbolAction(i18n("Symbol Names"), + 0, this, TQT_SLOT(symbolNames()), + collection, "formula_symbolnames"); + + TQStringList ff; + ff.append( i18n( "Normal" ) ); + ff.append( i18n( "Script" ) ); + ff.append( i18n( "Fraktur" ) ); + ff.append( i18n( "Double Struck" ) ); + m_fontFamily = new TDESelectAction(i18n("Font Family"), + 0, this, TQT_SLOT(fontFamily()), + collection, "formula_fontfamily"); + m_fontFamily->setItems( ff ); + m_fontFamily->setEnabled( false ); + + TQStringList et; + et.append( i18n( "Identifier" ) ); + et.append( i18n( "Operator" ) ); + et.append( i18n( "Number" ) ); + et.append( i18n( "Text" ) ); + m_tokenElement = new TDESelectAction( i18n( "Token Type" ), + 0, this, TQT_SLOT( tokenElement() ), + collection, "formula_tokenelement" ); + m_tokenElement->setItems( et ); +// m_tokenElements->setEnabled( true ); +} + + +void DocumentWrapper::paste() +{ + if (hasFormula()) { + formula()->paste(); + } +} + +void DocumentWrapper::copy() +{ + if (hasFormula()) { + formula()->copy(); + } +} + +void DocumentWrapper::cut() +{ + if (hasFormula()) { + formula()->cut(); + } +} + +void DocumentWrapper::undo() +{ + m_history->undo(); +} + +void DocumentWrapper::redo() +{ + m_history->redo(); +} + +void DocumentWrapper::addNegThinSpace() +{ + if (hasFormula()) { + SpaceRequest r( NEGTHIN ); + formula()->performRequest( &r ); + } +} +void DocumentWrapper::addThinSpace() +{ + if (hasFormula()) { + SpaceRequest r( THIN ); + formula()->performRequest( &r ); + } +} +void DocumentWrapper::addMediumSpace() +{ + if (hasFormula()) { + SpaceRequest r( MEDIUM ); + formula()->performRequest( &r ); + } +} +void DocumentWrapper::addThickSpace() +{ + if (hasFormula()) { + SpaceRequest r( THICK ); + formula()->performRequest( &r ); + } +} +void DocumentWrapper::addQuadSpace() +{ + if (hasFormula()) { + SpaceRequest r( QUAD ); + formula()->performRequest( &r ); + } +} + +void DocumentWrapper::addDefaultBracket() +{ + if (hasFormula()) { + BracketRequest r( m_leftBracketChar, m_rightBracketChar ); + formula()->performRequest( &r ); + } +} + +void DocumentWrapper::addBracket( SymbolType left, SymbolType right ) +{ + if (hasFormula()) { + BracketRequest r( left, right ); + formula()->performRequest( &r ); + } +} + +void DocumentWrapper::addParenthesis() +{ + if (hasFormula()) { + BracketRequest r( LeftRoundBracket, RightRoundBracket ); + formula()->performRequest( &r ); + } +} + +void DocumentWrapper::addSquareBracket() +{ + if (hasFormula()) { + BracketRequest r( LeftSquareBracket, RightSquareBracket ); + formula()->performRequest( &r ); + } +} + +void DocumentWrapper::addCurlyBracket() +{ + if (hasFormula()) { + BracketRequest r( LeftCurlyBracket, RightCurlyBracket ); + formula()->performRequest( &r ); + } +} + +void DocumentWrapper::addLineBracket() +{ + if (hasFormula()) { + BracketRequest r( LeftLineBracket, RightLineBracket ); + formula()->performRequest( &r ); + } +} + +void DocumentWrapper::addFraction() +{ + if (hasFormula()) { + Request r( req_addFraction ); + formula()->performRequest( &r ); + } +} + +void DocumentWrapper::addRoot() +{ + if (hasFormula()) { + Request r( req_addRoot ); + formula()->performRequest( &r ); + } +} + +void DocumentWrapper::addIntegral() +{ + if (hasFormula()) { + SymbolRequest r( Integral ); + formula()->performRequest( &r ); + } +} + +void DocumentWrapper::addProduct() +{ + if (hasFormula()) { + SymbolRequest r( Product ); + formula()->performRequest( &r ); + } +} + +void DocumentWrapper::addSum() +{ + if (hasFormula()) { + SymbolRequest r( Sum ); + formula()->performRequest( &r ); + } +} + +void DocumentWrapper::addMatrix( uint rows, uint columns ) +{ + if (hasFormula()) { + MatrixRequest r( rows, columns ); + formula()->performRequest( &r ); + } +} + +void DocumentWrapper::addOneByTwoMatrix() +{ + if (hasFormula()) { + Request r( req_addOneByTwoMatrix ); + formula()->performRequest( &r ); + } +} + +void DocumentWrapper::addNameSequence() +{ + if (hasFormula()) { + Request r( req_addNameSequence ); + formula()->performRequest( &r ); + } +} + +void DocumentWrapper::addLowerLeftIndex() +{ + if (hasFormula()) { + IndexRequest r( lowerLeftPos ); + formula()->performRequest( &r ); + } +} + +void DocumentWrapper::addUpperLeftIndex() +{ + if (hasFormula()) { + IndexRequest r( upperLeftPos ); + formula()->performRequest( &r ); + } +} + +void DocumentWrapper::addLowerRightIndex() +{ + if (hasFormula()) { + IndexRequest r( lowerRightPos ); + formula()->performRequest( &r ); + } +} + +void DocumentWrapper::addUpperRightIndex() +{ + if (hasFormula()) { + IndexRequest r( upperRightPos ); + formula()->performRequest( &r ); + } +} + +void DocumentWrapper::addGenericLowerIndex() +{ + if (hasFormula()) { + IndexRequest r( lowerMiddlePos ); + formula()->performRequest( &r ); + } +} + +void DocumentWrapper::addGenericUpperIndex() +{ + if (hasFormula()) { + IndexRequest r( upperMiddlePos ); + formula()->performRequest( &r ); + } +} + +void DocumentWrapper::addOverline() +{ + if (hasFormula()) { + Request r( req_addOverline ); + formula()->performRequest( &r ); + } +} + +void DocumentWrapper::addUnderline() +{ + if (hasFormula()) { + Request r( req_addUnderline ); + formula()->performRequest( &r ); + } +} + +void DocumentWrapper::addMultiline() +{ + if (hasFormula()) { + Request r( req_addMultiline ); + formula()->performRequest( &r ); + } +} + +void DocumentWrapper::removeEnclosing() +{ + if (hasFormula()) { + DirectedRemove r( req_removeEnclosing, beforeCursor ); + formula()->performRequest( &r ); + } +} + +void DocumentWrapper::makeGreek() +{ + if (hasFormula()) { + Request r( req_makeGreek ); + formula()->performRequest( &r ); + } +} + +void DocumentWrapper::insertSymbol() +{ + if ( hasFormula() && + m_document->m_contextStyle->symbolTable().contains( m_selectedName ) ) { + TQChar ch = m_document->m_contextStyle->symbolTable().unicode( m_selectedName ); + if ( ch != TQChar::null ) { + TextCharRequest r( ch, true ); + formula()->performRequest( &r ); + } + else { + TextRequest r( m_selectedName ); + formula()->performRequest( &r ); + } + } +} + +void DocumentWrapper::insertSymbol( TQString name ) +{ + if ( hasFormula() ) { + if ( m_document->m_contextStyle->symbolTable().contains( name ) ) { + TQChar ch = m_document->m_contextStyle->symbolTable().unicode( name ); + if ( ch != TQChar::null ) { + TextCharRequest r( ch, true ); + formula()->performRequest( &r ); + return; + } + } + TextRequest r( name ); + formula()->performRequest( &r ); + } +} + +void DocumentWrapper::appendColumn() +{ + if ( hasFormula() ) { + Request r( req_appendColumn ); + formula()->performRequest( &r ); + } +} + +void DocumentWrapper::insertColumn() +{ + if ( hasFormula() ) { + Request r( req_insertColumn ); + formula()->performRequest( &r ); + } +} + +void DocumentWrapper::removeColumn() +{ + if ( hasFormula() ) { + Request r( req_removeColumn ); + formula()->performRequest( &r ); + } +} + +void DocumentWrapper::appendRow() +{ + if ( hasFormula() ) { + Request r( req_appendRow ); + formula()->performRequest( &r ); + } +} + +void DocumentWrapper::insertRow() +{ + if ( hasFormula() ) { + Request r( req_insertRow ); + formula()->performRequest( &r ); + } +} + +void DocumentWrapper::removeRow() +{ + if ( hasFormula() ) { + Request r( req_removeRow ); + formula()->performRequest( &r ); + } +} + +void DocumentWrapper::toggleSyntaxHighlighting() +{ + m_document->m_contextStyle->setSyntaxHighlighting( m_syntaxHighlightingAction->isChecked() ); + // Only to notify all views. We don't expect to get new values. + m_document->recalc(); +} + +void DocumentWrapper::textBold() +{ + if ( hasFormula() ) { + CharStyleRequest r( req_formatBold, + getFormatBoldAction()->isChecked(), + getFormatItalicAction()->isChecked() ); + formula()->performRequest( &r ); + } +} + +void DocumentWrapper::textItalic() +{ + if ( hasFormula() ) { + CharStyleRequest r( req_formatItalic, + getFormatBoldAction()->isChecked(), + getFormatItalicAction()->isChecked() ); + formula()->performRequest( &r ); + } +} + +void DocumentWrapper::delimiterLeft() +{ + TQString left = m_leftBracket->currentText(); + switch ( left.at(0).latin1() ) { + case '[': + case ']': + case '{': + case '}': + case '<': + case '>': + case '(': + case ')': + case '/': + case '\\': + m_leftBracketChar = static_cast( left.at(0).latin1() ); + break; + case '|': + m_leftBracketChar = LeftLineBracket; + break; + case ' ': + m_leftBracketChar = EmptyBracket; + break; + } +} + +void DocumentWrapper::delimiterRight() +{ + TQString right = m_rightBracket->currentText(); + switch ( right.at(0).latin1() ) { + case '[': + case ']': + case '{': + case '}': + case '<': + case '>': + case '(': + case ')': + case '/': + case '\\': + m_rightBracketChar = static_cast( right.at(0).latin1() ); + break; + case '|': + m_rightBracketChar = RightLineBracket; + break; + case ' ': + m_rightBracketChar = EmptyBracket; + break; + } +} + +void DocumentWrapper::symbolNames() +{ + m_selectedName = m_symbolNamesAction->currentText(); +} + + +void DocumentWrapper::fontFamily() +{ + if ( hasFormula() ) { + int i = m_fontFamily->currentItem(); + CharFamily cf = anyFamily; + switch( i ) { + case 0: cf = normalFamily; break; + case 1: cf = scriptFamily; break; + case 2: cf = frakturFamily; break; + case 3: cf = doubleStruckFamily; break; + } + CharFamilyRequest r( cf ); + formula()->performRequest( &r ); + } +} + + +void DocumentWrapper::tokenElement() +{ + if ( hasFormula() ) { + int i = m_tokenElement->currentItem(); + TokenElementType te = anyElement; + switch( i ) { + case 0: te = identifierElement; break; + case 1: te = operatorElement; break; + case 2: te = numberElement; break; + case 3: te = textElement; break; + } + TokenElementRequest r( te ); + formula()->performRequest( &r ); + } +} + + +void DocumentWrapper::initSymbolNamesAction() +{ + if ( m_hasActions ) { + const SymbolTable& st = m_document->m_contextStyle->symbolTable(); + TQStringList names = st.allNames(); + TQFont font( m_document->m_contextStyle->getFontStyle() ); + TQMemArray chars( names.count() ); + + uint i = 0; + for ( TQStringList::Iterator it = names.begin(); + it != names.end(); + ++it, ++i ) { + chars[ i ] = st.unicode( *it ); + } + m_symbolNamesAction->setSymbols( names, m_document->m_contextStyle->getMathFont(), chars ); + m_selectedName = names[0]; + } +} + + +void DocumentWrapper::setEnabled( bool enabled ) +{ + kdDebug( DEBUGID ) << "DocumentWrapper::setEnabled " << enabled << endl; + getAddNegThinSpaceAction()->setEnabled( enabled ); + getMakeGreekAction()->setEnabled( enabled ); + getAddGenericUpperAction()->setEnabled( enabled ); + getAddGenericLowerAction()->setEnabled( enabled ); + getAddOverlineAction()->setEnabled( enabled ); + getAddUnderlineAction()->setEnabled( enabled ); + getRemoveEnclosingAction()->setEnabled( enabled ); + getInsertSymbolAction()->setEnabled( enabled ); + getAddThinSpaceAction()->setEnabled( enabled ); + getAddMediumSpaceAction()->setEnabled( enabled ); + getAddThickSpaceAction()->setEnabled( enabled ); + getAddQuadSpaceAction()->setEnabled( enabled ); + getAddBracketAction()->setEnabled( enabled ); + getAddSBracketAction()->setEnabled( enabled ); + getAddCBracketAction()->setEnabled( enabled ); + getAddAbsAction()->setEnabled(enabled); + getAddFractionAction()->setEnabled( enabled ); + getAddRootAction()->setEnabled( enabled ); + getAddSumAction()->setEnabled( enabled ); + getAddProductAction()->setEnabled( enabled ); + getAddIntegralAction()->setEnabled( enabled ); + getAddMatrixAction()->setEnabled( enabled ); + getAddOneByTwoMatrixAction()->setEnabled( enabled ); + getAddUpperLeftAction()->setEnabled( enabled ); + getAddLowerLeftAction()->setEnabled( enabled ); + getAddUpperRightAction()->setEnabled( enabled ); + getAddLowerRightAction()->setEnabled( enabled ); + + getAddGenericUpperAction()->setEnabled( enabled ); + getAddGenericLowerAction()->setEnabled( enabled ); + + + if ( enabled ) { + getAddGenericUpperAction()-> + setShortcut( TDEShortcut( CTRL + Key_U ) ); + getAddGenericLowerAction()-> + setShortcut( TDEShortcut( CTRL + Key_L ) ); + getRemoveEnclosingAction()-> + setShortcut( TDEShortcut( CTRL + Key_R ) ); + getMakeGreekAction()-> + setShortcut( TDEShortcut( CTRL + Key_G ) ); + getInsertSymbolAction()-> + setShortcut( TDEShortcut( CTRL + Key_I ) ); + getAddOverlineAction()-> + setShortcut( TDEShortcut( CTRL + SHIFT + Key_O ) ); + getAddUnderlineAction()-> + setShortcut( TDEShortcut( CTRL + SHIFT + Key_U ) ); + getAddBracketAction()-> + setShortcut( TDEShortcut( CTRL + SHIFT + Key_B ) ); + getAddSBracketAction()-> + setShortcut( TDEShortcut( CTRL + SHIFT + Key_D ) ); + getAddCBracketAction()-> + setShortcut( TDEShortcut( CTRL + SHIFT + Key_C ) ); + getAddAbsAction()-> + setShortcut( TDEShortcut( CTRL + SHIFT + Key_A ) ); + getAddFractionAction()-> + setShortcut( TDEShortcut( CTRL + SHIFT + Key_F ) ); + getAddRootAction()-> + setShortcut( TDEShortcut( CTRL + SHIFT + Key_R ) ); + getAddSumAction()-> + setShortcut( TDEShortcut( CTRL + SHIFT + Key_S ) ); + getAddProductAction()-> + setShortcut( TDEShortcut( CTRL + SHIFT + Key_P ) ); + getAddIntegralAction()-> + setShortcut( TDEShortcut( CTRL + SHIFT + Key_I ) ); + getAddMatrixAction()-> + setShortcut( TDEShortcut( CTRL + SHIFT + Key_M ) ); + + } + else { + getAddGenericUpperAction()->setShortcut( TDEShortcut() ); + getAddGenericLowerAction()->setShortcut( TDEShortcut() ); + getRemoveEnclosingAction()->setShortcut( TDEShortcut() ); + getMakeGreekAction()->setShortcut( TDEShortcut() ); + getInsertSymbolAction()->setShortcut( TDEShortcut() ); + getAddOverlineAction()->setShortcut( TDEShortcut() ); + getAddUnderlineAction()->setShortcut( TDEShortcut() ); + getAddBracketAction()->setShortcut( TDEShortcut() ); + getAddSBracketAction()->setShortcut( TDEShortcut() ); + getAddCBracketAction()->setShortcut( TDEShortcut() ); + getAddAbsAction()->setShortcut( TDEShortcut() ); + getAddFractionAction()->setShortcut( TDEShortcut() ); + getAddRootAction()->setShortcut( TDEShortcut() ); + getAddSumAction()->setShortcut( TDEShortcut() ); + getAddProductAction()->setShortcut( TDEShortcut() ); + getAddIntegralAction()->setShortcut( TDEShortcut() ); + getAddMatrixAction()->setShortcut( TDEShortcut() ); + } +} + +void DocumentWrapper::enableMatrixActions( bool b) +{ + getAppendColumnAction()->setEnabled( b ); + getInsertColumnAction()->setEnabled( b ); + getRemoveColumnAction()->setEnabled( b ); + getAppendRowAction()->setEnabled( b ); + getInsertRowAction()->setEnabled( b ); + getRemoveRowAction()->setEnabled( b ); +} + +void DocumentWrapper::updateConfig() +{ + m_syntaxHighlightingAction-> + setChecked( m_document->m_contextStyle->syntaxHighlighting() ); + initSymbolNamesAction(); +} + + +KFORMULA_NAMESPACE_END + +using namespace KFormula; +#include "kformuladocument.moc" diff --git a/lib/kformula/kformulainputfilter.cc b/lib/kformula/kformulainputfilter.cc deleted file mode 100644 index a2675271..00000000 --- a/lib/kformula/kformulainputfilter.cc +++ /dev/null @@ -1,24 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2001 Andrea Rizzi - Ulrich Kuettler - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - -#include "kformulainputfilter.h" - -using namespace KFormula; -#include "kformulainputfilter.moc" diff --git a/lib/kformula/kformulainputfilter.cpp b/lib/kformula/kformulainputfilter.cpp new file mode 100644 index 00000000..a2675271 --- /dev/null +++ b/lib/kformula/kformulainputfilter.cpp @@ -0,0 +1,24 @@ +/* This file is part of the KDE project + Copyright (C) 2001 Andrea Rizzi + Ulrich Kuettler + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "kformulainputfilter.h" + +using namespace KFormula; +#include "kformulainputfilter.moc" diff --git a/lib/kformula/kformulamathmlread.cc b/lib/kformula/kformulamathmlread.cc deleted file mode 100644 index ff941d6f..00000000 --- a/lib/kformula/kformulamathmlread.cc +++ /dev/null @@ -1,1794 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2001 Andrea Rizzi - Ulrich Kuettler - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - -#include -#include -#include - -#include -#include - -//#include - -#include "kformulamathmlread.h" -#include "symboltable.h" - -KFORMULA_NAMESPACE_BEGIN -using namespace std; - -class MathML2KFormulaPrivate -{ - friend class MathML2KFormula; - -public: - MathML2KFormulaPrivate( MathML2KFormula* mml_filter, - const ContextStyle& contextStyle, - const TQDomDocument& formuladoc ); - ~MathML2KFormulaPrivate(); - - void math( TQDomElement element ); - - // Token Elements - void mi( TQDomElement element, TQDomNode docnode ); - void mn( TQDomElement element, TQDomNode docnode ); - void mo( TQDomElement element, TQDomNode docnode ); - void mtext( TQDomElement element, TQDomNode docnode ); - void mspace( TQDomElement element, TQDomNode docnode ); - void ms( TQDomElement element, TQDomNode docnode ); - // mglyph not supported - - // General Layout Schemata - void mrow( TQDomElement element, TQDomNode docnode ); - void mfrac( TQDomElement element, TQDomNode docnode ); - void msqrt( TQDomElement element, TQDomNode docnode ); - void mroot( TQDomElement element, TQDomNode docnode ); - void mstyle( TQDomElement element, TQDomNode docnode ); - // merror not supported - // mpadded not supported - // mphantom not supported - void mfenced( TQDomElement element, TQDomNode docnode ); - // menclose not supported - - // Script and Limit Schemata - void msub_msup( TQDomElement element, TQDomNode docnode ); - void msubsup( TQDomElement element, TQDomNode docnode ); - void munder( TQDomElement element, TQDomNode docnode, bool oasisFormat ); - void mover( TQDomElement element, TQDomNode docnode, bool oasisFormat ); - void munderover( TQDomElement element, TQDomNode docnode, bool oasisFormat ); - // mmultiscripts not supported - - // Tables and Matrices - void mtable( TQDomElement element, TQDomNode docnode ); - // not much supported - - // Enlivening Expressions - // maction not supported - -protected: - void createTextElements( TQString text, TQDomNode docnode ); - void createNameSequence( TQString text, TQDomNode docnode ); - double convertToPoint( TQString value, bool* ok ); - bool isEmbellishedOperator( TQDomNode node, TQDomElement* mo, bool oasisFormat ); - bool isSpaceLike( TQDomNode node, bool oasisFormat ); - - enum MathVariant { - normal, - bold, - italic, - bold_italic, - double_struck, - bold_fraktur, - script, - bold_script, - fraktur, - sans_serif, - bold_sans_serif, - sans_serif_italic, - sans_serif_bold_italic, - monospace - }; - - struct MathStyle { - MathStyle() - : scriptsizemultiplier( 0.71 ), - scriptminsize( 8 ), - veryverythinmathspace( 1.0/18.0 ), - verythinmathspace( 2.0/18.0 ), - thinmathspace( 3.0/18.0 ), - mediummathspace( 4.0/18.0 ), - thickmathspace( 5.0/18.0 ), - verythickmathspace( 6.0/18.0 ), - veryverythickmathspace( 7.0/18.0 ), - - useVariant( false ) - { - } - - void styleChange() - { - kdDebug( DEBUGID ) << "Style Change:" - << "\n scriptlevel = " << scriptlevel - << "\n displaystyle = " << displaystyle - << "\n scriptsizemultiplier = " - << scriptsizemultiplier - << "\n scriptminsize = " << scriptminsize - << endl; - } - - void setStyles( TQDomElement element ) - { - if ( !useVariant ) - return; - - switch ( mathvariant ) - { - case normal: - element.setAttribute( "STYLE", "normal" ); - break; - case bold: - element.setAttribute( "STYLE", "bold" ); - break; - - case bold_italic: - element.setAttribute( "STYLE", "bolditalic" ); - break; - case italic: - element.setAttribute( "STYLE", "italic" ); - break; - - case double_struck: - element.setAttribute( "FAMILY", "doublestruck" ); - break; - - case bold_fraktur: - element.setAttribute( "STYLE", "bold" ); - case fraktur: - element.setAttribute( "FAMILY", "fraktur" ); - break; - - case bold_script: - element.setAttribute( "STYLE", "bold" ); - case script: - element.setAttribute( "FAMILY", "script" ); - break; - - case bold_sans_serif: - element.setAttribute( "STYLE", "bold" ); - case sans_serif: - element.setAttribute( "FAMILY", "normal" ); - break; - case sans_serif_bold_italic: - element.setAttribute( "STYLE", "bolditalic" ); - element.setAttribute( "FAMILY", "normal" ); - break; - case sans_serif_italic: - element.setAttribute( "STYLE", "italic" ); - element.setAttribute( "FAMILY", "normal" ); - break; - - //case monospace: - default: - break; - } - } - - void readStyles( TQDomElement mmlElement ) - { - if ( mmlElement.hasAttribute( "mathvariant" ) ) - { - useVariant = true; - - if ( mmlElement.attribute( "mathvariant" ) == "normal" ) - mathvariant = normal; - else if ( mmlElement.attribute( "mathvariant" ) == "bold" ) - mathvariant = bold; - else if ( mmlElement.attribute( "mathvariant" ) == "italic" ) - mathvariant = italic; - else if ( mmlElement.attribute( "mathvariant" ) == "bold-italic" ) - mathvariant = bold_italic; - else if ( mmlElement.attribute( "mathvariant" ) == "double-struck" ) - mathvariant = double_struck; - else if ( mmlElement.attribute( "mathvariant" ) == "bold-fraktur" ) - mathvariant = bold_fraktur; - else if ( mmlElement.attribute( "mathvariant" ) == "script" ) - mathvariant = script; - else if ( mmlElement.attribute( "mathvariant" ) == "bold-script" ) - mathvariant = bold_script; - else if ( mmlElement.attribute( "mathvariant" ) == "fraktur" ) - mathvariant = fraktur; - else if ( mmlElement.attribute( "mathvariant" ) == "sans-serif" ) - mathvariant = sans_serif; - else if ( mmlElement.attribute( "mathvariant" ) == "bold-sans-serif" ) - mathvariant = bold_sans_serif; - else if ( mmlElement.attribute( "mathvariant" ) == "sans-serif-italic" ) - mathvariant = sans_serif_italic; - else if ( mmlElement.attribute( "mathvariant" ) == "sans-serif-bold-italic" ) - mathvariant = sans_serif_bold_italic; - else if ( mmlElement.attribute( "mathvariant" ) == "monospace" ) - mathvariant = monospace; - } - } - - // Styles, set by // default - - int scriptlevel; // inherited - bool displaystyle; // inherited - double scriptsizemultiplier; // 0.71 - double scriptminsize; // 8pt - // color - // background - double veryverythinmathspace; // 1/18em = 0.0555556em - double verythinmathspace; // 2/18em = 0.111111em - double thinmathspace; // 3/18em = 0.166667em - double mediummathspace; // 4/18em = 0.222222em - double thickmathspace; // 5/18em = 0.277778em - double verythickmathspace; // 6/18em = 0.333333em - double veryverythickmathspace; // 7/18em = 0.388889em - - // 'Local' styles - - MathVariant mathvariant; - bool useVariant; - //int mathsize; - }; - - MathStyle style; - TQDomDocument doc; - -private: - const ContextStyle& context; - MathML2KFormula* filter; -}; - -MathML2KFormulaPrivate::MathML2KFormulaPrivate( MathML2KFormula* mml_filter, const ContextStyle& cs, const TQDomDocument& formuladoc ) - : doc( formuladoc ), context( cs ), filter( mml_filter ) -{ -} - -MathML2KFormulaPrivate::~MathML2KFormulaPrivate() -{ -} - -void MathML2KFormulaPrivate::math( TQDomElement element ) -{ - TQDomElement formula = doc.createElement( "FORMULA" ); - TQDomNode n = element.firstChild(); - - TQString display = element.attribute( "display" ); - - if ( display == "block" ) { - style.displaystyle = true; - } - else { - // if display == "inline" (default) or illegal (then use default) - style.displaystyle = false; - } - - style.scriptlevel = 0; - - /*kdDebug( DEBUGID ) << " element:\n displaystyle = " - << style.displaystyle << "\n scriptlevel = " - << style.scriptlevel << endl;*/ - - while ( !n.isNull() ) { - filter->processElement( n, doc, formula ); - n = n.nextSibling(); - } - - doc.appendChild( formula ); -} - -void MathML2KFormulaPrivate::mi( TQDomElement element, TQDomNode docnode ) -{ - MathStyle previousStyle( style ); - TQString text = element.text().stripWhiteSpace(); - if ( text.length() == 1 ) { // Default italic, only when content is one char - style.mathvariant = italic; - style.useVariant = true; - style.readStyles( element ); - createTextElements( text, docnode ); - } else { // If length is 0 or >1, it should be a text sequence - style.readStyles( element ); - createNameSequence( text, docnode ); - } - style = previousStyle; -} - -void MathML2KFormulaPrivate::mo( TQDomElement element, TQDomNode docnode ) -{ - MathStyle previousStyle( style ); - style.readStyles( element ); - - TQString text = element.text().stripWhiteSpace(); - createTextElements( text, docnode ); - - style = previousStyle; -} - -void MathML2KFormulaPrivate::mn( TQDomElement element, TQDomNode docnode ) -{ - MathStyle previousStyle( style ); - style.readStyles( element ); - - TQString text = element.text().stripWhiteSpace(); - createTextElements( text, docnode ); - - style = previousStyle; -} - -void MathML2KFormulaPrivate::mtext( TQDomElement element, TQDomNode docnode ) -{ - MathStyle previousStyle( style ); - style.readStyles( element ); - - TQDomNode n = element.firstChild(); - - while ( !n.isNull() ) { - if ( n.isText() ) { - TQString text = n.toText().data().stripWhiteSpace(); - createTextElements( text, docnode ); - } - else if ( n.isElement() ) { - filter->processElement( n, doc, docnode ); - } - else { - kdDebug( DEBUGID ) << " child: " << n.nodeName() << endl; - } - - n = n.nextSibling(); - } - - style = previousStyle; -} - -void MathML2KFormulaPrivate::ms( TQDomElement element, TQDomNode docnode ) -{ - TQString lquote = element.attribute( "lquote", "\"" ); - TQString rquote = element.attribute( "rquote", "\"" ); - TQString text; - - text = lquote; - text += element.text().stripWhiteSpace(); - text += rquote; - - createTextElements( text, docnode ); -} - -void MathML2KFormulaPrivate::mspace( TQDomElement element, TQDomNode docnode ) -{ - // we support only horizontal space - TQString width = element.attribute( "width" ); - - TQDomElement spaceelement = doc.createElement( "SPACE" ); - - // check for namedspace. We don't support much... - if ( width == "veryverythinmathspace" ) { - spaceelement.setAttribute( "WIDTH", "thin" ); - } - else if ( width == "verythinmathspace" ) { - spaceelement.setAttribute( "WIDTH", "thin" ); - } - else if ( width == "thinmathspace" ) { - spaceelement.setAttribute( "WIDTH", "thin" ); - } - else if ( width == "mediummathspace" ) { - spaceelement.setAttribute( "WIDTH", "medium" ); - } - else if ( width == "thickmathspace" ) { - spaceelement.setAttribute( "WIDTH", "thick" ); - } - else if ( width == "verythickmathspace" ) { - spaceelement.setAttribute( "WIDTH", "thick" ); - } - else if ( width == "veryverythickmathspace" ) { - spaceelement.setAttribute( "WIDTH", "quad" ); - } - - else { - // units - - double w = 0; - bool ok; - - if ( width.endsWith( "em" ) ) { - // See MathML specification, Appendix H - w = context.getDefaultFont().pointSize(); - if ( w == -1 ) { - TQFontMetrics fm( context.getDefaultFont() ); - w = fm.width( 'm' ); - } - w = w * width.remove( width.length() - 2, 2 ).toDouble( &ok ); - // w in points? - } - else if ( width.endsWith( "px" ) ) { - w = width.remove( width.length() - 2, 2 ).toDouble( &ok ); - // w in pixels - } - else if ( width.endsWith( "in" ) ) { - w = width.remove( width.length() - 2, 2 ).toDouble( &ok ); - w *= 72; // w in points - } - else if ( width.endsWith( "cm" ) ) { - w = width.remove( width.length() - 2, 2 ).toDouble( &ok ); - w *= 1/2.54 * 72; // w in points - } - else if ( width.endsWith( "mm" ) ) { - w = width.remove( width.length() - 2, 2 ).toDouble( &ok ); - w *= 1/25.4 * 72; // w in points - } - else if ( width.endsWith( "pt" ) ) { - w = width.remove( width.length() - 2, 2 ).toDouble( &ok ); - // w in points - } - else if ( width.endsWith( "pc" ) ) { - w = width.remove( width.length() - 2, 2 ).toDouble( &ok ); - w /= 12; // w in points - } - else { - w = width.toDouble( &ok ); - } - - if ( !ok ) - return; - - if ( w < 20 ) - spaceelement.setAttribute( "WIDTH", "thin" ); - else if ( w < 40 ) - spaceelement.setAttribute( "WIDTH", "medium" ); - else if ( w < 80 ) - spaceelement.setAttribute( "WIDTH", "thick" ); - else - spaceelement.setAttribute( "WIDTH", "quad" ); - } - - docnode.appendChild( spaceelement ); -} - -void MathML2KFormulaPrivate::mrow( TQDomElement element, TQDomNode docnode ) -{ - TQDomNode n = element.firstChild(); - while ( !n.isNull() ) { - if ( n.isElement () ) { - TQDomElement e = n.toElement(); - // We do not allow sequence inside sequence - filter->processElement( e, doc, docnode ); - } - else { - kdDebug( DEBUGID ) << " child: " << n.nodeName() << endl; - } - n = n.nextSibling(); - } -} - -void MathML2KFormulaPrivate::mfrac( TQDomElement element, TQDomNode docnode ) -{ - TQDomNode n = element.firstChild(); - TQDomElement fraction = doc.createElement( "FRACTION" ); - - MathStyle previousStyle( style ); - style.displaystyle ? style.displaystyle = false : style.scriptlevel += 1; - style.styleChange(); - - int i = 0; - while ( !n.isNull() && i < 2 ) { - if ( n.isElement() ) { - ++i; - if ( i == 1 ) { //first is numerator - TQDomElement numerator = - doc.createElement( "NUMERATOR" ); - TQDomElement sequence = doc.createElement( "SEQUENCE" ); - numerator.appendChild( sequence ); - TQDomElement e = n.toElement(); - filter->processElement( e, doc, sequence ); - fraction.appendChild( numerator ); - - } - else { - TQDomElement denominator = - doc.createElement( "DENOMINATOR" ); - TQDomElement sequence = doc.createElement( "SEQUENCE" ); - denominator.appendChild( sequence ); - TQDomElement e = n.toElement(); - filter->processElement( e, doc, sequence ); - fraction.appendChild( denominator ); - - } - } - else { - kdDebug( DEBUGID ) << " child: " << n.nodeName() << endl; - } - n = n.nextSibling(); - } - - style = previousStyle; - docnode.appendChild( fraction ); -} - -void MathML2KFormulaPrivate::mroot( TQDomElement element, TQDomNode docnode ) -{ - TQDomNode n = element.firstChild(); - int i = 0; - TQDomElement root = doc.createElement( "ROOT" ); - - while ( !n.isNull() && i < 2 ) { - if ( n.isElement() ) { - ++i; - if ( i == 1 ) { //first is content (base) - TQDomElement content = doc.createElement( "CONTENT" ); - TQDomElement sequence = doc.createElement( "SEQUENCE" ); - content.appendChild( sequence ); - TQDomElement e = n.toElement(); - filter->processElement( e, doc, sequence ); - - root.appendChild(content); - } - else { // index - MathStyle previousStyle( style ); - style.scriptlevel += 2; - style.displaystyle = false; - style.styleChange(); - - TQDomElement index = doc.createElement( "INDEX" ); - TQDomElement sequence = doc.createElement( "SEQUENCE" ); - index.appendChild( sequence ); - TQDomElement e = n.toElement(); - filter->processElement( e, doc, sequence ); - root.appendChild( index ); - - style = previousStyle; - } - } - else { - kdDebug( DEBUGID ) << " child: " << n.nodeName() << endl; - } - n = n.nextSibling(); - } - docnode.appendChild( root ); -} - -void MathML2KFormulaPrivate::msqrt( TQDomElement element, TQDomNode docnode ) -{ - TQDomNode n = element.firstChild(); - TQDomElement root = doc.createElement( "ROOT" ); - - TQDomElement content = doc.createElement( "CONTENT" ); - TQDomElement sequence = doc.createElement( "SEQUENCE" ); - content.appendChild( sequence ); - root.appendChild( content ); - - while ( !n.isNull() ) { - if ( n.isElement() ) { - filter->processElement( n.toElement(), doc, sequence ); - } - else { - kdDebug( DEBUGID ) << " child: " << n.nodeName() << endl; - } - n = n.nextSibling(); - } - - docnode.appendChild( root ); -} - -void MathML2KFormulaPrivate::mstyle( TQDomElement element, TQDomNode docnode ) -{ - bool ok; - - MathStyle previousStyle( style ); - style.readStyles( element ); - - if ( element.hasAttribute( "scriptlevel" ) ) { - TQString scriptlevel = element.attribute( "scriptlevel" ); - if ( scriptlevel.startsWith( "+" ) || scriptlevel.startsWith( "-" ) ) - style.scriptlevel += scriptlevel.toInt( &ok ); - else - style.scriptlevel = scriptlevel.toInt( &ok ); - if ( !ok ) - style.scriptlevel = previousStyle.scriptlevel; - } - if ( element.hasAttribute( "displaystyle" ) ) { - TQString displaystyle = element.attribute( "displaystyle" ); - if ( displaystyle == "true" ) - style.displaystyle = true; - else if ( displaystyle == "false" ) - style.displaystyle = false; - } - if ( element.hasAttribute( "scriptsizemultiplier" ) ) { - style.scriptsizemultiplier = - element.attribute( "scriptsizemultiplier" ).toDouble( &ok ); - if ( !ok ) - style.scriptsizemultiplier = previousStyle.scriptsizemultiplier; - } - if ( element.hasAttribute( "scriptminsize" ) ) { - TQString scriptminsize = element.attribute( "scriptminsize" ); - style.scriptminsize = convertToPoint( scriptminsize, &ok ); - if ( !ok ) - style.scriptminsize = previousStyle.scriptminsize; - } - - if ( element.hasAttribute( "veryverythinmathspace" ) ) { - TQString vvthinmspace = element.attribute( "veryverythinmathspace" ); - style.veryverythinmathspace = convertToPoint( vvthinmspace, &ok ); - if ( !ok ) - style.veryverythinmathspace = previousStyle.veryverythinmathspace; - } - if ( element.hasAttribute( "verythinmathspace" ) ) { - TQString vthinmspace = element.attribute( "verythinmathspace" ); - style.verythinmathspace = convertToPoint( vthinmspace, &ok ); - if ( !ok ) - style.verythinmathspace = previousStyle.verythinmathspace; - } - if ( element.hasAttribute( "thinmathspace" ) ) { - TQString thinmathspace = element.attribute( "thinmathspace" ); - style.thinmathspace = convertToPoint( thinmathspace, &ok ); - if ( !ok ) - style.thinmathspace = previousStyle.thinmathspace; - } - if ( element.hasAttribute( "mediummathspace" ) ) { - TQString mediummathspace = element.attribute( "mediummathspace" ); - style.mediummathspace = convertToPoint( mediummathspace, &ok ); - if ( !ok ) - style.mediummathspace = previousStyle.mediummathspace; - } - if ( element.hasAttribute( "thickmathspace" ) ) { - TQString thickmathspace = element.attribute( "thickmathspace" ); - style.thickmathspace = convertToPoint( thickmathspace, &ok ); - if ( !ok ) - style.thickmathspace = previousStyle.thickmathspace; - } - if ( element.hasAttribute( "verythickmathspace" ) ) { - TQString vthickmspace = element.attribute( "verythickmathspace" ); - style.verythickmathspace = convertToPoint( vthickmspace, &ok ); - if ( !ok ) - style.verythickmathspace = previousStyle.verythickmathspace; - } - if ( element.hasAttribute( "veryverythickmathspace" ) ) { - TQString vvthickmspace = element.attribute( "veryverythickmathspace" ); - style.veryverythickmathspace = convertToPoint( vvthickmspace, &ok ); - if ( !ok ) - style.veryverythickmathspace = - previousStyle.veryverythickmathspace; - } - - style.styleChange(); - - TQDomNode n = element.firstChild(); - while ( !n.isNull() ) { - filter->processElement( n, doc, docnode ); - n = n.nextSibling(); - } - - style = previousStyle; -} - -void MathML2KFormulaPrivate::mfenced( TQDomElement element, TQDomNode docnode ) -{ - TQDomElement bracket = doc.createElement( "BRACKET" ); - TQString value = element.attribute( "open", "(" ); - bracket.setAttribute( "LEFT", TQString::number( value.at( 0 ).latin1() ) ); - value = element.attribute( "close", ")" ); - bracket.setAttribute( "RIGHT", TQString::number( value.at( 0 ).latin1() ) ); - - TQDomElement content = doc.createElement( "CONTENT" ); - TQDomElement sequence = doc.createElement( "SEQUENCE" ); - content.appendChild( sequence ); - - TQString separators = element.attribute( "separators", "," ); - - TQDomNode n = element.firstChild(); - uint i = 0; - while ( !n.isNull() ) { - if ( n.isElement() ) { - if ( i != 0 && !separators.isEmpty() ) { - TQDomElement textelement = doc.createElement( "TEXT" ); - if ( i > separators.length() ) - i = separators.length(); - textelement.setAttribute( "CHAR", TQString( separators.at( i - 1 ) ) ); - //style.setStyles( textelement ); - sequence.appendChild( textelement ); - } - ++i; - TQDomElement e = n.toElement(); - filter->processElement( e, doc, sequence ); - } - else { - kdDebug( DEBUGID ) << " child: " << n.nodeName() << endl; - } - n = n.nextSibling(); - } - bracket.appendChild( content ); - docnode.appendChild( bracket ); -} - -void MathML2KFormulaPrivate::mtable( TQDomElement element, TQDomNode docnode ) -{ - MathStyle previousStyle( style ); - TQString displaystyle = element.attribute( "displaystyle", "false" ); - if ( displaystyle == "true" ) { - style.displaystyle = true; - } - else { - // false is default and also used for illegal values - style.displaystyle = false; - } - style.styleChange(); - - TQString subtag; - int rows = 0; int cols = 0; - TQDomNode n = element.firstChild(); - - while ( !n.isNull() ) { - if ( n.isElement() ) { - TQDomElement e = n.toElement(); - subtag = e.tagName(); - if (subtag == "mtr") - { - ++rows; - - /* Determins the number of columns */ - - TQDomNode cellnode = e.firstChild(); - int cc = 0; - - while ( !cellnode.isNull() ) { - if ( cellnode.isElement() ) - cc++; - cellnode = cellnode.nextSibling(); - } - - if ( cc > cols ) - cols = cc; - - } - } - else { - kdDebug( DEBUGID ) << " child: " << n.nodeName() << endl; - } - n = n.nextSibling(); - } - - /* Again createing elements, I need to know the number - of rows and cols to leave empty spaces */ - - n = element.firstChild(); - TQDomElement matrix = doc.createElement( "MATRIX" ); - matrix.setAttribute( "COLUMNS", cols ); - matrix.setAttribute( "ROWS", rows ); - - while ( !n.isNull() ) { - if ( n.isElement() ) { - TQDomElement e = n.toElement(); - subtag = e.tagName(); - if ( subtag == "mtr" ) { - TQDomNode cellnode = e.firstChild(); - int cc = 0; - while ( !cellnode.isNull() ) { - if ( cellnode.isElement() ) { - ++cc; - TQDomElement cell = doc.createElement( "SEQUENCE" ); - TQDomElement cellelement = cellnode.toElement(); - filter->processElement( cellelement, doc, cell ); - matrix.appendChild( cell ); - } - cellnode = cellnode.nextSibling(); - } - - /* Add empty elements */ - for(; cc < cols; cc++ ) { - TQDomElement cell = doc.createElement( "SEQUENCE" ); - matrix.appendChild( cell ); - } - } - } - n = n.nextSibling(); - } - - style = previousStyle; - docnode.appendChild(matrix); -} - -void MathML2KFormulaPrivate::msub_msup( TQDomElement element, TQDomNode docnode ) -{ - TQDomNode n = element.firstChild(); - int i = 0; - TQDomElement root = doc.createElement( "INDEX" ); - - while ( !n.isNull() && i < 2 ) { - if ( n.isElement() ) { - ++i; - if ( i == 1 ) { // first is content (base) - TQDomElement content = doc.createElement( "CONTENT" ); - TQDomElement sequence = doc.createElement( "SEQUENCE" ); - content.appendChild( sequence ); - TQDomElement e = n.toElement(); - filter->processElement( e, doc, sequence ); - - root.appendChild( content ); - } - else { - TQDomElement index; - if ( element.tagName() == "msup" ) - index = doc.createElement( "UPPERRIGHT" ); - else - index = doc.createElement( "LOWERRIGHT" ); - - MathStyle previousStyle( style ); - style.scriptlevel += 1; - style.displaystyle = false; - style.styleChange(); - - TQDomElement sequence = doc.createElement( "SEQUENCE" ); - index.appendChild( sequence ); - TQDomElement e = n.toElement(); - filter->processElement( e, doc, sequence ); - root.appendChild( index ); - - style = previousStyle; - } - } - else { - kdDebug( DEBUGID ) << "<" << element.tagName() << "> child: " - << n.nodeName() << endl; - } - n = n.nextSibling(); - } - docnode.appendChild( root ); -} - -void MathML2KFormulaPrivate::munder( TQDomElement element, TQDomNode docnode, bool oasisFormat ) -{ - bool accentunder; - - TQString au = element.attribute( "accentunder" ); - if ( au == "true" ) - accentunder = true; - else if ( au == "false" ) - accentunder = false; - else { - // use default - - TQDomElement mo; - // is underscript an embellished operator? - if ( isEmbellishedOperator( element.childNodes().item( 1 ), &mo, oasisFormat ) ) { - if ( mo.attribute( "accent" ) == "true" ) - accentunder = true; - else - accentunder = false; - } - else - accentunder = false; - } - - TQDomNode n = element.firstChild(); - int i = 0; - TQDomElement root = doc.createElement( "INDEX" ); - - while ( !n.isNull() && i < 2 ) { - if ( n.isElement() ) { - ++i; - if ( i == 1 ) { // first is content (base) - TQDomElement content = doc.createElement( "CONTENT" ); - TQDomElement sequence = doc.createElement( "SEQUENCE" ); - content.appendChild( sequence ); - TQDomElement e = n.toElement(); - filter->processElement( e, doc, sequence ); - - root.appendChild( content ); - } - else { // underscript - MathStyle previousStyle( style ); - style.displaystyle = false; - if ( !accentunder ) { - style.scriptlevel += 1; - style.styleChange(); - } - - TQDomElement mo; TQDomElement index; - if ( isEmbellishedOperator( n.previousSibling(), &mo, oasisFormat ) && - !previousStyle.displaystyle && - mo.attribute( "movablelimits" ) == "true" ) - { - index = doc.createElement( "LOWERRIGHT" ); - } - else { - index = doc.createElement( "LOWERMIDDLE" ); - } - - TQDomElement sequence = doc.createElement( "SEQUENCE" ); - index.appendChild( sequence ); - TQDomElement e = n.toElement(); - filter->processElement( e, doc, sequence ); - root.appendChild( index ); - - style = previousStyle; - } - } - else { - kdDebug( DEBUGID ) << "<" << element.tagName() << "> child: " - << n.nodeName() << endl; - } - n = n.nextSibling(); - } - - docnode.appendChild( root ); -} - -void MathML2KFormulaPrivate::mover( TQDomElement element, TQDomNode docnode, bool oasisFormat ) -{ - bool accent; - - TQString ac = element.attribute( "accent" ); - if ( ac == "true" ) - accent = true; - else if ( ac == "false" ) - accent = false; - else { - // use default - - TQDomElement mo; - // is overscript an embellished operator? - if ( isEmbellishedOperator( element.childNodes().item( 1 ), &mo, oasisFormat ) ) { - if ( mo.attribute( "accent" ) == "true" ) - accent = true; - else - accent = false; - } - else - accent = false; - } - - TQDomNode n = element.firstChild(); - int i = 0; - TQDomElement root = doc.createElement( "INDEX" ); - - while ( !n.isNull() && i < 2 ) { - if ( n.isElement() ) { - ++i; - if ( i == 1 ) { // first is content (base) - TQDomElement content = doc.createElement( "CONTENT" ); - TQDomElement sequence = doc.createElement( "SEQUENCE" ); - content.appendChild( sequence ); - TQDomElement e = n.toElement(); - filter->processElement( e, doc, sequence ); - - root.appendChild( content ); - } - else { // overscript - MathStyle previousStyle( style ); - style.displaystyle = false; - if ( !accent ) { - style.scriptlevel += 1; - style.styleChange(); - } - - TQDomElement mo; TQDomElement index; - if ( isEmbellishedOperator( n.previousSibling(), &mo, oasisFormat ) && - !previousStyle.displaystyle && - mo.attribute( "movablelimits" ) == "true" ) - { - index = doc.createElement( "UPPERRIGHT" ); - } - else { - index = doc.createElement( "UPPERMIDDLE" ); - } - - TQDomElement sequence = doc.createElement( "SEQUENCE" ); - index.appendChild( sequence ); - TQDomElement e = n.toElement(); - filter->processElement( e, doc, sequence ); - root.appendChild( index ); - - style = previousStyle; - } - } - else { - kdDebug( DEBUGID ) << "<" << element.tagName() << "> child: " - << n.nodeName() << endl; - } - n = n.nextSibling(); - } - - docnode.appendChild( root ); -} - -void MathML2KFormulaPrivate::munderover( TQDomElement element, TQDomNode docnode, bool oasisFormat ) -{ - bool accent; - bool accentunder; - - TQString value = element.attribute( "accentunder" ); - if ( value == "true" ) - accentunder = true; - else if ( value == "false" ) - accentunder = false; - else { - // use default - - TQDomElement mo; - // is underscript an embellished operator? - if ( isEmbellishedOperator( element.childNodes().item( 1 ), &mo, oasisFormat ) ) { - if ( mo.attribute( "accent" ) == "true" ) - accentunder = true; - else - accentunder = false; - } - else - accentunder = false; - } - value = element.attribute( "accent" ); - if ( value == "true" ) - accent = true; - else if ( value == "false" ) - accent = false; - else { - // use default - - TQDomElement mo; - // is overscript an embellished operator? - if ( isEmbellishedOperator( element.childNodes().item( 2 ), &mo,oasisFormat ) ) { - kdDebug( DEBUGID ) << "embellished operator" << endl; - if ( mo.attribute( "accent" ) == "true" ) - accent = true; - else - accent = false; - } - else - accent = false; - } - kdDebug( DEBUGID ) << "munderover:\n accentunder = " << accentunder - << "\n accent = " << accent << endl; - - TQDomNode n = element.firstChild(); - int i = 0; - TQDomElement root = doc.createElement( "INDEX" ); - - while ( !n.isNull() && i < 3 ) { - if ( n.isElement() ) { - ++i; - if ( i == 1 ) { // base - TQDomElement content = doc.createElement( "CONTENT" ); - TQDomElement sequence = doc.createElement( "SEQUENCE" ); - content.appendChild( sequence ); - TQDomElement e = n.toElement(); - filter->processElement( e, doc, sequence ); - - root.appendChild( content ); - } - else if ( i == 2 ) { // underscript - MathStyle previousStyle( style ); - style.displaystyle = false; - if ( !accentunder ) { - style.scriptlevel += 1; - style.styleChange(); - } - - TQDomElement mo; TQDomElement index; - // is the base an embellished operator? - if ( isEmbellishedOperator( element.firstChild(), &mo, oasisFormat ) && - !previousStyle.displaystyle && - mo.attribute( "movablelimits" ) == "true" ) - { - index = doc.createElement( "LOWERRIGHT" ); - } - else { - index = doc.createElement( "LOWERMIDDLE" ); - } - - TQDomElement sequence = doc.createElement( "SEQUENCE" ); - index.appendChild( sequence ); - TQDomElement e = n.toElement(); - filter->processElement( e, doc, sequence ); - root.appendChild( index ); - - style = previousStyle; - } - else { // overscript - MathStyle previousStyle( style ); - style.displaystyle = false; - if ( !accent ) { - style.scriptlevel += 1; - style.styleChange(); - } - - TQDomElement mo; TQDomElement index; - if ( isEmbellishedOperator( element.firstChild(), &mo, oasisFormat ) && - !previousStyle.displaystyle && - mo.attribute( "movablelimits" ) == "true" ) - { - index = doc.createElement( "UPPERRIGHT" ); - } - else { - index = doc.createElement( "UPPERMIDDLE" ); - } - - TQDomElement sequence = doc.createElement( "SEQUENCE" ); - index.appendChild( sequence ); - TQDomElement e = n.toElement(); - filter->processElement( e, doc, sequence ); - root.appendChild( index ); - - style = previousStyle; - } - } - else { - kdDebug( DEBUGID ) << "<" << element.tagName() << "> child: " - << n.nodeName() << endl; - } - n = n.nextSibling(); - } - - docnode.appendChild( root ); -} - -void MathML2KFormulaPrivate::msubsup( TQDomElement element, TQDomNode docnode ) -{ - TQDomNode n = element.firstChild(); - int i = 0; - TQDomElement root = doc.createElement("INDEX"); - MathStyle previousStyle( style ); - - while ( !n.isNull() && i < 2 ) { - if ( n.isElement() ) { - ++i; - if ( i == 1 ) { // base - TQDomElement content = doc.createElement( "CONTENT" ); - TQDomElement sequence = doc.createElement( "SEQUENCE" ); - content.appendChild( sequence ); - TQDomElement e = n.toElement(); - filter->processElement( e, doc, sequence ); - - root.appendChild( content ); - } - else if ( i == 2 ) { // subscript - style.scriptlevel += 1; - style.displaystyle = false; - style.styleChange(); - - TQDomElement index; - index = doc.createElement( "LOWERRIGHT" ); - - TQDomElement sequence = doc.createElement( "SEQUENCE" ); - index.appendChild( sequence ); - TQDomElement e = n.toElement(); - filter->processElement( e, doc, sequence ); - root.appendChild( index ); - } - else { // superscript - TQDomElement index; - index = doc.createElement( "UPPERRIGHT" ); - - TQDomElement sequence = doc.createElement( "SEQUENCE" ); - index.appendChild( sequence ); - TQDomElement e = n.toElement(); - filter->processElement( e, doc, sequence ); - root.appendChild( index ); - - style = previousStyle; - - } - } - else { - kdDebug( DEBUGID ) << " child: " << n.nodeName() << endl; - } - n = n.nextSibling(); - } - docnode.appendChild( root ); -} - -void MathML2KFormulaPrivate::createTextElements( TQString text, TQDomNode docnode ) -{ - for ( uint i = 0; i < text.length(); ++i ) { - TQDomElement textelement = doc.createElement( "TEXT" ); - textelement.setAttribute( "CHAR", TQString( text.at( i ) ) ); - style.setStyles( textelement ); - if ( context.symbolTable().inTable( text.at( i ) ) ) { - // The element is a symbol. - textelement.setAttribute( "SYMBOL", "3" ); - } - docnode.appendChild( textelement ); - } -} - -void MathML2KFormulaPrivate::createNameSequence( TQString text, TQDomNode docnode ) -{ - TQDomElement namesequence = doc.createElement( "NAMESEQUENCE" ); - for ( uint i = 0; i < text.length(); ++i ) { - TQDomElement textelement = doc.createElement( "TEXT" ); - textelement.setAttribute( "CHAR", TQString( text.at( i ) ) ); - style.setStyles( textelement ); - if ( context.symbolTable().inTable( text.at( i ) ) ) { - // The element is a symbol. - textelement.setAttribute( "SYMBOL", "3" ); - } - namesequence.appendChild( textelement ); - } - docnode.appendChild( namesequence ); -} - -double MathML2KFormulaPrivate::convertToPoint( TQString value, bool* ok ) -{ - double pt = 0; - - if ( value.endsWith( "em" ) ) { - // See MathML specification, Appendix H - pt = context.getDefaultFont().pointSize(); - if ( pt == -1 ) { - TQFontMetrics fm( context.getDefaultFont() ); - pt = fm.width( 'M' ); - // PIXELS! - } - pt = pt * value.remove( value.length() - 2, 2 ).toDouble( ok ); - } - else if ( value.endsWith( "ex" ) ) { - TQFontMetrics fm( context.getDefaultFont() ); - pt = fm.height(); - // PIXELS, and totally wrong! - } - else if ( value.endsWith( "px" ) ) { - pt = value.remove( value.length() - 2, 2 ).toDouble( ok ); - // PIXELS! - } - else if ( value.endsWith( "in" ) ) { - pt = value.remove( value.length() - 2, 2 ).toDouble( ok ); - pt *= 72; - } - else if ( value.endsWith( "cm" ) ) { - pt = value.remove( value.length() - 2, 2 ).toDouble( ok ); - pt *= 1/2.54 * 72; - } - else if ( value.endsWith( "mm" ) ) { - pt = value.remove( value.length() - 2, 2 ).toDouble( ok ); - pt *= 1/25.4 * 72; - } - else if ( value.endsWith( "pt" ) ) { - pt = value.remove( value.length() - 2, 2 ).toDouble( ok ); - } - else if ( value.endsWith( "pc" ) ) { - pt = value.remove( value.length() - 2, 2 ).toDouble( ok ); - pt /= 12; - } - else { - pt = value.toDouble( ok ); - } - - return pt; -} - -bool MathML2KFormulaPrivate::isEmbellishedOperator( TQDomNode node, - TQDomElement* mo, bool oasisFormat ) -{ - // See MathML 2.0 specification: 3.2.5.7 - - if ( !node.isElement() ) - return false; - - TQDomElement element = node.toElement(); - TQString tag = element.tagName(); - - if ( tag == "mo" ) - { - *mo = element; - return true; - } - if ( tag == "msub" || tag == "msup" || tag == "msubsup" || - tag == "munder" || tag == "mover" || tag == "munderover" || - tag == "mmultiscripts" || tag == "mfrac" || tag == "semantics" ) - { - return isEmbellishedOperator( element.firstChild(), mo,oasisFormat ); - } - if ( tag == "maction" ) - { - return false; // not supported - } - if ( tag == "mrow" || tag == "mstyle" || tag == "mphantom" || tag == "mpadded" ) { - TQDomNode n = element.firstChild(); - int i = 0; - - while ( !n.isNull() ) { - if ( isEmbellishedOperator( n, mo,oasisFormat ) ) { - if ( ++i > 1 ) // one (only one) embellished operator - return false; - } - else if ( !isSpaceLike( n, oasisFormat ) ) { // zero or more space-like elements - return false; - } - n = n.nextSibling(); - } - return ( i == 1 ); - } - return false; -} - -bool MathML2KFormulaPrivate::isSpaceLike( TQDomNode node, bool oasisFormat ) -{ - // See MathML 2.0 specification: 3.2.7.3 - - if ( !node.isElement() ) - return false; - - TQDomElement element = node.toElement(); - TQString tag = element.tagName(); - - if ( tag == "mtext" || tag == "mspace" || - tag == "maligngroup" || tag == "malignmark" ) { - return true; - } - if ( tag == "mstyle" || tag == "mphantom" || tag == "mpadded" || tag == "mrow" ) { - TQDomNode n = element.firstChild(); - while ( !n.isNull() ) { - if ( isSpaceLike( n,oasisFormat ) ) - n = n.nextSibling(); - else - return false; - } - return true; - } - if ( tag == "maction" ) { - return false; // not supported - } - - return false; -} - - -MathML2KFormula::MathML2KFormula( const TQDomDocument& mmldoc, const ContextStyle &contextStyle, bool _oasisFormat ) - : m_error( false ), oasisFormat( _oasisFormat ), context( contextStyle ) -{ - orig_element = mmldoc.documentElement(); - done = false; -} - -MathML2KFormula::MathML2KFormula( const TQDomElement& mmlelm, const ContextStyle &contextStyle, bool _oasisFormat ) - : m_error( false ), orig_element( mmlelm ), oasisFormat( _oasisFormat ), context( contextStyle ) -{ - done = false; -} - -TQDomDocument MathML2KFormula::getKFormulaDom() -{ - return formuladoc; -} - - - -void MathML2KFormula::startConversion() -{ - //TODO:let it be async - //kdDebug() << origdoc.toString() << endl; - done = false; - formuladoc = TQDomDocument( "KFORMULA" ); - impl = new MathML2KFormulaPrivate( this, context, formuladoc ); - if ( orig_element.tagName() == "math" ) { - impl->math( orig_element ); - m_error = false; - } - else { - kdError() << "Not a MathML document!" << endl; - KMessageBox::error( 0, i18n( "The document does not seem to be MathML." ), i18n( "MathML Import Error" ) ); - m_error = true; - } - done = true; -} - -bool MathML2KFormula::processElement( TQDomNode node, TQDomDocument& doc, TQDomNode docnode ) -{ - - //TQDomElement *element; - Type type = UNKNOWN; - - if ( node.isElement() ) { - TQDomElement element = node.toElement(); - TQString tag = element.tagName(); - - if ( tag == "mi" ) { - type = TOKEN; - impl->mi( element, docnode ); - } - else if ( tag == "mo" ) { - type = TOKEN; - impl->mo( element, docnode ); - } - else if ( tag == "mn" ) { - type = TOKEN; - impl->mn( element, docnode ); - } - else if ( tag == "mtext" ) { - type = TOKEN; - impl->mtext( element, docnode ); - } - else if ( tag == "ms" ) { - type = TOKEN; - impl->ms( element, docnode ); - } - else if ( tag == "mspace" ) { - type = TOKEN; - impl->mspace( element, docnode ); - } - else if ( tag == "mrow" ) { - type = LAYOUT; - impl->mrow( element, docnode ); - } - else if ( tag == "mfrac" ) { - type = LAYOUT; - impl->mfrac( element, docnode ); - } - else if ( tag == "mroot" ) { - type = LAYOUT; - impl->mroot( element, docnode ); - } - else if ( tag == "msqrt" ) { - type = LAYOUT; - impl->msqrt( element, docnode ); - } - else if ( tag == "mstyle" ) { - type = LAYOUT; - impl->mstyle( element, docnode ); - } - else if ( tag == "mfenced" ) { - type = LAYOUT; - impl->mfenced( element, docnode ); - } - else if ( tag == "mtable" ) { - type = TABLE; - impl->mtable( element, docnode ); - } - else if ( tag == "msub" || tag == "msup" ) { - type = SCRIPT; - impl->msub_msup( element, docnode ); - } - else if ( tag == "munder" ) { - type = SCRIPT; - impl->munder( element, docnode,oasisFormat ); - } - else if ( tag == "mover" ) { - type = SCRIPT; - impl->mover( element, docnode,oasisFormat ); - } - else if ( tag == "munderover" ) { - type = SCRIPT; - impl->munderover( element, docnode, oasisFormat ); - } - else if ( tag == "msubsup" ) { - type = SCRIPT; - impl->msubsup( element, docnode ); - } - - // content markup (not yet complete) - else if ( tag == "apply" ) { - type = CONTENT; - TQDomNode n = element.firstChild(); - TQDomElement op = n.toElement(); - uint count = element.childNodes().count(); - //adding explicit brackets to replace "apply"s implicit ones - TQDomElement brackets = doc.createElement("BRACKET"); - brackets.setAttribute("RIGHT", "41"); - brackets.setAttribute("LEFT", "40"); - TQDomElement content = doc.createElement("CONTENT"); - brackets.appendChild(content); - TQDomElement base = doc.createElement("SEQUENCE"); - content.appendChild(base); - docnode.appendChild(brackets); - //Arithmetic, Algebra and Logic operators status - // quotient X - // factorial O - // divide O - // max, min X - // minus O - // plus O - // power O - // rem X - // times O - // root X - // gcd X - // and O - // or O - // xor O - // not O - // implies O - // forall X - // exists X - // abs O - // conjugate X - // arg X - // real X - // imaginary X - // lcm X - // floor X - // ceiling X - - // n-ary - if ( op.tagName() == "plus" || op.tagName() == "times" || - op.tagName() == "and" || op.tagName() == "or" || - op.tagName() == "xor" ) { - - n = n.nextSibling(); - bool first = true; - - while ( !n.isNull() ) { - if ( n.isElement() ) { - if ( !first ) { - TQDomElement text = doc.createElement( "TEXT" ); - TQString value; - - if ( op.tagName() == "plus" ) - value = "+"; - else if ( op.tagName() == "times" ) - value = "*"; - else if ( op.tagName() == "and" ) - value = "&"; - else if ( op.tagName() == "or" ) - value = "|"; - else if ( op.tagName() == "xor" ) - value = "^"; // ??? - - text.setAttribute( "CHAR", value ); //switch to createTextElements? - base.appendChild( text ); - } - first = false; - TQDomElement e = n.toElement(); - processElement( e, doc, base ); - } - n = n.nextSibling(); - } - } - - else if ( op.tagName() == "factorial" ) { - TQDomElement e = n.nextSibling().toElement(); - processElement( e, doc, docnode ); - impl->createTextElements( "!", base ); - } - else if ( op.tagName() == "minus" ) { - n = n.nextSibling(); - if ( count == 2 ) { // unary - impl->createTextElements( "-", base ); - TQDomElement e = n.toElement(); - processElement( e, doc, base ); - } - else if ( count == 3 ) { // binary - TQDomElement e = n.toElement(); - processElement( e, doc, base ); - impl->createTextElements( "-", base ); - n = n.nextSibling(); - e = n.toElement(); - processElement( e, doc, base ); - } - } - - else if ( op.tagName() == "divide" && count == 3 ) { - n = n.nextSibling(); - TQDomElement e = n.toElement(); - processElement( e, doc, base ); - impl->createTextElements("/", base); - n = n.nextSibling(); - e = n.toElement(); - processElement( e, doc, base ); - } - else if ( op.tagName() == "power" && count == 3 ) { - //code duplication of msub_sup(), but I can't find a way to cleanly call it - n = n.nextSibling(); - TQDomElement e = n.toElement(); - TQDomElement index = doc.createElement("INDEX"); - base.appendChild(index); - TQDomElement content = doc.createElement("CONTENT"); - index.appendChild(content); - TQDomElement sequence = doc.createElement("SEQUENCE"); - content.appendChild(sequence); - processElement(e, doc, sequence); - TQDomElement upper = doc.createElement("UPPERRIGHT"); - index.appendChild(upper); - sequence = doc.createElement("SEQUENCE"); - upper.appendChild(sequence); - n = n.nextSibling(); - e = n.toElement(); - processElement(e, doc, sequence); - } - else if ( op.tagName() == "abs" && count == 2) { - n = n.nextSibling(); - TQDomElement e = n.toElement(); - TQDomElement bracket = doc.createElement("BRACKET"); - bracket.setAttribute("RIGHT", "257"); - bracket.setAttribute("LEFT", "256"); - base.appendChild(bracket); - TQDomElement content = doc.createElement("CONTENT"); - bracket.appendChild(content); - TQDomElement sequence = doc.createElement("SEQUENCE"); - content.appendChild(sequence); - processElement(e, doc, sequence); - } - else if ( op.tagName() == "not" && count == 2) { - n = n.nextSibling(); - TQDomElement e = n.toElement(); - impl->createTextElements(TQString(TQChar(0xAC)), base); - processElement(e, doc, base); - } - else if ( op.tagName() == "implies" && count == 3 ) { - n = n.nextSibling(); - TQDomElement e = n.toElement(); - processElement( e, doc, base ); - impl->createTextElements(TQString(TQChar(0x21D2)), base); - n = n.nextSibling(); - e = n.toElement(); - processElement( e, doc, base ); - } - // many, many more... - - } - - else if ( tag == "cn" ) { - type = CONTENT; - TQString type = element.attribute( "type", "real" ); - - if ( type == "real" || type == "constant" ) { - impl->createTextElements( element.text().stripWhiteSpace(), - docnode ); - } - else if ( type == "integer" ) { - TQString base = element.attribute( "base" ); - if ( !base ) { - impl->createTextElements( element.text().stripWhiteSpace(), - docnode ); - } - else { - TQDomElement index = doc.createElement( "INDEX" ); - TQDomElement content = doc.createElement( "CONTENT" ); - TQDomElement sequence = doc.createElement( "SEQUENCE" ); - impl->createTextElements( element.text().stripWhiteSpace(), - sequence ); - content.appendChild( sequence ); - index.appendChild( content ); - - TQDomElement lowerright = doc.createElement( "LOWERRIGHT" ); - sequence = doc.createElement( "SEQUENCE" ); - - impl->createTextElements( base, sequence ); - - lowerright.appendChild( sequence ); - index.appendChild( lowerright ); - - docnode.appendChild( index ); - } - } - else if ( type == "rational" ) { - TQDomNode n = element.firstChild(); - impl->createTextElements( n.toText().data().stripWhiteSpace(), - docnode ); - - n = n.nextSibling(); // - impl->createTextElements( "/", docnode ); - - n = n.nextSibling(); - impl->createTextElements( n.toText().data().stripWhiteSpace(), - docnode ); - } - else if ( type == "complex-cartesian" ) { - TQDomNode n = element.firstChild(); - impl->createTextElements( n.toText().data().stripWhiteSpace(), - docnode ); - - n = n.nextSibling(); // - impl->createTextElements( "+", docnode ); - - n = n.nextSibling(); - impl->createTextElements( n.toText().data().stripWhiteSpace(), - docnode ); - - impl->createTextElements( "i", docnode ); - } - - else if ( type == "complex-polar" ) { - TQDomNode n = element.firstChild(); - impl->createTextElements( n.toText().data().stripWhiteSpace(), - docnode ); - - n = n.nextSibling(); // - TQDomElement index = doc.createElement( "INDEX" ); - TQDomElement content = doc.createElement( "CONTENT" ); - TQDomElement sequence = doc.createElement( "SEQUENCE" ); - TQDomElement textelement = doc.createElement( "TEXT" ); - textelement.setAttribute( "CHAR", "e" ); - sequence.appendChild( textelement ); - content.appendChild( sequence ); - index.appendChild( content ); - - TQDomElement upperright = doc.createElement( "UPPERRIGHT" ); - sequence = doc.createElement( "SEQUENCE" ); - textelement = doc.createElement( "TEXT" ); - textelement.setAttribute( "CHAR", "i" ); - sequence.appendChild( textelement ); - - n = n.nextSibling(); - impl->createTextElements( n.toText().data().stripWhiteSpace(), - sequence ); - - upperright.appendChild( sequence ); - index.appendChild( upperright ); - - docnode.appendChild( index ); - } - } - - else if ( tag == "ci" ) { - type = CONTENT; - TQDomNode n = element.firstChild(); - - if ( n.isText() ) { - impl->createTextElements( n.toText().data().stripWhiteSpace(), - docnode ); - } - else if ( n.isElement() ) { - TQDomElement e = n.toElement(); - processElement( e, doc, docnode ); - } - else if ( n.isEntityReference() ) { - kdDebug( DEBUGID ) << "isEntityReference: " - << n.toEntityReference().nodeName().latin1() - << endl; - } - else - kdDebug( DEBUGID ) << "ci: " << n.nodeName().latin1() << endl; - } - - else if ( tag == "list" ) { - type = CONTENT; - TQDomNode n = element.firstChild(); - - TQDomElement bracket = doc.createElement( "BRACKET" ); - bracket.setAttribute( "LEFT", 91 ); // [ - bracket.setAttribute( "RIGHT", 93 ); // ] - TQDomElement content = doc.createElement( "CONTENT" ); - TQDomElement sequence = doc.createElement( "SEQUENCE" ); - - bool first = true; - - while ( !n.isNull() ) { - if ( n.isElement() ) { - if ( !first ) { - TQDomElement textelement = doc.createElement( "TEXT" ); - textelement.setAttribute( "CHAR", "," ); - sequence.appendChild( textelement ); - } - first = false; - TQDomElement e = n.toElement(); - processElement( e, doc, sequence ); - } - n = n.nextSibling(); - } - - content.appendChild( sequence ); - bracket.appendChild( content ); - docnode.appendChild( bracket ); - } - } - - if ( type == UNKNOWN && node.nodeType() != TQDomNode::AttributeNode ) { - kdDebug() << "Not an element: " << node.nodeName() << endl; - TQDomNode n = node.firstChild(); - while ( !n.isNull() ) { - processElement( n, doc, docnode ); - n = n.nextSibling(); - } - } - - return true; -} - -KFORMULA_NAMESPACE_END - -using namespace KFormula; -#include "kformulamathmlread.moc" diff --git a/lib/kformula/kformulamathmlread.cpp b/lib/kformula/kformulamathmlread.cpp new file mode 100644 index 00000000..ff941d6f --- /dev/null +++ b/lib/kformula/kformulamathmlread.cpp @@ -0,0 +1,1794 @@ +/* This file is part of the KDE project + Copyright (C) 2001 Andrea Rizzi + Ulrich Kuettler + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include + +#include +#include + +//#include + +#include "kformulamathmlread.h" +#include "symboltable.h" + +KFORMULA_NAMESPACE_BEGIN +using namespace std; + +class MathML2KFormulaPrivate +{ + friend class MathML2KFormula; + +public: + MathML2KFormulaPrivate( MathML2KFormula* mml_filter, + const ContextStyle& contextStyle, + const TQDomDocument& formuladoc ); + ~MathML2KFormulaPrivate(); + + void math( TQDomElement element ); + + // Token Elements + void mi( TQDomElement element, TQDomNode docnode ); + void mn( TQDomElement element, TQDomNode docnode ); + void mo( TQDomElement element, TQDomNode docnode ); + void mtext( TQDomElement element, TQDomNode docnode ); + void mspace( TQDomElement element, TQDomNode docnode ); + void ms( TQDomElement element, TQDomNode docnode ); + // mglyph not supported + + // General Layout Schemata + void mrow( TQDomElement element, TQDomNode docnode ); + void mfrac( TQDomElement element, TQDomNode docnode ); + void msqrt( TQDomElement element, TQDomNode docnode ); + void mroot( TQDomElement element, TQDomNode docnode ); + void mstyle( TQDomElement element, TQDomNode docnode ); + // merror not supported + // mpadded not supported + // mphantom not supported + void mfenced( TQDomElement element, TQDomNode docnode ); + // menclose not supported + + // Script and Limit Schemata + void msub_msup( TQDomElement element, TQDomNode docnode ); + void msubsup( TQDomElement element, TQDomNode docnode ); + void munder( TQDomElement element, TQDomNode docnode, bool oasisFormat ); + void mover( TQDomElement element, TQDomNode docnode, bool oasisFormat ); + void munderover( TQDomElement element, TQDomNode docnode, bool oasisFormat ); + // mmultiscripts not supported + + // Tables and Matrices + void mtable( TQDomElement element, TQDomNode docnode ); + // not much supported + + // Enlivening Expressions + // maction not supported + +protected: + void createTextElements( TQString text, TQDomNode docnode ); + void createNameSequence( TQString text, TQDomNode docnode ); + double convertToPoint( TQString value, bool* ok ); + bool isEmbellishedOperator( TQDomNode node, TQDomElement* mo, bool oasisFormat ); + bool isSpaceLike( TQDomNode node, bool oasisFormat ); + + enum MathVariant { + normal, + bold, + italic, + bold_italic, + double_struck, + bold_fraktur, + script, + bold_script, + fraktur, + sans_serif, + bold_sans_serif, + sans_serif_italic, + sans_serif_bold_italic, + monospace + }; + + struct MathStyle { + MathStyle() + : scriptsizemultiplier( 0.71 ), + scriptminsize( 8 ), + veryverythinmathspace( 1.0/18.0 ), + verythinmathspace( 2.0/18.0 ), + thinmathspace( 3.0/18.0 ), + mediummathspace( 4.0/18.0 ), + thickmathspace( 5.0/18.0 ), + verythickmathspace( 6.0/18.0 ), + veryverythickmathspace( 7.0/18.0 ), + + useVariant( false ) + { + } + + void styleChange() + { + kdDebug( DEBUGID ) << "Style Change:" + << "\n scriptlevel = " << scriptlevel + << "\n displaystyle = " << displaystyle + << "\n scriptsizemultiplier = " + << scriptsizemultiplier + << "\n scriptminsize = " << scriptminsize + << endl; + } + + void setStyles( TQDomElement element ) + { + if ( !useVariant ) + return; + + switch ( mathvariant ) + { + case normal: + element.setAttribute( "STYLE", "normal" ); + break; + case bold: + element.setAttribute( "STYLE", "bold" ); + break; + + case bold_italic: + element.setAttribute( "STYLE", "bolditalic" ); + break; + case italic: + element.setAttribute( "STYLE", "italic" ); + break; + + case double_struck: + element.setAttribute( "FAMILY", "doublestruck" ); + break; + + case bold_fraktur: + element.setAttribute( "STYLE", "bold" ); + case fraktur: + element.setAttribute( "FAMILY", "fraktur" ); + break; + + case bold_script: + element.setAttribute( "STYLE", "bold" ); + case script: + element.setAttribute( "FAMILY", "script" ); + break; + + case bold_sans_serif: + element.setAttribute( "STYLE", "bold" ); + case sans_serif: + element.setAttribute( "FAMILY", "normal" ); + break; + case sans_serif_bold_italic: + element.setAttribute( "STYLE", "bolditalic" ); + element.setAttribute( "FAMILY", "normal" ); + break; + case sans_serif_italic: + element.setAttribute( "STYLE", "italic" ); + element.setAttribute( "FAMILY", "normal" ); + break; + + //case monospace: + default: + break; + } + } + + void readStyles( TQDomElement mmlElement ) + { + if ( mmlElement.hasAttribute( "mathvariant" ) ) + { + useVariant = true; + + if ( mmlElement.attribute( "mathvariant" ) == "normal" ) + mathvariant = normal; + else if ( mmlElement.attribute( "mathvariant" ) == "bold" ) + mathvariant = bold; + else if ( mmlElement.attribute( "mathvariant" ) == "italic" ) + mathvariant = italic; + else if ( mmlElement.attribute( "mathvariant" ) == "bold-italic" ) + mathvariant = bold_italic; + else if ( mmlElement.attribute( "mathvariant" ) == "double-struck" ) + mathvariant = double_struck; + else if ( mmlElement.attribute( "mathvariant" ) == "bold-fraktur" ) + mathvariant = bold_fraktur; + else if ( mmlElement.attribute( "mathvariant" ) == "script" ) + mathvariant = script; + else if ( mmlElement.attribute( "mathvariant" ) == "bold-script" ) + mathvariant = bold_script; + else if ( mmlElement.attribute( "mathvariant" ) == "fraktur" ) + mathvariant = fraktur; + else if ( mmlElement.attribute( "mathvariant" ) == "sans-serif" ) + mathvariant = sans_serif; + else if ( mmlElement.attribute( "mathvariant" ) == "bold-sans-serif" ) + mathvariant = bold_sans_serif; + else if ( mmlElement.attribute( "mathvariant" ) == "sans-serif-italic" ) + mathvariant = sans_serif_italic; + else if ( mmlElement.attribute( "mathvariant" ) == "sans-serif-bold-italic" ) + mathvariant = sans_serif_bold_italic; + else if ( mmlElement.attribute( "mathvariant" ) == "monospace" ) + mathvariant = monospace; + } + } + + // Styles, set by // default + + int scriptlevel; // inherited + bool displaystyle; // inherited + double scriptsizemultiplier; // 0.71 + double scriptminsize; // 8pt + // color + // background + double veryverythinmathspace; // 1/18em = 0.0555556em + double verythinmathspace; // 2/18em = 0.111111em + double thinmathspace; // 3/18em = 0.166667em + double mediummathspace; // 4/18em = 0.222222em + double thickmathspace; // 5/18em = 0.277778em + double verythickmathspace; // 6/18em = 0.333333em + double veryverythickmathspace; // 7/18em = 0.388889em + + // 'Local' styles + + MathVariant mathvariant; + bool useVariant; + //int mathsize; + }; + + MathStyle style; + TQDomDocument doc; + +private: + const ContextStyle& context; + MathML2KFormula* filter; +}; + +MathML2KFormulaPrivate::MathML2KFormulaPrivate( MathML2KFormula* mml_filter, const ContextStyle& cs, const TQDomDocument& formuladoc ) + : doc( formuladoc ), context( cs ), filter( mml_filter ) +{ +} + +MathML2KFormulaPrivate::~MathML2KFormulaPrivate() +{ +} + +void MathML2KFormulaPrivate::math( TQDomElement element ) +{ + TQDomElement formula = doc.createElement( "FORMULA" ); + TQDomNode n = element.firstChild(); + + TQString display = element.attribute( "display" ); + + if ( display == "block" ) { + style.displaystyle = true; + } + else { + // if display == "inline" (default) or illegal (then use default) + style.displaystyle = false; + } + + style.scriptlevel = 0; + + /*kdDebug( DEBUGID ) << " element:\n displaystyle = " + << style.displaystyle << "\n scriptlevel = " + << style.scriptlevel << endl;*/ + + while ( !n.isNull() ) { + filter->processElement( n, doc, formula ); + n = n.nextSibling(); + } + + doc.appendChild( formula ); +} + +void MathML2KFormulaPrivate::mi( TQDomElement element, TQDomNode docnode ) +{ + MathStyle previousStyle( style ); + TQString text = element.text().stripWhiteSpace(); + if ( text.length() == 1 ) { // Default italic, only when content is one char + style.mathvariant = italic; + style.useVariant = true; + style.readStyles( element ); + createTextElements( text, docnode ); + } else { // If length is 0 or >1, it should be a text sequence + style.readStyles( element ); + createNameSequence( text, docnode ); + } + style = previousStyle; +} + +void MathML2KFormulaPrivate::mo( TQDomElement element, TQDomNode docnode ) +{ + MathStyle previousStyle( style ); + style.readStyles( element ); + + TQString text = element.text().stripWhiteSpace(); + createTextElements( text, docnode ); + + style = previousStyle; +} + +void MathML2KFormulaPrivate::mn( TQDomElement element, TQDomNode docnode ) +{ + MathStyle previousStyle( style ); + style.readStyles( element ); + + TQString text = element.text().stripWhiteSpace(); + createTextElements( text, docnode ); + + style = previousStyle; +} + +void MathML2KFormulaPrivate::mtext( TQDomElement element, TQDomNode docnode ) +{ + MathStyle previousStyle( style ); + style.readStyles( element ); + + TQDomNode n = element.firstChild(); + + while ( !n.isNull() ) { + if ( n.isText() ) { + TQString text = n.toText().data().stripWhiteSpace(); + createTextElements( text, docnode ); + } + else if ( n.isElement() ) { + filter->processElement( n, doc, docnode ); + } + else { + kdDebug( DEBUGID ) << " child: " << n.nodeName() << endl; + } + + n = n.nextSibling(); + } + + style = previousStyle; +} + +void MathML2KFormulaPrivate::ms( TQDomElement element, TQDomNode docnode ) +{ + TQString lquote = element.attribute( "lquote", "\"" ); + TQString rquote = element.attribute( "rquote", "\"" ); + TQString text; + + text = lquote; + text += element.text().stripWhiteSpace(); + text += rquote; + + createTextElements( text, docnode ); +} + +void MathML2KFormulaPrivate::mspace( TQDomElement element, TQDomNode docnode ) +{ + // we support only horizontal space + TQString width = element.attribute( "width" ); + + TQDomElement spaceelement = doc.createElement( "SPACE" ); + + // check for namedspace. We don't support much... + if ( width == "veryverythinmathspace" ) { + spaceelement.setAttribute( "WIDTH", "thin" ); + } + else if ( width == "verythinmathspace" ) { + spaceelement.setAttribute( "WIDTH", "thin" ); + } + else if ( width == "thinmathspace" ) { + spaceelement.setAttribute( "WIDTH", "thin" ); + } + else if ( width == "mediummathspace" ) { + spaceelement.setAttribute( "WIDTH", "medium" ); + } + else if ( width == "thickmathspace" ) { + spaceelement.setAttribute( "WIDTH", "thick" ); + } + else if ( width == "verythickmathspace" ) { + spaceelement.setAttribute( "WIDTH", "thick" ); + } + else if ( width == "veryverythickmathspace" ) { + spaceelement.setAttribute( "WIDTH", "quad" ); + } + + else { + // units + + double w = 0; + bool ok; + + if ( width.endsWith( "em" ) ) { + // See MathML specification, Appendix H + w = context.getDefaultFont().pointSize(); + if ( w == -1 ) { + TQFontMetrics fm( context.getDefaultFont() ); + w = fm.width( 'm' ); + } + w = w * width.remove( width.length() - 2, 2 ).toDouble( &ok ); + // w in points? + } + else if ( width.endsWith( "px" ) ) { + w = width.remove( width.length() - 2, 2 ).toDouble( &ok ); + // w in pixels + } + else if ( width.endsWith( "in" ) ) { + w = width.remove( width.length() - 2, 2 ).toDouble( &ok ); + w *= 72; // w in points + } + else if ( width.endsWith( "cm" ) ) { + w = width.remove( width.length() - 2, 2 ).toDouble( &ok ); + w *= 1/2.54 * 72; // w in points + } + else if ( width.endsWith( "mm" ) ) { + w = width.remove( width.length() - 2, 2 ).toDouble( &ok ); + w *= 1/25.4 * 72; // w in points + } + else if ( width.endsWith( "pt" ) ) { + w = width.remove( width.length() - 2, 2 ).toDouble( &ok ); + // w in points + } + else if ( width.endsWith( "pc" ) ) { + w = width.remove( width.length() - 2, 2 ).toDouble( &ok ); + w /= 12; // w in points + } + else { + w = width.toDouble( &ok ); + } + + if ( !ok ) + return; + + if ( w < 20 ) + spaceelement.setAttribute( "WIDTH", "thin" ); + else if ( w < 40 ) + spaceelement.setAttribute( "WIDTH", "medium" ); + else if ( w < 80 ) + spaceelement.setAttribute( "WIDTH", "thick" ); + else + spaceelement.setAttribute( "WIDTH", "quad" ); + } + + docnode.appendChild( spaceelement ); +} + +void MathML2KFormulaPrivate::mrow( TQDomElement element, TQDomNode docnode ) +{ + TQDomNode n = element.firstChild(); + while ( !n.isNull() ) { + if ( n.isElement () ) { + TQDomElement e = n.toElement(); + // We do not allow sequence inside sequence + filter->processElement( e, doc, docnode ); + } + else { + kdDebug( DEBUGID ) << " child: " << n.nodeName() << endl; + } + n = n.nextSibling(); + } +} + +void MathML2KFormulaPrivate::mfrac( TQDomElement element, TQDomNode docnode ) +{ + TQDomNode n = element.firstChild(); + TQDomElement fraction = doc.createElement( "FRACTION" ); + + MathStyle previousStyle( style ); + style.displaystyle ? style.displaystyle = false : style.scriptlevel += 1; + style.styleChange(); + + int i = 0; + while ( !n.isNull() && i < 2 ) { + if ( n.isElement() ) { + ++i; + if ( i == 1 ) { //first is numerator + TQDomElement numerator = + doc.createElement( "NUMERATOR" ); + TQDomElement sequence = doc.createElement( "SEQUENCE" ); + numerator.appendChild( sequence ); + TQDomElement e = n.toElement(); + filter->processElement( e, doc, sequence ); + fraction.appendChild( numerator ); + + } + else { + TQDomElement denominator = + doc.createElement( "DENOMINATOR" ); + TQDomElement sequence = doc.createElement( "SEQUENCE" ); + denominator.appendChild( sequence ); + TQDomElement e = n.toElement(); + filter->processElement( e, doc, sequence ); + fraction.appendChild( denominator ); + + } + } + else { + kdDebug( DEBUGID ) << " child: " << n.nodeName() << endl; + } + n = n.nextSibling(); + } + + style = previousStyle; + docnode.appendChild( fraction ); +} + +void MathML2KFormulaPrivate::mroot( TQDomElement element, TQDomNode docnode ) +{ + TQDomNode n = element.firstChild(); + int i = 0; + TQDomElement root = doc.createElement( "ROOT" ); + + while ( !n.isNull() && i < 2 ) { + if ( n.isElement() ) { + ++i; + if ( i == 1 ) { //first is content (base) + TQDomElement content = doc.createElement( "CONTENT" ); + TQDomElement sequence = doc.createElement( "SEQUENCE" ); + content.appendChild( sequence ); + TQDomElement e = n.toElement(); + filter->processElement( e, doc, sequence ); + + root.appendChild(content); + } + else { // index + MathStyle previousStyle( style ); + style.scriptlevel += 2; + style.displaystyle = false; + style.styleChange(); + + TQDomElement index = doc.createElement( "INDEX" ); + TQDomElement sequence = doc.createElement( "SEQUENCE" ); + index.appendChild( sequence ); + TQDomElement e = n.toElement(); + filter->processElement( e, doc, sequence ); + root.appendChild( index ); + + style = previousStyle; + } + } + else { + kdDebug( DEBUGID ) << " child: " << n.nodeName() << endl; + } + n = n.nextSibling(); + } + docnode.appendChild( root ); +} + +void MathML2KFormulaPrivate::msqrt( TQDomElement element, TQDomNode docnode ) +{ + TQDomNode n = element.firstChild(); + TQDomElement root = doc.createElement( "ROOT" ); + + TQDomElement content = doc.createElement( "CONTENT" ); + TQDomElement sequence = doc.createElement( "SEQUENCE" ); + content.appendChild( sequence ); + root.appendChild( content ); + + while ( !n.isNull() ) { + if ( n.isElement() ) { + filter->processElement( n.toElement(), doc, sequence ); + } + else { + kdDebug( DEBUGID ) << " child: " << n.nodeName() << endl; + } + n = n.nextSibling(); + } + + docnode.appendChild( root ); +} + +void MathML2KFormulaPrivate::mstyle( TQDomElement element, TQDomNode docnode ) +{ + bool ok; + + MathStyle previousStyle( style ); + style.readStyles( element ); + + if ( element.hasAttribute( "scriptlevel" ) ) { + TQString scriptlevel = element.attribute( "scriptlevel" ); + if ( scriptlevel.startsWith( "+" ) || scriptlevel.startsWith( "-" ) ) + style.scriptlevel += scriptlevel.toInt( &ok ); + else + style.scriptlevel = scriptlevel.toInt( &ok ); + if ( !ok ) + style.scriptlevel = previousStyle.scriptlevel; + } + if ( element.hasAttribute( "displaystyle" ) ) { + TQString displaystyle = element.attribute( "displaystyle" ); + if ( displaystyle == "true" ) + style.displaystyle = true; + else if ( displaystyle == "false" ) + style.displaystyle = false; + } + if ( element.hasAttribute( "scriptsizemultiplier" ) ) { + style.scriptsizemultiplier = + element.attribute( "scriptsizemultiplier" ).toDouble( &ok ); + if ( !ok ) + style.scriptsizemultiplier = previousStyle.scriptsizemultiplier; + } + if ( element.hasAttribute( "scriptminsize" ) ) { + TQString scriptminsize = element.attribute( "scriptminsize" ); + style.scriptminsize = convertToPoint( scriptminsize, &ok ); + if ( !ok ) + style.scriptminsize = previousStyle.scriptminsize; + } + + if ( element.hasAttribute( "veryverythinmathspace" ) ) { + TQString vvthinmspace = element.attribute( "veryverythinmathspace" ); + style.veryverythinmathspace = convertToPoint( vvthinmspace, &ok ); + if ( !ok ) + style.veryverythinmathspace = previousStyle.veryverythinmathspace; + } + if ( element.hasAttribute( "verythinmathspace" ) ) { + TQString vthinmspace = element.attribute( "verythinmathspace" ); + style.verythinmathspace = convertToPoint( vthinmspace, &ok ); + if ( !ok ) + style.verythinmathspace = previousStyle.verythinmathspace; + } + if ( element.hasAttribute( "thinmathspace" ) ) { + TQString thinmathspace = element.attribute( "thinmathspace" ); + style.thinmathspace = convertToPoint( thinmathspace, &ok ); + if ( !ok ) + style.thinmathspace = previousStyle.thinmathspace; + } + if ( element.hasAttribute( "mediummathspace" ) ) { + TQString mediummathspace = element.attribute( "mediummathspace" ); + style.mediummathspace = convertToPoint( mediummathspace, &ok ); + if ( !ok ) + style.mediummathspace = previousStyle.mediummathspace; + } + if ( element.hasAttribute( "thickmathspace" ) ) { + TQString thickmathspace = element.attribute( "thickmathspace" ); + style.thickmathspace = convertToPoint( thickmathspace, &ok ); + if ( !ok ) + style.thickmathspace = previousStyle.thickmathspace; + } + if ( element.hasAttribute( "verythickmathspace" ) ) { + TQString vthickmspace = element.attribute( "verythickmathspace" ); + style.verythickmathspace = convertToPoint( vthickmspace, &ok ); + if ( !ok ) + style.verythickmathspace = previousStyle.verythickmathspace; + } + if ( element.hasAttribute( "veryverythickmathspace" ) ) { + TQString vvthickmspace = element.attribute( "veryverythickmathspace" ); + style.veryverythickmathspace = convertToPoint( vvthickmspace, &ok ); + if ( !ok ) + style.veryverythickmathspace = + previousStyle.veryverythickmathspace; + } + + style.styleChange(); + + TQDomNode n = element.firstChild(); + while ( !n.isNull() ) { + filter->processElement( n, doc, docnode ); + n = n.nextSibling(); + } + + style = previousStyle; +} + +void MathML2KFormulaPrivate::mfenced( TQDomElement element, TQDomNode docnode ) +{ + TQDomElement bracket = doc.createElement( "BRACKET" ); + TQString value = element.attribute( "open", "(" ); + bracket.setAttribute( "LEFT", TQString::number( value.at( 0 ).latin1() ) ); + value = element.attribute( "close", ")" ); + bracket.setAttribute( "RIGHT", TQString::number( value.at( 0 ).latin1() ) ); + + TQDomElement content = doc.createElement( "CONTENT" ); + TQDomElement sequence = doc.createElement( "SEQUENCE" ); + content.appendChild( sequence ); + + TQString separators = element.attribute( "separators", "," ); + + TQDomNode n = element.firstChild(); + uint i = 0; + while ( !n.isNull() ) { + if ( n.isElement() ) { + if ( i != 0 && !separators.isEmpty() ) { + TQDomElement textelement = doc.createElement( "TEXT" ); + if ( i > separators.length() ) + i = separators.length(); + textelement.setAttribute( "CHAR", TQString( separators.at( i - 1 ) ) ); + //style.setStyles( textelement ); + sequence.appendChild( textelement ); + } + ++i; + TQDomElement e = n.toElement(); + filter->processElement( e, doc, sequence ); + } + else { + kdDebug( DEBUGID ) << " child: " << n.nodeName() << endl; + } + n = n.nextSibling(); + } + bracket.appendChild( content ); + docnode.appendChild( bracket ); +} + +void MathML2KFormulaPrivate::mtable( TQDomElement element, TQDomNode docnode ) +{ + MathStyle previousStyle( style ); + TQString displaystyle = element.attribute( "displaystyle", "false" ); + if ( displaystyle == "true" ) { + style.displaystyle = true; + } + else { + // false is default and also used for illegal values + style.displaystyle = false; + } + style.styleChange(); + + TQString subtag; + int rows = 0; int cols = 0; + TQDomNode n = element.firstChild(); + + while ( !n.isNull() ) { + if ( n.isElement() ) { + TQDomElement e = n.toElement(); + subtag = e.tagName(); + if (subtag == "mtr") + { + ++rows; + + /* Determins the number of columns */ + + TQDomNode cellnode = e.firstChild(); + int cc = 0; + + while ( !cellnode.isNull() ) { + if ( cellnode.isElement() ) + cc++; + cellnode = cellnode.nextSibling(); + } + + if ( cc > cols ) + cols = cc; + + } + } + else { + kdDebug( DEBUGID ) << " child: " << n.nodeName() << endl; + } + n = n.nextSibling(); + } + + /* Again createing elements, I need to know the number + of rows and cols to leave empty spaces */ + + n = element.firstChild(); + TQDomElement matrix = doc.createElement( "MATRIX" ); + matrix.setAttribute( "COLUMNS", cols ); + matrix.setAttribute( "ROWS", rows ); + + while ( !n.isNull() ) { + if ( n.isElement() ) { + TQDomElement e = n.toElement(); + subtag = e.tagName(); + if ( subtag == "mtr" ) { + TQDomNode cellnode = e.firstChild(); + int cc = 0; + while ( !cellnode.isNull() ) { + if ( cellnode.isElement() ) { + ++cc; + TQDomElement cell = doc.createElement( "SEQUENCE" ); + TQDomElement cellelement = cellnode.toElement(); + filter->processElement( cellelement, doc, cell ); + matrix.appendChild( cell ); + } + cellnode = cellnode.nextSibling(); + } + + /* Add empty elements */ + for(; cc < cols; cc++ ) { + TQDomElement cell = doc.createElement( "SEQUENCE" ); + matrix.appendChild( cell ); + } + } + } + n = n.nextSibling(); + } + + style = previousStyle; + docnode.appendChild(matrix); +} + +void MathML2KFormulaPrivate::msub_msup( TQDomElement element, TQDomNode docnode ) +{ + TQDomNode n = element.firstChild(); + int i = 0; + TQDomElement root = doc.createElement( "INDEX" ); + + while ( !n.isNull() && i < 2 ) { + if ( n.isElement() ) { + ++i; + if ( i == 1 ) { // first is content (base) + TQDomElement content = doc.createElement( "CONTENT" ); + TQDomElement sequence = doc.createElement( "SEQUENCE" ); + content.appendChild( sequence ); + TQDomElement e = n.toElement(); + filter->processElement( e, doc, sequence ); + + root.appendChild( content ); + } + else { + TQDomElement index; + if ( element.tagName() == "msup" ) + index = doc.createElement( "UPPERRIGHT" ); + else + index = doc.createElement( "LOWERRIGHT" ); + + MathStyle previousStyle( style ); + style.scriptlevel += 1; + style.displaystyle = false; + style.styleChange(); + + TQDomElement sequence = doc.createElement( "SEQUENCE" ); + index.appendChild( sequence ); + TQDomElement e = n.toElement(); + filter->processElement( e, doc, sequence ); + root.appendChild( index ); + + style = previousStyle; + } + } + else { + kdDebug( DEBUGID ) << "<" << element.tagName() << "> child: " + << n.nodeName() << endl; + } + n = n.nextSibling(); + } + docnode.appendChild( root ); +} + +void MathML2KFormulaPrivate::munder( TQDomElement element, TQDomNode docnode, bool oasisFormat ) +{ + bool accentunder; + + TQString au = element.attribute( "accentunder" ); + if ( au == "true" ) + accentunder = true; + else if ( au == "false" ) + accentunder = false; + else { + // use default + + TQDomElement mo; + // is underscript an embellished operator? + if ( isEmbellishedOperator( element.childNodes().item( 1 ), &mo, oasisFormat ) ) { + if ( mo.attribute( "accent" ) == "true" ) + accentunder = true; + else + accentunder = false; + } + else + accentunder = false; + } + + TQDomNode n = element.firstChild(); + int i = 0; + TQDomElement root = doc.createElement( "INDEX" ); + + while ( !n.isNull() && i < 2 ) { + if ( n.isElement() ) { + ++i; + if ( i == 1 ) { // first is content (base) + TQDomElement content = doc.createElement( "CONTENT" ); + TQDomElement sequence = doc.createElement( "SEQUENCE" ); + content.appendChild( sequence ); + TQDomElement e = n.toElement(); + filter->processElement( e, doc, sequence ); + + root.appendChild( content ); + } + else { // underscript + MathStyle previousStyle( style ); + style.displaystyle = false; + if ( !accentunder ) { + style.scriptlevel += 1; + style.styleChange(); + } + + TQDomElement mo; TQDomElement index; + if ( isEmbellishedOperator( n.previousSibling(), &mo, oasisFormat ) && + !previousStyle.displaystyle && + mo.attribute( "movablelimits" ) == "true" ) + { + index = doc.createElement( "LOWERRIGHT" ); + } + else { + index = doc.createElement( "LOWERMIDDLE" ); + } + + TQDomElement sequence = doc.createElement( "SEQUENCE" ); + index.appendChild( sequence ); + TQDomElement e = n.toElement(); + filter->processElement( e, doc, sequence ); + root.appendChild( index ); + + style = previousStyle; + } + } + else { + kdDebug( DEBUGID ) << "<" << element.tagName() << "> child: " + << n.nodeName() << endl; + } + n = n.nextSibling(); + } + + docnode.appendChild( root ); +} + +void MathML2KFormulaPrivate::mover( TQDomElement element, TQDomNode docnode, bool oasisFormat ) +{ + bool accent; + + TQString ac = element.attribute( "accent" ); + if ( ac == "true" ) + accent = true; + else if ( ac == "false" ) + accent = false; + else { + // use default + + TQDomElement mo; + // is overscript an embellished operator? + if ( isEmbellishedOperator( element.childNodes().item( 1 ), &mo, oasisFormat ) ) { + if ( mo.attribute( "accent" ) == "true" ) + accent = true; + else + accent = false; + } + else + accent = false; + } + + TQDomNode n = element.firstChild(); + int i = 0; + TQDomElement root = doc.createElement( "INDEX" ); + + while ( !n.isNull() && i < 2 ) { + if ( n.isElement() ) { + ++i; + if ( i == 1 ) { // first is content (base) + TQDomElement content = doc.createElement( "CONTENT" ); + TQDomElement sequence = doc.createElement( "SEQUENCE" ); + content.appendChild( sequence ); + TQDomElement e = n.toElement(); + filter->processElement( e, doc, sequence ); + + root.appendChild( content ); + } + else { // overscript + MathStyle previousStyle( style ); + style.displaystyle = false; + if ( !accent ) { + style.scriptlevel += 1; + style.styleChange(); + } + + TQDomElement mo; TQDomElement index; + if ( isEmbellishedOperator( n.previousSibling(), &mo, oasisFormat ) && + !previousStyle.displaystyle && + mo.attribute( "movablelimits" ) == "true" ) + { + index = doc.createElement( "UPPERRIGHT" ); + } + else { + index = doc.createElement( "UPPERMIDDLE" ); + } + + TQDomElement sequence = doc.createElement( "SEQUENCE" ); + index.appendChild( sequence ); + TQDomElement e = n.toElement(); + filter->processElement( e, doc, sequence ); + root.appendChild( index ); + + style = previousStyle; + } + } + else { + kdDebug( DEBUGID ) << "<" << element.tagName() << "> child: " + << n.nodeName() << endl; + } + n = n.nextSibling(); + } + + docnode.appendChild( root ); +} + +void MathML2KFormulaPrivate::munderover( TQDomElement element, TQDomNode docnode, bool oasisFormat ) +{ + bool accent; + bool accentunder; + + TQString value = element.attribute( "accentunder" ); + if ( value == "true" ) + accentunder = true; + else if ( value == "false" ) + accentunder = false; + else { + // use default + + TQDomElement mo; + // is underscript an embellished operator? + if ( isEmbellishedOperator( element.childNodes().item( 1 ), &mo, oasisFormat ) ) { + if ( mo.attribute( "accent" ) == "true" ) + accentunder = true; + else + accentunder = false; + } + else + accentunder = false; + } + value = element.attribute( "accent" ); + if ( value == "true" ) + accent = true; + else if ( value == "false" ) + accent = false; + else { + // use default + + TQDomElement mo; + // is overscript an embellished operator? + if ( isEmbellishedOperator( element.childNodes().item( 2 ), &mo,oasisFormat ) ) { + kdDebug( DEBUGID ) << "embellished operator" << endl; + if ( mo.attribute( "accent" ) == "true" ) + accent = true; + else + accent = false; + } + else + accent = false; + } + kdDebug( DEBUGID ) << "munderover:\n accentunder = " << accentunder + << "\n accent = " << accent << endl; + + TQDomNode n = element.firstChild(); + int i = 0; + TQDomElement root = doc.createElement( "INDEX" ); + + while ( !n.isNull() && i < 3 ) { + if ( n.isElement() ) { + ++i; + if ( i == 1 ) { // base + TQDomElement content = doc.createElement( "CONTENT" ); + TQDomElement sequence = doc.createElement( "SEQUENCE" ); + content.appendChild( sequence ); + TQDomElement e = n.toElement(); + filter->processElement( e, doc, sequence ); + + root.appendChild( content ); + } + else if ( i == 2 ) { // underscript + MathStyle previousStyle( style ); + style.displaystyle = false; + if ( !accentunder ) { + style.scriptlevel += 1; + style.styleChange(); + } + + TQDomElement mo; TQDomElement index; + // is the base an embellished operator? + if ( isEmbellishedOperator( element.firstChild(), &mo, oasisFormat ) && + !previousStyle.displaystyle && + mo.attribute( "movablelimits" ) == "true" ) + { + index = doc.createElement( "LOWERRIGHT" ); + } + else { + index = doc.createElement( "LOWERMIDDLE" ); + } + + TQDomElement sequence = doc.createElement( "SEQUENCE" ); + index.appendChild( sequence ); + TQDomElement e = n.toElement(); + filter->processElement( e, doc, sequence ); + root.appendChild( index ); + + style = previousStyle; + } + else { // overscript + MathStyle previousStyle( style ); + style.displaystyle = false; + if ( !accent ) { + style.scriptlevel += 1; + style.styleChange(); + } + + TQDomElement mo; TQDomElement index; + if ( isEmbellishedOperator( element.firstChild(), &mo, oasisFormat ) && + !previousStyle.displaystyle && + mo.attribute( "movablelimits" ) == "true" ) + { + index = doc.createElement( "UPPERRIGHT" ); + } + else { + index = doc.createElement( "UPPERMIDDLE" ); + } + + TQDomElement sequence = doc.createElement( "SEQUENCE" ); + index.appendChild( sequence ); + TQDomElement e = n.toElement(); + filter->processElement( e, doc, sequence ); + root.appendChild( index ); + + style = previousStyle; + } + } + else { + kdDebug( DEBUGID ) << "<" << element.tagName() << "> child: " + << n.nodeName() << endl; + } + n = n.nextSibling(); + } + + docnode.appendChild( root ); +} + +void MathML2KFormulaPrivate::msubsup( TQDomElement element, TQDomNode docnode ) +{ + TQDomNode n = element.firstChild(); + int i = 0; + TQDomElement root = doc.createElement("INDEX"); + MathStyle previousStyle( style ); + + while ( !n.isNull() && i < 2 ) { + if ( n.isElement() ) { + ++i; + if ( i == 1 ) { // base + TQDomElement content = doc.createElement( "CONTENT" ); + TQDomElement sequence = doc.createElement( "SEQUENCE" ); + content.appendChild( sequence ); + TQDomElement e = n.toElement(); + filter->processElement( e, doc, sequence ); + + root.appendChild( content ); + } + else if ( i == 2 ) { // subscript + style.scriptlevel += 1; + style.displaystyle = false; + style.styleChange(); + + TQDomElement index; + index = doc.createElement( "LOWERRIGHT" ); + + TQDomElement sequence = doc.createElement( "SEQUENCE" ); + index.appendChild( sequence ); + TQDomElement e = n.toElement(); + filter->processElement( e, doc, sequence ); + root.appendChild( index ); + } + else { // superscript + TQDomElement index; + index = doc.createElement( "UPPERRIGHT" ); + + TQDomElement sequence = doc.createElement( "SEQUENCE" ); + index.appendChild( sequence ); + TQDomElement e = n.toElement(); + filter->processElement( e, doc, sequence ); + root.appendChild( index ); + + style = previousStyle; + + } + } + else { + kdDebug( DEBUGID ) << " child: " << n.nodeName() << endl; + } + n = n.nextSibling(); + } + docnode.appendChild( root ); +} + +void MathML2KFormulaPrivate::createTextElements( TQString text, TQDomNode docnode ) +{ + for ( uint i = 0; i < text.length(); ++i ) { + TQDomElement textelement = doc.createElement( "TEXT" ); + textelement.setAttribute( "CHAR", TQString( text.at( i ) ) ); + style.setStyles( textelement ); + if ( context.symbolTable().inTable( text.at( i ) ) ) { + // The element is a symbol. + textelement.setAttribute( "SYMBOL", "3" ); + } + docnode.appendChild( textelement ); + } +} + +void MathML2KFormulaPrivate::createNameSequence( TQString text, TQDomNode docnode ) +{ + TQDomElement namesequence = doc.createElement( "NAMESEQUENCE" ); + for ( uint i = 0; i < text.length(); ++i ) { + TQDomElement textelement = doc.createElement( "TEXT" ); + textelement.setAttribute( "CHAR", TQString( text.at( i ) ) ); + style.setStyles( textelement ); + if ( context.symbolTable().inTable( text.at( i ) ) ) { + // The element is a symbol. + textelement.setAttribute( "SYMBOL", "3" ); + } + namesequence.appendChild( textelement ); + } + docnode.appendChild( namesequence ); +} + +double MathML2KFormulaPrivate::convertToPoint( TQString value, bool* ok ) +{ + double pt = 0; + + if ( value.endsWith( "em" ) ) { + // See MathML specification, Appendix H + pt = context.getDefaultFont().pointSize(); + if ( pt == -1 ) { + TQFontMetrics fm( context.getDefaultFont() ); + pt = fm.width( 'M' ); + // PIXELS! + } + pt = pt * value.remove( value.length() - 2, 2 ).toDouble( ok ); + } + else if ( value.endsWith( "ex" ) ) { + TQFontMetrics fm( context.getDefaultFont() ); + pt = fm.height(); + // PIXELS, and totally wrong! + } + else if ( value.endsWith( "px" ) ) { + pt = value.remove( value.length() - 2, 2 ).toDouble( ok ); + // PIXELS! + } + else if ( value.endsWith( "in" ) ) { + pt = value.remove( value.length() - 2, 2 ).toDouble( ok ); + pt *= 72; + } + else if ( value.endsWith( "cm" ) ) { + pt = value.remove( value.length() - 2, 2 ).toDouble( ok ); + pt *= 1/2.54 * 72; + } + else if ( value.endsWith( "mm" ) ) { + pt = value.remove( value.length() - 2, 2 ).toDouble( ok ); + pt *= 1/25.4 * 72; + } + else if ( value.endsWith( "pt" ) ) { + pt = value.remove( value.length() - 2, 2 ).toDouble( ok ); + } + else if ( value.endsWith( "pc" ) ) { + pt = value.remove( value.length() - 2, 2 ).toDouble( ok ); + pt /= 12; + } + else { + pt = value.toDouble( ok ); + } + + return pt; +} + +bool MathML2KFormulaPrivate::isEmbellishedOperator( TQDomNode node, + TQDomElement* mo, bool oasisFormat ) +{ + // See MathML 2.0 specification: 3.2.5.7 + + if ( !node.isElement() ) + return false; + + TQDomElement element = node.toElement(); + TQString tag = element.tagName(); + + if ( tag == "mo" ) + { + *mo = element; + return true; + } + if ( tag == "msub" || tag == "msup" || tag == "msubsup" || + tag == "munder" || tag == "mover" || tag == "munderover" || + tag == "mmultiscripts" || tag == "mfrac" || tag == "semantics" ) + { + return isEmbellishedOperator( element.firstChild(), mo,oasisFormat ); + } + if ( tag == "maction" ) + { + return false; // not supported + } + if ( tag == "mrow" || tag == "mstyle" || tag == "mphantom" || tag == "mpadded" ) { + TQDomNode n = element.firstChild(); + int i = 0; + + while ( !n.isNull() ) { + if ( isEmbellishedOperator( n, mo,oasisFormat ) ) { + if ( ++i > 1 ) // one (only one) embellished operator + return false; + } + else if ( !isSpaceLike( n, oasisFormat ) ) { // zero or more space-like elements + return false; + } + n = n.nextSibling(); + } + return ( i == 1 ); + } + return false; +} + +bool MathML2KFormulaPrivate::isSpaceLike( TQDomNode node, bool oasisFormat ) +{ + // See MathML 2.0 specification: 3.2.7.3 + + if ( !node.isElement() ) + return false; + + TQDomElement element = node.toElement(); + TQString tag = element.tagName(); + + if ( tag == "mtext" || tag == "mspace" || + tag == "maligngroup" || tag == "malignmark" ) { + return true; + } + if ( tag == "mstyle" || tag == "mphantom" || tag == "mpadded" || tag == "mrow" ) { + TQDomNode n = element.firstChild(); + while ( !n.isNull() ) { + if ( isSpaceLike( n,oasisFormat ) ) + n = n.nextSibling(); + else + return false; + } + return true; + } + if ( tag == "maction" ) { + return false; // not supported + } + + return false; +} + + +MathML2KFormula::MathML2KFormula( const TQDomDocument& mmldoc, const ContextStyle &contextStyle, bool _oasisFormat ) + : m_error( false ), oasisFormat( _oasisFormat ), context( contextStyle ) +{ + orig_element = mmldoc.documentElement(); + done = false; +} + +MathML2KFormula::MathML2KFormula( const TQDomElement& mmlelm, const ContextStyle &contextStyle, bool _oasisFormat ) + : m_error( false ), orig_element( mmlelm ), oasisFormat( _oasisFormat ), context( contextStyle ) +{ + done = false; +} + +TQDomDocument MathML2KFormula::getKFormulaDom() +{ + return formuladoc; +} + + + +void MathML2KFormula::startConversion() +{ + //TODO:let it be async + //kdDebug() << origdoc.toString() << endl; + done = false; + formuladoc = TQDomDocument( "KFORMULA" ); + impl = new MathML2KFormulaPrivate( this, context, formuladoc ); + if ( orig_element.tagName() == "math" ) { + impl->math( orig_element ); + m_error = false; + } + else { + kdError() << "Not a MathML document!" << endl; + KMessageBox::error( 0, i18n( "The document does not seem to be MathML." ), i18n( "MathML Import Error" ) ); + m_error = true; + } + done = true; +} + +bool MathML2KFormula::processElement( TQDomNode node, TQDomDocument& doc, TQDomNode docnode ) +{ + + //TQDomElement *element; + Type type = UNKNOWN; + + if ( node.isElement() ) { + TQDomElement element = node.toElement(); + TQString tag = element.tagName(); + + if ( tag == "mi" ) { + type = TOKEN; + impl->mi( element, docnode ); + } + else if ( tag == "mo" ) { + type = TOKEN; + impl->mo( element, docnode ); + } + else if ( tag == "mn" ) { + type = TOKEN; + impl->mn( element, docnode ); + } + else if ( tag == "mtext" ) { + type = TOKEN; + impl->mtext( element, docnode ); + } + else if ( tag == "ms" ) { + type = TOKEN; + impl->ms( element, docnode ); + } + else if ( tag == "mspace" ) { + type = TOKEN; + impl->mspace( element, docnode ); + } + else if ( tag == "mrow" ) { + type = LAYOUT; + impl->mrow( element, docnode ); + } + else if ( tag == "mfrac" ) { + type = LAYOUT; + impl->mfrac( element, docnode ); + } + else if ( tag == "mroot" ) { + type = LAYOUT; + impl->mroot( element, docnode ); + } + else if ( tag == "msqrt" ) { + type = LAYOUT; + impl->msqrt( element, docnode ); + } + else if ( tag == "mstyle" ) { + type = LAYOUT; + impl->mstyle( element, docnode ); + } + else if ( tag == "mfenced" ) { + type = LAYOUT; + impl->mfenced( element, docnode ); + } + else if ( tag == "mtable" ) { + type = TABLE; + impl->mtable( element, docnode ); + } + else if ( tag == "msub" || tag == "msup" ) { + type = SCRIPT; + impl->msub_msup( element, docnode ); + } + else if ( tag == "munder" ) { + type = SCRIPT; + impl->munder( element, docnode,oasisFormat ); + } + else if ( tag == "mover" ) { + type = SCRIPT; + impl->mover( element, docnode,oasisFormat ); + } + else if ( tag == "munderover" ) { + type = SCRIPT; + impl->munderover( element, docnode, oasisFormat ); + } + else if ( tag == "msubsup" ) { + type = SCRIPT; + impl->msubsup( element, docnode ); + } + + // content markup (not yet complete) + else if ( tag == "apply" ) { + type = CONTENT; + TQDomNode n = element.firstChild(); + TQDomElement op = n.toElement(); + uint count = element.childNodes().count(); + //adding explicit brackets to replace "apply"s implicit ones + TQDomElement brackets = doc.createElement("BRACKET"); + brackets.setAttribute("RIGHT", "41"); + brackets.setAttribute("LEFT", "40"); + TQDomElement content = doc.createElement("CONTENT"); + brackets.appendChild(content); + TQDomElement base = doc.createElement("SEQUENCE"); + content.appendChild(base); + docnode.appendChild(brackets); + //Arithmetic, Algebra and Logic operators status + // quotient X + // factorial O + // divide O + // max, min X + // minus O + // plus O + // power O + // rem X + // times O + // root X + // gcd X + // and O + // or O + // xor O + // not O + // implies O + // forall X + // exists X + // abs O + // conjugate X + // arg X + // real X + // imaginary X + // lcm X + // floor X + // ceiling X + + // n-ary + if ( op.tagName() == "plus" || op.tagName() == "times" || + op.tagName() == "and" || op.tagName() == "or" || + op.tagName() == "xor" ) { + + n = n.nextSibling(); + bool first = true; + + while ( !n.isNull() ) { + if ( n.isElement() ) { + if ( !first ) { + TQDomElement text = doc.createElement( "TEXT" ); + TQString value; + + if ( op.tagName() == "plus" ) + value = "+"; + else if ( op.tagName() == "times" ) + value = "*"; + else if ( op.tagName() == "and" ) + value = "&"; + else if ( op.tagName() == "or" ) + value = "|"; + else if ( op.tagName() == "xor" ) + value = "^"; // ??? + + text.setAttribute( "CHAR", value ); //switch to createTextElements? + base.appendChild( text ); + } + first = false; + TQDomElement e = n.toElement(); + processElement( e, doc, base ); + } + n = n.nextSibling(); + } + } + + else if ( op.tagName() == "factorial" ) { + TQDomElement e = n.nextSibling().toElement(); + processElement( e, doc, docnode ); + impl->createTextElements( "!", base ); + } + else if ( op.tagName() == "minus" ) { + n = n.nextSibling(); + if ( count == 2 ) { // unary + impl->createTextElements( "-", base ); + TQDomElement e = n.toElement(); + processElement( e, doc, base ); + } + else if ( count == 3 ) { // binary + TQDomElement e = n.toElement(); + processElement( e, doc, base ); + impl->createTextElements( "-", base ); + n = n.nextSibling(); + e = n.toElement(); + processElement( e, doc, base ); + } + } + + else if ( op.tagName() == "divide" && count == 3 ) { + n = n.nextSibling(); + TQDomElement e = n.toElement(); + processElement( e, doc, base ); + impl->createTextElements("/", base); + n = n.nextSibling(); + e = n.toElement(); + processElement( e, doc, base ); + } + else if ( op.tagName() == "power" && count == 3 ) { + //code duplication of msub_sup(), but I can't find a way to cleanly call it + n = n.nextSibling(); + TQDomElement e = n.toElement(); + TQDomElement index = doc.createElement("INDEX"); + base.appendChild(index); + TQDomElement content = doc.createElement("CONTENT"); + index.appendChild(content); + TQDomElement sequence = doc.createElement("SEQUENCE"); + content.appendChild(sequence); + processElement(e, doc, sequence); + TQDomElement upper = doc.createElement("UPPERRIGHT"); + index.appendChild(upper); + sequence = doc.createElement("SEQUENCE"); + upper.appendChild(sequence); + n = n.nextSibling(); + e = n.toElement(); + processElement(e, doc, sequence); + } + else if ( op.tagName() == "abs" && count == 2) { + n = n.nextSibling(); + TQDomElement e = n.toElement(); + TQDomElement bracket = doc.createElement("BRACKET"); + bracket.setAttribute("RIGHT", "257"); + bracket.setAttribute("LEFT", "256"); + base.appendChild(bracket); + TQDomElement content = doc.createElement("CONTENT"); + bracket.appendChild(content); + TQDomElement sequence = doc.createElement("SEQUENCE"); + content.appendChild(sequence); + processElement(e, doc, sequence); + } + else if ( op.tagName() == "not" && count == 2) { + n = n.nextSibling(); + TQDomElement e = n.toElement(); + impl->createTextElements(TQString(TQChar(0xAC)), base); + processElement(e, doc, base); + } + else if ( op.tagName() == "implies" && count == 3 ) { + n = n.nextSibling(); + TQDomElement e = n.toElement(); + processElement( e, doc, base ); + impl->createTextElements(TQString(TQChar(0x21D2)), base); + n = n.nextSibling(); + e = n.toElement(); + processElement( e, doc, base ); + } + // many, many more... + + } + + else if ( tag == "cn" ) { + type = CONTENT; + TQString type = element.attribute( "type", "real" ); + + if ( type == "real" || type == "constant" ) { + impl->createTextElements( element.text().stripWhiteSpace(), + docnode ); + } + else if ( type == "integer" ) { + TQString base = element.attribute( "base" ); + if ( !base ) { + impl->createTextElements( element.text().stripWhiteSpace(), + docnode ); + } + else { + TQDomElement index = doc.createElement( "INDEX" ); + TQDomElement content = doc.createElement( "CONTENT" ); + TQDomElement sequence = doc.createElement( "SEQUENCE" ); + impl->createTextElements( element.text().stripWhiteSpace(), + sequence ); + content.appendChild( sequence ); + index.appendChild( content ); + + TQDomElement lowerright = doc.createElement( "LOWERRIGHT" ); + sequence = doc.createElement( "SEQUENCE" ); + + impl->createTextElements( base, sequence ); + + lowerright.appendChild( sequence ); + index.appendChild( lowerright ); + + docnode.appendChild( index ); + } + } + else if ( type == "rational" ) { + TQDomNode n = element.firstChild(); + impl->createTextElements( n.toText().data().stripWhiteSpace(), + docnode ); + + n = n.nextSibling(); // + impl->createTextElements( "/", docnode ); + + n = n.nextSibling(); + impl->createTextElements( n.toText().data().stripWhiteSpace(), + docnode ); + } + else if ( type == "complex-cartesian" ) { + TQDomNode n = element.firstChild(); + impl->createTextElements( n.toText().data().stripWhiteSpace(), + docnode ); + + n = n.nextSibling(); // + impl->createTextElements( "+", docnode ); + + n = n.nextSibling(); + impl->createTextElements( n.toText().data().stripWhiteSpace(), + docnode ); + + impl->createTextElements( "i", docnode ); + } + + else if ( type == "complex-polar" ) { + TQDomNode n = element.firstChild(); + impl->createTextElements( n.toText().data().stripWhiteSpace(), + docnode ); + + n = n.nextSibling(); // + TQDomElement index = doc.createElement( "INDEX" ); + TQDomElement content = doc.createElement( "CONTENT" ); + TQDomElement sequence = doc.createElement( "SEQUENCE" ); + TQDomElement textelement = doc.createElement( "TEXT" ); + textelement.setAttribute( "CHAR", "e" ); + sequence.appendChild( textelement ); + content.appendChild( sequence ); + index.appendChild( content ); + + TQDomElement upperright = doc.createElement( "UPPERRIGHT" ); + sequence = doc.createElement( "SEQUENCE" ); + textelement = doc.createElement( "TEXT" ); + textelement.setAttribute( "CHAR", "i" ); + sequence.appendChild( textelement ); + + n = n.nextSibling(); + impl->createTextElements( n.toText().data().stripWhiteSpace(), + sequence ); + + upperright.appendChild( sequence ); + index.appendChild( upperright ); + + docnode.appendChild( index ); + } + } + + else if ( tag == "ci" ) { + type = CONTENT; + TQDomNode n = element.firstChild(); + + if ( n.isText() ) { + impl->createTextElements( n.toText().data().stripWhiteSpace(), + docnode ); + } + else if ( n.isElement() ) { + TQDomElement e = n.toElement(); + processElement( e, doc, docnode ); + } + else if ( n.isEntityReference() ) { + kdDebug( DEBUGID ) << "isEntityReference: " + << n.toEntityReference().nodeName().latin1() + << endl; + } + else + kdDebug( DEBUGID ) << "ci: " << n.nodeName().latin1() << endl; + } + + else if ( tag == "list" ) { + type = CONTENT; + TQDomNode n = element.firstChild(); + + TQDomElement bracket = doc.createElement( "BRACKET" ); + bracket.setAttribute( "LEFT", 91 ); // [ + bracket.setAttribute( "RIGHT", 93 ); // ] + TQDomElement content = doc.createElement( "CONTENT" ); + TQDomElement sequence = doc.createElement( "SEQUENCE" ); + + bool first = true; + + while ( !n.isNull() ) { + if ( n.isElement() ) { + if ( !first ) { + TQDomElement textelement = doc.createElement( "TEXT" ); + textelement.setAttribute( "CHAR", "," ); + sequence.appendChild( textelement ); + } + first = false; + TQDomElement e = n.toElement(); + processElement( e, doc, sequence ); + } + n = n.nextSibling(); + } + + content.appendChild( sequence ); + bracket.appendChild( content ); + docnode.appendChild( bracket ); + } + } + + if ( type == UNKNOWN && node.nodeType() != TQDomNode::AttributeNode ) { + kdDebug() << "Not an element: " << node.nodeName() << endl; + TQDomNode n = node.firstChild(); + while ( !n.isNull() ) { + processElement( n, doc, docnode ); + n = n.nextSibling(); + } + } + + return true; +} + +KFORMULA_NAMESPACE_END + +using namespace KFormula; +#include "kformulamathmlread.moc" diff --git a/lib/kformula/kformulamimesource.cc b/lib/kformula/kformulamimesource.cc deleted file mode 100644 index 4c7df0c7..00000000 --- a/lib/kformula/kformulamimesource.cc +++ /dev/null @@ -1,154 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2001 Andrea Rizzi - Ulrich Kuettler - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - -#include - -#include -#include -#include -#include -#include -#include - -#include - -#include "contextstyle.h" -#include "formulacursor.h" -#include "formulaelement.h" -#include "kformuladocument.h" -#include "kformulamimesource.h" - -KFORMULA_NAMESPACE_BEGIN -using namespace std; - - -MimeSource::MimeSource(Document* doc, const TQDomDocument& formula) - : formulaDocument( doc ), document(formula) -{ - // The query for text/plain comes very often. So make sure - // it's fast. - - rootElement = new FormulaElement(this); - FormulaCursor cursor(rootElement); - - TQPtrList list; - list.setAutoDelete(true); - if ( cursor.buildElementsFromDom( document.documentElement(), list ) ) { - cursor.insert(list); - latexString = rootElement->toLatex().utf8(); - if (latexString.size() > 0) { - latexString.truncate(latexString.size()-1); - } - } -} - -MimeSource::~MimeSource() -{ - delete rootElement; -} - -const char * MimeSource::selectionMimeType() -{ - return "application/x-kformula"; -} - -const char* MimeSource::format( int n ) const -{ - switch (n) { - case 0: - return selectionMimeType(); - case 1: - return "image/ppm"; - case 2: - return "text/plain"; - case 3: - return "text/x-tex"; - } - return NULL; -} - -bool MimeSource::provides( const char * format) const -{ -//This is not completed - if(TQString(format)==selectionMimeType()) - return true; - else if(TQString(format)=="image/ppm") - return true; - else if(TQString(format)=="text/plain") - return true; - else if(TQString(format)=="text/x-tex") - return true; - else - return false; -} - -TQByteArray MimeSource::encodedData ( const char *format ) const -{ - TQString fmt=format; //case sensitive? - - if ((fmt=="text/plain") || (fmt=="text/x-tex")) - return latexString; - - if (fmt==selectionMimeType()) { - TQByteArray d=document.toCString(); - d.truncate(d.size()-1); - return d; - } - - if (fmt=="image/ppm") { - - //cerr << "asking image" << endl; - ContextStyle& context = formulaDocument->getContextStyle( false ); - //context.setResolution(5, 5); - - rootElement->calcSizes(context); - TQRect rect(rootElement->getX(), rootElement->getY(), - rootElement->getWidth(), rootElement->getHeight()); - - TQPixmap pm( context.layoutUnitToPixelX( rootElement->getWidth() ), - context.layoutUnitToPixelY( rootElement->getHeight() ) ); - pm.fill(); - TQPainter paint(&pm); - rootElement->draw(paint, rect, context); - paint.end(); - - TQByteArray d; - TQBuffer buff(d); - buff.open(IO_WriteOnly); - TQImageIO io(&buff,"PPM"); - TQImage ima=pm.convertToImage(); - ima.detach(); - io.setImage(ima); - if(!io.write()) - return TQByteArray(); - - buff.close(); - return d; - } - - return TQByteArray(); -} - -const SymbolTable& MimeSource::getSymbolTable() const -{ - return formulaDocument->getContextStyle( false ).symbolTable(); -} - -KFORMULA_NAMESPACE_END diff --git a/lib/kformula/kformulamimesource.cpp b/lib/kformula/kformulamimesource.cpp new file mode 100644 index 00000000..4c7df0c7 --- /dev/null +++ b/lib/kformula/kformulamimesource.cpp @@ -0,0 +1,154 @@ +/* This file is part of the KDE project + Copyright (C) 2001 Andrea Rizzi + Ulrich Kuettler + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "contextstyle.h" +#include "formulacursor.h" +#include "formulaelement.h" +#include "kformuladocument.h" +#include "kformulamimesource.h" + +KFORMULA_NAMESPACE_BEGIN +using namespace std; + + +MimeSource::MimeSource(Document* doc, const TQDomDocument& formula) + : formulaDocument( doc ), document(formula) +{ + // The query for text/plain comes very often. So make sure + // it's fast. + + rootElement = new FormulaElement(this); + FormulaCursor cursor(rootElement); + + TQPtrList list; + list.setAutoDelete(true); + if ( cursor.buildElementsFromDom( document.documentElement(), list ) ) { + cursor.insert(list); + latexString = rootElement->toLatex().utf8(); + if (latexString.size() > 0) { + latexString.truncate(latexString.size()-1); + } + } +} + +MimeSource::~MimeSource() +{ + delete rootElement; +} + +const char * MimeSource::selectionMimeType() +{ + return "application/x-kformula"; +} + +const char* MimeSource::format( int n ) const +{ + switch (n) { + case 0: + return selectionMimeType(); + case 1: + return "image/ppm"; + case 2: + return "text/plain"; + case 3: + return "text/x-tex"; + } + return NULL; +} + +bool MimeSource::provides( const char * format) const +{ +//This is not completed + if(TQString(format)==selectionMimeType()) + return true; + else if(TQString(format)=="image/ppm") + return true; + else if(TQString(format)=="text/plain") + return true; + else if(TQString(format)=="text/x-tex") + return true; + else + return false; +} + +TQByteArray MimeSource::encodedData ( const char *format ) const +{ + TQString fmt=format; //case sensitive? + + if ((fmt=="text/plain") || (fmt=="text/x-tex")) + return latexString; + + if (fmt==selectionMimeType()) { + TQByteArray d=document.toCString(); + d.truncate(d.size()-1); + return d; + } + + if (fmt=="image/ppm") { + + //cerr << "asking image" << endl; + ContextStyle& context = formulaDocument->getContextStyle( false ); + //context.setResolution(5, 5); + + rootElement->calcSizes(context); + TQRect rect(rootElement->getX(), rootElement->getY(), + rootElement->getWidth(), rootElement->getHeight()); + + TQPixmap pm( context.layoutUnitToPixelX( rootElement->getWidth() ), + context.layoutUnitToPixelY( rootElement->getHeight() ) ); + pm.fill(); + TQPainter paint(&pm); + rootElement->draw(paint, rect, context); + paint.end(); + + TQByteArray d; + TQBuffer buff(d); + buff.open(IO_WriteOnly); + TQImageIO io(&buff,"PPM"); + TQImage ima=pm.convertToImage(); + ima.detach(); + io.setImage(ima); + if(!io.write()) + return TQByteArray(); + + buff.close(); + return d; + } + + return TQByteArray(); +} + +const SymbolTable& MimeSource::getSymbolTable() const +{ + return formulaDocument->getContextStyle( false ).symbolTable(); +} + +KFORMULA_NAMESPACE_END diff --git a/lib/kformula/kformulaview.cc b/lib/kformula/kformulaview.cc deleted file mode 100644 index 1e50694d..00000000 --- a/lib/kformula/kformulaview.cc +++ /dev/null @@ -1,413 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2001 Andrea Rizzi - Ulrich Kuettler - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - -#include - -#include -#include - -#include -#include - -#include "basicelement.h" -#include "formulacursor.h" -#include "formulaelement.h" -#include "kformulacontainer.h" -#include "kformuladocument.h" -#include "kformulaview.h" - -KFORMULA_NAMESPACE_BEGIN - -struct View::View_Impl { - - View_Impl(Container* doc, View* view) - : smallCursor(false), activeCursor(true), cursorHasChanged(true), - document(doc) - { - connect(document, TQT_SIGNAL(elementWillVanish(BasicElement*)), - view, TQT_SLOT(slotElementWillVanish(BasicElement*))); - connect(document, TQT_SIGNAL(formulaLoaded(FormulaElement*)), - view, TQT_SLOT(slotFormulaLoaded(FormulaElement*))); - connect(document, TQT_SIGNAL(cursorMoved(FormulaCursor*)), - view, TQT_SLOT(slotCursorMoved(FormulaCursor*))); - - cursor = document->createCursor(); - blinkTimer = new TQTimer( view ); - connect( blinkTimer, TQT_SIGNAL( timeout() ), - view, TQT_SLOT( slotBlinkCursor() ) ); - if ( TQApplication::cursorFlashTime() > 0 ) - blinkTimer->start( TQApplication::cursorFlashTime() / 2 ); - } - - void startTimer() - { - if ( TQApplication::cursorFlashTime() > 0 ) - blinkTimer->start( TQApplication::cursorFlashTime() / 2 ); - } - - void stopTimer() - { - blinkTimer->stop(); - } - - ~View_Impl() - { - if ( document->activeCursor() == cursor ) { - document->setActiveCursor( 0 ); - } - delete cursor; - delete blinkTimer; - } - - /** - * If set the cursor will never be bigger that the formula. - */ - bool smallCursor; - - /** - * Whether the cursor is visible (for blinking) - */ - bool activeCursor; - - /** - * Whether the cursor changed since the last time - * we emitted a cursorChanged signal. - */ - bool cursorHasChanged; - - /** - * Timer for cursor blinking - */ - TQTimer *blinkTimer; - - /** - * The formula we show. - */ - Container* document; - - /** - * Out cursor. - */ - FormulaCursor* cursor; -}; - - -FormulaCursor* View::cursor() const { return impl->cursor; } -bool& View::cursorHasChanged() { return impl->cursorHasChanged; } -bool& View::smallCursor() { return impl->smallCursor; } -bool& View::activeCursor() { return impl->activeCursor; } -Container* View::container() const { return impl->document; } -void View::startCursorTimer() { impl->startTimer(); } -void View::stopCursorTimer() { impl->stopTimer(); } - - -View::View(Container* doc) -{ - impl = new View_Impl(doc, this); - cursor()->calcCursorSize( contextStyle(), smallCursor() ); -} - -View::~View() -{ - delete impl; -} - - -TQPoint View::getCursorPoint() const -{ - return contextStyle().layoutUnitToPixel( cursor()->getCursorPoint() ); -} - -void View::setReadOnly(bool ro) -{ - cursor()->setReadOnly(ro); -} - - -void View::calcCursor() -{ - cursor()->calcCursorSize( contextStyle(), smallCursor() ); -} - - -void View::draw(TQPainter& painter, const TQRect& rect, const TQColorGroup& cg) -{ -// kdDebug( DEBUGID ) << "View::draw: " << rect.x() << " " << rect.y() << " " -// << rect.width() << " " << rect.height() << endl; - container()->draw( painter, rect, cg, true ); - if ( cursorVisible() ) { - StyleAttributes style; - cursor()->draw( painter, contextStyle(), style, smallCursor(), activeCursor() ); - } -} - -void View::draw(TQPainter& painter, const TQRect& rect) -{ - container()->draw( painter, rect, true ); - if ( cursorVisible() ) { - StyleAttributes style; - cursor()->draw( painter, contextStyle(), style, smallCursor(), activeCursor() ); - } -} - -void View::keyPressEvent( TQKeyEvent* event ) -{ - container()->input( event ); -} - - -void View::focusInEvent(TQFocusEvent*) -{ - //cursor()->calcCursorSize( contextStyle(), smallCursor() ); - container()->setActiveCursor(cursor()); - activeCursor() = true; - startCursorTimer(); - smallCursor() = false; - emitCursorChanged(); -} - -void View::focusOutEvent(TQFocusEvent*) -{ - //container()->setActiveCursor(0); - activeCursor() = false; - stopCursorTimer(); - smallCursor() = true; - emitCursorChanged(); -} - -void View::mousePressEvent( TQMouseEvent* event ) -{ - const ContextStyle& context = contextStyle(); - mousePressEvent( event, context.pixelToLayoutUnit( event->pos() ) ); -} - -void View::mouseReleaseEvent( TQMouseEvent* event ) -{ - const ContextStyle& context = contextStyle(); - mouseReleaseEvent( event, context.pixelToLayoutUnit( event->pos() ) ); -} - -void View::mouseDoubleClickEvent( TQMouseEvent* event ) -{ - const ContextStyle& context = contextStyle(); - mouseDoubleClickEvent( event, context.pixelToLayoutUnit( event->pos() ) ); -} - -void View::mouseMoveEvent( TQMouseEvent* event ) -{ - const ContextStyle& context = contextStyle(); - mouseMoveEvent( event, context.pixelToLayoutUnit( event->pos() ) ); -} - -void View::wheelEvent( TQWheelEvent* event ) -{ - const ContextStyle& context = contextStyle(); - wheelEvent( event, context.pixelToLayoutUnit( event->pos() ) ); -} - -void View::mousePressEvent( TQMouseEvent* event, const PtPoint& pos ) -{ - const ContextStyle& context = contextStyle(); - mousePressEvent( event, context.ptToLayoutUnitPix( pos ) ); -} - -void View::mouseReleaseEvent( TQMouseEvent* event, const PtPoint& pos ) -{ - const ContextStyle& context = contextStyle(); - mouseReleaseEvent( event, context.ptToLayoutUnitPix( pos ) ); -} - -void View::mouseDoubleClickEvent( TQMouseEvent* event, const PtPoint& pos ) -{ - const ContextStyle& context = contextStyle(); - mouseDoubleClickEvent( event, context.ptToLayoutUnitPix( pos ) ); -} - -void View::mouseMoveEvent( TQMouseEvent* event, const PtPoint& pos ) -{ - const ContextStyle& context = contextStyle(); - mouseMoveEvent( event, context.ptToLayoutUnitPix( pos ) ); -} - -void View::wheelEvent( TQWheelEvent* event, const PtPoint& pos ) -{ - const ContextStyle& context = contextStyle(); - wheelEvent( event, context.ptToLayoutUnitPix( pos ) ); -} - - -void View::mousePressEvent( TQMouseEvent* event, const LuPixelPoint& pos ) -{ - int flags = movementFlag( event->state() ); - cursor()->mousePress( pos, flags ); - emitCursorChanged(); -} - -void View::mouseReleaseEvent( TQMouseEvent* event, const LuPixelPoint& pos ) -{ - int flags = movementFlag( event->state() ); - cursor()->mouseRelease( pos, flags ); - emitCursorChanged(); -} - -void View::mouseDoubleClickEvent( TQMouseEvent*, const LuPixelPoint& ) -{ - cursor()->moveRight( WordMovement ); - cursor()->moveLeft( SelectMovement | WordMovement ); - emitCursorChanged(); -} - -void View::mouseMoveEvent( TQMouseEvent* event, const LuPixelPoint& pos ) -{ - int flags = movementFlag( event->state() ); - cursor()->mouseMove( pos, flags ); - emitCursorChanged(); -} - -void View::wheelEvent( TQWheelEvent*, const LuPixelPoint& ) -{ -} - - -void View::slotCursorMoved(FormulaCursor* c) -{ - if (c == cursor()) { - cursorHasChanged() = true; - emitCursorChanged(); - } -} - -void View::slotFormulaLoaded(FormulaElement* formula) -{ - cursor()->formulaLoaded(formula); -} - -void View::slotElementWillVanish(BasicElement* element) -{ - cursor()->elementWillVanish(element); - emitCursorChanged(); -} - -void View::slotBlinkCursor() -{ - activeCursor() = ! activeCursor(); - emitCursorChanged(); -} - -void View::slotSelectAll() -{ - cursor()->moveHome(WordMovement); - cursor()->moveEnd(SelectMovement | WordMovement); - emitCursorChanged(); -} - - -void View::moveLeft( int flag ) -{ - cursor()->moveLeft( flag ); - emitCursorChanged(); -} - -void View::moveRight( int flag ) -{ - cursor()->moveRight( flag ); - emitCursorChanged(); -} - -void View::moveUp( int flag ) -{ - cursor()->moveUp( flag ); - emitCursorChanged(); -} - -void View::moveDown( int flag ) -{ - cursor()->moveDown( flag ); - emitCursorChanged(); -} - - -void View::moveHome( int flag ) -{ - cursor()->moveHome( flag ); - emitCursorChanged(); -} - -void View::moveEnd( int flag ) -{ - cursor()->moveEnd( flag ); - emitCursorChanged(); -} - - -void View::setSmallCursor(bool small) -{ - smallCursor() = small; -} - -bool View::isHome() const -{ - return cursor()->isHome(); -} - -bool View::isEnd() const -{ - return cursor()->isEnd(); -} - -void View::eraseSelection( Direction direction ) -{ - DirectedRemove r( req_remove, direction ); - container()->performRequest( &r ); -} - -void View::addText( TQString str ) -{ - TextRequest r( str ); - container()->performRequest( &r ); -} - -void View::emitCursorChanged() -{ - if (cursor()->hasChanged() || cursorHasChanged()) { - getDocument()->updateMatrixActions(); - cursor()->clearChangedFlag(); - cursorHasChanged() = false; - cursor()->calcCursorSize( contextStyle(), smallCursor() ); - activeCursor() = true; - startCursorTimer(); - } - emit cursorChanged(cursorVisible(), cursor()->isSelection()); -} - -const ContextStyle& View::contextStyle() const -{ - return container()->document()->getContextStyle(); -} - -bool View::cursorVisible() -{ - return !cursor()->isReadOnly() || cursor()->isSelection(); -} - -KFORMULA_NAMESPACE_END - -using namespace KFormula; -#include "kformulaview.moc" diff --git a/lib/kformula/kformulaview.cpp b/lib/kformula/kformulaview.cpp new file mode 100644 index 00000000..1e50694d --- /dev/null +++ b/lib/kformula/kformulaview.cpp @@ -0,0 +1,413 @@ +/* This file is part of the KDE project + Copyright (C) 2001 Andrea Rizzi + Ulrich Kuettler + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include + +#include +#include + +#include +#include + +#include "basicelement.h" +#include "formulacursor.h" +#include "formulaelement.h" +#include "kformulacontainer.h" +#include "kformuladocument.h" +#include "kformulaview.h" + +KFORMULA_NAMESPACE_BEGIN + +struct View::View_Impl { + + View_Impl(Container* doc, View* view) + : smallCursor(false), activeCursor(true), cursorHasChanged(true), + document(doc) + { + connect(document, TQT_SIGNAL(elementWillVanish(BasicElement*)), + view, TQT_SLOT(slotElementWillVanish(BasicElement*))); + connect(document, TQT_SIGNAL(formulaLoaded(FormulaElement*)), + view, TQT_SLOT(slotFormulaLoaded(FormulaElement*))); + connect(document, TQT_SIGNAL(cursorMoved(FormulaCursor*)), + view, TQT_SLOT(slotCursorMoved(FormulaCursor*))); + + cursor = document->createCursor(); + blinkTimer = new TQTimer( view ); + connect( blinkTimer, TQT_SIGNAL( timeout() ), + view, TQT_SLOT( slotBlinkCursor() ) ); + if ( TQApplication::cursorFlashTime() > 0 ) + blinkTimer->start( TQApplication::cursorFlashTime() / 2 ); + } + + void startTimer() + { + if ( TQApplication::cursorFlashTime() > 0 ) + blinkTimer->start( TQApplication::cursorFlashTime() / 2 ); + } + + void stopTimer() + { + blinkTimer->stop(); + } + + ~View_Impl() + { + if ( document->activeCursor() == cursor ) { + document->setActiveCursor( 0 ); + } + delete cursor; + delete blinkTimer; + } + + /** + * If set the cursor will never be bigger that the formula. + */ + bool smallCursor; + + /** + * Whether the cursor is visible (for blinking) + */ + bool activeCursor; + + /** + * Whether the cursor changed since the last time + * we emitted a cursorChanged signal. + */ + bool cursorHasChanged; + + /** + * Timer for cursor blinking + */ + TQTimer *blinkTimer; + + /** + * The formula we show. + */ + Container* document; + + /** + * Out cursor. + */ + FormulaCursor* cursor; +}; + + +FormulaCursor* View::cursor() const { return impl->cursor; } +bool& View::cursorHasChanged() { return impl->cursorHasChanged; } +bool& View::smallCursor() { return impl->smallCursor; } +bool& View::activeCursor() { return impl->activeCursor; } +Container* View::container() const { return impl->document; } +void View::startCursorTimer() { impl->startTimer(); } +void View::stopCursorTimer() { impl->stopTimer(); } + + +View::View(Container* doc) +{ + impl = new View_Impl(doc, this); + cursor()->calcCursorSize( contextStyle(), smallCursor() ); +} + +View::~View() +{ + delete impl; +} + + +TQPoint View::getCursorPoint() const +{ + return contextStyle().layoutUnitToPixel( cursor()->getCursorPoint() ); +} + +void View::setReadOnly(bool ro) +{ + cursor()->setReadOnly(ro); +} + + +void View::calcCursor() +{ + cursor()->calcCursorSize( contextStyle(), smallCursor() ); +} + + +void View::draw(TQPainter& painter, const TQRect& rect, const TQColorGroup& cg) +{ +// kdDebug( DEBUGID ) << "View::draw: " << rect.x() << " " << rect.y() << " " +// << rect.width() << " " << rect.height() << endl; + container()->draw( painter, rect, cg, true ); + if ( cursorVisible() ) { + StyleAttributes style; + cursor()->draw( painter, contextStyle(), style, smallCursor(), activeCursor() ); + } +} + +void View::draw(TQPainter& painter, const TQRect& rect) +{ + container()->draw( painter, rect, true ); + if ( cursorVisible() ) { + StyleAttributes style; + cursor()->draw( painter, contextStyle(), style, smallCursor(), activeCursor() ); + } +} + +void View::keyPressEvent( TQKeyEvent* event ) +{ + container()->input( event ); +} + + +void View::focusInEvent(TQFocusEvent*) +{ + //cursor()->calcCursorSize( contextStyle(), smallCursor() ); + container()->setActiveCursor(cursor()); + activeCursor() = true; + startCursorTimer(); + smallCursor() = false; + emitCursorChanged(); +} + +void View::focusOutEvent(TQFocusEvent*) +{ + //container()->setActiveCursor(0); + activeCursor() = false; + stopCursorTimer(); + smallCursor() = true; + emitCursorChanged(); +} + +void View::mousePressEvent( TQMouseEvent* event ) +{ + const ContextStyle& context = contextStyle(); + mousePressEvent( event, context.pixelToLayoutUnit( event->pos() ) ); +} + +void View::mouseReleaseEvent( TQMouseEvent* event ) +{ + const ContextStyle& context = contextStyle(); + mouseReleaseEvent( event, context.pixelToLayoutUnit( event->pos() ) ); +} + +void View::mouseDoubleClickEvent( TQMouseEvent* event ) +{ + const ContextStyle& context = contextStyle(); + mouseDoubleClickEvent( event, context.pixelToLayoutUnit( event->pos() ) ); +} + +void View::mouseMoveEvent( TQMouseEvent* event ) +{ + const ContextStyle& context = contextStyle(); + mouseMoveEvent( event, context.pixelToLayoutUnit( event->pos() ) ); +} + +void View::wheelEvent( TQWheelEvent* event ) +{ + const ContextStyle& context = contextStyle(); + wheelEvent( event, context.pixelToLayoutUnit( event->pos() ) ); +} + +void View::mousePressEvent( TQMouseEvent* event, const PtPoint& pos ) +{ + const ContextStyle& context = contextStyle(); + mousePressEvent( event, context.ptToLayoutUnitPix( pos ) ); +} + +void View::mouseReleaseEvent( TQMouseEvent* event, const PtPoint& pos ) +{ + const ContextStyle& context = contextStyle(); + mouseReleaseEvent( event, context.ptToLayoutUnitPix( pos ) ); +} + +void View::mouseDoubleClickEvent( TQMouseEvent* event, const PtPoint& pos ) +{ + const ContextStyle& context = contextStyle(); + mouseDoubleClickEvent( event, context.ptToLayoutUnitPix( pos ) ); +} + +void View::mouseMoveEvent( TQMouseEvent* event, const PtPoint& pos ) +{ + const ContextStyle& context = contextStyle(); + mouseMoveEvent( event, context.ptToLayoutUnitPix( pos ) ); +} + +void View::wheelEvent( TQWheelEvent* event, const PtPoint& pos ) +{ + const ContextStyle& context = contextStyle(); + wheelEvent( event, context.ptToLayoutUnitPix( pos ) ); +} + + +void View::mousePressEvent( TQMouseEvent* event, const LuPixelPoint& pos ) +{ + int flags = movementFlag( event->state() ); + cursor()->mousePress( pos, flags ); + emitCursorChanged(); +} + +void View::mouseReleaseEvent( TQMouseEvent* event, const LuPixelPoint& pos ) +{ + int flags = movementFlag( event->state() ); + cursor()->mouseRelease( pos, flags ); + emitCursorChanged(); +} + +void View::mouseDoubleClickEvent( TQMouseEvent*, const LuPixelPoint& ) +{ + cursor()->moveRight( WordMovement ); + cursor()->moveLeft( SelectMovement | WordMovement ); + emitCursorChanged(); +} + +void View::mouseMoveEvent( TQMouseEvent* event, const LuPixelPoint& pos ) +{ + int flags = movementFlag( event->state() ); + cursor()->mouseMove( pos, flags ); + emitCursorChanged(); +} + +void View::wheelEvent( TQWheelEvent*, const LuPixelPoint& ) +{ +} + + +void View::slotCursorMoved(FormulaCursor* c) +{ + if (c == cursor()) { + cursorHasChanged() = true; + emitCursorChanged(); + } +} + +void View::slotFormulaLoaded(FormulaElement* formula) +{ + cursor()->formulaLoaded(formula); +} + +void View::slotElementWillVanish(BasicElement* element) +{ + cursor()->elementWillVanish(element); + emitCursorChanged(); +} + +void View::slotBlinkCursor() +{ + activeCursor() = ! activeCursor(); + emitCursorChanged(); +} + +void View::slotSelectAll() +{ + cursor()->moveHome(WordMovement); + cursor()->moveEnd(SelectMovement | WordMovement); + emitCursorChanged(); +} + + +void View::moveLeft( int flag ) +{ + cursor()->moveLeft( flag ); + emitCursorChanged(); +} + +void View::moveRight( int flag ) +{ + cursor()->moveRight( flag ); + emitCursorChanged(); +} + +void View::moveUp( int flag ) +{ + cursor()->moveUp( flag ); + emitCursorChanged(); +} + +void View::moveDown( int flag ) +{ + cursor()->moveDown( flag ); + emitCursorChanged(); +} + + +void View::moveHome( int flag ) +{ + cursor()->moveHome( flag ); + emitCursorChanged(); +} + +void View::moveEnd( int flag ) +{ + cursor()->moveEnd( flag ); + emitCursorChanged(); +} + + +void View::setSmallCursor(bool small) +{ + smallCursor() = small; +} + +bool View::isHome() const +{ + return cursor()->isHome(); +} + +bool View::isEnd() const +{ + return cursor()->isEnd(); +} + +void View::eraseSelection( Direction direction ) +{ + DirectedRemove r( req_remove, direction ); + container()->performRequest( &r ); +} + +void View::addText( TQString str ) +{ + TextRequest r( str ); + container()->performRequest( &r ); +} + +void View::emitCursorChanged() +{ + if (cursor()->hasChanged() || cursorHasChanged()) { + getDocument()->updateMatrixActions(); + cursor()->clearChangedFlag(); + cursorHasChanged() = false; + cursor()->calcCursorSize( contextStyle(), smallCursor() ); + activeCursor() = true; + startCursorTimer(); + } + emit cursorChanged(cursorVisible(), cursor()->isSelection()); +} + +const ContextStyle& View::contextStyle() const +{ + return container()->document()->getContextStyle(); +} + +bool View::cursorVisible() +{ + return !cursor()->isReadOnly() || cursor()->isSelection(); +} + +KFORMULA_NAMESPACE_END + +using namespace KFormula; +#include "kformulaview.moc" diff --git a/lib/kformula/kformulawidget.cc b/lib/kformula/kformulawidget.cc deleted file mode 100644 index 68f941d9..00000000 --- a/lib/kformula/kformulawidget.cc +++ /dev/null @@ -1,171 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2001 Andrea Rizzi - Ulrich Kuettler - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - -#include - -#include - -#include -#include -//#include -//#include - -#include "basicelement.h" -#include "formulacursor.h" -#include "formulaelement.h" -#include "kformulacontainer.h" -#include "kformuladocument.h" -#include "kformulawidget.h" - - -KFormulaWidget::KFormulaWidget(Container* doc, TQWidget* parent, const char* name, WFlags f) - : TQWidget(parent, name, f | WRepaintNoErase | WResizeNoErase), - formulaView(doc) -{ - connect(doc, TQT_SIGNAL(formulaChanged(int, int)), - this, TQT_SLOT(slotFormulaChanged(int, int))); - connect(&formulaView, TQT_SIGNAL(cursorChanged(bool, bool)), - this, TQT_SLOT(slotCursorChanged(bool, bool))); - - setFocusPolicy(TQ_StrongFocus); - setBackgroundMode(NoBackground/*TQWidget::PaletteBase*/); - - TQRect rect = doc->boundingRect(); - slotFormulaChanged(rect.width(), rect.height()); -} - -KFormulaWidget::~KFormulaWidget() -{ -} - - -TQPoint KFormulaWidget::getCursorPoint() const -{ - return formulaView.getCursorPoint(); -} - -void KFormulaWidget::setReadOnly(bool ro) -{ - formulaView.setReadOnly(ro); -} - - -void KFormulaWidget::paintEvent(TQPaintEvent* event) -{ - // Always repaint the buffer. This is not so much more work - // than it seems to be as each cursor movement requires a repaint. - TQPainter p( &buffer ); - //p.translate( -fr.x(), -fr.y() ); - formulaView.draw( p, event->rect(), colorGroup() ); - - TQPainter painter; - painter.begin(this); - painter.drawPixmap( event->rect().x(), event->rect().y(), - buffer, event->rect().x(), event->rect().y(), event->rect().width(), event->rect().height() ); - painter.end(); -} - -void KFormulaWidget::keyPressEvent(TQKeyEvent* event) -{ - formulaView.keyPressEvent(event); -} - - -void KFormulaWidget::focusInEvent(TQFocusEvent* event) -{ - formulaView.focusInEvent(event); -} - -void KFormulaWidget::focusOutEvent(TQFocusEvent* event) -{ - formulaView.focusOutEvent(event); -} - -void KFormulaWidget::mousePressEvent(TQMouseEvent* event) -{ - formulaView.mousePressEvent(event); -} - -void KFormulaWidget::mouseReleaseEvent(TQMouseEvent* event) -{ - formulaView.mouseReleaseEvent(event); -} - -void KFormulaWidget::mouseDoubleClickEvent(TQMouseEvent* event) -{ - formulaView.mouseDoubleClickEvent(event); -} - -void KFormulaWidget::mouseMoveEvent(TQMouseEvent* event) -{ - formulaView.mouseMoveEvent(event); -} - -void KFormulaWidget::wheelEvent(TQWheelEvent* event) -{ - formulaView.wheelEvent(event); -} - -void KFormulaWidget::slotFormulaChanged(int width, int height) -{ - // Magic numbers just to see the cursor. - resize(width + 5, height + 5); - buffer.resize(width + 5, height + 5); - // repaint is needed even if the size doesn't change. - //update(); -} - -/** - * The document we show. - */ -Container* KFormulaWidget::getDocument() -{ - return formulaView.getDocument(); -} - -/** - * Our cursor. - */ -FormulaCursor* KFormulaWidget::getCursor() -{ - return formulaView.getCursor(); -} - - -void KFormulaWidget::slotSelectAll() -{ - formulaView.slotSelectAll(); -} - -void KFormulaWidget::slotCursorChanged(bool visible, bool selecting) -{ - emit cursorChanged(visible, selecting); -// kdDebug( 40000 ) << "KFormulaWidget::slotCursorChanged " -// << formulaView.getDirtyArea().x() << " " -// << formulaView.getDirtyArea().y() << " " -// << formulaView.getDirtyArea().width() << " " -// << formulaView.getDirtyArea().height() << " " -// << endl; - // sadly this doesn't work - //update(formulaView.getDirtyArea()); - update(); -} - -#include "kformulawidget.moc" diff --git a/lib/kformula/kformulawidget.cpp b/lib/kformula/kformulawidget.cpp new file mode 100644 index 00000000..68f941d9 --- /dev/null +++ b/lib/kformula/kformulawidget.cpp @@ -0,0 +1,171 @@ +/* This file is part of the KDE project + Copyright (C) 2001 Andrea Rizzi + Ulrich Kuettler + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include + +#include + +#include +#include +//#include +//#include + +#include "basicelement.h" +#include "formulacursor.h" +#include "formulaelement.h" +#include "kformulacontainer.h" +#include "kformuladocument.h" +#include "kformulawidget.h" + + +KFormulaWidget::KFormulaWidget(Container* doc, TQWidget* parent, const char* name, WFlags f) + : TQWidget(parent, name, f | WRepaintNoErase | WResizeNoErase), + formulaView(doc) +{ + connect(doc, TQT_SIGNAL(formulaChanged(int, int)), + this, TQT_SLOT(slotFormulaChanged(int, int))); + connect(&formulaView, TQT_SIGNAL(cursorChanged(bool, bool)), + this, TQT_SLOT(slotCursorChanged(bool, bool))); + + setFocusPolicy(TQ_StrongFocus); + setBackgroundMode(NoBackground/*TQWidget::PaletteBase*/); + + TQRect rect = doc->boundingRect(); + slotFormulaChanged(rect.width(), rect.height()); +} + +KFormulaWidget::~KFormulaWidget() +{ +} + + +TQPoint KFormulaWidget::getCursorPoint() const +{ + return formulaView.getCursorPoint(); +} + +void KFormulaWidget::setReadOnly(bool ro) +{ + formulaView.setReadOnly(ro); +} + + +void KFormulaWidget::paintEvent(TQPaintEvent* event) +{ + // Always repaint the buffer. This is not so much more work + // than it seems to be as each cursor movement requires a repaint. + TQPainter p( &buffer ); + //p.translate( -fr.x(), -fr.y() ); + formulaView.draw( p, event->rect(), colorGroup() ); + + TQPainter painter; + painter.begin(this); + painter.drawPixmap( event->rect().x(), event->rect().y(), + buffer, event->rect().x(), event->rect().y(), event->rect().width(), event->rect().height() ); + painter.end(); +} + +void KFormulaWidget::keyPressEvent(TQKeyEvent* event) +{ + formulaView.keyPressEvent(event); +} + + +void KFormulaWidget::focusInEvent(TQFocusEvent* event) +{ + formulaView.focusInEvent(event); +} + +void KFormulaWidget::focusOutEvent(TQFocusEvent* event) +{ + formulaView.focusOutEvent(event); +} + +void KFormulaWidget::mousePressEvent(TQMouseEvent* event) +{ + formulaView.mousePressEvent(event); +} + +void KFormulaWidget::mouseReleaseEvent(TQMouseEvent* event) +{ + formulaView.mouseReleaseEvent(event); +} + +void KFormulaWidget::mouseDoubleClickEvent(TQMouseEvent* event) +{ + formulaView.mouseDoubleClickEvent(event); +} + +void KFormulaWidget::mouseMoveEvent(TQMouseEvent* event) +{ + formulaView.mouseMoveEvent(event); +} + +void KFormulaWidget::wheelEvent(TQWheelEvent* event) +{ + formulaView.wheelEvent(event); +} + +void KFormulaWidget::slotFormulaChanged(int width, int height) +{ + // Magic numbers just to see the cursor. + resize(width + 5, height + 5); + buffer.resize(width + 5, height + 5); + // repaint is needed even if the size doesn't change. + //update(); +} + +/** + * The document we show. + */ +Container* KFormulaWidget::getDocument() +{ + return formulaView.getDocument(); +} + +/** + * Our cursor. + */ +FormulaCursor* KFormulaWidget::getCursor() +{ + return formulaView.getCursor(); +} + + +void KFormulaWidget::slotSelectAll() +{ + formulaView.slotSelectAll(); +} + +void KFormulaWidget::slotCursorChanged(bool visible, bool selecting) +{ + emit cursorChanged(visible, selecting); +// kdDebug( 40000 ) << "KFormulaWidget::slotCursorChanged " +// << formulaView.getDirtyArea().x() << " " +// << formulaView.getDirtyArea().y() << " " +// << formulaView.getDirtyArea().width() << " " +// << formulaView.getDirtyArea().height() << " " +// << endl; + // sadly this doesn't work + //update(formulaView.getDirtyArea()); + update(); +} + +#include "kformulawidget.moc" diff --git a/lib/kformula/main.cc b/lib/kformula/main.cc deleted file mode 100644 index c92adfd7..00000000 --- a/lib/kformula/main.cc +++ /dev/null @@ -1,298 +0,0 @@ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "elementtype.h" -#include "kformulacommand.h" -#include "kformulacontainer.h" -#include "kformuladocument.h" -#include "kformulawidget.h" -#include "scrollview.h" - -using namespace KFormula; - - -class TestWidget : public KFormulaWidget { -public: - TestWidget(Container* doc, TQWidget* parent=0, const char* name=0, WFlags f=0) - : KFormulaWidget(doc, parent, name, f) {} - -protected: - virtual void keyPressEvent(TQKeyEvent* event); - -private: -}; - - -void save( const TQString &filename, const TQDomDocument& doc ) -{ - TQFile f( filename ); - if(!f.open(IO_Truncate | IO_ReadWrite)) { - kdWarning( DEBUGID ) << "Error opening file " << filename.latin1() << endl; - return; - } - - TQTextStream stream(&f); - stream.setEncoding(TQTextStream::UnicodeUTF8); - doc.save(stream, 2); - f.close(); -} - - -void load( KFormula::Document* document, const TQString &filename ) -{ - TQFile f(filename); - if (!f.open(IO_ReadOnly)) { - kdWarning( DEBUGID ) << "Error opening file " << filename.latin1() << endl; - return; - } - TQTextStream stream(&f); - stream.setEncoding(TQTextStream::UnicodeUTF8); - TQString content = stream.read(); - f.close(); - //kdDebug( DEBUGID ) << content << endl; - TQDomDocument doc; - if ( !doc.setContent( content ) ) { - return; - } - if ( !document->loadXML( doc ) ) { - kdWarning( DEBUGID ) << "Failed." << endl; - } -} - - -void saveMathML( KFormula::Container* formula, const TQString &filename, bool oasisFormat ) -{ - TQFile f( filename ); - if ( !f.open( IO_Truncate | IO_ReadWrite ) ) { - kdWarning( DEBUGID ) << "Error opening file " << filename.latin1() << endl; - return; - } - - TQTextStream stream( &f ); - stream.setEncoding( TQTextStream::UnicodeUTF8 ); - formula->saveMathML( stream, oasisFormat ); - f.close(); -} - - -void loadMathML( KFormula::Container* formula, const TQString &filename ) -{ - TQFile f( filename ); - if ( !f.open( IO_ReadOnly ) ) { - kdWarning( DEBUGID ) << "Error opening file " << filename.latin1() << endl; - return; - } - TQTextStream stream( &f ); - stream.setEncoding( TQTextStream::UnicodeUTF8 ); - TQString content = stream.read(); - - TQDomDocument doc; - TQString errorMsg; - int errorLine; - int errorColumn; - if ( !doc.setContent( content, true, - &errorMsg, &errorLine, &errorColumn ) ) { - kdWarning( DEBUGID ) << "MathML built error: " << errorMsg - << " at line " << errorLine - << " and column " << errorColumn << endl; - f.close(); - return; - } - - /*kdDebug( DEBUGID ) << "Container::loadMathML\n" - << doc.toCString() << endl;*/ - - if ( !formula->loadMathML( doc ) ) { - kdWarning( DEBUGID ) << "Failed." << endl; - } - f.close(); -} - - -void TestWidget::keyPressEvent(TQKeyEvent* event) -{ - Container* document = getDocument(); - - //int action = event->key(); - int state = event->state(); - //MoveFlag flag = movementFlag(state); - - if ( ( state & TQt::ShiftButton ) && ( state & TQt::ControlButton ) ) { - switch (event->key()) { - case TQt::Key_B: document->document()->wrapper()->appendColumn(); return; - case TQt::Key_I: document->document()->wrapper()->insertColumn(); return; - case TQt::Key_R: document->document()->wrapper()->removeColumn(); return; - case TQt::Key_Z: document->document()->wrapper()->redo(); return; - case TQt::Key_F: saveMathML( document, "test.mml", true/*save to oasis format*/ ); return; - case TQt::Key_M: saveMathML( document, "test.mml", false ); return; - case TQt::Key_O: { - TQString file = KFileDialog::getOpenFileName(); - kdDebug( DEBUGID ) << file << endl; - if( !file.isEmpty() ) { - TQFileInfo fi( file ); - if ( fi.extension() == "mml" ) { - loadMathML( document, file ); - } - else if ( fi.extension() == "xml" ) { - load( document->document(), file ); - } - } - return; - } - } - } - else if (state & TQt::ControlButton) { - switch (event->key()) { - case TQt::Key_1: document->document()->wrapper()->addSum(); return; - case TQt::Key_2: document->document()->wrapper()->addProduct(); return; - case TQt::Key_3: document->document()->wrapper()->addIntegral(); return; - case TQt::Key_4: document->document()->wrapper()->addRoot(); return; - case TQt::Key_5: document->document()->wrapper()->addFraction(); return; - case TQt::Key_6: document->document()->wrapper()->addMatrix(); return; - case TQt::Key_7: document->document()->wrapper()->addOneByTwoMatrix(); return; - case TQt::Key_8: document->document()->wrapper()->addOverline(); return; - case TQt::Key_9: document->document()->wrapper()->addUnderline(); return; - case TQt::Key_A: slotSelectAll(); return; - case TQt::Key_B: document->document()->wrapper()->appendRow(); return; - case TQt::Key_C: document->document()->wrapper()->copy(); return; - case TQt::Key_D: document->document()->wrapper()->removeEnclosing(); return; - case TQt::Key_G: document->document()->wrapper()->makeGreek(); return; - case TQt::Key_I: document->document()->wrapper()->insertRow(); return; - case TQt::Key_R: document->document()->wrapper()->removeRow(); return; - case TQt::Key_K: document->document()->wrapper()->addMultiline(); return; - case TQt::Key_L: document->document()->wrapper()->addGenericLowerIndex(); return; - case TQt::Key_M: loadMathML( document, "test.mml" ); return; - case TQt::Key_O: load( document->document(), "test.xml" ); return; - case TQt::Key_Q: kapp->quit(); return; - case TQt::Key_S: save( "test.xml", document->document()->saveXML() ); return; - case TQt::Key_T: std::cout << document->texString().latin1() << std::endl; return; - case TQt::Key_U: document->document()->wrapper()->addGenericUpperIndex(); return; - case TQt::Key_V: document->document()->wrapper()->paste(); return; - case TQt::Key_X: document->document()->wrapper()->cut(); return; - case TQt::Key_Z: document->document()->wrapper()->undo(); return; - default: - //std::cerr << "Key: " << event->key() << std::endl; - break; - } - } - - KFormulaWidget::keyPressEvent(event); -} - - -ScrollView::ScrollView() - : TQScrollView(), child(0) -{ -} - -void ScrollView::addChild(KFormulaWidget* c, int x, int y) -{ - TQScrollView::addChild(c, x, y); - child = c; - connect(child, TQT_SIGNAL(cursorChanged(bool, bool)), - this, TQT_SLOT(cursorChanged(bool, bool))); -} - -void ScrollView::focusInEvent(TQFocusEvent*) -{ - if (child != 0) child->setFocus(); -} - - -void ScrollView::cursorChanged(bool visible, bool /*selecting*/) -{ - if (visible) { - int x = child->getCursorPoint().x(); - int y = child->getCursorPoint().y(); - ensureVisible(x, y); - } -} - - -static const TDECmdLineOptions options[]= { - { "+file", "File to open", 0 }, - TDECmdLineLastOption -}; - -int main(int argc, char** argv) -{ - TDEAboutData aboutData("math test", "KFormula test", - "0.01", "test", TDEAboutData::License_GPL, - "(c) 2003, Ulrich Kuettler"); - aboutData.addAuthor("Ulrich Kuettler",0, "ulrich.kuettler@gmx.de"); - - TDECmdLineArgs::init(argc, argv, &aboutData); - TDECmdLineArgs::addCmdLineOptions(options); - - TDEApplication app; - - app.connect(&app, TQT_SIGNAL(lastWindowClosed()), &app, TQT_SLOT(quit())); - - DocumentWrapper* wrapper = new DocumentWrapper( kapp->config(), 0 ); - Document* document = new Document; - wrapper->document( document ); - Container* container1 = document->createFormula(); - - ScrollView* scrollview1a = new ScrollView; - - KFormulaWidget* mw1a = new TestWidget(container1, scrollview1a, "test1a"); - - scrollview1a->addChild(mw1a); - scrollview1a->setCaption("Test1a of the formula engine"); - scrollview1a->show(); - - TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs(); - for ( int i = 0; i < args->count(); ++i ) { - TQFileInfo fi( args->url( i ).path() ); - if ( fi.extension() == "mml" ) - loadMathML( container1, args->url( i ).path() ); - else if ( fi.extension() == "xml" ) - load( container1->document(), args->url( i ).path() ); - } - - int result = app.exec(); - - delete container1; - delete wrapper; - - // Make sure there are no elements in the clipboard. - // Okey for a debug app. - TQApplication::clipboard()->clear(); - - int destruct = BasicElement::getEvilDestructionCount(); - if (destruct != 0) { - std::cerr << "BasicElement::EvilDestructionCount: " << destruct << std::endl; - } - destruct = PlainCommand::getEvilDestructionCount(); - if (destruct != 0) { - std::cerr << "PlainCommand::EvilDestructionCount: " << destruct << std::endl; - } - destruct = ElementType::getEvilDestructionCount(); - if (destruct != 0) { - std::cerr << "ElementType::EvilDestructionCount: " << destruct << std::endl; - } - - return result; -} - -#include "scrollview.moc" diff --git a/lib/kformula/main.cpp b/lib/kformula/main.cpp new file mode 100644 index 00000000..c92adfd7 --- /dev/null +++ b/lib/kformula/main.cpp @@ -0,0 +1,298 @@ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "elementtype.h" +#include "kformulacommand.h" +#include "kformulacontainer.h" +#include "kformuladocument.h" +#include "kformulawidget.h" +#include "scrollview.h" + +using namespace KFormula; + + +class TestWidget : public KFormulaWidget { +public: + TestWidget(Container* doc, TQWidget* parent=0, const char* name=0, WFlags f=0) + : KFormulaWidget(doc, parent, name, f) {} + +protected: + virtual void keyPressEvent(TQKeyEvent* event); + +private: +}; + + +void save( const TQString &filename, const TQDomDocument& doc ) +{ + TQFile f( filename ); + if(!f.open(IO_Truncate | IO_ReadWrite)) { + kdWarning( DEBUGID ) << "Error opening file " << filename.latin1() << endl; + return; + } + + TQTextStream stream(&f); + stream.setEncoding(TQTextStream::UnicodeUTF8); + doc.save(stream, 2); + f.close(); +} + + +void load( KFormula::Document* document, const TQString &filename ) +{ + TQFile f(filename); + if (!f.open(IO_ReadOnly)) { + kdWarning( DEBUGID ) << "Error opening file " << filename.latin1() << endl; + return; + } + TQTextStream stream(&f); + stream.setEncoding(TQTextStream::UnicodeUTF8); + TQString content = stream.read(); + f.close(); + //kdDebug( DEBUGID ) << content << endl; + TQDomDocument doc; + if ( !doc.setContent( content ) ) { + return; + } + if ( !document->loadXML( doc ) ) { + kdWarning( DEBUGID ) << "Failed." << endl; + } +} + + +void saveMathML( KFormula::Container* formula, const TQString &filename, bool oasisFormat ) +{ + TQFile f( filename ); + if ( !f.open( IO_Truncate | IO_ReadWrite ) ) { + kdWarning( DEBUGID ) << "Error opening file " << filename.latin1() << endl; + return; + } + + TQTextStream stream( &f ); + stream.setEncoding( TQTextStream::UnicodeUTF8 ); + formula->saveMathML( stream, oasisFormat ); + f.close(); +} + + +void loadMathML( KFormula::Container* formula, const TQString &filename ) +{ + TQFile f( filename ); + if ( !f.open( IO_ReadOnly ) ) { + kdWarning( DEBUGID ) << "Error opening file " << filename.latin1() << endl; + return; + } + TQTextStream stream( &f ); + stream.setEncoding( TQTextStream::UnicodeUTF8 ); + TQString content = stream.read(); + + TQDomDocument doc; + TQString errorMsg; + int errorLine; + int errorColumn; + if ( !doc.setContent( content, true, + &errorMsg, &errorLine, &errorColumn ) ) { + kdWarning( DEBUGID ) << "MathML built error: " << errorMsg + << " at line " << errorLine + << " and column " << errorColumn << endl; + f.close(); + return; + } + + /*kdDebug( DEBUGID ) << "Container::loadMathML\n" + << doc.toCString() << endl;*/ + + if ( !formula->loadMathML( doc ) ) { + kdWarning( DEBUGID ) << "Failed." << endl; + } + f.close(); +} + + +void TestWidget::keyPressEvent(TQKeyEvent* event) +{ + Container* document = getDocument(); + + //int action = event->key(); + int state = event->state(); + //MoveFlag flag = movementFlag(state); + + if ( ( state & TQt::ShiftButton ) && ( state & TQt::ControlButton ) ) { + switch (event->key()) { + case TQt::Key_B: document->document()->wrapper()->appendColumn(); return; + case TQt::Key_I: document->document()->wrapper()->insertColumn(); return; + case TQt::Key_R: document->document()->wrapper()->removeColumn(); return; + case TQt::Key_Z: document->document()->wrapper()->redo(); return; + case TQt::Key_F: saveMathML( document, "test.mml", true/*save to oasis format*/ ); return; + case TQt::Key_M: saveMathML( document, "test.mml", false ); return; + case TQt::Key_O: { + TQString file = KFileDialog::getOpenFileName(); + kdDebug( DEBUGID ) << file << endl; + if( !file.isEmpty() ) { + TQFileInfo fi( file ); + if ( fi.extension() == "mml" ) { + loadMathML( document, file ); + } + else if ( fi.extension() == "xml" ) { + load( document->document(), file ); + } + } + return; + } + } + } + else if (state & TQt::ControlButton) { + switch (event->key()) { + case TQt::Key_1: document->document()->wrapper()->addSum(); return; + case TQt::Key_2: document->document()->wrapper()->addProduct(); return; + case TQt::Key_3: document->document()->wrapper()->addIntegral(); return; + case TQt::Key_4: document->document()->wrapper()->addRoot(); return; + case TQt::Key_5: document->document()->wrapper()->addFraction(); return; + case TQt::Key_6: document->document()->wrapper()->addMatrix(); return; + case TQt::Key_7: document->document()->wrapper()->addOneByTwoMatrix(); return; + case TQt::Key_8: document->document()->wrapper()->addOverline(); return; + case TQt::Key_9: document->document()->wrapper()->addUnderline(); return; + case TQt::Key_A: slotSelectAll(); return; + case TQt::Key_B: document->document()->wrapper()->appendRow(); return; + case TQt::Key_C: document->document()->wrapper()->copy(); return; + case TQt::Key_D: document->document()->wrapper()->removeEnclosing(); return; + case TQt::Key_G: document->document()->wrapper()->makeGreek(); return; + case TQt::Key_I: document->document()->wrapper()->insertRow(); return; + case TQt::Key_R: document->document()->wrapper()->removeRow(); return; + case TQt::Key_K: document->document()->wrapper()->addMultiline(); return; + case TQt::Key_L: document->document()->wrapper()->addGenericLowerIndex(); return; + case TQt::Key_M: loadMathML( document, "test.mml" ); return; + case TQt::Key_O: load( document->document(), "test.xml" ); return; + case TQt::Key_Q: kapp->quit(); return; + case TQt::Key_S: save( "test.xml", document->document()->saveXML() ); return; + case TQt::Key_T: std::cout << document->texString().latin1() << std::endl; return; + case TQt::Key_U: document->document()->wrapper()->addGenericUpperIndex(); return; + case TQt::Key_V: document->document()->wrapper()->paste(); return; + case TQt::Key_X: document->document()->wrapper()->cut(); return; + case TQt::Key_Z: document->document()->wrapper()->undo(); return; + default: + //std::cerr << "Key: " << event->key() << std::endl; + break; + } + } + + KFormulaWidget::keyPressEvent(event); +} + + +ScrollView::ScrollView() + : TQScrollView(), child(0) +{ +} + +void ScrollView::addChild(KFormulaWidget* c, int x, int y) +{ + TQScrollView::addChild(c, x, y); + child = c; + connect(child, TQT_SIGNAL(cursorChanged(bool, bool)), + this, TQT_SLOT(cursorChanged(bool, bool))); +} + +void ScrollView::focusInEvent(TQFocusEvent*) +{ + if (child != 0) child->setFocus(); +} + + +void ScrollView::cursorChanged(bool visible, bool /*selecting*/) +{ + if (visible) { + int x = child->getCursorPoint().x(); + int y = child->getCursorPoint().y(); + ensureVisible(x, y); + } +} + + +static const TDECmdLineOptions options[]= { + { "+file", "File to open", 0 }, + TDECmdLineLastOption +}; + +int main(int argc, char** argv) +{ + TDEAboutData aboutData("math test", "KFormula test", + "0.01", "test", TDEAboutData::License_GPL, + "(c) 2003, Ulrich Kuettler"); + aboutData.addAuthor("Ulrich Kuettler",0, "ulrich.kuettler@gmx.de"); + + TDECmdLineArgs::init(argc, argv, &aboutData); + TDECmdLineArgs::addCmdLineOptions(options); + + TDEApplication app; + + app.connect(&app, TQT_SIGNAL(lastWindowClosed()), &app, TQT_SLOT(quit())); + + DocumentWrapper* wrapper = new DocumentWrapper( kapp->config(), 0 ); + Document* document = new Document; + wrapper->document( document ); + Container* container1 = document->createFormula(); + + ScrollView* scrollview1a = new ScrollView; + + KFormulaWidget* mw1a = new TestWidget(container1, scrollview1a, "test1a"); + + scrollview1a->addChild(mw1a); + scrollview1a->setCaption("Test1a of the formula engine"); + scrollview1a->show(); + + TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs(); + for ( int i = 0; i < args->count(); ++i ) { + TQFileInfo fi( args->url( i ).path() ); + if ( fi.extension() == "mml" ) + loadMathML( container1, args->url( i ).path() ); + else if ( fi.extension() == "xml" ) + load( container1->document(), args->url( i ).path() ); + } + + int result = app.exec(); + + delete container1; + delete wrapper; + + // Make sure there are no elements in the clipboard. + // Okey for a debug app. + TQApplication::clipboard()->clear(); + + int destruct = BasicElement::getEvilDestructionCount(); + if (destruct != 0) { + std::cerr << "BasicElement::EvilDestructionCount: " << destruct << std::endl; + } + destruct = PlainCommand::getEvilDestructionCount(); + if (destruct != 0) { + std::cerr << "PlainCommand::EvilDestructionCount: " << destruct << std::endl; + } + destruct = ElementType::getEvilDestructionCount(); + if (destruct != 0) { + std::cerr << "ElementType::EvilDestructionCount: " << destruct << std::endl; + } + + return result; +} + +#include "scrollview.moc" diff --git a/lib/kformula/matrixelement.cc b/lib/kformula/matrixelement.cc deleted file mode 100644 index 6b878380..00000000 --- a/lib/kformula/matrixelement.cc +++ /dev/null @@ -1,2692 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2001 Andrea Rizzi - Ulrich Kuettler - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - -#include -#include -#include - -#include -#include - -#include "MatrixDialog.h" -#include "elementvisitor.h" -#include "formulaelement.h" -#include "formulacursor.h" -#include "kformulacontainer.h" -#include "kformulacommand.h" -#include "matrixelement.h" -#include "sequenceelement.h" -#include "spaceelement.h" - - -KFORMULA_NAMESPACE_BEGIN - - -class MatrixSequenceElement : public SequenceElement { - typedef SequenceElement inherited; -public: - - MatrixSequenceElement( BasicElement* parent = 0 ) : SequenceElement( parent ) {} - virtual MatrixSequenceElement* clone() { - return new MatrixSequenceElement( *this ); - } - - /** - * This is called by the container to get a command depending on - * the current cursor position (this is how the element gets chosen) - * and the request. - * - * @returns the command that performs the requested action with - * the containers active cursor. - */ - virtual KCommand* buildCommand( Container*, Request* ); -}; - - -class KFCRemoveRow : public Command { -public: - KFCRemoveRow( const TQString& name, Container* document, MatrixElement* m, uint r, uint c ); - ~KFCRemoveRow(); - - virtual void execute(); - virtual void unexecute(); - -protected: - MatrixElement* matrix; - uint rowPos; - uint colPos; - - TQPtrList* row; -}; - - -class KFCInsertRow : public KFCRemoveRow { -public: - KFCInsertRow( const TQString& name, Container* document, MatrixElement* m, uint r, uint c ); - - virtual void execute() { KFCRemoveRow::unexecute(); } - virtual void unexecute() { KFCRemoveRow::execute(); } -}; - - -class KFCRemoveColumn : public Command { -public: - KFCRemoveColumn( const TQString& name, Container* document, MatrixElement* m, uint r, uint c ); - ~KFCRemoveColumn(); - - virtual void execute(); - virtual void unexecute(); - -protected: - MatrixElement* matrix; - uint rowPos; - uint colPos; - - TQPtrList* column; -}; - - -class KFCInsertColumn : public KFCRemoveColumn { -public: - KFCInsertColumn( const TQString& name, Container* document, MatrixElement* m, uint r, uint c ); - - virtual void execute() { KFCRemoveColumn::unexecute(); } - virtual void unexecute() { KFCRemoveColumn::execute(); } -}; - - -KCommand* MatrixSequenceElement::buildCommand( Container* container, Request* request ) -{ - FormulaCursor* cursor = container->activeCursor(); - if ( cursor->isReadOnly() ) { - return 0; - } - - switch ( *request ) { - case req_appendColumn: - case req_appendRow: - case req_insertColumn: - case req_removeColumn: - case req_insertRow: - case req_removeRow: { - MatrixElement* matrix = static_cast( getParent() ); - FormulaCursor* cursor = container->activeCursor(); - for ( uint row = 0; row < matrix->getRows(); row++ ) { - for ( uint col = 0; col < matrix->getColumns(); col++ ) { - if ( matrix->getElement( row, col ) == cursor->getElement() ) { - switch ( *request ) { - case req_appendColumn: - return new KFCInsertColumn( i18n( "Append Column" ), container, matrix, row, matrix->getColumns() ); - case req_appendRow: - return new KFCInsertRow( i18n( "Append Row" ), container, matrix, matrix->getRows(), col ); - case req_insertColumn: - return new KFCInsertColumn( i18n( "Insert Column" ), container, matrix, row, col ); - case req_removeColumn: - if ( matrix->getColumns() > 1 ) { - return new KFCRemoveColumn( i18n( "Remove Column" ), container, matrix, row, col ); - } - break; - case req_insertRow: - return new KFCInsertRow( i18n( "Insert Row" ), container, matrix, row, col ); - case req_removeRow: - if ( matrix->getRows() > 1 ) { - return new KFCRemoveRow( i18n( "Remove Row" ), container, matrix, row, col ); - } - break; - default: - break; - } - } - } - } - kdWarning( DEBUGID ) << "MatrixSequenceElement::buildCommand: Sequence not found." << endl; - break; - } - default: - break; - } - return inherited::buildCommand( container, request ); -} - - -KFCRemoveRow::KFCRemoveRow( const TQString& name, Container* document, MatrixElement* m, uint r, uint c ) - : Command( name, document ), matrix( m ), rowPos( r ), colPos( c ), row( 0 ) -{ -} - -KFCRemoveRow::~KFCRemoveRow() -{ - delete row; -} - -void KFCRemoveRow::execute() -{ - FormulaCursor* cursor = getExecuteCursor(); - row = matrix->content.at( rowPos ); - FormulaElement* formula = matrix->formula(); - for ( uint i = matrix->getColumns(); i > 0; i-- ) { - formula->elementRemoval( row->at( i-1 ) ); - } - matrix->content.take( rowPos ); - formula->changed(); - if ( rowPos < matrix->getRows() ) { - matrix->getElement( rowPos, colPos )->goInside( cursor ); - } - else { - matrix->getElement( rowPos-1, colPos )->goInside( cursor ); - } - testDirty(); -} - -void KFCRemoveRow::unexecute() -{ - matrix->content.insert( rowPos, row ); - row = 0; - FormulaCursor* cursor = getExecuteCursor(); - matrix->getElement( rowPos, colPos )->goInside( cursor ); - matrix->formula()->changed(); - testDirty(); -} - - -KFCInsertRow::KFCInsertRow( const TQString& name, Container* document, MatrixElement* m, uint r, uint c ) - : KFCRemoveRow( name, document, m, r, c ) -{ - row = new TQPtrList< MatrixSequenceElement >; - row->setAutoDelete( true ); - for ( uint i = 0; i < matrix->getColumns(); i++ ) { - row->append( new MatrixSequenceElement( matrix ) ); - } -} - - -KFCRemoveColumn::KFCRemoveColumn( const TQString& name, Container* document, MatrixElement* m, uint r, uint c ) - : Command( name, document ), matrix( m ), rowPos( r ), colPos( c ) -{ - column = new TQPtrList< MatrixSequenceElement >; - column->setAutoDelete( true ); -} - -KFCRemoveColumn::~KFCRemoveColumn() -{ - delete column; -} - -void KFCRemoveColumn::execute() -{ - FormulaCursor* cursor = getExecuteCursor(); - FormulaElement* formula = matrix->formula(); - for ( uint i = 0; i < matrix->getRows(); i++ ) { - column->append( matrix->getElement( i, colPos ) ); - formula->elementRemoval( column->at( i ) ); - matrix->content.at( i )->take( colPos ); - } - formula->changed(); - if ( colPos < matrix->getColumns() ) { - matrix->getElement( rowPos, colPos )->goInside( cursor ); - } - else { - matrix->getElement( rowPos, colPos-1 )->goInside( cursor ); - } - testDirty(); -} - -void KFCRemoveColumn::unexecute() -{ - for ( uint i = 0; i < matrix->getRows(); i++ ) { - matrix->content.at( i )->insert( colPos, column->take( 0 ) ); - } - FormulaCursor* cursor = getExecuteCursor(); - matrix->getElement( rowPos, colPos )->goInside( cursor ); - matrix->formula()->changed(); - testDirty(); -} - - -KFCInsertColumn::KFCInsertColumn( const TQString& name, Container* document, MatrixElement* m, uint r, uint c ) - : KFCRemoveColumn( name, document, m, r, c ) -{ - for ( uint i = 0; i < matrix->getRows(); i++ ) { - column->append( new MatrixSequenceElement( matrix ) ); - } -} - - -MatrixElement::MatrixElement(uint rows, uint columns, BasicElement* parent) - : BasicElement(parent), - m_rowNumber( 0 ), - m_align( NoAlign ), - m_widthType( NoSize ), - m_frame( NoLine ), - m_frameHSpacing( NoSize ), - m_frameVSpacing( NoSize ), - m_side( NoSide ), - m_minLabelSpacingType( NoSize ), - m_customEqualRows( false ), - m_customEqualColumns( false ), - m_customDisplayStyle( false ) -{ - for (uint r = 0; r < rows; r++) { - TQPtrList< MatrixSequenceElement >* list = new TQPtrList< MatrixSequenceElement >; - list->setAutoDelete(true); - for (uint c = 0; c < columns; c++) { - list->append(new MatrixSequenceElement(this)); - } - content.append(list); - } - content.setAutoDelete(true); -} - -MatrixElement::~MatrixElement() -{ -} - - -MatrixElement::MatrixElement( const MatrixElement& other ) - : BasicElement( other ) -{ - uint rows = other.getRows(); - uint columns = other.getColumns(); - - TQPtrListIterator< TQPtrList< MatrixSequenceElement > > rowIter( other.content ); - for (uint r = 0; r < rows; r++) { - ++rowIter; - TQPtrListIterator< MatrixSequenceElement > colIter( *rowIter.current() ); - - TQPtrList< MatrixSequenceElement >* list = new TQPtrList< MatrixSequenceElement >; - list->setAutoDelete(true); - for (uint c = 0; c < columns; c++) { - ++colIter; - MatrixSequenceElement *mse = - //new MatrixSequenceElement( *( other.getElement( r, c ) ) ); - new MatrixSequenceElement( *colIter.current() ); - list->append( mse ); - mse->setParent( this ); - } - content.append(list); - } - content.setAutoDelete(true); -} - - -bool MatrixElement::accept( ElementVisitor* visitor ) -{ - return visitor->visit( this ); -} - - -void MatrixElement::entered( SequenceElement* /*child*/ ) -{ - formula()->tell( i18n( "Matrix element" ) ); -} - - -BasicElement* MatrixElement::goToPos( FormulaCursor* cursor, bool& handled, - const LuPixelPoint& point, const LuPixelPoint& parentOrigin ) -{ - BasicElement* e = BasicElement::goToPos(cursor, handled, point, parentOrigin); - if (e != 0) { - LuPixelPoint myPos(parentOrigin.x() + getX(), - parentOrigin.y() + getY()); - - uint rows = getRows(); - uint columns = getColumns(); - - for (uint r = 0; r < rows; r++) { - for (uint c = 0; c < columns; c++) { - BasicElement* element = getElement(r, c); - e = element->goToPos(cursor, handled, point, myPos); - if (e != 0) { - return e; - } - } - } - - // We are in one of those gaps. - luPixel dx = point.x() - myPos.x(); - luPixel dy = point.y() - myPos.y(); - - uint row = rows; - for (uint r = 0; r < rows; r++) { - BasicElement* element = getElement(r, 0); - if (element->getY() > dy) { - row = r; - break; - } - } - if (row == 0) { - BasicElement* element = getParent(); - element->moveLeft(cursor, this); - handled = true; - return element; - } - row--; - - uint column = columns; - for (uint c = 0; c < columns; c++) { - BasicElement* element = getElement(row, c); - if (element->getX() > dx) { - column = c; - break; - } - } - if (column == 0) { - BasicElement* element = getParent(); - element->moveLeft(cursor, this); - handled = true; - return element; - } - column--; - - // Rescan the rows with the actual colums required. - row = rows; - for (uint r = 0; r < rows; r++) { - BasicElement* element = getElement(r, column); - if (element->getY() > dy) { - row = r; - break; - } - } - if (row == 0) { - BasicElement* element = getParent(); - element->moveLeft(cursor, this); - handled = true; - return element; - } - row--; - - BasicElement* element = getElement(row, column); - element->moveLeft(cursor, this); - handled = true; - return element; - } - return 0; -} - - -// drawing -// -// Drawing depends on a context which knows the required properties like -// fonts, spaces and such. -// It is essential to calculate elements size with the same context -// before you draw. - -/** - * Calculates our width and height and - * our children's parentPosition. - */ -void MatrixElement::calcSizes( const ContextStyle& context, - ContextStyle::TextStyle tstyle, - ContextStyle::IndexStyle istyle, - StyleAttributes& style ) -{ - TQMemArray toMidlines(getRows()); - TQMemArray fromMidlines(getRows()); - TQMemArray widths(getColumns()); - - toMidlines.fill(0); - fromMidlines.fill(0); - widths.fill(0); - - uint rows = getRows(); - uint columns = getColumns(); - - ContextStyle::TextStyle i_tstyle = context.convertTextStyleFraction(tstyle); - ContextStyle::IndexStyle i_istyle = context.convertIndexStyleUpper(istyle); - double factor = style.sizeFactor(); - - for (uint r = 0; r < rows; r++) { - TQPtrList< MatrixSequenceElement >* list = content.at(r); - for (uint c = 0; c < columns; c++) { - SequenceElement* element = list->at(c); - element->calcSizes( context, i_tstyle, i_istyle, style ); - toMidlines[r] = TQMAX(toMidlines[r], element->axis( context, i_tstyle, factor )); - fromMidlines[r] = TQMAX(fromMidlines[r], - element->getHeight()-element->axis( context, i_tstyle, factor )); - widths[c] = TQMAX(widths[c], element->getWidth()); - } - } - - luPixel distX = context.ptToPixelX( context.getThinSpace( tstyle, factor ) ); - luPixel distY = context.ptToPixelY( context.getThinSpace( tstyle, factor ) ); - - luPixel yPos = 0; - for (uint r = 0; r < rows; r++) { - TQPtrList< MatrixSequenceElement >* list = content.at(r); - luPixel xPos = 0; - yPos += toMidlines[r]; - for (uint c = 0; c < columns; c++) { - SequenceElement* element = list->at(c); - switch (context.getMatrixAlignment()) { - case ContextStyle::left: - element->setX(xPos); - break; - case ContextStyle::center: - element->setX(xPos + (widths[c] - element->getWidth())/2); - break; - case ContextStyle::right: - element->setX(xPos + widths[c] - element->getWidth()); - break; - } - element->setY(yPos - element->axis( context, i_tstyle, factor )); - xPos += widths[c] + distX; - } - yPos += fromMidlines[r] + distY; - } - - luPixel width = distX * (columns - 1); - luPixel height = distY * (rows - 1); - - for (uint r = 0; r < rows; r++) height += toMidlines[r] + fromMidlines[r]; - for (uint c = 0; c < columns; c++) width += widths[c]; - - setWidth(width); - setHeight(height); - if ((rows == 2) && (columns == 1)) { - setBaseline( getMainChild()->getHeight() + distY / 2 + context.axisHeight( tstyle, factor ) ); - } - else { - setBaseline( height/2 + context.axisHeight( tstyle, factor ) ); - } -} - -/** - * Draws the whole element including its children. - * The `parentOrigin' is the point this element's parent starts. - * We can use our parentPosition to get our own origin then. - */ -void MatrixElement::draw( TQPainter& painter, const LuPixelRect& rect, - const ContextStyle& context, - ContextStyle::TextStyle tstyle, - ContextStyle::IndexStyle istyle, - StyleAttributes& style, - const LuPixelPoint& parentOrigin ) -{ - LuPixelPoint myPos( parentOrigin.x()+getX(), parentOrigin.y()+getY() ); - //if ( !LuPixelRect( myPos.x(), myPos.y(), getWidth(), getHeight() ).intersects( rect ) ) - // return; - - uint rows = getRows(); - uint columns = getColumns(); - - for (uint r = 0; r < rows; r++) { - for (uint c = 0; c < columns; c++) { - getElement(r, c)->draw(painter, rect, context, - context.convertTextStyleFraction(tstyle), - context.convertIndexStyleUpper(istyle), - style, - myPos); - } - } - - // Debug - //painter.setPen(TQt::red); - //painter.drawRect(myPos.x(), myPos.y(), getWidth(), getHeight()); -} - - -void MatrixElement::dispatchFontCommand( FontCommand* cmd ) -{ - uint rows = getRows(); - uint columns = getColumns(); - - for (uint r = 0; r < rows; r++) { - for (uint c = 0; c < columns; c++) { - getElement(r, c)->dispatchFontCommand( cmd ); - } - } -} - - -// navigation -// -// The elements are responsible to handle cursor movement themselves. -// To do this they need to know the direction the cursor moves and -// the element it comes from. -// -// The cursor might be in normal or in selection mode. - -/** - * Enters this element while moving to the left starting inside - * the element `from'. Searches for a cursor position inside - * this element or to the left of it. - */ -void MatrixElement::moveLeft(FormulaCursor* cursor, BasicElement* from) -{ - if (cursor->isSelectionMode()) { - getParent()->moveLeft(cursor, this); - } - else { - if (from == getParent()) { - getElement(getRows()-1, getColumns()-1)->moveLeft(cursor, this); - } - else { - bool linear = cursor->getLinearMovement(); - uint row = 0; - uint column = 0; - if (searchElement(from, row, column)) { - if (column > 0) { - getElement(row, column-1)->moveLeft(cursor, this); - } - else if (linear && (row > 0)) { - getElement(row-1, getColumns()-1)->moveLeft(cursor, this); - } - else { - getParent()->moveLeft(cursor, this); - } - } - else { - getParent()->moveLeft(cursor, this); - } - } - } -} - -/** - * Enters this element while moving to the right starting inside - * the element `from'. Searches for a cursor position inside - * this element or to the right of it. - */ -void MatrixElement::moveRight(FormulaCursor* cursor, BasicElement* from) -{ - if (cursor->isSelectionMode()) { - getParent()->moveRight(cursor, this); - } - else { - if (from == getParent()) { - getElement(0, 0)->moveRight(cursor, this); - } - else { - bool linear = cursor->getLinearMovement(); - uint row = 0; - uint column = 0; - if (searchElement(from, row, column)) { - if (column < getColumns()-1) { - getElement(row, column+1)->moveRight(cursor, this); - } - else if (linear && (row < getRows()-1)) { - getElement(row+1, 0)->moveRight(cursor, this); - } - else { - getParent()->moveRight(cursor, this); - } - } - else { - getParent()->moveRight(cursor, this); - } - } - } -} - -/** - * Enters this element while moving up starting inside - * the element `from'. Searches for a cursor position inside - * this element or above it. - */ -void MatrixElement::moveUp(FormulaCursor* cursor, BasicElement* from) -{ - if (cursor->isSelectionMode()) { - getParent()->moveUp(cursor, this); - } - else { - if (from == getParent()) { - getElement(0, 0)->moveRight(cursor, this); - } - else { - uint row = 0; - uint column = 0; - if (searchElement(from, row, column)) { - if (row > 0) { - getElement(row-1, column)->moveRight(cursor, this); - } - else { - getParent()->moveUp(cursor, this); - } - } - else { - getParent()->moveUp(cursor, this); - } - } - } -} - -/** - * Enters this element while moving down starting inside - * the element `from'. Searches for a cursor position inside - * this element or below it. - */ -void MatrixElement::moveDown(FormulaCursor* cursor, BasicElement* from) -{ - if (cursor->isSelectionMode()) { - getParent()->moveDown(cursor, this); - } - else { - if (from == getParent()) { - getElement(0, 0)->moveRight(cursor, this); - } - else { - uint row = 0; - uint column = 0; - if (searchElement(from, row, column)) { - if (row < getRows()-1) { - getElement(row+1, column)->moveRight(cursor, this); - } - else { - getParent()->moveDown(cursor, this); - } - } - else { - getParent()->moveDown(cursor, this); - } - } - } -} - -/** - * Sets the cursor inside this element to its start position. - * For most elements that is the main child. - */ -void MatrixElement::goInside(FormulaCursor* cursor) -{ - getElement(0, 0)->goInside(cursor); -} - - -// If there is a main child we must provide the insert/remove semantics. -SequenceElement* MatrixElement::getMainChild() -{ - return content.at(0)->at(0); -} - -void MatrixElement::selectChild(FormulaCursor* cursor, BasicElement* child) -{ - uint rows = getRows(); - uint columns = getColumns(); - for (uint r = 0; r < rows; r++) { - for (uint c = 0; c < columns; c++) { - if (child == getElement(r, c)) { - cursor->setTo(this, r*columns+c); - } - } - } -} - -const MatrixSequenceElement* MatrixElement::getElement( uint row, uint column ) const -{ - TQPtrListIterator< TQPtrList < MatrixSequenceElement > > rows( content ); - rows += row; - if ( ! rows.current() ) - return 0; - - TQPtrListIterator< MatrixSequenceElement > cols ( *rows.current() ); - cols += column; - return cols.current(); -} - - -bool MatrixElement::searchElement(BasicElement* element, uint& row, uint& column) -{ - uint rows = getRows(); - uint columns = getColumns(); - for (uint r = 0; r < rows; r++) { - for (uint c = 0; c < columns; c++) { - if (element == getElement(r, c)) { - row = r; - column = c; - return true; - } - } - } - return false; -} - - -/** - * Appends our attributes to the dom element. - */ -void MatrixElement::writeDom(TQDomElement element) -{ - BasicElement::writeDom(element); - - uint rows = getRows(); - uint cols = getColumns(); - - element.setAttribute("ROWS", rows); - element.setAttribute("COLUMNS", cols); - - TQDomDocument doc = element.ownerDocument(); - - for (uint r = 0; r < rows; r++) { - for (uint c = 0; c < cols; c++) { - TQDomElement tmp = getElement(r,c)->getElementDom(doc); - element.appendChild(tmp); - } - element.appendChild(doc.createComment("end of row")); - } -} - -/** - * Reads our attributes from the element. - * Returns false if it failed. - */ -bool MatrixElement::readAttributesFromDom(TQDomElement element) -{ - if (!BasicElement::readAttributesFromDom(element)) { - return false; - } - uint rows = 0; - TQString rowStr = element.attribute("ROWS"); - if(!rowStr.isNull()) { - rows = rowStr.toInt(); - } - if (rows == 0) { - kdWarning( DEBUGID ) << "Rows <= 0 in MatrixElement." << endl; - return false; - } - - TQString columnStr = element.attribute("COLUMNS"); - uint cols = 0; - if(!columnStr.isNull()) { - cols = columnStr.toInt(); - } - if (cols == 0) { - kdWarning( DEBUGID ) << "Columns <= 0 in MatrixElement." << endl; - return false; - } - - content.clear(); - for (uint r = 0; r < rows; r++) { - TQPtrList< MatrixSequenceElement >* list = new TQPtrList< MatrixSequenceElement >; - list->setAutoDelete(true); - content.append(list); - for (uint c = 0; c < cols; c++) { - MatrixSequenceElement* element = new MatrixSequenceElement(this); - list->append(element); - } - } - return true; -} - -/** - * Reads our content from the node. Sets the node to the next node - * that needs to be read. - * Returns false if it failed. - */ -bool MatrixElement::readContentFromDom(TQDomNode& node) -{ - if (!BasicElement::readContentFromDom(node)) { - return false; - } - - uint rows = getRows(); - uint cols = getColumns(); - - uint r = 0; - uint c = 0; - while ( !node.isNull() && r < rows ) { - if ( node.isElement() ) { - SequenceElement* element = getElement( r, c ); - TQDomElement e = node.toElement(); - if ( !element->buildFromDom( e ) ) { - return false; - } - c++; - if ( c == cols ) { - c = 0; - r++; - } - } - node = node.nextSibling(); - } - return true; -} - -bool MatrixElement::readAttributesFromMathMLDom( const TQDomElement& element ) -{ - if ( ! BasicElement::readAttributesFromMathMLDom( element ) ) { - return false; - } - - TQString alignStr = element.attribute( "align" ).lower(); - if ( ! alignStr.isNull() ) { - if ( alignStr.find( "top" ) != -1 ) { - m_align = TopAlign; - } - else if ( alignStr.find( "bottom" ) != -1 ) { - m_align = BottomAlign; - } - else if ( alignStr.find( "center" ) != -1 ) { - m_align = CenterAlign; - } - else if ( alignStr.find( "baseline" ) != -1 ) { - m_align = BaselineAlign; - } - else if ( alignStr.find( "axis" ) != -1 ) { - m_align = AxisAlign; - } - int index = alignStr.findRev( ' ' ); - if ( index != -1 ) { - m_rowNumber = alignStr.right( index + 1 ).toInt(); - } - } - TQString rowalignStr = element.attribute( "rowalign" ).lower(); - if ( ! rowalignStr.isNull() ) { - TQStringList list = TQStringList::split( ' ', rowalignStr ); - for ( TQStringList::iterator it = list.begin(); it != list.end(); it++ ) { - if ( *it == "top" ) { - m_rowAlign.append( TopAlign ); - } - else if ( *it == "bottom" ) { - m_rowAlign.append( BottomAlign ); - } - else if ( *it == "center" ) { - m_rowAlign.append( CenterAlign ); - } - else if ( *it == "baseline" ) { - m_rowAlign.append( BaselineAlign ); - } - else if ( *it == "axis" ) { - m_rowAlign.append( AxisAlign ); - } - } - } - TQString columnalignStr = element.attribute( "columnalign" ).lower(); - if ( ! columnalignStr.isNull() ) { - TQStringList list = TQStringList::split( ' ', columnalignStr ); - for ( TQStringList::iterator it = list.begin(); it != list.end(); it++ ) { - if ( *it == "left" ) { - m_columnAlign.append( LeftHorizontalAlign ); - } - else if ( *it == "center" ) { - m_columnAlign.append( CenterHorizontalAlign ); - } - else if ( *it == "right" ) { - m_columnAlign.append( RightHorizontalAlign ); - } - } - } - TQString alignmentscopeStr = element.attribute( "alignmentscope" ).lower(); - if ( ! alignmentscopeStr.isNull() ) { - TQStringList list = TQStringList::split( ' ', alignmentscopeStr ); - for ( TQStringList::iterator it = list.begin(); it != list.end(); it++ ) { - if ( *it == "true" ) { - m_alignmentScope.append( true ); - } - else if ( *it == "false" ) { - m_alignmentScope.append( false ); - } - } - } - TQString columnwidthStr = element.attribute( "columnwidth" ).lower(); - if ( columnwidthStr.isNull() ) { - TQStringList list = TQStringList::split( ' ', columnwidthStr ); - for ( TQStringList::iterator it = list.begin(); it != list.end(); it++ ) { - SizeType type = NoSize; - double length; - if ( *it == "auto" ) { - type = AutoSize; - } - else if ( *it == "fit" ) { - type = FitSize; - } - else { - length = getSize( columnwidthStr, &type ); - if ( type == NoSize ) { - type = getSpace( columnwidthStr ); - } - } - if ( type != NoSize ) { - m_columnWidthType.append( type ); - if ( type == RelativeSize || type == AbsoluteSize || type == PixelSize ) { - m_columnWidth.append( length ); - } - } - } - } - TQString widthStr = element.attribute( "width" ).lower(); - if ( ! widthStr.isNull() ) { - if ( widthStr == "auto" ) { - m_widthType = AutoSize; - } - else { - m_width = getSize( widthStr, &m_widthType ); - } - } - TQString rowspacingStr = element.attribute( "rowspacing" ).lower(); - if ( ! rowspacingStr.isNull() ) { - TQStringList list = TQStringList::split( ' ', rowspacingStr ); - for ( TQStringList::iterator it = list.begin(); it != list.end(); it++ ) { - SizeType type; - double length = getSize( *it, &type ); - if ( type != NoSize ) { - m_rowSpacingType.append( type ); - m_rowSpacing.append( length ); - } - } - } - TQString columnspacingStr = element.attribute( "columnspacing" ).lower(); - if ( ! columnspacingStr.isNull() ) { - TQStringList list = TQStringList::split( ' ', columnspacingStr ); - for ( TQStringList::iterator it = list.begin(); it != list.end(); it++ ) { - SizeType type; - double length = getSize( *it, &type ); - if ( type == NoSize ) { - type = getSpace( columnspacingStr ); - } - if ( type != NoSize ) { - m_columnSpacingType.append( type ); - if ( type == RelativeSize || type == AbsoluteSize || type == PixelSize ) { - m_columnSpacing.append( length ); - } - } - } - } - TQString rowlinesStr = element.attribute( "rowlines" ).lower(); - if ( ! rowlinesStr.isNull() ) { - TQStringList list = TQStringList::split( ' ', rowlinesStr ); - for ( TQStringList::iterator it = list.begin(); it != list.end(); it++ ) { - if ( *it == "none" ) { - m_rowLines.append( NoneLine ); - } - else if ( *it == "solid" ) { - m_rowLines.append( SolidLine ); - } - else if ( *it == "dashed" ) { - m_rowLines.append( DashedLine ); - } - } - } - TQString columnlinesStr = element.attribute( "columnlines" ).lower(); - if ( ! columnlinesStr.isNull() ) { - TQStringList list = TQStringList::split( ' ', columnlinesStr ); - for ( TQStringList::iterator it = list.begin(); it != list.end(); it++ ) { - if ( *it == "none" ) { - m_columnLines.append( NoneLine ); - } - else if ( *it == "solid" ) { - m_columnLines.append( SolidLine ); - } - else if ( *it == "dashed" ) { - m_columnLines.append( DashedLine ); - } - } - } - TQString frameStr = element.attribute( "frame" ).stripWhiteSpace().lower(); - if ( ! frameStr.isNull() ) { - if ( frameStr == "none" ) { - m_frame = NoneLine; - } - else if ( frameStr == "solid" ) { - m_frame = SolidLine; - } - else if ( frameStr == "dashed" ) { - m_frame = DashedLine; - } - } - TQString framespacingStr = element.attribute( "framespacing" ); - if ( ! framespacingStr.isNull() ) { - TQStringList list = TQStringList::split( ' ', framespacingStr ); - m_frameHSpacing = getSize( list[0], &m_frameHSpacingType ); - if ( m_frameHSpacingType == NoSize ) { - m_frameHSpacingType = getSpace( list[0] ); - } - if ( list.count() > 1 ) { - m_frameVSpacing = getSize( list[1], &m_frameVSpacingType ); - if ( m_frameVSpacingType == NoSize ) { - m_frameVSpacingType = getSpace( list[1] ); - } - } - } - TQString equalrowsStr = element.attribute( "equalrows" ).stripWhiteSpace().lower(); - if ( ! equalrowsStr.isNull() ) { - m_customEqualRows = true; - if ( equalrowsStr == "false" ) { - m_equalRows = false; - } - else { - m_equalRows = true; - } - } - TQString equalcolumnsStr = element.attribute( "equalcolumns" ).stripWhiteSpace().lower(); - if ( ! equalcolumnsStr.isNull() ) { - m_customEqualColumns = true; - if ( equalcolumnsStr == "false" ) { - m_equalColumns = false; - } - else { - m_equalColumns = true; - } - } - TQString displaystyleStr = element.attribute( "displaystyle" ).stripWhiteSpace().lower(); - if ( ! displaystyleStr.isNull() ) { - m_customDisplayStyle = true; - if ( displaystyleStr == "false" ) { - m_displayStyle = false; - } - else { - m_displayStyle = true; - } - } - TQString sideStr = element.attribute( "side" ).stripWhiteSpace().lower(); - if ( ! sideStr.isNull() ) { - if ( sideStr == "left" ) { - m_side = LeftSide; - } - else if ( sideStr == "right" ) { - m_side = RightSide; - } - else if ( sideStr == "leftoverlap" ) { - m_side = LeftOverlapSide; - } - else if ( sideStr == "rightoverlap" ) { - m_side = RightOverlapSide; - } - } - TQString minlabelspacingStr = element.attribute( "minlabelspacing" ).stripWhiteSpace().lower(); - if ( ! minlabelspacingStr.isNull() ) { - m_minLabelSpacing = getSize( minlabelspacingStr, &m_minLabelSpacingType ); - if ( m_minLabelSpacingType == NoSize ) { - m_minLabelSpacingType = getSpace( minlabelspacingStr ); - } - } - return true; -} - -/** - * Reads our content from the MathML node. Sets the node to the next node - * that needs to be read. It is sometimes needed to read more than one node - * (e. g. for fence operators). - * Returns the number of nodes processed or -1 if it failed. - */ -int MatrixElement::readContentFromMathMLDom( TQDomNode& node ) -{ - // We have twice, since there may be empty elements and we need to know how - // many of them we have. So, first pass, get number of rows and columns - - if ( BasicElement::readContentFromMathMLDom( node ) == -1 ) { - return -1; - } - - uint rows = 0; - uint cols = 0; - TQDomNode n = node; - while ( !n.isNull() ) { - if ( n.isElement() ) { - TQDomElement e = n.toElement(); - if ( e.tagName().lower() == "mtr" || e.tagName().lower() == "mlabeledtr" ) - { - rows++; - - /* Determins the number of columns */ - TQDomNode cellnode = e.firstChild(); - int cc = 0; - - while ( !cellnode.isNull() ) { - if ( cellnode.isElement() ) - cc++; - cellnode = cellnode.nextSibling(); - } - if ( cc > 0 && e.tagName().lower() == "mlabeledtr" ) - cc--; - if ( cc > cols ) - cols = cc; - } - } - n = n.nextSibling(); - } - - // Create elements - content.clear(); - for (uint r = 0; r < rows; r++) { - TQPtrList< MatrixSequenceElement >* list = new TQPtrList< MatrixSequenceElement >; - list->setAutoDelete(true); - content.append(list); - for (uint c = 0; c < cols; c++) { - MatrixSequenceElement* element = new MatrixSequenceElement(this); - list->append(element); - } - } - - // Second pass, read elements now - uint r = 0; - uint c = 0; - while ( !node.isNull() ) { - if ( node.isElement() ) { - TQDomElement e = node.toElement(); - if ( e.tagName().lower() == "mtr" || e.tagName().lower() == "mlabeledtr" ) { - TQDomNode cellnode = e.firstChild(); - if ( e.tagName().lower() == "mlabeledtr" ) { - while ( ! cellnode.isNull() && ! cellnode.isElement() ) - cellnode = cellnode.nextSibling(); - if ( ! cellnode.isNull() ) - cellnode = cellnode.nextSibling(); - } - while ( !cellnode.isNull() ) { - if ( cellnode.isElement() ) { - TQDomElement cellelement = cellnode.toElement(); - if ( cellelement.tagName().lower() != "mtd" ) { - // TODO: Inferred mtd. Deprecated in MathML 2.0 - kdWarning( DEBUGID ) << "Unsupported tag " - << cellelement.tagName() - << " inside matrix row\n"; - } - else { - SequenceElement* element = getElement(r, c); - if ( element->buildFromMathMLDom( cellelement ) == -1 ) - return -1; - c++; - } - } - cellnode = cellnode.nextSibling(); - } - c = 0; - r++; - } - } - node = node.nextSibling(); - } - return 1; -} - -TQString MatrixElement::toLatex() -{ - //All the border handling must be implemented here too - - TQString matrix; - uint cols=getColumns(); - uint rows=getRows(); - - matrix="\\begin{array}{ "; - for(uint i=0;itoLatex(); - if( c < cols-1) matrix+=" & "; - } - if(r < rows-1 ) matrix+=" \\\\ "; - } - - matrix+=" \\end{array}"; - - return matrix; -} - -TQString MatrixElement::formulaString() -{ - TQString matrix = "["; - uint cols=getColumns(); - uint rows=getRows(); - for (uint r = 0; r < rows; r++) { - matrix += "["; - for (uint c = 0; c < cols; c++) { - matrix+=getElement(r, c)->formulaString(); - if ( c < cols-1 ) matrix+=", "; - } - matrix += "]"; - if ( r < rows-1 ) matrix += ", "; - } - matrix += "]"; - return matrix; -} - - -SequenceElement* MatrixElement::elementAt(uint row, uint column) -{ - return getElement( row, column ); -} - -void MatrixElement::writeMathMLAttributes( TQDomElement& element ) const -{ - TQString rownumber; - if ( m_rowNumber ) { - rownumber = TQString( " %1" ).arg( m_rowNumber ); - } - switch ( m_align ) { - case TopAlign: - element.setAttribute( "align", "top" + rownumber ); - break; - case BottomAlign: - element.setAttribute( "align", "bottom" + rownumber ); - break; - case CenterAlign: - element.setAttribute( "align", "center" + rownumber ); - break; - case BaselineAlign: - element.setAttribute( "align", "baseline" + rownumber ); - break; - case AxisAlign: - element.setAttribute( "align", "axis" + rownumber ); - break; - default: - break; - } - TQString rowalign; - for ( TQValueList::const_iterator it = m_rowAlign.begin(); it != m_rowAlign.end(); it++ ) - { - switch ( *it ) { - case TopAlign: - rowalign.append( "top " ); - break; - case BottomAlign: - rowalign.append( "bottom " ); - break; - case CenterAlign: - rowalign.append( "center " ); - break; - case BaselineAlign: - rowalign.append( "baseline " ); - break; - case AxisAlign: - rowalign.append( "axis " ); - break; - default: - break; - } - } - if ( ! rowalign.isNull() ) { - element.setAttribute( "rowalign", rowalign.stripWhiteSpace() ); - } - TQString columnalign; - for ( TQValueList::const_iterator it = m_columnAlign.begin(); it != m_columnAlign.end(); it++ ) - { - switch ( *it ) { - case LeftHorizontalAlign: - rowalign.append( "left " ); - break; - case CenterHorizontalAlign: - rowalign.append( "center " ); - break; - case RightHorizontalAlign: - rowalign.append( "right " ); - break; - default: - break; - } - } - if ( ! columnalign.isNull() ) { - element.setAttribute( "columnalign", columnalign.stripWhiteSpace() ); - } - TQString alignmentscope; - for ( TQValueList< bool >::const_iterator it = m_alignmentScope.begin(); it != m_alignmentScope.end(); it++ ) - { - if ( *it ) { - alignmentscope.append( "true " ); - } - else { - alignmentscope.append( "false " ); - } - } - if ( ! alignmentscope.isNull() ) { - element.setAttribute( "alignmentscope", alignmentscope.stripWhiteSpace() ); - } - TQString columnwidth; - TQValueList< double >::const_iterator lengthIt = m_columnWidth.begin(); - for ( TQValueList< SizeType >::const_iterator typeIt = m_columnWidthType.begin(); - typeIt != m_columnWidthType.end(); typeIt ++ ) { - switch ( *typeIt ) { - case AutoSize: - columnwidth.append( "auto " ); - break; - case FitSize: - columnwidth.append( "fit " ); - break; - case AbsoluteSize: - columnwidth.append( TQString( "%1pt " ).arg( *lengthIt ) ); - lengthIt++; - break; - case RelativeSize: - columnwidth.append( TQString( "%1% " ).arg( *lengthIt * 100.0 ) ); - lengthIt++; - break; - case PixelSize: - columnwidth.append( TQString( "%1px " ).arg( *lengthIt ) ); - lengthIt++; - break; - case NegativeVeryVeryThinMathSpace: - columnwidth.append( "negativeveryverythinmathspace " ); - break; - case NegativeVeryThinMathSpace: - columnwidth.append( "negativeverythinmathspace " ); - break; - case NegativeThinMathSpace: - columnwidth.append( "negativethinmathspace " ); - break; - case NegativeMediumMathSpace: - columnwidth.append( "negativemediummathspace " ); - break; - case NegativeThickMathSpace: - columnwidth.append( "negativethickmathspace " ); - break; - case NegativeVeryThickMathSpace: - columnwidth.append( "negativeverythickmathspace " ); - break; - case NegativeVeryVeryThickMathSpace: - columnwidth.append( "negativeveryverythickmathspace " ); - break; - case VeryVeryThinMathSpace: - columnwidth.append( "veryverythinmathspace " ); - break; - case VeryThinMathSpace: - columnwidth.append( "verythinmathspace " ); - break; - case ThinMathSpace: - columnwidth.append( "thinmathspace " ); - break; - case MediumMathSpace: - columnwidth.append( "mediummathspace " ); - break; - case ThickMathSpace: - columnwidth.append( "thickmathspace " ); - break; - case VeryThickMathSpace: - columnwidth.append( "verythickmathspace " ); - break; - case VeryVeryThickMathSpace: - columnwidth.append( "veryverythickmathspace " ); - break; - default: - break; - } - } - if ( ! columnwidth.isNull() ) { - element.setAttribute( "columnwidth", columnwidth.stripWhiteSpace() ); - } - switch ( m_widthType ) { - case AutoSize: - element.setAttribute( "width", "auto" ); - break; - case AbsoluteSize: - element.setAttribute( "width", TQString( "%1pt" ).arg( m_width ) ); - break; - case RelativeSize: - element.setAttribute( "width", TQString( "%1% " ).arg( m_width * 100.0 ) ); - break; - case PixelSize: - element.setAttribute( "width", TQString( "%1px " ).arg( m_width ) ); - break; - default: - break; - } - TQString rowspacing; - lengthIt = m_rowSpacing.begin(); - for ( TQValueList< SizeType >::const_iterator typeIt = m_rowSpacingType.begin(); - typeIt != m_rowSpacingType.end(); typeIt++, lengthIt++ ) { - switch ( *typeIt ) { - case AbsoluteSize: - rowspacing.append( TQString( "%1pt " ).arg( *lengthIt ) ); - break; - case RelativeSize: - rowspacing.append( TQString( "%1% " ).arg( *lengthIt * 100.0 ) ); - break; - case PixelSize: - rowspacing.append( TQString( "%1px " ).arg( *lengthIt ) ); - break; - default: - break; - } - } - if ( ! rowspacing.isNull() ) { - element.setAttribute( "rowspacing", rowspacing.stripWhiteSpace() ); - } - TQString columnspacing; - lengthIt = m_columnSpacing.begin(); - for ( TQValueList< SizeType >::const_iterator typeIt = m_columnSpacingType.begin(); - typeIt != m_columnSpacingType.end(); typeIt++ ) { - switch ( *typeIt ) { - case AbsoluteSize: - columnspacing.append( TQString( "%1pt " ).arg( *lengthIt ) ); - lengthIt++; - break; - case RelativeSize: - columnspacing.append( TQString( "%1% " ).arg( *lengthIt * 100.0 ) ); - lengthIt++; - break; - case PixelSize: - columnspacing.append( TQString( "%1px " ).arg( *lengthIt ) ); - lengthIt++; - break; - case NegativeVeryVeryThinMathSpace: - columnspacing.append( "negativeveryverythinmathspace " ); - break; - case NegativeVeryThinMathSpace: - columnspacing.append( "negativeverythinmathspace " ); - break; - case NegativeThinMathSpace: - columnspacing.append( "negativethinmathspace " ); - break; - case NegativeMediumMathSpace: - columnspacing.append( "negativemediummathspace " ); - break; - case NegativeThickMathSpace: - columnspacing.append( "negativethickmathspace " ); - break; - case NegativeVeryThickMathSpace: - columnspacing.append( "negativeverythickmathspace " ); - break; - case NegativeVeryVeryThickMathSpace: - columnspacing.append( "negativeveryverythickmathspace " ); - break; - case VeryVeryThinMathSpace: - columnspacing.append( "veryverythinmathspace " ); - break; - case VeryThinMathSpace: - columnspacing.append( "verythinmathspace " ); - break; - case ThinMathSpace: - columnspacing.append( "thinmathspace " ); - break; - case MediumMathSpace: - columnspacing.append( "mediummathspace " ); - break; - case ThickMathSpace: - columnspacing.append( "thickmathspace " ); - break; - case VeryThickMathSpace: - columnspacing.append( "verythickmathspace " ); - break; - case VeryVeryThickMathSpace: - columnspacing.append( "veryverythickmathspace " ); - break; - default: - break; - } - } - if ( ! rowspacing.isNull() ) { - element.setAttribute( "rowspacing", rowspacing.stripWhiteSpace() ); - } - TQString rowlines; - for ( TQValueList< LineType >::const_iterator it = m_rowLines.begin(); it != m_rowLines.end(); it++ ) - { - switch ( *it ) { - case NoneLine: - rowlines.append( "none " ); - break; - case SolidLine: - rowlines.append( "solid " ); - break; - case DashedLine: - rowlines.append( "dashed " ); - break; - default: - break; - } - } - if ( ! rowlines.isNull() ) { - element.setAttribute( "rowlines", rowlines.stripWhiteSpace() ); - } - TQString columnlines; - for ( TQValueList< LineType >::const_iterator it = m_columnLines.begin(); it != m_columnLines.end(); it++ ) - { - switch ( *it ) { - case NoneLine: - columnlines.append( "none " ); - break; - case SolidLine: - columnlines.append( "solid " ); - break; - case DashedLine: - columnlines.append( "dashed " ); - break; - default: - break; - } - } - if ( ! columnlines.isNull() ) { - element.setAttribute( "columnlines", columnlines.stripWhiteSpace() ); - } - switch ( m_frame ) { - case NoneLine: - element.setAttribute( "frame", "none" ); - break; - case SolidLine: - element.setAttribute( "frame", "solid" ); - break; - case DashedLine: - element.setAttribute( "frame", "dashed" ); - break; - default: - break; - } - TQString framespacing; - switch ( m_frameHSpacingType ) { - case AbsoluteSize: - framespacing.append( TQString( "%1pt " ).arg( m_frameHSpacing ) ); - break; - case RelativeSize: - framespacing.append( TQString( "%1% " ).arg( m_frameHSpacing * 100.0 ) ); - break; - case PixelSize: - framespacing.append( TQString( "%1px " ).arg( m_frameHSpacing ) ); - break; - case NegativeVeryVeryThinMathSpace: - framespacing.append( "negativeveryverythinmathspace " ); - break; - case NegativeVeryThinMathSpace: - framespacing.append( "negativeverythinmathspace " ); - break; - case NegativeThinMathSpace: - framespacing.append( "negativethinmathspace " ); - break; - case NegativeMediumMathSpace: - framespacing.append( "negativemediummathspace " ); - break; - case NegativeThickMathSpace: - framespacing.append( "negativethickmathspace " ); - break; - case NegativeVeryThickMathSpace: - framespacing.append( "negativeverythickmathspace " ); - break; - case NegativeVeryVeryThickMathSpace: - framespacing.append( "negativeveryverythickmathspace " ); - break; - case VeryVeryThinMathSpace: - framespacing.append( "veryverythinmathspace " ); - break; - case VeryThinMathSpace: - framespacing.append( "verythinmathspace " ); - break; - case ThinMathSpace: - framespacing.append( "thinmathspace " ); - break; - case MediumMathSpace: - framespacing.append( "mediummathspace " ); - break; - case ThickMathSpace: - framespacing.append( "thickmathspace " ); - break; - case VeryThickMathSpace: - framespacing.append( "verythickmathspace " ); - break; - case VeryVeryThickMathSpace: - framespacing.append( "veryverythickmathspace " ); - break; - default: - break; - } - switch ( m_frameVSpacingType ) { - case AbsoluteSize: - framespacing.append( TQString( "%1pt " ).arg( m_frameVSpacing ) ); - break; - case RelativeSize: - framespacing.append( TQString( "%1% " ).arg( m_frameVSpacing * 100.0 ) ); - break; - case PixelSize: - framespacing.append( TQString( "%1px " ).arg( m_frameVSpacing ) ); - break; - case NegativeVeryVeryThinMathSpace: - framespacing.append( "negativeveryverythinmathspace " ); - break; - case NegativeVeryThinMathSpace: - framespacing.append( "negativeverythinmathspace " ); - break; - case NegativeThinMathSpace: - framespacing.append( "negativethinmathspace " ); - break; - case NegativeMediumMathSpace: - framespacing.append( "negativemediummathspace " ); - break; - case NegativeThickMathSpace: - framespacing.append( "negativethickmathspace " ); - break; - case NegativeVeryThickMathSpace: - framespacing.append( "negativeverythickmathspace " ); - break; - case NegativeVeryVeryThickMathSpace: - framespacing.append( "negativeveryverythickmathspace " ); - break; - case VeryVeryThinMathSpace: - framespacing.append( "veryverythinmathspace " ); - break; - case VeryThinMathSpace: - framespacing.append( "verythinmathspace " ); - break; - case ThinMathSpace: - framespacing.append( "thinmathspace " ); - break; - case MediumMathSpace: - framespacing.append( "mediummathspace " ); - break; - case ThickMathSpace: - framespacing.append( "thickmathspace " ); - break; - case VeryThickMathSpace: - framespacing.append( "verythickmathspace " ); - break; - case VeryVeryThickMathSpace: - framespacing.append( "veryverythickmathspace " ); - break; - default: - break; - } - if ( ! framespacing.isNull() ) { - element.setAttribute( "framespacing", framespacing.stripWhiteSpace() ); - } - if ( m_customEqualRows ) { - element.setAttribute( "equalrows", m_equalRows ? "true" : "false" ); - } - if ( m_customEqualColumns ) { - element.setAttribute( "equalcolumns", m_equalColumns ? "true" : "false" ); - } - if ( m_customDisplayStyle ) { - element.setAttribute( "displaystyle", m_displayStyle ? "true" : "false" ); - } - switch ( m_side ) { - case LeftSide: - element.setAttribute( "side", "left" ); - break; - case RightSide: - element.setAttribute( "side", "right" ); - break; - case LeftOverlapSide: - element.setAttribute( "side", "leftoverlap" ); - break; - case RightOverlapSide: - element.setAttribute( "side", "rightoverlap" ); - break; - default: - break; - } - switch ( m_minLabelSpacingType ) { - case AbsoluteSize: - element.setAttribute( "minlabelspacing", TQString( "%1pt" ).arg( m_minLabelSpacing ) ); - break; - case RelativeSize: - element.setAttribute( "minlabelspacing", TQString( "%1%" ).arg( m_minLabelSpacing * 100.0 ) ); - break; - case PixelSize: - element.setAttribute( "minlabelspacing", TQString( "%1px" ).arg( m_minLabelSpacing ) ); - break; - case NegativeVeryVeryThinMathSpace: - element.setAttribute( "minlabelspacing", "negativeveryverythinmathspace" ); - break; - case NegativeVeryThinMathSpace: - element.setAttribute( "minlabelspacing", "negativeverythinmathspace" ); - break; - case NegativeThinMathSpace: - element.setAttribute( "minlabelspacing", "negativethinmathspace" ); - break; - case NegativeMediumMathSpace: - element.setAttribute( "minlabelspacing", "negativemediummathspace" ); - break; - case NegativeThickMathSpace: - element.setAttribute( "minlabelspacing", "negativethickmathspace" ); - break; - case NegativeVeryThickMathSpace: - element.setAttribute( "minlabelspacing", "negativeverythickmathspace" ); - break; - case NegativeVeryVeryThickMathSpace: - element.setAttribute( "minlabelspacing", "negativeveryverythickmathspace" ); - break; - case VeryVeryThinMathSpace: - element.setAttribute( "minlabelspacing", "veryverythinmathspace" ); - break; - case VeryThinMathSpace: - element.setAttribute( "minlabelspacing", "verythinmathspace" ); - break; - case ThinMathSpace: - element.setAttribute( "minlabelspacing", "thinmathspace" ); - break; - case MediumMathSpace: - element.setAttribute( "minlabelspacing", "mediummathspace" ); - break; - case ThickMathSpace: - element.setAttribute( "minlabelspacing", "thickmathspace" ); - break; - case VeryThickMathSpace: - element.setAttribute( "minlabelspacing", "verythickmathspace" ); - break; - case VeryVeryThickMathSpace: - element.setAttribute( "minlabelspacing", "veryverythickmathspace" ); - break; - default: - break; - } -} - -void MatrixElement::writeMathMLContent( TQDomDocument& doc, - TQDomElement& element, - bool oasisFormat ) const -{ - TQDomElement row; - TQDomElement cell; - - uint rows = getRows(); - uint cols = getColumns(); - - for ( uint r = 0; r < rows; r++ ) - { - row = doc.createElement( oasisFormat ? "math:mtr" : "mtr" ); - element.appendChild( row ); - for ( uint c = 0; c < cols; c++ ) - { - cell = doc.createElement( oasisFormat ? "math:mtd" : "mtd" ); - row.appendChild( cell ); - getElement(r,c)->writeMathML( doc, cell, oasisFormat ); - } - } -} - - -////////////////////////////////////////////////////////////////////////////// - - -/** - * The lines behaviour is (a little) different from that - * of ordinary sequences. - */ -class MultilineSequenceElement : public SequenceElement { - typedef SequenceElement inherited; -public: - - MultilineSequenceElement( BasicElement* parent = 0 ); - - virtual MultilineSequenceElement* clone() { - return new MultilineSequenceElement( *this ); - } - - virtual BasicElement* goToPos( FormulaCursor*, bool& handled, - const LuPixelPoint& point, const LuPixelPoint& parentOrigin ); - - /** - * Calculates our width and height and - * our children's parentPosition. - */ - virtual void calcSizes( const ContextStyle& context, - ContextStyle::TextStyle tstyle, - ContextStyle::IndexStyle istyle, - StyleAttributes& style ); - - virtual void registerTab( BasicElement* tab ); - - /** - * This is called by the container to get a command depending on - * the current cursor position (this is how the element gets chosen) - * and the request. - * - * @returns the command that performs the requested action with - * the containers active cursor. - */ - virtual KCommand* buildCommand( Container*, Request* ); - - virtual KCommand* input( Container* container, TQKeyEvent* event ); - - virtual KCommand* input( Container* container, TQChar ch ); - - uint tabCount() const { return tabs.count(); } - - BasicElement* tab( uint i ) { return tabs.at( i ); } - - /// Change the width of tab i and move all elements after it. - void moveTabTo( uint i, luPixel pos ); - - /// Return the greatest tab number less than pos. - int tabBefore( uint pos ); - - /// Return the position of tab i. - int tabPos( uint i ); - - virtual void writeMathML( TQDomDocument& doc, TQDomNode& parent, bool oasisFormat = false ) const ; - -private: - - TQPtrList tabs; -}; - - -// Split the line at position pos. -class KFCNewLine : public Command { -public: - KFCNewLine( const TQString& name, Container* document, - MultilineSequenceElement* line, uint pos ); - - virtual ~KFCNewLine(); - - virtual void execute(); - virtual void unexecute(); - -private: - MultilineSequenceElement* m_line; - MultilineSequenceElement* m_newline; - uint m_pos; -}; - - -KFCNewLine::KFCNewLine( const TQString& name, Container* document, - MultilineSequenceElement* line, uint pos ) - : Command( name, document ), - m_line( line ), m_pos( pos ) -{ - m_newline = new MultilineSequenceElement( m_line->getParent() ); -} - - -KFCNewLine::~KFCNewLine() -{ - delete m_newline; -} - - -void KFCNewLine::execute() -{ - FormulaCursor* cursor = getExecuteCursor(); - MultilineElement* parent = static_cast( m_line->getParent() ); - int linePos = parent->content.find( m_line ); - parent->content.insert( linePos+1, m_newline ); - - // If there are children to be moved. - if ( m_line->countChildren() > static_cast( m_pos ) ) { - - // Remove anything after position pos from the current line - m_line->selectAllChildren( cursor ); - cursor->setMark( m_pos ); - TQPtrList elementList; - m_line->remove( cursor, elementList, beforeCursor ); - - // Insert the removed stuff into the new line - m_newline->goInside( cursor ); - m_newline->insert( cursor, elementList, beforeCursor ); - cursor->setPos( cursor->getMark() ); - } - else { - m_newline->goInside( cursor ); - } - - // The command no longer owns the new line. - m_newline = 0; - - // Tell that something changed - FormulaElement* formula = m_line->formula(); - formula->changed(); - testDirty(); -} - - -void KFCNewLine::unexecute() -{ - FormulaCursor* cursor = getExecuteCursor(); - MultilineElement* parent = static_cast( m_line->getParent() ); - int linePos = parent->content.find( m_line ); - - // Now the command owns the new line again. - m_newline = parent->content.at( linePos+1 ); - - // Tell all cursors to leave this sequence - FormulaElement* formula = m_line->formula(); - formula->elementRemoval( m_newline ); - - // If there are children to be moved. - if ( m_newline->countChildren() > 0 ) { - - // Remove anything from the line to be deleted - m_newline->selectAllChildren( cursor ); - TQPtrList elementList; - m_newline->remove( cursor, elementList, beforeCursor ); - - // Insert the removed stuff into the previous line - m_line->moveEnd( cursor ); - m_line->insert( cursor, elementList, beforeCursor ); - cursor->setPos( cursor->getMark() ); - } - else { - m_line->moveEnd( cursor ); - } - parent->content.take( linePos+1 ); - - // Tell that something changed - formula->changed(); - testDirty(); -} - - -MultilineSequenceElement::MultilineSequenceElement( BasicElement* parent ) - : SequenceElement( parent ) -{ - tabs.setAutoDelete( false ); -} - - -BasicElement* MultilineSequenceElement::goToPos( FormulaCursor* cursor, bool& handled, - const LuPixelPoint& point, const LuPixelPoint& parentOrigin ) -{ - //LuPixelPoint myPos(parentOrigin.x() + getX(), - // parentOrigin.y() + getY()); - BasicElement* e = inherited::goToPos(cursor, handled, point, parentOrigin); - - if (e == 0) { - // If the mouse was behind this line put the cursor to the last position. - if ( ( point.x() > getX()+getWidth() ) && - ( point.y() >= getY() ) && - ( point.y() < getY()+getHeight() ) ) { - cursor->setTo(this, countChildren()); - handled = true; - return this; - } - } - return e; -} - - -void MultilineSequenceElement::calcSizes( const ContextStyle& context, - ContextStyle::TextStyle tstyle, - ContextStyle::IndexStyle istyle, - StyleAttributes& style ) -{ - tabs.clear(); - inherited::calcSizes( context, tstyle, istyle, style ); -} - - -void MultilineSequenceElement::registerTab( BasicElement* tab ) -{ - tabs.append( tab ); -} - - -KCommand* MultilineSequenceElement::buildCommand( Container* container, Request* request ) -{ - FormulaCursor* cursor = container->activeCursor(); - if ( cursor->isReadOnly() ) { - return 0; - } - - switch ( *request ) { - case req_remove: { - // Remove this line if its empty. - // Remove the formula if this line was the only one. - break; - } - case req_addNewline: { - FormulaCursor* cursor = container->activeCursor(); - return new KFCNewLine( i18n( "Add Newline" ), container, this, cursor->getPos() ); - } - case req_addTabMark: { - KFCReplace* command = new KFCReplace( i18n("Add Tabmark"), container ); - SpaceElement* element = new SpaceElement( THIN, true ); - command->addElement( element ); - return command; - } - default: - break; - } - return inherited::buildCommand( container, request ); -} - - -KCommand* MultilineSequenceElement::input( Container* container, TQKeyEvent* event ) -{ - int action = event->key(); - //int state = event->state(); - //MoveFlag flag = movementFlag(state); - - switch ( action ) { - case TQt::Key_Enter: - case TQt::Key_Return: { - Request newline( req_addNewline ); - return buildCommand( container, &newline ); - } - case TQt::Key_Tab: { - Request r( req_addTabMark ); - return buildCommand( container, &r ); - } - } - return inherited::input( container, event ); -} - - -KCommand* MultilineSequenceElement::input( Container* container, TQChar ch ) -{ - int latin1 = ch.latin1(); - switch (latin1) { - case '&': { - Request r( req_addTabMark ); - return buildCommand( container, &r ); - } - } - return inherited::input( container, ch ); -} - - -void MultilineSequenceElement::moveTabTo( uint i, luPixel pos ) -{ - BasicElement* marker = tab( i ); - luPixel diff = pos - marker->getX(); - marker->setWidth( marker->getWidth() + diff ); - - for ( int p = childPos( marker )+1; p < countChildren(); ++p ) { - BasicElement* child = getChild( p ); - child->setX( child->getX() + diff ); - } - - setWidth( getWidth()+diff ); -} - - -int MultilineSequenceElement::tabBefore( uint pos ) -{ - if ( tabs.isEmpty() ) { - return -1; - } - uint tabNum = 0; - for ( uint i=0; i( tabNum )-1; -} - - -int MultilineSequenceElement::tabPos( uint i ) -{ - if ( i < tabs.count() ) { - return childPos( tabs.at( i ) ); - } - return -1; -} - - -void MultilineSequenceElement::writeMathML( TQDomDocument& doc, - TQDomNode& parent, bool oasisFormat ) const -{ - // parent is required to be a tag - - TQDomElement tmp = doc.createElement( "TMP" ); - - inherited::writeMathML( doc, tmp, oasisFormat ); - - /* Now we re-parse the Dom tree, because of the TabMarkers - * that have no direct representation in MathML but mark the - * end of a tag. - */ - - TQDomElement mtd = doc.createElement( oasisFormat ? "math:mtd" : "mtd" ); - - // The mrow, if it exists. - TQDomNode n = tmp.firstChild().firstChild(); - while ( !n.isNull() ) { - // the illegal TabMarkers are children of the mrow, child of tmp. - if ( n.isElement() && n.toElement().tagName() == "TAB" ) { - parent.appendChild( mtd ); - mtd = doc.createElement( oasisFormat ? "math:mtd" : "mtd" ); - } - else { - mtd.appendChild( n.cloneNode() ); // cloneNode needed? - } - n = n.nextSibling(); - } - - parent.appendChild( mtd ); -} - - -MultilineElement::MultilineElement( BasicElement* parent ) - : BasicElement( parent ) -{ - content.setAutoDelete( true ); - content.append( new MultilineSequenceElement( this ) ); -} - -MultilineElement::~MultilineElement() -{ -} - -MultilineElement::MultilineElement( const MultilineElement& other ) - : BasicElement( other ) -{ - content.setAutoDelete( true ); - uint count = other.content.count(); - for (uint i = 0; i < count; i++) { - MultilineSequenceElement* line = content.at(i)->clone(); - line->setParent( this ); - content.append( line ); - } -} - - -bool MultilineElement::accept( ElementVisitor* visitor ) -{ - return visitor->visit( this ); -} - - -void MultilineElement::entered( SequenceElement* /*child*/ ) -{ - formula()->tell( i18n( "Multi line element" ) ); -} - - -/** - * Returns the element the point is in. - */ -BasicElement* MultilineElement::goToPos( FormulaCursor* cursor, bool& handled, - const LuPixelPoint& point, const LuPixelPoint& parentOrigin ) -{ - BasicElement* e = inherited::goToPos(cursor, handled, point, parentOrigin); - if ( e != 0 ) { - LuPixelPoint myPos(parentOrigin.x() + getX(), - parentOrigin.y() + getY()); - - uint count = content.count(); - for ( uint i = 0; i < count; ++i ) { - MultilineSequenceElement* line = content.at(i); - e = line->goToPos(cursor, handled, point, myPos); - if (e != 0) { - return e; - } - } - return this; - } - return 0; -} - -void MultilineElement::goInside( FormulaCursor* cursor ) -{ - content.at( 0 )->goInside( cursor ); -} - -void MultilineElement::moveLeft( FormulaCursor* cursor, BasicElement* from ) -{ - // If you want to select more than one line you'll have to - // select the whole element. - if (cursor->isSelectionMode()) { - getParent()->moveLeft(cursor, this); - } - else { - // Coming from the parent (sequence) we go to - // the very last position - if (from == getParent()) { - content.at( content.count()-1 )->moveLeft(cursor, this); - } - else { - // Coming from one of the lines we go to the previous line - // or to the parent if there is none. - int pos = content.find( static_cast( from ) ); - if ( pos > -1 ) { - if ( pos > 0 ) { - content.at( pos-1 )->moveLeft( cursor, this ); - } - else { - getParent()->moveLeft(cursor, this); - } - } - else { - kdDebug( DEBUGID ) << k_funcinfo << endl; - kdDebug( DEBUGID ) << "Serious confusion. Must never happen." << endl; - } - } - } -} - -void MultilineElement::moveRight( FormulaCursor* cursor, BasicElement* from ) -{ - if (cursor->isSelectionMode()) { - getParent()->moveRight(cursor, this); - } - else { - if (from == getParent()) { - content.at( 0 )->moveRight(cursor, this); - } - else { - int pos = content.find( static_cast( from ) ); - if ( pos > -1 ) { - uint upos = pos; - if ( upos < content.count() ) { - if ( upos < content.count()-1 ) { - content.at( upos+1 )->moveRight( cursor, this ); - } - else { - getParent()->moveRight(cursor, this); - } - return; - } - } - kdDebug( DEBUGID ) << k_funcinfo << endl; - kdDebug( DEBUGID ) << "Serious confusion. Must never happen." << endl; - } - } -} - -void MultilineElement::moveUp( FormulaCursor* cursor, BasicElement* from ) -{ - // If you want to select more than one line you'll have to - // select the whole element. - if (cursor->isSelectionMode()) { - getParent()->moveLeft(cursor, this); - } - else { - // Coming from the parent (sequence) we go to - // the very last position - if (from == getParent()) { - content.at( content.count()-1 )->moveLeft(cursor, this); - } - else { - // Coming from one of the lines we go to the previous line - // or to the parent if there is none. - int pos = content.find( static_cast( from ) ); - if ( pos > -1 ) { - if ( pos > 0 ) { - //content.at( pos-1 )->moveLeft( cursor, this ); - // This is rather hackish. - // But we know what elements we have here. - int cursorPos = cursor->getPos(); - MultilineSequenceElement* current = content.at( pos ); - MultilineSequenceElement* newLine = content.at( pos-1 ); - int tabNum = current->tabBefore( cursorPos ); - if ( tabNum > -1 ) { - int oldTabPos = current->tabPos( tabNum ); - int newTabPos = newLine->tabPos( tabNum ); - if ( newTabPos > -1 ) { - cursorPos += newTabPos-oldTabPos; - int nextNewTabPos = newLine->tabPos( tabNum+1 ); - if ( nextNewTabPos > -1 ) { - cursorPos = TQMIN( cursorPos, nextNewTabPos ); - } - } - else { - cursorPos = newLine->countChildren(); - } - } - else { - int nextNewTabPos = newLine->tabPos( 0 ); - if ( nextNewTabPos > -1 ) { - cursorPos = TQMIN( cursorPos, nextNewTabPos ); - } - } - cursor->setTo( newLine, - TQMIN( cursorPos, - newLine->countChildren() ) ); - } - else { - getParent()->moveLeft(cursor, this); - } - } - else { - kdDebug( DEBUGID ) << k_funcinfo << endl; - kdDebug( DEBUGID ) << "Serious confusion. Must never happen." << endl; - } - } - } -} - -void MultilineElement::moveDown( FormulaCursor* cursor, BasicElement* from ) -{ - if (cursor->isSelectionMode()) { - getParent()->moveRight(cursor, this); - } - else { - if (from == getParent()) { - content.at( 0 )->moveRight(cursor, this); - } - else { - int pos = content.find( static_cast( from ) ); - if ( pos > -1 ) { - uint upos = pos; - if ( upos < content.count() ) { - if ( upos < content.count()-1 ) { - //content.at( upos+1 )->moveRight( cursor, this ); - // This is rather hackish. - // But we know what elements we have here. - int cursorPos = cursor->getPos(); - MultilineSequenceElement* current = content.at( upos ); - MultilineSequenceElement* newLine = content.at( upos+1 ); - int tabNum = current->tabBefore( cursorPos ); - if ( tabNum > -1 ) { - int oldTabPos = current->tabPos( tabNum ); - int newTabPos = newLine->tabPos( tabNum ); - if ( newTabPos > -1 ) { - cursorPos += newTabPos-oldTabPos; - int nextNewTabPos = newLine->tabPos( tabNum+1 ); - if ( nextNewTabPos > -1 ) { - cursorPos = TQMIN( cursorPos, nextNewTabPos ); - } - } - else { - cursorPos = newLine->countChildren(); - } - } - else { - int nextNewTabPos = newLine->tabPos( 0 ); - if ( nextNewTabPos > -1 ) { - cursorPos = TQMIN( cursorPos, nextNewTabPos ); - } - } - cursor->setTo( newLine, - TQMIN( cursorPos, - newLine->countChildren() ) ); - } - else { - getParent()->moveRight(cursor, this); - } - return; - } - } - kdDebug( DEBUGID ) << k_funcinfo << endl; - kdDebug( DEBUGID ) << "Serious confusion. Must never happen." << endl; - } - } -} - - -void MultilineElement::calcSizes( const ContextStyle& context, - ContextStyle::TextStyle tstyle, - ContextStyle::IndexStyle istyle, - StyleAttributes& style ) -{ - double factor = style.sizeFactor(); - luPt mySize = context.getAdjustedSize( tstyle, factor ); - TQFont font = context.getDefaultFont(); - font.setPointSizeFloat( context.layoutUnitPtToPt( mySize ) ); - TQFontMetrics fm( font ); - luPixel leading = context.ptToLayoutUnitPt( fm.leading() ); - luPixel distY = context.ptToPixelY( context.getThinSpace( tstyle, factor ) ); - - uint count = content.count(); - luPixel height = -leading; - luPixel width = 0; - uint tabCount = 0; - for ( uint i = 0; i < count; ++i ) { - MultilineSequenceElement* line = content.at(i); - line->calcSizes( context, tstyle, istyle, style ); - tabCount = TQMAX( tabCount, line->tabCount() ); - - height += leading; - line->setX( 0 ); - line->setY( height ); - height += line->getHeight() + distY; - width = TQMAX( line->getWidth(), width ); - } - - // calculate the tab positions - for ( uint t = 0; t < tabCount; ++t ) { - luPixel pos = 0; - for ( uint i = 0; i < count; ++i ) { - MultilineSequenceElement* line = content.at(i); - if ( t < line->tabCount() ) { - pos = TQMAX( pos, line->tab( t )->getX() ); - } - else { - pos = TQMAX( pos, line->getWidth() ); - } - } - for ( uint i = 0; i < count; ++i ) { - MultilineSequenceElement* line = content.at(i); - if ( t < line->tabCount() ) { - line->moveTabTo( t, pos ); - width = TQMAX( width, line->getWidth() ); - } - } - } - - setHeight( height ); - setWidth( width ); - if ( count == 1 ) { - setBaseline( content.at( 0 )->getBaseline() ); - } - else { - // There's always a first line. No formulas without lines. - setBaseline( height/2 + context.axisHeight( tstyle, factor ) ); - } -} - -void MultilineElement::draw( TQPainter& painter, const LuPixelRect& r, - const ContextStyle& context, - ContextStyle::TextStyle tstyle, - ContextStyle::IndexStyle istyle, - StyleAttributes& style, - const LuPixelPoint& parentOrigin ) -{ - LuPixelPoint myPos( parentOrigin.x() + getX(), parentOrigin.y() + getY() ); - uint count = content.count(); - - if ( context.edit() ) { - uint tabCount = 0; - painter.setPen( context.getHelpColor() ); - for ( uint i = 0; i < count; ++i ) { - MultilineSequenceElement* line = content.at(i); - if ( tabCount < line->tabCount() ) { - for ( uint t = tabCount; t < line->tabCount(); ++t ) { - BasicElement* marker = line->tab( t ); - painter.drawLine( context.layoutUnitToPixelX( myPos.x()+marker->getX() ), - context.layoutUnitToPixelY( myPos.y() ), - context.layoutUnitToPixelX( myPos.x()+marker->getX() ), - context.layoutUnitToPixelY( myPos.y()+getHeight() ) ); - } - tabCount = line->tabCount(); - } - } - } - - for ( uint i = 0; i < count; ++i ) { - MultilineSequenceElement* line = content.at(i); - line->draw( painter, r, context, tstyle, istyle, style, myPos ); - } -} - - -void MultilineElement::dispatchFontCommand( FontCommand* cmd ) -{ - uint count = content.count(); - for ( uint i = 0; i < count; ++i ) { - MultilineSequenceElement* line = content.at(i); - line->dispatchFontCommand( cmd ); - } -} - -void MultilineElement::insert( FormulaCursor* cursor, - TQPtrList& newChildren, - Direction direction ) -{ - MultilineSequenceElement* e = static_cast(newChildren.take(0)); - e->setParent(this); - content.insert( cursor->getPos(), e ); - - if (direction == beforeCursor) { - e->moveLeft(cursor, this); - } - else { - e->moveRight(cursor, this); - } - cursor->setSelection(false); - formula()->changed(); -} - -void MultilineElement::remove( FormulaCursor* cursor, - TQPtrList& removedChildren, - Direction direction ) -{ - if ( content.count() == 1 ) { //&& ( cursor->getPos() == 0 ) ) { - getParent()->selectChild(cursor, this); - getParent()->remove(cursor, removedChildren, direction); - } - else { - MultilineSequenceElement* e = content.take( cursor->getPos() ); - removedChildren.append( e ); - formula()->elementRemoval( e ); - //cursor->setTo( this, denominatorPos ); - formula()->changed(); - } -} - -void MultilineElement::normalize( FormulaCursor* cursor, Direction direction ) -{ - int pos = cursor->getPos(); - if ( ( cursor->getElement() == this ) && - ( pos > -1 ) && ( static_cast( pos ) <= content.count() ) ) { - switch ( direction ) { - case beforeCursor: - if ( pos > 0 ) { - content.at( pos-1 )->moveLeft( cursor, this ); - break; - } - // no break! intended! - case afterCursor: - if ( static_cast( pos ) < content.count() ) { - content.at( pos )->moveRight( cursor, this ); - } - else { - content.at( pos-1 )->moveLeft( cursor, this ); - } - break; - } - } - else { - inherited::normalize( cursor, direction ); - } -} - -SequenceElement* MultilineElement::getMainChild() -{ - return content.at( 0 ); -} - -void MultilineElement::selectChild(FormulaCursor* cursor, BasicElement* child) -{ - int pos = content.find( dynamic_cast( child ) ); - if ( pos > -1 ) { - cursor->setTo( this, pos ); - //content.at( pos )->moveRight( cursor, this ); - } -} - - -/** - * Appends our attributes to the dom element. - */ -void MultilineElement::writeDom(TQDomElement element) -{ - BasicElement::writeDom(element); - - uint lineCount = content.count(); - element.setAttribute( "LINES", lineCount ); - - TQDomDocument doc = element.ownerDocument(); - for ( uint i = 0; i < lineCount; ++i ) { - TQDomElement tmp = content.at( i )->getElementDom(doc); - element.appendChild(tmp); - } -} - -void MultilineElement::writeMathML( TQDomDocument& doc, TQDomNode& parent, bool oasisFormat ) const -{ - TQDomElement de = doc.createElement( oasisFormat ? "math:mtable" : "mtable" ); - TQDomElement row; TQDomElement cell; - - for ( TQPtrListIterator < MultilineSequenceElement > it( content ); it.current(); ++it ) { - row = doc.createElement( oasisFormat ? "math:mtr" : "mtr" ); - de.appendChild( row ); - //cell = doc.createElement( "mtd" ); - //row.appendChild( cell ); - - //content.at( i )->writeMathML( doc, cell ); - it.current()->writeMathML( doc, row, oasisFormat ); - } - - parent.appendChild( de ); -} - -/** - * Reads our attributes from the element. - * Returns false if it failed. - */ -bool MultilineElement::readAttributesFromDom(TQDomElement element) -{ - if (!BasicElement::readAttributesFromDom(element)) { - return false; - } - uint lineCount = 0; - TQString lineCountStr = element.attribute("LINES"); - if(!lineCountStr.isNull()) { - lineCount = lineCountStr.toInt(); - } - if (lineCount == 0) { - kdWarning( DEBUGID ) << "lineCount <= 0 in MultilineElement." << endl; - return false; - } - - content.clear(); - for ( uint i = 0; i < lineCount; ++i ) { - MultilineSequenceElement* element = new MultilineSequenceElement(this); - content.append(element); - } - return true; -} - -/** - * Reads our content from the node. Sets the node to the next node - * that needs to be read. - * Returns false if it failed. - */ -bool MultilineElement::readContentFromDom(TQDomNode& node) -{ - if (!BasicElement::readContentFromDom(node)) { - return false; - } - - uint lineCount = content.count(); - uint i = 0; - while ( !node.isNull() && i < lineCount ) { - if ( node.isElement() ) { - SequenceElement* element = content.at( i ); - TQDomElement e = node.toElement(); - if ( !element->buildFromDom( e ) ) { - return false; - } - ++i; - } - node = node.nextSibling(); - } - return true; -} - -TQString MultilineElement::toLatex() -{ - uint lineCount = content.count(); - TQString muliline = "\\begin{split} "; - for ( uint i = 0; i < lineCount; ++i ) { - muliline += content.at( i )->toLatex(); - muliline += " \\\\ "; - } - muliline += "\\end{split}"; - return muliline; -} - -// Does this make any sense at all? -TQString MultilineElement::formulaString() -{ - uint lineCount = content.count(); - TQString muliline = ""; - for ( uint i = 0; i < lineCount; ++i ) { - muliline += content.at( i )->formulaString(); - muliline += "\n"; - } - //muliline += ""; - return muliline; -} - - -KFORMULA_NAMESPACE_END diff --git a/lib/kformula/matrixelement.cpp b/lib/kformula/matrixelement.cpp new file mode 100644 index 00000000..6b878380 --- /dev/null +++ b/lib/kformula/matrixelement.cpp @@ -0,0 +1,2692 @@ +/* This file is part of the KDE project + Copyright (C) 2001 Andrea Rizzi + Ulrich Kuettler + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include + +#include +#include + +#include "MatrixDialog.h" +#include "elementvisitor.h" +#include "formulaelement.h" +#include "formulacursor.h" +#include "kformulacontainer.h" +#include "kformulacommand.h" +#include "matrixelement.h" +#include "sequenceelement.h" +#include "spaceelement.h" + + +KFORMULA_NAMESPACE_BEGIN + + +class MatrixSequenceElement : public SequenceElement { + typedef SequenceElement inherited; +public: + + MatrixSequenceElement( BasicElement* parent = 0 ) : SequenceElement( parent ) {} + virtual MatrixSequenceElement* clone() { + return new MatrixSequenceElement( *this ); + } + + /** + * This is called by the container to get a command depending on + * the current cursor position (this is how the element gets chosen) + * and the request. + * + * @returns the command that performs the requested action with + * the containers active cursor. + */ + virtual KCommand* buildCommand( Container*, Request* ); +}; + + +class KFCRemoveRow : public Command { +public: + KFCRemoveRow( const TQString& name, Container* document, MatrixElement* m, uint r, uint c ); + ~KFCRemoveRow(); + + virtual void execute(); + virtual void unexecute(); + +protected: + MatrixElement* matrix; + uint rowPos; + uint colPos; + + TQPtrList* row; +}; + + +class KFCInsertRow : public KFCRemoveRow { +public: + KFCInsertRow( const TQString& name, Container* document, MatrixElement* m, uint r, uint c ); + + virtual void execute() { KFCRemoveRow::unexecute(); } + virtual void unexecute() { KFCRemoveRow::execute(); } +}; + + +class KFCRemoveColumn : public Command { +public: + KFCRemoveColumn( const TQString& name, Container* document, MatrixElement* m, uint r, uint c ); + ~KFCRemoveColumn(); + + virtual void execute(); + virtual void unexecute(); + +protected: + MatrixElement* matrix; + uint rowPos; + uint colPos; + + TQPtrList* column; +}; + + +class KFCInsertColumn : public KFCRemoveColumn { +public: + KFCInsertColumn( const TQString& name, Container* document, MatrixElement* m, uint r, uint c ); + + virtual void execute() { KFCRemoveColumn::unexecute(); } + virtual void unexecute() { KFCRemoveColumn::execute(); } +}; + + +KCommand* MatrixSequenceElement::buildCommand( Container* container, Request* request ) +{ + FormulaCursor* cursor = container->activeCursor(); + if ( cursor->isReadOnly() ) { + return 0; + } + + switch ( *request ) { + case req_appendColumn: + case req_appendRow: + case req_insertColumn: + case req_removeColumn: + case req_insertRow: + case req_removeRow: { + MatrixElement* matrix = static_cast( getParent() ); + FormulaCursor* cursor = container->activeCursor(); + for ( uint row = 0; row < matrix->getRows(); row++ ) { + for ( uint col = 0; col < matrix->getColumns(); col++ ) { + if ( matrix->getElement( row, col ) == cursor->getElement() ) { + switch ( *request ) { + case req_appendColumn: + return new KFCInsertColumn( i18n( "Append Column" ), container, matrix, row, matrix->getColumns() ); + case req_appendRow: + return new KFCInsertRow( i18n( "Append Row" ), container, matrix, matrix->getRows(), col ); + case req_insertColumn: + return new KFCInsertColumn( i18n( "Insert Column" ), container, matrix, row, col ); + case req_removeColumn: + if ( matrix->getColumns() > 1 ) { + return new KFCRemoveColumn( i18n( "Remove Column" ), container, matrix, row, col ); + } + break; + case req_insertRow: + return new KFCInsertRow( i18n( "Insert Row" ), container, matrix, row, col ); + case req_removeRow: + if ( matrix->getRows() > 1 ) { + return new KFCRemoveRow( i18n( "Remove Row" ), container, matrix, row, col ); + } + break; + default: + break; + } + } + } + } + kdWarning( DEBUGID ) << "MatrixSequenceElement::buildCommand: Sequence not found." << endl; + break; + } + default: + break; + } + return inherited::buildCommand( container, request ); +} + + +KFCRemoveRow::KFCRemoveRow( const TQString& name, Container* document, MatrixElement* m, uint r, uint c ) + : Command( name, document ), matrix( m ), rowPos( r ), colPos( c ), row( 0 ) +{ +} + +KFCRemoveRow::~KFCRemoveRow() +{ + delete row; +} + +void KFCRemoveRow::execute() +{ + FormulaCursor* cursor = getExecuteCursor(); + row = matrix->content.at( rowPos ); + FormulaElement* formula = matrix->formula(); + for ( uint i = matrix->getColumns(); i > 0; i-- ) { + formula->elementRemoval( row->at( i-1 ) ); + } + matrix->content.take( rowPos ); + formula->changed(); + if ( rowPos < matrix->getRows() ) { + matrix->getElement( rowPos, colPos )->goInside( cursor ); + } + else { + matrix->getElement( rowPos-1, colPos )->goInside( cursor ); + } + testDirty(); +} + +void KFCRemoveRow::unexecute() +{ + matrix->content.insert( rowPos, row ); + row = 0; + FormulaCursor* cursor = getExecuteCursor(); + matrix->getElement( rowPos, colPos )->goInside( cursor ); + matrix->formula()->changed(); + testDirty(); +} + + +KFCInsertRow::KFCInsertRow( const TQString& name, Container* document, MatrixElement* m, uint r, uint c ) + : KFCRemoveRow( name, document, m, r, c ) +{ + row = new TQPtrList< MatrixSequenceElement >; + row->setAutoDelete( true ); + for ( uint i = 0; i < matrix->getColumns(); i++ ) { + row->append( new MatrixSequenceElement( matrix ) ); + } +} + + +KFCRemoveColumn::KFCRemoveColumn( const TQString& name, Container* document, MatrixElement* m, uint r, uint c ) + : Command( name, document ), matrix( m ), rowPos( r ), colPos( c ) +{ + column = new TQPtrList< MatrixSequenceElement >; + column->setAutoDelete( true ); +} + +KFCRemoveColumn::~KFCRemoveColumn() +{ + delete column; +} + +void KFCRemoveColumn::execute() +{ + FormulaCursor* cursor = getExecuteCursor(); + FormulaElement* formula = matrix->formula(); + for ( uint i = 0; i < matrix->getRows(); i++ ) { + column->append( matrix->getElement( i, colPos ) ); + formula->elementRemoval( column->at( i ) ); + matrix->content.at( i )->take( colPos ); + } + formula->changed(); + if ( colPos < matrix->getColumns() ) { + matrix->getElement( rowPos, colPos )->goInside( cursor ); + } + else { + matrix->getElement( rowPos, colPos-1 )->goInside( cursor ); + } + testDirty(); +} + +void KFCRemoveColumn::unexecute() +{ + for ( uint i = 0; i < matrix->getRows(); i++ ) { + matrix->content.at( i )->insert( colPos, column->take( 0 ) ); + } + FormulaCursor* cursor = getExecuteCursor(); + matrix->getElement( rowPos, colPos )->goInside( cursor ); + matrix->formula()->changed(); + testDirty(); +} + + +KFCInsertColumn::KFCInsertColumn( const TQString& name, Container* document, MatrixElement* m, uint r, uint c ) + : KFCRemoveColumn( name, document, m, r, c ) +{ + for ( uint i = 0; i < matrix->getRows(); i++ ) { + column->append( new MatrixSequenceElement( matrix ) ); + } +} + + +MatrixElement::MatrixElement(uint rows, uint columns, BasicElement* parent) + : BasicElement(parent), + m_rowNumber( 0 ), + m_align( NoAlign ), + m_widthType( NoSize ), + m_frame( NoLine ), + m_frameHSpacing( NoSize ), + m_frameVSpacing( NoSize ), + m_side( NoSide ), + m_minLabelSpacingType( NoSize ), + m_customEqualRows( false ), + m_customEqualColumns( false ), + m_customDisplayStyle( false ) +{ + for (uint r = 0; r < rows; r++) { + TQPtrList< MatrixSequenceElement >* list = new TQPtrList< MatrixSequenceElement >; + list->setAutoDelete(true); + for (uint c = 0; c < columns; c++) { + list->append(new MatrixSequenceElement(this)); + } + content.append(list); + } + content.setAutoDelete(true); +} + +MatrixElement::~MatrixElement() +{ +} + + +MatrixElement::MatrixElement( const MatrixElement& other ) + : BasicElement( other ) +{ + uint rows = other.getRows(); + uint columns = other.getColumns(); + + TQPtrListIterator< TQPtrList< MatrixSequenceElement > > rowIter( other.content ); + for (uint r = 0; r < rows; r++) { + ++rowIter; + TQPtrListIterator< MatrixSequenceElement > colIter( *rowIter.current() ); + + TQPtrList< MatrixSequenceElement >* list = new TQPtrList< MatrixSequenceElement >; + list->setAutoDelete(true); + for (uint c = 0; c < columns; c++) { + ++colIter; + MatrixSequenceElement *mse = + //new MatrixSequenceElement( *( other.getElement( r, c ) ) ); + new MatrixSequenceElement( *colIter.current() ); + list->append( mse ); + mse->setParent( this ); + } + content.append(list); + } + content.setAutoDelete(true); +} + + +bool MatrixElement::accept( ElementVisitor* visitor ) +{ + return visitor->visit( this ); +} + + +void MatrixElement::entered( SequenceElement* /*child*/ ) +{ + formula()->tell( i18n( "Matrix element" ) ); +} + + +BasicElement* MatrixElement::goToPos( FormulaCursor* cursor, bool& handled, + const LuPixelPoint& point, const LuPixelPoint& parentOrigin ) +{ + BasicElement* e = BasicElement::goToPos(cursor, handled, point, parentOrigin); + if (e != 0) { + LuPixelPoint myPos(parentOrigin.x() + getX(), + parentOrigin.y() + getY()); + + uint rows = getRows(); + uint columns = getColumns(); + + for (uint r = 0; r < rows; r++) { + for (uint c = 0; c < columns; c++) { + BasicElement* element = getElement(r, c); + e = element->goToPos(cursor, handled, point, myPos); + if (e != 0) { + return e; + } + } + } + + // We are in one of those gaps. + luPixel dx = point.x() - myPos.x(); + luPixel dy = point.y() - myPos.y(); + + uint row = rows; + for (uint r = 0; r < rows; r++) { + BasicElement* element = getElement(r, 0); + if (element->getY() > dy) { + row = r; + break; + } + } + if (row == 0) { + BasicElement* element = getParent(); + element->moveLeft(cursor, this); + handled = true; + return element; + } + row--; + + uint column = columns; + for (uint c = 0; c < columns; c++) { + BasicElement* element = getElement(row, c); + if (element->getX() > dx) { + column = c; + break; + } + } + if (column == 0) { + BasicElement* element = getParent(); + element->moveLeft(cursor, this); + handled = true; + return element; + } + column--; + + // Rescan the rows with the actual colums required. + row = rows; + for (uint r = 0; r < rows; r++) { + BasicElement* element = getElement(r, column); + if (element->getY() > dy) { + row = r; + break; + } + } + if (row == 0) { + BasicElement* element = getParent(); + element->moveLeft(cursor, this); + handled = true; + return element; + } + row--; + + BasicElement* element = getElement(row, column); + element->moveLeft(cursor, this); + handled = true; + return element; + } + return 0; +} + + +// drawing +// +// Drawing depends on a context which knows the required properties like +// fonts, spaces and such. +// It is essential to calculate elements size with the same context +// before you draw. + +/** + * Calculates our width and height and + * our children's parentPosition. + */ +void MatrixElement::calcSizes( const ContextStyle& context, + ContextStyle::TextStyle tstyle, + ContextStyle::IndexStyle istyle, + StyleAttributes& style ) +{ + TQMemArray toMidlines(getRows()); + TQMemArray fromMidlines(getRows()); + TQMemArray widths(getColumns()); + + toMidlines.fill(0); + fromMidlines.fill(0); + widths.fill(0); + + uint rows = getRows(); + uint columns = getColumns(); + + ContextStyle::TextStyle i_tstyle = context.convertTextStyleFraction(tstyle); + ContextStyle::IndexStyle i_istyle = context.convertIndexStyleUpper(istyle); + double factor = style.sizeFactor(); + + for (uint r = 0; r < rows; r++) { + TQPtrList< MatrixSequenceElement >* list = content.at(r); + for (uint c = 0; c < columns; c++) { + SequenceElement* element = list->at(c); + element->calcSizes( context, i_tstyle, i_istyle, style ); + toMidlines[r] = TQMAX(toMidlines[r], element->axis( context, i_tstyle, factor )); + fromMidlines[r] = TQMAX(fromMidlines[r], + element->getHeight()-element->axis( context, i_tstyle, factor )); + widths[c] = TQMAX(widths[c], element->getWidth()); + } + } + + luPixel distX = context.ptToPixelX( context.getThinSpace( tstyle, factor ) ); + luPixel distY = context.ptToPixelY( context.getThinSpace( tstyle, factor ) ); + + luPixel yPos = 0; + for (uint r = 0; r < rows; r++) { + TQPtrList< MatrixSequenceElement >* list = content.at(r); + luPixel xPos = 0; + yPos += toMidlines[r]; + for (uint c = 0; c < columns; c++) { + SequenceElement* element = list->at(c); + switch (context.getMatrixAlignment()) { + case ContextStyle::left: + element->setX(xPos); + break; + case ContextStyle::center: + element->setX(xPos + (widths[c] - element->getWidth())/2); + break; + case ContextStyle::right: + element->setX(xPos + widths[c] - element->getWidth()); + break; + } + element->setY(yPos - element->axis( context, i_tstyle, factor )); + xPos += widths[c] + distX; + } + yPos += fromMidlines[r] + distY; + } + + luPixel width = distX * (columns - 1); + luPixel height = distY * (rows - 1); + + for (uint r = 0; r < rows; r++) height += toMidlines[r] + fromMidlines[r]; + for (uint c = 0; c < columns; c++) width += widths[c]; + + setWidth(width); + setHeight(height); + if ((rows == 2) && (columns == 1)) { + setBaseline( getMainChild()->getHeight() + distY / 2 + context.axisHeight( tstyle, factor ) ); + } + else { + setBaseline( height/2 + context.axisHeight( tstyle, factor ) ); + } +} + +/** + * Draws the whole element including its children. + * The `parentOrigin' is the point this element's parent starts. + * We can use our parentPosition to get our own origin then. + */ +void MatrixElement::draw( TQPainter& painter, const LuPixelRect& rect, + const ContextStyle& context, + ContextStyle::TextStyle tstyle, + ContextStyle::IndexStyle istyle, + StyleAttributes& style, + const LuPixelPoint& parentOrigin ) +{ + LuPixelPoint myPos( parentOrigin.x()+getX(), parentOrigin.y()+getY() ); + //if ( !LuPixelRect( myPos.x(), myPos.y(), getWidth(), getHeight() ).intersects( rect ) ) + // return; + + uint rows = getRows(); + uint columns = getColumns(); + + for (uint r = 0; r < rows; r++) { + for (uint c = 0; c < columns; c++) { + getElement(r, c)->draw(painter, rect, context, + context.convertTextStyleFraction(tstyle), + context.convertIndexStyleUpper(istyle), + style, + myPos); + } + } + + // Debug + //painter.setPen(TQt::red); + //painter.drawRect(myPos.x(), myPos.y(), getWidth(), getHeight()); +} + + +void MatrixElement::dispatchFontCommand( FontCommand* cmd ) +{ + uint rows = getRows(); + uint columns = getColumns(); + + for (uint r = 0; r < rows; r++) { + for (uint c = 0; c < columns; c++) { + getElement(r, c)->dispatchFontCommand( cmd ); + } + } +} + + +// navigation +// +// The elements are responsible to handle cursor movement themselves. +// To do this they need to know the direction the cursor moves and +// the element it comes from. +// +// The cursor might be in normal or in selection mode. + +/** + * Enters this element while moving to the left starting inside + * the element `from'. Searches for a cursor position inside + * this element or to the left of it. + */ +void MatrixElement::moveLeft(FormulaCursor* cursor, BasicElement* from) +{ + if (cursor->isSelectionMode()) { + getParent()->moveLeft(cursor, this); + } + else { + if (from == getParent()) { + getElement(getRows()-1, getColumns()-1)->moveLeft(cursor, this); + } + else { + bool linear = cursor->getLinearMovement(); + uint row = 0; + uint column = 0; + if (searchElement(from, row, column)) { + if (column > 0) { + getElement(row, column-1)->moveLeft(cursor, this); + } + else if (linear && (row > 0)) { + getElement(row-1, getColumns()-1)->moveLeft(cursor, this); + } + else { + getParent()->moveLeft(cursor, this); + } + } + else { + getParent()->moveLeft(cursor, this); + } + } + } +} + +/** + * Enters this element while moving to the right starting inside + * the element `from'. Searches for a cursor position inside + * this element or to the right of it. + */ +void MatrixElement::moveRight(FormulaCursor* cursor, BasicElement* from) +{ + if (cursor->isSelectionMode()) { + getParent()->moveRight(cursor, this); + } + else { + if (from == getParent()) { + getElement(0, 0)->moveRight(cursor, this); + } + else { + bool linear = cursor->getLinearMovement(); + uint row = 0; + uint column = 0; + if (searchElement(from, row, column)) { + if (column < getColumns()-1) { + getElement(row, column+1)->moveRight(cursor, this); + } + else if (linear && (row < getRows()-1)) { + getElement(row+1, 0)->moveRight(cursor, this); + } + else { + getParent()->moveRight(cursor, this); + } + } + else { + getParent()->moveRight(cursor, this); + } + } + } +} + +/** + * Enters this element while moving up starting inside + * the element `from'. Searches for a cursor position inside + * this element or above it. + */ +void MatrixElement::moveUp(FormulaCursor* cursor, BasicElement* from) +{ + if (cursor->isSelectionMode()) { + getParent()->moveUp(cursor, this); + } + else { + if (from == getParent()) { + getElement(0, 0)->moveRight(cursor, this); + } + else { + uint row = 0; + uint column = 0; + if (searchElement(from, row, column)) { + if (row > 0) { + getElement(row-1, column)->moveRight(cursor, this); + } + else { + getParent()->moveUp(cursor, this); + } + } + else { + getParent()->moveUp(cursor, this); + } + } + } +} + +/** + * Enters this element while moving down starting inside + * the element `from'. Searches for a cursor position inside + * this element or below it. + */ +void MatrixElement::moveDown(FormulaCursor* cursor, BasicElement* from) +{ + if (cursor->isSelectionMode()) { + getParent()->moveDown(cursor, this); + } + else { + if (from == getParent()) { + getElement(0, 0)->moveRight(cursor, this); + } + else { + uint row = 0; + uint column = 0; + if (searchElement(from, row, column)) { + if (row < getRows()-1) { + getElement(row+1, column)->moveRight(cursor, this); + } + else { + getParent()->moveDown(cursor, this); + } + } + else { + getParent()->moveDown(cursor, this); + } + } + } +} + +/** + * Sets the cursor inside this element to its start position. + * For most elements that is the main child. + */ +void MatrixElement::goInside(FormulaCursor* cursor) +{ + getElement(0, 0)->goInside(cursor); +} + + +// If there is a main child we must provide the insert/remove semantics. +SequenceElement* MatrixElement::getMainChild() +{ + return content.at(0)->at(0); +} + +void MatrixElement::selectChild(FormulaCursor* cursor, BasicElement* child) +{ + uint rows = getRows(); + uint columns = getColumns(); + for (uint r = 0; r < rows; r++) { + for (uint c = 0; c < columns; c++) { + if (child == getElement(r, c)) { + cursor->setTo(this, r*columns+c); + } + } + } +} + +const MatrixSequenceElement* MatrixElement::getElement( uint row, uint column ) const +{ + TQPtrListIterator< TQPtrList < MatrixSequenceElement > > rows( content ); + rows += row; + if ( ! rows.current() ) + return 0; + + TQPtrListIterator< MatrixSequenceElement > cols ( *rows.current() ); + cols += column; + return cols.current(); +} + + +bool MatrixElement::searchElement(BasicElement* element, uint& row, uint& column) +{ + uint rows = getRows(); + uint columns = getColumns(); + for (uint r = 0; r < rows; r++) { + for (uint c = 0; c < columns; c++) { + if (element == getElement(r, c)) { + row = r; + column = c; + return true; + } + } + } + return false; +} + + +/** + * Appends our attributes to the dom element. + */ +void MatrixElement::writeDom(TQDomElement element) +{ + BasicElement::writeDom(element); + + uint rows = getRows(); + uint cols = getColumns(); + + element.setAttribute("ROWS", rows); + element.setAttribute("COLUMNS", cols); + + TQDomDocument doc = element.ownerDocument(); + + for (uint r = 0; r < rows; r++) { + for (uint c = 0; c < cols; c++) { + TQDomElement tmp = getElement(r,c)->getElementDom(doc); + element.appendChild(tmp); + } + element.appendChild(doc.createComment("end of row")); + } +} + +/** + * Reads our attributes from the element. + * Returns false if it failed. + */ +bool MatrixElement::readAttributesFromDom(TQDomElement element) +{ + if (!BasicElement::readAttributesFromDom(element)) { + return false; + } + uint rows = 0; + TQString rowStr = element.attribute("ROWS"); + if(!rowStr.isNull()) { + rows = rowStr.toInt(); + } + if (rows == 0) { + kdWarning( DEBUGID ) << "Rows <= 0 in MatrixElement." << endl; + return false; + } + + TQString columnStr = element.attribute("COLUMNS"); + uint cols = 0; + if(!columnStr.isNull()) { + cols = columnStr.toInt(); + } + if (cols == 0) { + kdWarning( DEBUGID ) << "Columns <= 0 in MatrixElement." << endl; + return false; + } + + content.clear(); + for (uint r = 0; r < rows; r++) { + TQPtrList< MatrixSequenceElement >* list = new TQPtrList< MatrixSequenceElement >; + list->setAutoDelete(true); + content.append(list); + for (uint c = 0; c < cols; c++) { + MatrixSequenceElement* element = new MatrixSequenceElement(this); + list->append(element); + } + } + return true; +} + +/** + * Reads our content from the node. Sets the node to the next node + * that needs to be read. + * Returns false if it failed. + */ +bool MatrixElement::readContentFromDom(TQDomNode& node) +{ + if (!BasicElement::readContentFromDom(node)) { + return false; + } + + uint rows = getRows(); + uint cols = getColumns(); + + uint r = 0; + uint c = 0; + while ( !node.isNull() && r < rows ) { + if ( node.isElement() ) { + SequenceElement* element = getElement( r, c ); + TQDomElement e = node.toElement(); + if ( !element->buildFromDom( e ) ) { + return false; + } + c++; + if ( c == cols ) { + c = 0; + r++; + } + } + node = node.nextSibling(); + } + return true; +} + +bool MatrixElement::readAttributesFromMathMLDom( const TQDomElement& element ) +{ + if ( ! BasicElement::readAttributesFromMathMLDom( element ) ) { + return false; + } + + TQString alignStr = element.attribute( "align" ).lower(); + if ( ! alignStr.isNull() ) { + if ( alignStr.find( "top" ) != -1 ) { + m_align = TopAlign; + } + else if ( alignStr.find( "bottom" ) != -1 ) { + m_align = BottomAlign; + } + else if ( alignStr.find( "center" ) != -1 ) { + m_align = CenterAlign; + } + else if ( alignStr.find( "baseline" ) != -1 ) { + m_align = BaselineAlign; + } + else if ( alignStr.find( "axis" ) != -1 ) { + m_align = AxisAlign; + } + int index = alignStr.findRev( ' ' ); + if ( index != -1 ) { + m_rowNumber = alignStr.right( index + 1 ).toInt(); + } + } + TQString rowalignStr = element.attribute( "rowalign" ).lower(); + if ( ! rowalignStr.isNull() ) { + TQStringList list = TQStringList::split( ' ', rowalignStr ); + for ( TQStringList::iterator it = list.begin(); it != list.end(); it++ ) { + if ( *it == "top" ) { + m_rowAlign.append( TopAlign ); + } + else if ( *it == "bottom" ) { + m_rowAlign.append( BottomAlign ); + } + else if ( *it == "center" ) { + m_rowAlign.append( CenterAlign ); + } + else if ( *it == "baseline" ) { + m_rowAlign.append( BaselineAlign ); + } + else if ( *it == "axis" ) { + m_rowAlign.append( AxisAlign ); + } + } + } + TQString columnalignStr = element.attribute( "columnalign" ).lower(); + if ( ! columnalignStr.isNull() ) { + TQStringList list = TQStringList::split( ' ', columnalignStr ); + for ( TQStringList::iterator it = list.begin(); it != list.end(); it++ ) { + if ( *it == "left" ) { + m_columnAlign.append( LeftHorizontalAlign ); + } + else if ( *it == "center" ) { + m_columnAlign.append( CenterHorizontalAlign ); + } + else if ( *it == "right" ) { + m_columnAlign.append( RightHorizontalAlign ); + } + } + } + TQString alignmentscopeStr = element.attribute( "alignmentscope" ).lower(); + if ( ! alignmentscopeStr.isNull() ) { + TQStringList list = TQStringList::split( ' ', alignmentscopeStr ); + for ( TQStringList::iterator it = list.begin(); it != list.end(); it++ ) { + if ( *it == "true" ) { + m_alignmentScope.append( true ); + } + else if ( *it == "false" ) { + m_alignmentScope.append( false ); + } + } + } + TQString columnwidthStr = element.attribute( "columnwidth" ).lower(); + if ( columnwidthStr.isNull() ) { + TQStringList list = TQStringList::split( ' ', columnwidthStr ); + for ( TQStringList::iterator it = list.begin(); it != list.end(); it++ ) { + SizeType type = NoSize; + double length; + if ( *it == "auto" ) { + type = AutoSize; + } + else if ( *it == "fit" ) { + type = FitSize; + } + else { + length = getSize( columnwidthStr, &type ); + if ( type == NoSize ) { + type = getSpace( columnwidthStr ); + } + } + if ( type != NoSize ) { + m_columnWidthType.append( type ); + if ( type == RelativeSize || type == AbsoluteSize || type == PixelSize ) { + m_columnWidth.append( length ); + } + } + } + } + TQString widthStr = element.attribute( "width" ).lower(); + if ( ! widthStr.isNull() ) { + if ( widthStr == "auto" ) { + m_widthType = AutoSize; + } + else { + m_width = getSize( widthStr, &m_widthType ); + } + } + TQString rowspacingStr = element.attribute( "rowspacing" ).lower(); + if ( ! rowspacingStr.isNull() ) { + TQStringList list = TQStringList::split( ' ', rowspacingStr ); + for ( TQStringList::iterator it = list.begin(); it != list.end(); it++ ) { + SizeType type; + double length = getSize( *it, &type ); + if ( type != NoSize ) { + m_rowSpacingType.append( type ); + m_rowSpacing.append( length ); + } + } + } + TQString columnspacingStr = element.attribute( "columnspacing" ).lower(); + if ( ! columnspacingStr.isNull() ) { + TQStringList list = TQStringList::split( ' ', columnspacingStr ); + for ( TQStringList::iterator it = list.begin(); it != list.end(); it++ ) { + SizeType type; + double length = getSize( *it, &type ); + if ( type == NoSize ) { + type = getSpace( columnspacingStr ); + } + if ( type != NoSize ) { + m_columnSpacingType.append( type ); + if ( type == RelativeSize || type == AbsoluteSize || type == PixelSize ) { + m_columnSpacing.append( length ); + } + } + } + } + TQString rowlinesStr = element.attribute( "rowlines" ).lower(); + if ( ! rowlinesStr.isNull() ) { + TQStringList list = TQStringList::split( ' ', rowlinesStr ); + for ( TQStringList::iterator it = list.begin(); it != list.end(); it++ ) { + if ( *it == "none" ) { + m_rowLines.append( NoneLine ); + } + else if ( *it == "solid" ) { + m_rowLines.append( SolidLine ); + } + else if ( *it == "dashed" ) { + m_rowLines.append( DashedLine ); + } + } + } + TQString columnlinesStr = element.attribute( "columnlines" ).lower(); + if ( ! columnlinesStr.isNull() ) { + TQStringList list = TQStringList::split( ' ', columnlinesStr ); + for ( TQStringList::iterator it = list.begin(); it != list.end(); it++ ) { + if ( *it == "none" ) { + m_columnLines.append( NoneLine ); + } + else if ( *it == "solid" ) { + m_columnLines.append( SolidLine ); + } + else if ( *it == "dashed" ) { + m_columnLines.append( DashedLine ); + } + } + } + TQString frameStr = element.attribute( "frame" ).stripWhiteSpace().lower(); + if ( ! frameStr.isNull() ) { + if ( frameStr == "none" ) { + m_frame = NoneLine; + } + else if ( frameStr == "solid" ) { + m_frame = SolidLine; + } + else if ( frameStr == "dashed" ) { + m_frame = DashedLine; + } + } + TQString framespacingStr = element.attribute( "framespacing" ); + if ( ! framespacingStr.isNull() ) { + TQStringList list = TQStringList::split( ' ', framespacingStr ); + m_frameHSpacing = getSize( list[0], &m_frameHSpacingType ); + if ( m_frameHSpacingType == NoSize ) { + m_frameHSpacingType = getSpace( list[0] ); + } + if ( list.count() > 1 ) { + m_frameVSpacing = getSize( list[1], &m_frameVSpacingType ); + if ( m_frameVSpacingType == NoSize ) { + m_frameVSpacingType = getSpace( list[1] ); + } + } + } + TQString equalrowsStr = element.attribute( "equalrows" ).stripWhiteSpace().lower(); + if ( ! equalrowsStr.isNull() ) { + m_customEqualRows = true; + if ( equalrowsStr == "false" ) { + m_equalRows = false; + } + else { + m_equalRows = true; + } + } + TQString equalcolumnsStr = element.attribute( "equalcolumns" ).stripWhiteSpace().lower(); + if ( ! equalcolumnsStr.isNull() ) { + m_customEqualColumns = true; + if ( equalcolumnsStr == "false" ) { + m_equalColumns = false; + } + else { + m_equalColumns = true; + } + } + TQString displaystyleStr = element.attribute( "displaystyle" ).stripWhiteSpace().lower(); + if ( ! displaystyleStr.isNull() ) { + m_customDisplayStyle = true; + if ( displaystyleStr == "false" ) { + m_displayStyle = false; + } + else { + m_displayStyle = true; + } + } + TQString sideStr = element.attribute( "side" ).stripWhiteSpace().lower(); + if ( ! sideStr.isNull() ) { + if ( sideStr == "left" ) { + m_side = LeftSide; + } + else if ( sideStr == "right" ) { + m_side = RightSide; + } + else if ( sideStr == "leftoverlap" ) { + m_side = LeftOverlapSide; + } + else if ( sideStr == "rightoverlap" ) { + m_side = RightOverlapSide; + } + } + TQString minlabelspacingStr = element.attribute( "minlabelspacing" ).stripWhiteSpace().lower(); + if ( ! minlabelspacingStr.isNull() ) { + m_minLabelSpacing = getSize( minlabelspacingStr, &m_minLabelSpacingType ); + if ( m_minLabelSpacingType == NoSize ) { + m_minLabelSpacingType = getSpace( minlabelspacingStr ); + } + } + return true; +} + +/** + * Reads our content from the MathML node. Sets the node to the next node + * that needs to be read. It is sometimes needed to read more than one node + * (e. g. for fence operators). + * Returns the number of nodes processed or -1 if it failed. + */ +int MatrixElement::readContentFromMathMLDom( TQDomNode& node ) +{ + // We have twice, since there may be empty elements and we need to know how + // many of them we have. So, first pass, get number of rows and columns + + if ( BasicElement::readContentFromMathMLDom( node ) == -1 ) { + return -1; + } + + uint rows = 0; + uint cols = 0; + TQDomNode n = node; + while ( !n.isNull() ) { + if ( n.isElement() ) { + TQDomElement e = n.toElement(); + if ( e.tagName().lower() == "mtr" || e.tagName().lower() == "mlabeledtr" ) + { + rows++; + + /* Determins the number of columns */ + TQDomNode cellnode = e.firstChild(); + int cc = 0; + + while ( !cellnode.isNull() ) { + if ( cellnode.isElement() ) + cc++; + cellnode = cellnode.nextSibling(); + } + if ( cc > 0 && e.tagName().lower() == "mlabeledtr" ) + cc--; + if ( cc > cols ) + cols = cc; + } + } + n = n.nextSibling(); + } + + // Create elements + content.clear(); + for (uint r = 0; r < rows; r++) { + TQPtrList< MatrixSequenceElement >* list = new TQPtrList< MatrixSequenceElement >; + list->setAutoDelete(true); + content.append(list); + for (uint c = 0; c < cols; c++) { + MatrixSequenceElement* element = new MatrixSequenceElement(this); + list->append(element); + } + } + + // Second pass, read elements now + uint r = 0; + uint c = 0; + while ( !node.isNull() ) { + if ( node.isElement() ) { + TQDomElement e = node.toElement(); + if ( e.tagName().lower() == "mtr" || e.tagName().lower() == "mlabeledtr" ) { + TQDomNode cellnode = e.firstChild(); + if ( e.tagName().lower() == "mlabeledtr" ) { + while ( ! cellnode.isNull() && ! cellnode.isElement() ) + cellnode = cellnode.nextSibling(); + if ( ! cellnode.isNull() ) + cellnode = cellnode.nextSibling(); + } + while ( !cellnode.isNull() ) { + if ( cellnode.isElement() ) { + TQDomElement cellelement = cellnode.toElement(); + if ( cellelement.tagName().lower() != "mtd" ) { + // TODO: Inferred mtd. Deprecated in MathML 2.0 + kdWarning( DEBUGID ) << "Unsupported tag " + << cellelement.tagName() + << " inside matrix row\n"; + } + else { + SequenceElement* element = getElement(r, c); + if ( element->buildFromMathMLDom( cellelement ) == -1 ) + return -1; + c++; + } + } + cellnode = cellnode.nextSibling(); + } + c = 0; + r++; + } + } + node = node.nextSibling(); + } + return 1; +} + +TQString MatrixElement::toLatex() +{ + //All the border handling must be implemented here too + + TQString matrix; + uint cols=getColumns(); + uint rows=getRows(); + + matrix="\\begin{array}{ "; + for(uint i=0;itoLatex(); + if( c < cols-1) matrix+=" & "; + } + if(r < rows-1 ) matrix+=" \\\\ "; + } + + matrix+=" \\end{array}"; + + return matrix; +} + +TQString MatrixElement::formulaString() +{ + TQString matrix = "["; + uint cols=getColumns(); + uint rows=getRows(); + for (uint r = 0; r < rows; r++) { + matrix += "["; + for (uint c = 0; c < cols; c++) { + matrix+=getElement(r, c)->formulaString(); + if ( c < cols-1 ) matrix+=", "; + } + matrix += "]"; + if ( r < rows-1 ) matrix += ", "; + } + matrix += "]"; + return matrix; +} + + +SequenceElement* MatrixElement::elementAt(uint row, uint column) +{ + return getElement( row, column ); +} + +void MatrixElement::writeMathMLAttributes( TQDomElement& element ) const +{ + TQString rownumber; + if ( m_rowNumber ) { + rownumber = TQString( " %1" ).arg( m_rowNumber ); + } + switch ( m_align ) { + case TopAlign: + element.setAttribute( "align", "top" + rownumber ); + break; + case BottomAlign: + element.setAttribute( "align", "bottom" + rownumber ); + break; + case CenterAlign: + element.setAttribute( "align", "center" + rownumber ); + break; + case BaselineAlign: + element.setAttribute( "align", "baseline" + rownumber ); + break; + case AxisAlign: + element.setAttribute( "align", "axis" + rownumber ); + break; + default: + break; + } + TQString rowalign; + for ( TQValueList::const_iterator it = m_rowAlign.begin(); it != m_rowAlign.end(); it++ ) + { + switch ( *it ) { + case TopAlign: + rowalign.append( "top " ); + break; + case BottomAlign: + rowalign.append( "bottom " ); + break; + case CenterAlign: + rowalign.append( "center " ); + break; + case BaselineAlign: + rowalign.append( "baseline " ); + break; + case AxisAlign: + rowalign.append( "axis " ); + break; + default: + break; + } + } + if ( ! rowalign.isNull() ) { + element.setAttribute( "rowalign", rowalign.stripWhiteSpace() ); + } + TQString columnalign; + for ( TQValueList::const_iterator it = m_columnAlign.begin(); it != m_columnAlign.end(); it++ ) + { + switch ( *it ) { + case LeftHorizontalAlign: + rowalign.append( "left " ); + break; + case CenterHorizontalAlign: + rowalign.append( "center " ); + break; + case RightHorizontalAlign: + rowalign.append( "right " ); + break; + default: + break; + } + } + if ( ! columnalign.isNull() ) { + element.setAttribute( "columnalign", columnalign.stripWhiteSpace() ); + } + TQString alignmentscope; + for ( TQValueList< bool >::const_iterator it = m_alignmentScope.begin(); it != m_alignmentScope.end(); it++ ) + { + if ( *it ) { + alignmentscope.append( "true " ); + } + else { + alignmentscope.append( "false " ); + } + } + if ( ! alignmentscope.isNull() ) { + element.setAttribute( "alignmentscope", alignmentscope.stripWhiteSpace() ); + } + TQString columnwidth; + TQValueList< double >::const_iterator lengthIt = m_columnWidth.begin(); + for ( TQValueList< SizeType >::const_iterator typeIt = m_columnWidthType.begin(); + typeIt != m_columnWidthType.end(); typeIt ++ ) { + switch ( *typeIt ) { + case AutoSize: + columnwidth.append( "auto " ); + break; + case FitSize: + columnwidth.append( "fit " ); + break; + case AbsoluteSize: + columnwidth.append( TQString( "%1pt " ).arg( *lengthIt ) ); + lengthIt++; + break; + case RelativeSize: + columnwidth.append( TQString( "%1% " ).arg( *lengthIt * 100.0 ) ); + lengthIt++; + break; + case PixelSize: + columnwidth.append( TQString( "%1px " ).arg( *lengthIt ) ); + lengthIt++; + break; + case NegativeVeryVeryThinMathSpace: + columnwidth.append( "negativeveryverythinmathspace " ); + break; + case NegativeVeryThinMathSpace: + columnwidth.append( "negativeverythinmathspace " ); + break; + case NegativeThinMathSpace: + columnwidth.append( "negativethinmathspace " ); + break; + case NegativeMediumMathSpace: + columnwidth.append( "negativemediummathspace " ); + break; + case NegativeThickMathSpace: + columnwidth.append( "negativethickmathspace " ); + break; + case NegativeVeryThickMathSpace: + columnwidth.append( "negativeverythickmathspace " ); + break; + case NegativeVeryVeryThickMathSpace: + columnwidth.append( "negativeveryverythickmathspace " ); + break; + case VeryVeryThinMathSpace: + columnwidth.append( "veryverythinmathspace " ); + break; + case VeryThinMathSpace: + columnwidth.append( "verythinmathspace " ); + break; + case ThinMathSpace: + columnwidth.append( "thinmathspace " ); + break; + case MediumMathSpace: + columnwidth.append( "mediummathspace " ); + break; + case ThickMathSpace: + columnwidth.append( "thickmathspace " ); + break; + case VeryThickMathSpace: + columnwidth.append( "verythickmathspace " ); + break; + case VeryVeryThickMathSpace: + columnwidth.append( "veryverythickmathspace " ); + break; + default: + break; + } + } + if ( ! columnwidth.isNull() ) { + element.setAttribute( "columnwidth", columnwidth.stripWhiteSpace() ); + } + switch ( m_widthType ) { + case AutoSize: + element.setAttribute( "width", "auto" ); + break; + case AbsoluteSize: + element.setAttribute( "width", TQString( "%1pt" ).arg( m_width ) ); + break; + case RelativeSize: + element.setAttribute( "width", TQString( "%1% " ).arg( m_width * 100.0 ) ); + break; + case PixelSize: + element.setAttribute( "width", TQString( "%1px " ).arg( m_width ) ); + break; + default: + break; + } + TQString rowspacing; + lengthIt = m_rowSpacing.begin(); + for ( TQValueList< SizeType >::const_iterator typeIt = m_rowSpacingType.begin(); + typeIt != m_rowSpacingType.end(); typeIt++, lengthIt++ ) { + switch ( *typeIt ) { + case AbsoluteSize: + rowspacing.append( TQString( "%1pt " ).arg( *lengthIt ) ); + break; + case RelativeSize: + rowspacing.append( TQString( "%1% " ).arg( *lengthIt * 100.0 ) ); + break; + case PixelSize: + rowspacing.append( TQString( "%1px " ).arg( *lengthIt ) ); + break; + default: + break; + } + } + if ( ! rowspacing.isNull() ) { + element.setAttribute( "rowspacing", rowspacing.stripWhiteSpace() ); + } + TQString columnspacing; + lengthIt = m_columnSpacing.begin(); + for ( TQValueList< SizeType >::const_iterator typeIt = m_columnSpacingType.begin(); + typeIt != m_columnSpacingType.end(); typeIt++ ) { + switch ( *typeIt ) { + case AbsoluteSize: + columnspacing.append( TQString( "%1pt " ).arg( *lengthIt ) ); + lengthIt++; + break; + case RelativeSize: + columnspacing.append( TQString( "%1% " ).arg( *lengthIt * 100.0 ) ); + lengthIt++; + break; + case PixelSize: + columnspacing.append( TQString( "%1px " ).arg( *lengthIt ) ); + lengthIt++; + break; + case NegativeVeryVeryThinMathSpace: + columnspacing.append( "negativeveryverythinmathspace " ); + break; + case NegativeVeryThinMathSpace: + columnspacing.append( "negativeverythinmathspace " ); + break; + case NegativeThinMathSpace: + columnspacing.append( "negativethinmathspace " ); + break; + case NegativeMediumMathSpace: + columnspacing.append( "negativemediummathspace " ); + break; + case NegativeThickMathSpace: + columnspacing.append( "negativethickmathspace " ); + break; + case NegativeVeryThickMathSpace: + columnspacing.append( "negativeverythickmathspace " ); + break; + case NegativeVeryVeryThickMathSpace: + columnspacing.append( "negativeveryverythickmathspace " ); + break; + case VeryVeryThinMathSpace: + columnspacing.append( "veryverythinmathspace " ); + break; + case VeryThinMathSpace: + columnspacing.append( "verythinmathspace " ); + break; + case ThinMathSpace: + columnspacing.append( "thinmathspace " ); + break; + case MediumMathSpace: + columnspacing.append( "mediummathspace " ); + break; + case ThickMathSpace: + columnspacing.append( "thickmathspace " ); + break; + case VeryThickMathSpace: + columnspacing.append( "verythickmathspace " ); + break; + case VeryVeryThickMathSpace: + columnspacing.append( "veryverythickmathspace " ); + break; + default: + break; + } + } + if ( ! rowspacing.isNull() ) { + element.setAttribute( "rowspacing", rowspacing.stripWhiteSpace() ); + } + TQString rowlines; + for ( TQValueList< LineType >::const_iterator it = m_rowLines.begin(); it != m_rowLines.end(); it++ ) + { + switch ( *it ) { + case NoneLine: + rowlines.append( "none " ); + break; + case SolidLine: + rowlines.append( "solid " ); + break; + case DashedLine: + rowlines.append( "dashed " ); + break; + default: + break; + } + } + if ( ! rowlines.isNull() ) { + element.setAttribute( "rowlines", rowlines.stripWhiteSpace() ); + } + TQString columnlines; + for ( TQValueList< LineType >::const_iterator it = m_columnLines.begin(); it != m_columnLines.end(); it++ ) + { + switch ( *it ) { + case NoneLine: + columnlines.append( "none " ); + break; + case SolidLine: + columnlines.append( "solid " ); + break; + case DashedLine: + columnlines.append( "dashed " ); + break; + default: + break; + } + } + if ( ! columnlines.isNull() ) { + element.setAttribute( "columnlines", columnlines.stripWhiteSpace() ); + } + switch ( m_frame ) { + case NoneLine: + element.setAttribute( "frame", "none" ); + break; + case SolidLine: + element.setAttribute( "frame", "solid" ); + break; + case DashedLine: + element.setAttribute( "frame", "dashed" ); + break; + default: + break; + } + TQString framespacing; + switch ( m_frameHSpacingType ) { + case AbsoluteSize: + framespacing.append( TQString( "%1pt " ).arg( m_frameHSpacing ) ); + break; + case RelativeSize: + framespacing.append( TQString( "%1% " ).arg( m_frameHSpacing * 100.0 ) ); + break; + case PixelSize: + framespacing.append( TQString( "%1px " ).arg( m_frameHSpacing ) ); + break; + case NegativeVeryVeryThinMathSpace: + framespacing.append( "negativeveryverythinmathspace " ); + break; + case NegativeVeryThinMathSpace: + framespacing.append( "negativeverythinmathspace " ); + break; + case NegativeThinMathSpace: + framespacing.append( "negativethinmathspace " ); + break; + case NegativeMediumMathSpace: + framespacing.append( "negativemediummathspace " ); + break; + case NegativeThickMathSpace: + framespacing.append( "negativethickmathspace " ); + break; + case NegativeVeryThickMathSpace: + framespacing.append( "negativeverythickmathspace " ); + break; + case NegativeVeryVeryThickMathSpace: + framespacing.append( "negativeveryverythickmathspace " ); + break; + case VeryVeryThinMathSpace: + framespacing.append( "veryverythinmathspace " ); + break; + case VeryThinMathSpace: + framespacing.append( "verythinmathspace " ); + break; + case ThinMathSpace: + framespacing.append( "thinmathspace " ); + break; + case MediumMathSpace: + framespacing.append( "mediummathspace " ); + break; + case ThickMathSpace: + framespacing.append( "thickmathspace " ); + break; + case VeryThickMathSpace: + framespacing.append( "verythickmathspace " ); + break; + case VeryVeryThickMathSpace: + framespacing.append( "veryverythickmathspace " ); + break; + default: + break; + } + switch ( m_frameVSpacingType ) { + case AbsoluteSize: + framespacing.append( TQString( "%1pt " ).arg( m_frameVSpacing ) ); + break; + case RelativeSize: + framespacing.append( TQString( "%1% " ).arg( m_frameVSpacing * 100.0 ) ); + break; + case PixelSize: + framespacing.append( TQString( "%1px " ).arg( m_frameVSpacing ) ); + break; + case NegativeVeryVeryThinMathSpace: + framespacing.append( "negativeveryverythinmathspace " ); + break; + case NegativeVeryThinMathSpace: + framespacing.append( "negativeverythinmathspace " ); + break; + case NegativeThinMathSpace: + framespacing.append( "negativethinmathspace " ); + break; + case NegativeMediumMathSpace: + framespacing.append( "negativemediummathspace " ); + break; + case NegativeThickMathSpace: + framespacing.append( "negativethickmathspace " ); + break; + case NegativeVeryThickMathSpace: + framespacing.append( "negativeverythickmathspace " ); + break; + case NegativeVeryVeryThickMathSpace: + framespacing.append( "negativeveryverythickmathspace " ); + break; + case VeryVeryThinMathSpace: + framespacing.append( "veryverythinmathspace " ); + break; + case VeryThinMathSpace: + framespacing.append( "verythinmathspace " ); + break; + case ThinMathSpace: + framespacing.append( "thinmathspace " ); + break; + case MediumMathSpace: + framespacing.append( "mediummathspace " ); + break; + case ThickMathSpace: + framespacing.append( "thickmathspace " ); + break; + case VeryThickMathSpace: + framespacing.append( "verythickmathspace " ); + break; + case VeryVeryThickMathSpace: + framespacing.append( "veryverythickmathspace " ); + break; + default: + break; + } + if ( ! framespacing.isNull() ) { + element.setAttribute( "framespacing", framespacing.stripWhiteSpace() ); + } + if ( m_customEqualRows ) { + element.setAttribute( "equalrows", m_equalRows ? "true" : "false" ); + } + if ( m_customEqualColumns ) { + element.setAttribute( "equalcolumns", m_equalColumns ? "true" : "false" ); + } + if ( m_customDisplayStyle ) { + element.setAttribute( "displaystyle", m_displayStyle ? "true" : "false" ); + } + switch ( m_side ) { + case LeftSide: + element.setAttribute( "side", "left" ); + break; + case RightSide: + element.setAttribute( "side", "right" ); + break; + case LeftOverlapSide: + element.setAttribute( "side", "leftoverlap" ); + break; + case RightOverlapSide: + element.setAttribute( "side", "rightoverlap" ); + break; + default: + break; + } + switch ( m_minLabelSpacingType ) { + case AbsoluteSize: + element.setAttribute( "minlabelspacing", TQString( "%1pt" ).arg( m_minLabelSpacing ) ); + break; + case RelativeSize: + element.setAttribute( "minlabelspacing", TQString( "%1%" ).arg( m_minLabelSpacing * 100.0 ) ); + break; + case PixelSize: + element.setAttribute( "minlabelspacing", TQString( "%1px" ).arg( m_minLabelSpacing ) ); + break; + case NegativeVeryVeryThinMathSpace: + element.setAttribute( "minlabelspacing", "negativeveryverythinmathspace" ); + break; + case NegativeVeryThinMathSpace: + element.setAttribute( "minlabelspacing", "negativeverythinmathspace" ); + break; + case NegativeThinMathSpace: + element.setAttribute( "minlabelspacing", "negativethinmathspace" ); + break; + case NegativeMediumMathSpace: + element.setAttribute( "minlabelspacing", "negativemediummathspace" ); + break; + case NegativeThickMathSpace: + element.setAttribute( "minlabelspacing", "negativethickmathspace" ); + break; + case NegativeVeryThickMathSpace: + element.setAttribute( "minlabelspacing", "negativeverythickmathspace" ); + break; + case NegativeVeryVeryThickMathSpace: + element.setAttribute( "minlabelspacing", "negativeveryverythickmathspace" ); + break; + case VeryVeryThinMathSpace: + element.setAttribute( "minlabelspacing", "veryverythinmathspace" ); + break; + case VeryThinMathSpace: + element.setAttribute( "minlabelspacing", "verythinmathspace" ); + break; + case ThinMathSpace: + element.setAttribute( "minlabelspacing", "thinmathspace" ); + break; + case MediumMathSpace: + element.setAttribute( "minlabelspacing", "mediummathspace" ); + break; + case ThickMathSpace: + element.setAttribute( "minlabelspacing", "thickmathspace" ); + break; + case VeryThickMathSpace: + element.setAttribute( "minlabelspacing", "verythickmathspace" ); + break; + case VeryVeryThickMathSpace: + element.setAttribute( "minlabelspacing", "veryverythickmathspace" ); + break; + default: + break; + } +} + +void MatrixElement::writeMathMLContent( TQDomDocument& doc, + TQDomElement& element, + bool oasisFormat ) const +{ + TQDomElement row; + TQDomElement cell; + + uint rows = getRows(); + uint cols = getColumns(); + + for ( uint r = 0; r < rows; r++ ) + { + row = doc.createElement( oasisFormat ? "math:mtr" : "mtr" ); + element.appendChild( row ); + for ( uint c = 0; c < cols; c++ ) + { + cell = doc.createElement( oasisFormat ? "math:mtd" : "mtd" ); + row.appendChild( cell ); + getElement(r,c)->writeMathML( doc, cell, oasisFormat ); + } + } +} + + +////////////////////////////////////////////////////////////////////////////// + + +/** + * The lines behaviour is (a little) different from that + * of ordinary sequences. + */ +class MultilineSequenceElement : public SequenceElement { + typedef SequenceElement inherited; +public: + + MultilineSequenceElement( BasicElement* parent = 0 ); + + virtual MultilineSequenceElement* clone() { + return new MultilineSequenceElement( *this ); + } + + virtual BasicElement* goToPos( FormulaCursor*, bool& handled, + const LuPixelPoint& point, const LuPixelPoint& parentOrigin ); + + /** + * Calculates our width and height and + * our children's parentPosition. + */ + virtual void calcSizes( const ContextStyle& context, + ContextStyle::TextStyle tstyle, + ContextStyle::IndexStyle istyle, + StyleAttributes& style ); + + virtual void registerTab( BasicElement* tab ); + + /** + * This is called by the container to get a command depending on + * the current cursor position (this is how the element gets chosen) + * and the request. + * + * @returns the command that performs the requested action with + * the containers active cursor. + */ + virtual KCommand* buildCommand( Container*, Request* ); + + virtual KCommand* input( Container* container, TQKeyEvent* event ); + + virtual KCommand* input( Container* container, TQChar ch ); + + uint tabCount() const { return tabs.count(); } + + BasicElement* tab( uint i ) { return tabs.at( i ); } + + /// Change the width of tab i and move all elements after it. + void moveTabTo( uint i, luPixel pos ); + + /// Return the greatest tab number less than pos. + int tabBefore( uint pos ); + + /// Return the position of tab i. + int tabPos( uint i ); + + virtual void writeMathML( TQDomDocument& doc, TQDomNode& parent, bool oasisFormat = false ) const ; + +private: + + TQPtrList tabs; +}; + + +// Split the line at position pos. +class KFCNewLine : public Command { +public: + KFCNewLine( const TQString& name, Container* document, + MultilineSequenceElement* line, uint pos ); + + virtual ~KFCNewLine(); + + virtual void execute(); + virtual void unexecute(); + +private: + MultilineSequenceElement* m_line; + MultilineSequenceElement* m_newline; + uint m_pos; +}; + + +KFCNewLine::KFCNewLine( const TQString& name, Container* document, + MultilineSequenceElement* line, uint pos ) + : Command( name, document ), + m_line( line ), m_pos( pos ) +{ + m_newline = new MultilineSequenceElement( m_line->getParent() ); +} + + +KFCNewLine::~KFCNewLine() +{ + delete m_newline; +} + + +void KFCNewLine::execute() +{ + FormulaCursor* cursor = getExecuteCursor(); + MultilineElement* parent = static_cast( m_line->getParent() ); + int linePos = parent->content.find( m_line ); + parent->content.insert( linePos+1, m_newline ); + + // If there are children to be moved. + if ( m_line->countChildren() > static_cast( m_pos ) ) { + + // Remove anything after position pos from the current line + m_line->selectAllChildren( cursor ); + cursor->setMark( m_pos ); + TQPtrList elementList; + m_line->remove( cursor, elementList, beforeCursor ); + + // Insert the removed stuff into the new line + m_newline->goInside( cursor ); + m_newline->insert( cursor, elementList, beforeCursor ); + cursor->setPos( cursor->getMark() ); + } + else { + m_newline->goInside( cursor ); + } + + // The command no longer owns the new line. + m_newline = 0; + + // Tell that something changed + FormulaElement* formula = m_line->formula(); + formula->changed(); + testDirty(); +} + + +void KFCNewLine::unexecute() +{ + FormulaCursor* cursor = getExecuteCursor(); + MultilineElement* parent = static_cast( m_line->getParent() ); + int linePos = parent->content.find( m_line ); + + // Now the command owns the new line again. + m_newline = parent->content.at( linePos+1 ); + + // Tell all cursors to leave this sequence + FormulaElement* formula = m_line->formula(); + formula->elementRemoval( m_newline ); + + // If there are children to be moved. + if ( m_newline->countChildren() > 0 ) { + + // Remove anything from the line to be deleted + m_newline->selectAllChildren( cursor ); + TQPtrList elementList; + m_newline->remove( cursor, elementList, beforeCursor ); + + // Insert the removed stuff into the previous line + m_line->moveEnd( cursor ); + m_line->insert( cursor, elementList, beforeCursor ); + cursor->setPos( cursor->getMark() ); + } + else { + m_line->moveEnd( cursor ); + } + parent->content.take( linePos+1 ); + + // Tell that something changed + formula->changed(); + testDirty(); +} + + +MultilineSequenceElement::MultilineSequenceElement( BasicElement* parent ) + : SequenceElement( parent ) +{ + tabs.setAutoDelete( false ); +} + + +BasicElement* MultilineSequenceElement::goToPos( FormulaCursor* cursor, bool& handled, + const LuPixelPoint& point, const LuPixelPoint& parentOrigin ) +{ + //LuPixelPoint myPos(parentOrigin.x() + getX(), + // parentOrigin.y() + getY()); + BasicElement* e = inherited::goToPos(cursor, handled, point, parentOrigin); + + if (e == 0) { + // If the mouse was behind this line put the cursor to the last position. + if ( ( point.x() > getX()+getWidth() ) && + ( point.y() >= getY() ) && + ( point.y() < getY()+getHeight() ) ) { + cursor->setTo(this, countChildren()); + handled = true; + return this; + } + } + return e; +} + + +void MultilineSequenceElement::calcSizes( const ContextStyle& context, + ContextStyle::TextStyle tstyle, + ContextStyle::IndexStyle istyle, + StyleAttributes& style ) +{ + tabs.clear(); + inherited::calcSizes( context, tstyle, istyle, style ); +} + + +void MultilineSequenceElement::registerTab( BasicElement* tab ) +{ + tabs.append( tab ); +} + + +KCommand* MultilineSequenceElement::buildCommand( Container* container, Request* request ) +{ + FormulaCursor* cursor = container->activeCursor(); + if ( cursor->isReadOnly() ) { + return 0; + } + + switch ( *request ) { + case req_remove: { + // Remove this line if its empty. + // Remove the formula if this line was the only one. + break; + } + case req_addNewline: { + FormulaCursor* cursor = container->activeCursor(); + return new KFCNewLine( i18n( "Add Newline" ), container, this, cursor->getPos() ); + } + case req_addTabMark: { + KFCReplace* command = new KFCReplace( i18n("Add Tabmark"), container ); + SpaceElement* element = new SpaceElement( THIN, true ); + command->addElement( element ); + return command; + } + default: + break; + } + return inherited::buildCommand( container, request ); +} + + +KCommand* MultilineSequenceElement::input( Container* container, TQKeyEvent* event ) +{ + int action = event->key(); + //int state = event->state(); + //MoveFlag flag = movementFlag(state); + + switch ( action ) { + case TQt::Key_Enter: + case TQt::Key_Return: { + Request newline( req_addNewline ); + return buildCommand( container, &newline ); + } + case TQt::Key_Tab: { + Request r( req_addTabMark ); + return buildCommand( container, &r ); + } + } + return inherited::input( container, event ); +} + + +KCommand* MultilineSequenceElement::input( Container* container, TQChar ch ) +{ + int latin1 = ch.latin1(); + switch (latin1) { + case '&': { + Request r( req_addTabMark ); + return buildCommand( container, &r ); + } + } + return inherited::input( container, ch ); +} + + +void MultilineSequenceElement::moveTabTo( uint i, luPixel pos ) +{ + BasicElement* marker = tab( i ); + luPixel diff = pos - marker->getX(); + marker->setWidth( marker->getWidth() + diff ); + + for ( int p = childPos( marker )+1; p < countChildren(); ++p ) { + BasicElement* child = getChild( p ); + child->setX( child->getX() + diff ); + } + + setWidth( getWidth()+diff ); +} + + +int MultilineSequenceElement::tabBefore( uint pos ) +{ + if ( tabs.isEmpty() ) { + return -1; + } + uint tabNum = 0; + for ( uint i=0; i( tabNum )-1; +} + + +int MultilineSequenceElement::tabPos( uint i ) +{ + if ( i < tabs.count() ) { + return childPos( tabs.at( i ) ); + } + return -1; +} + + +void MultilineSequenceElement::writeMathML( TQDomDocument& doc, + TQDomNode& parent, bool oasisFormat ) const +{ + // parent is required to be a tag + + TQDomElement tmp = doc.createElement( "TMP" ); + + inherited::writeMathML( doc, tmp, oasisFormat ); + + /* Now we re-parse the Dom tree, because of the TabMarkers + * that have no direct representation in MathML but mark the + * end of a tag. + */ + + TQDomElement mtd = doc.createElement( oasisFormat ? "math:mtd" : "mtd" ); + + // The mrow, if it exists. + TQDomNode n = tmp.firstChild().firstChild(); + while ( !n.isNull() ) { + // the illegal TabMarkers are children of the mrow, child of tmp. + if ( n.isElement() && n.toElement().tagName() == "TAB" ) { + parent.appendChild( mtd ); + mtd = doc.createElement( oasisFormat ? "math:mtd" : "mtd" ); + } + else { + mtd.appendChild( n.cloneNode() ); // cloneNode needed? + } + n = n.nextSibling(); + } + + parent.appendChild( mtd ); +} + + +MultilineElement::MultilineElement( BasicElement* parent ) + : BasicElement( parent ) +{ + content.setAutoDelete( true ); + content.append( new MultilineSequenceElement( this ) ); +} + +MultilineElement::~MultilineElement() +{ +} + +MultilineElement::MultilineElement( const MultilineElement& other ) + : BasicElement( other ) +{ + content.setAutoDelete( true ); + uint count = other.content.count(); + for (uint i = 0; i < count; i++) { + MultilineSequenceElement* line = content.at(i)->clone(); + line->setParent( this ); + content.append( line ); + } +} + + +bool MultilineElement::accept( ElementVisitor* visitor ) +{ + return visitor->visit( this ); +} + + +void MultilineElement::entered( SequenceElement* /*child*/ ) +{ + formula()->tell( i18n( "Multi line element" ) ); +} + + +/** + * Returns the element the point is in. + */ +BasicElement* MultilineElement::goToPos( FormulaCursor* cursor, bool& handled, + const LuPixelPoint& point, const LuPixelPoint& parentOrigin ) +{ + BasicElement* e = inherited::goToPos(cursor, handled, point, parentOrigin); + if ( e != 0 ) { + LuPixelPoint myPos(parentOrigin.x() + getX(), + parentOrigin.y() + getY()); + + uint count = content.count(); + for ( uint i = 0; i < count; ++i ) { + MultilineSequenceElement* line = content.at(i); + e = line->goToPos(cursor, handled, point, myPos); + if (e != 0) { + return e; + } + } + return this; + } + return 0; +} + +void MultilineElement::goInside( FormulaCursor* cursor ) +{ + content.at( 0 )->goInside( cursor ); +} + +void MultilineElement::moveLeft( FormulaCursor* cursor, BasicElement* from ) +{ + // If you want to select more than one line you'll have to + // select the whole element. + if (cursor->isSelectionMode()) { + getParent()->moveLeft(cursor, this); + } + else { + // Coming from the parent (sequence) we go to + // the very last position + if (from == getParent()) { + content.at( content.count()-1 )->moveLeft(cursor, this); + } + else { + // Coming from one of the lines we go to the previous line + // or to the parent if there is none. + int pos = content.find( static_cast( from ) ); + if ( pos > -1 ) { + if ( pos > 0 ) { + content.at( pos-1 )->moveLeft( cursor, this ); + } + else { + getParent()->moveLeft(cursor, this); + } + } + else { + kdDebug( DEBUGID ) << k_funcinfo << endl; + kdDebug( DEBUGID ) << "Serious confusion. Must never happen." << endl; + } + } + } +} + +void MultilineElement::moveRight( FormulaCursor* cursor, BasicElement* from ) +{ + if (cursor->isSelectionMode()) { + getParent()->moveRight(cursor, this); + } + else { + if (from == getParent()) { + content.at( 0 )->moveRight(cursor, this); + } + else { + int pos = content.find( static_cast( from ) ); + if ( pos > -1 ) { + uint upos = pos; + if ( upos < content.count() ) { + if ( upos < content.count()-1 ) { + content.at( upos+1 )->moveRight( cursor, this ); + } + else { + getParent()->moveRight(cursor, this); + } + return; + } + } + kdDebug( DEBUGID ) << k_funcinfo << endl; + kdDebug( DEBUGID ) << "Serious confusion. Must never happen." << endl; + } + } +} + +void MultilineElement::moveUp( FormulaCursor* cursor, BasicElement* from ) +{ + // If you want to select more than one line you'll have to + // select the whole element. + if (cursor->isSelectionMode()) { + getParent()->moveLeft(cursor, this); + } + else { + // Coming from the parent (sequence) we go to + // the very last position + if (from == getParent()) { + content.at( content.count()-1 )->moveLeft(cursor, this); + } + else { + // Coming from one of the lines we go to the previous line + // or to the parent if there is none. + int pos = content.find( static_cast( from ) ); + if ( pos > -1 ) { + if ( pos > 0 ) { + //content.at( pos-1 )->moveLeft( cursor, this ); + // This is rather hackish. + // But we know what elements we have here. + int cursorPos = cursor->getPos(); + MultilineSequenceElement* current = content.at( pos ); + MultilineSequenceElement* newLine = content.at( pos-1 ); + int tabNum = current->tabBefore( cursorPos ); + if ( tabNum > -1 ) { + int oldTabPos = current->tabPos( tabNum ); + int newTabPos = newLine->tabPos( tabNum ); + if ( newTabPos > -1 ) { + cursorPos += newTabPos-oldTabPos; + int nextNewTabPos = newLine->tabPos( tabNum+1 ); + if ( nextNewTabPos > -1 ) { + cursorPos = TQMIN( cursorPos, nextNewTabPos ); + } + } + else { + cursorPos = newLine->countChildren(); + } + } + else { + int nextNewTabPos = newLine->tabPos( 0 ); + if ( nextNewTabPos > -1 ) { + cursorPos = TQMIN( cursorPos, nextNewTabPos ); + } + } + cursor->setTo( newLine, + TQMIN( cursorPos, + newLine->countChildren() ) ); + } + else { + getParent()->moveLeft(cursor, this); + } + } + else { + kdDebug( DEBUGID ) << k_funcinfo << endl; + kdDebug( DEBUGID ) << "Serious confusion. Must never happen." << endl; + } + } + } +} + +void MultilineElement::moveDown( FormulaCursor* cursor, BasicElement* from ) +{ + if (cursor->isSelectionMode()) { + getParent()->moveRight(cursor, this); + } + else { + if (from == getParent()) { + content.at( 0 )->moveRight(cursor, this); + } + else { + int pos = content.find( static_cast( from ) ); + if ( pos > -1 ) { + uint upos = pos; + if ( upos < content.count() ) { + if ( upos < content.count()-1 ) { + //content.at( upos+1 )->moveRight( cursor, this ); + // This is rather hackish. + // But we know what elements we have here. + int cursorPos = cursor->getPos(); + MultilineSequenceElement* current = content.at( upos ); + MultilineSequenceElement* newLine = content.at( upos+1 ); + int tabNum = current->tabBefore( cursorPos ); + if ( tabNum > -1 ) { + int oldTabPos = current->tabPos( tabNum ); + int newTabPos = newLine->tabPos( tabNum ); + if ( newTabPos > -1 ) { + cursorPos += newTabPos-oldTabPos; + int nextNewTabPos = newLine->tabPos( tabNum+1 ); + if ( nextNewTabPos > -1 ) { + cursorPos = TQMIN( cursorPos, nextNewTabPos ); + } + } + else { + cursorPos = newLine->countChildren(); + } + } + else { + int nextNewTabPos = newLine->tabPos( 0 ); + if ( nextNewTabPos > -1 ) { + cursorPos = TQMIN( cursorPos, nextNewTabPos ); + } + } + cursor->setTo( newLine, + TQMIN( cursorPos, + newLine->countChildren() ) ); + } + else { + getParent()->moveRight(cursor, this); + } + return; + } + } + kdDebug( DEBUGID ) << k_funcinfo << endl; + kdDebug( DEBUGID ) << "Serious confusion. Must never happen." << endl; + } + } +} + + +void MultilineElement::calcSizes( const ContextStyle& context, + ContextStyle::TextStyle tstyle, + ContextStyle::IndexStyle istyle, + StyleAttributes& style ) +{ + double factor = style.sizeFactor(); + luPt mySize = context.getAdjustedSize( tstyle, factor ); + TQFont font = context.getDefaultFont(); + font.setPointSizeFloat( context.layoutUnitPtToPt( mySize ) ); + TQFontMetrics fm( font ); + luPixel leading = context.ptToLayoutUnitPt( fm.leading() ); + luPixel distY = context.ptToPixelY( context.getThinSpace( tstyle, factor ) ); + + uint count = content.count(); + luPixel height = -leading; + luPixel width = 0; + uint tabCount = 0; + for ( uint i = 0; i < count; ++i ) { + MultilineSequenceElement* line = content.at(i); + line->calcSizes( context, tstyle, istyle, style ); + tabCount = TQMAX( tabCount, line->tabCount() ); + + height += leading; + line->setX( 0 ); + line->setY( height ); + height += line->getHeight() + distY; + width = TQMAX( line->getWidth(), width ); + } + + // calculate the tab positions + for ( uint t = 0; t < tabCount; ++t ) { + luPixel pos = 0; + for ( uint i = 0; i < count; ++i ) { + MultilineSequenceElement* line = content.at(i); + if ( t < line->tabCount() ) { + pos = TQMAX( pos, line->tab( t )->getX() ); + } + else { + pos = TQMAX( pos, line->getWidth() ); + } + } + for ( uint i = 0; i < count; ++i ) { + MultilineSequenceElement* line = content.at(i); + if ( t < line->tabCount() ) { + line->moveTabTo( t, pos ); + width = TQMAX( width, line->getWidth() ); + } + } + } + + setHeight( height ); + setWidth( width ); + if ( count == 1 ) { + setBaseline( content.at( 0 )->getBaseline() ); + } + else { + // There's always a first line. No formulas without lines. + setBaseline( height/2 + context.axisHeight( tstyle, factor ) ); + } +} + +void MultilineElement::draw( TQPainter& painter, const LuPixelRect& r, + const ContextStyle& context, + ContextStyle::TextStyle tstyle, + ContextStyle::IndexStyle istyle, + StyleAttributes& style, + const LuPixelPoint& parentOrigin ) +{ + LuPixelPoint myPos( parentOrigin.x() + getX(), parentOrigin.y() + getY() ); + uint count = content.count(); + + if ( context.edit() ) { + uint tabCount = 0; + painter.setPen( context.getHelpColor() ); + for ( uint i = 0; i < count; ++i ) { + MultilineSequenceElement* line = content.at(i); + if ( tabCount < line->tabCount() ) { + for ( uint t = tabCount; t < line->tabCount(); ++t ) { + BasicElement* marker = line->tab( t ); + painter.drawLine( context.layoutUnitToPixelX( myPos.x()+marker->getX() ), + context.layoutUnitToPixelY( myPos.y() ), + context.layoutUnitToPixelX( myPos.x()+marker->getX() ), + context.layoutUnitToPixelY( myPos.y()+getHeight() ) ); + } + tabCount = line->tabCount(); + } + } + } + + for ( uint i = 0; i < count; ++i ) { + MultilineSequenceElement* line = content.at(i); + line->draw( painter, r, context, tstyle, istyle, style, myPos ); + } +} + + +void MultilineElement::dispatchFontCommand( FontCommand* cmd ) +{ + uint count = content.count(); + for ( uint i = 0; i < count; ++i ) { + MultilineSequenceElement* line = content.at(i); + line->dispatchFontCommand( cmd ); + } +} + +void MultilineElement::insert( FormulaCursor* cursor, + TQPtrList& newChildren, + Direction direction ) +{ + MultilineSequenceElement* e = static_cast(newChildren.take(0)); + e->setParent(this); + content.insert( cursor->getPos(), e ); + + if (direction == beforeCursor) { + e->moveLeft(cursor, this); + } + else { + e->moveRight(cursor, this); + } + cursor->setSelection(false); + formula()->changed(); +} + +void MultilineElement::remove( FormulaCursor* cursor, + TQPtrList& removedChildren, + Direction direction ) +{ + if ( content.count() == 1 ) { //&& ( cursor->getPos() == 0 ) ) { + getParent()->selectChild(cursor, this); + getParent()->remove(cursor, removedChildren, direction); + } + else { + MultilineSequenceElement* e = content.take( cursor->getPos() ); + removedChildren.append( e ); + formula()->elementRemoval( e ); + //cursor->setTo( this, denominatorPos ); + formula()->changed(); + } +} + +void MultilineElement::normalize( FormulaCursor* cursor, Direction direction ) +{ + int pos = cursor->getPos(); + if ( ( cursor->getElement() == this ) && + ( pos > -1 ) && ( static_cast( pos ) <= content.count() ) ) { + switch ( direction ) { + case beforeCursor: + if ( pos > 0 ) { + content.at( pos-1 )->moveLeft( cursor, this ); + break; + } + // no break! intended! + case afterCursor: + if ( static_cast( pos ) < content.count() ) { + content.at( pos )->moveRight( cursor, this ); + } + else { + content.at( pos-1 )->moveLeft( cursor, this ); + } + break; + } + } + else { + inherited::normalize( cursor, direction ); + } +} + +SequenceElement* MultilineElement::getMainChild() +{ + return content.at( 0 ); +} + +void MultilineElement::selectChild(FormulaCursor* cursor, BasicElement* child) +{ + int pos = content.find( dynamic_cast( child ) ); + if ( pos > -1 ) { + cursor->setTo( this, pos ); + //content.at( pos )->moveRight( cursor, this ); + } +} + + +/** + * Appends our attributes to the dom element. + */ +void MultilineElement::writeDom(TQDomElement element) +{ + BasicElement::writeDom(element); + + uint lineCount = content.count(); + element.setAttribute( "LINES", lineCount ); + + TQDomDocument doc = element.ownerDocument(); + for ( uint i = 0; i < lineCount; ++i ) { + TQDomElement tmp = content.at( i )->getElementDom(doc); + element.appendChild(tmp); + } +} + +void MultilineElement::writeMathML( TQDomDocument& doc, TQDomNode& parent, bool oasisFormat ) const +{ + TQDomElement de = doc.createElement( oasisFormat ? "math:mtable" : "mtable" ); + TQDomElement row; TQDomElement cell; + + for ( TQPtrListIterator < MultilineSequenceElement > it( content ); it.current(); ++it ) { + row = doc.createElement( oasisFormat ? "math:mtr" : "mtr" ); + de.appendChild( row ); + //cell = doc.createElement( "mtd" ); + //row.appendChild( cell ); + + //content.at( i )->writeMathML( doc, cell ); + it.current()->writeMathML( doc, row, oasisFormat ); + } + + parent.appendChild( de ); +} + +/** + * Reads our attributes from the element. + * Returns false if it failed. + */ +bool MultilineElement::readAttributesFromDom(TQDomElement element) +{ + if (!BasicElement::readAttributesFromDom(element)) { + return false; + } + uint lineCount = 0; + TQString lineCountStr = element.attribute("LINES"); + if(!lineCountStr.isNull()) { + lineCount = lineCountStr.toInt(); + } + if (lineCount == 0) { + kdWarning( DEBUGID ) << "lineCount <= 0 in MultilineElement." << endl; + return false; + } + + content.clear(); + for ( uint i = 0; i < lineCount; ++i ) { + MultilineSequenceElement* element = new MultilineSequenceElement(this); + content.append(element); + } + return true; +} + +/** + * Reads our content from the node. Sets the node to the next node + * that needs to be read. + * Returns false if it failed. + */ +bool MultilineElement::readContentFromDom(TQDomNode& node) +{ + if (!BasicElement::readContentFromDom(node)) { + return false; + } + + uint lineCount = content.count(); + uint i = 0; + while ( !node.isNull() && i < lineCount ) { + if ( node.isElement() ) { + SequenceElement* element = content.at( i ); + TQDomElement e = node.toElement(); + if ( !element->buildFromDom( e ) ) { + return false; + } + ++i; + } + node = node.nextSibling(); + } + return true; +} + +TQString MultilineElement::toLatex() +{ + uint lineCount = content.count(); + TQString muliline = "\\begin{split} "; + for ( uint i = 0; i < lineCount; ++i ) { + muliline += content.at( i )->toLatex(); + muliline += " \\\\ "; + } + muliline += "\\end{split}"; + return muliline; +} + +// Does this make any sense at all? +TQString MultilineElement::formulaString() +{ + uint lineCount = content.count(); + TQString muliline = ""; + for ( uint i = 0; i < lineCount; ++i ) { + muliline += content.at( i )->formulaString(); + muliline += "\n"; + } + //muliline += ""; + return muliline; +} + + +KFORMULA_NAMESPACE_END diff --git a/lib/kformula/numberelement.cc b/lib/kformula/numberelement.cc deleted file mode 100644 index 7705e3ab..00000000 --- a/lib/kformula/numberelement.cc +++ /dev/null @@ -1,153 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2006 Alfredo Beaumont Sainz - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - -#include - -#include "numberelement.h" -#include "kformuladefs.h" -#include "textelement.h" -#include "identifierelement.h" -#include "operatorelement.h" -#include "kformulacommand.h" -#include "kformulacontainer.h" -#include "formulaelement.h" -#include "creationstrategy.h" - -KFORMULA_NAMESPACE_BEGIN - -NumberElement::NumberElement( BasicElement* parent ) : TokenElement( parent ) {} - -/* - * Token elements' content has to be of homogeneous type. Every token element - * must (TODO: check this) appear inside a non-token sequence, and thus, if - * the command asks for a different content, a new element has to be created in - * parent sequence. - */ -KCommand* NumberElement::buildCommand( Container* container, Request* request ) -{ - FormulaCursor* cursor = container->activeCursor(); - if ( cursor->isReadOnly() ) { - formula()->tell( i18n( "write protection" ) ); - return 0; - } - - if ( *request == req_addNumber ) { - KFCReplace* command = new KFCReplace( i18n("Add Number"), container ); - NumberRequest* nr = static_cast( request ); - TextElement* element = creationStrategy->createTextElement( nr->ch(), false ); - command->addElement( element ); - return command; - } - - if ( countChildren() == 0 || cursor->getPos() == countChildren() ) { - // We are in the last position, so it's easy, call the parent to - // create a new child - SequenceElement* parent = static_cast( getParent() ); - if ( parent ) { - uint pos = parent->childPos( this ); - cursor->setTo( parent, pos + 1); - return parent->buildCommand( container, request ); - } - } - if ( cursor->getPos() == 0 ) { - SequenceElement* parent = static_cast( getParent() ); - if ( parent ) { - uint pos = parent->childPos( this ); - cursor->setTo( parent, pos ); - return parent->buildCommand( container, request ); - } - } - - // We are in the middle of a token, so: - // a) Cut from mark to the end - // b) Create a new token and add an element from key pressed - // c) Create a new token and add elements cut previously - // d) Move cursor to parent so that it command execution works fine - - switch( *request ) { - case req_addTextChar: { - KFCSplitToken* command = new KFCSplitToken( i18n("Add Text"), container ); - TextCharRequest* tr = static_cast( request ); - IdentifierElement* id = creationStrategy->createIdentifierElement(); - TextElement* text = creationStrategy->createTextElement( tr->ch() ); - command->addCursor( cursor ); - command->addToken( id ); - command->addContent( id, text ); - SequenceElement* parent = static_cast< SequenceElement* >( getParent() ); - if ( parent ) { - cursor->setTo( parent, parent->childPos( this ) + 1 ); - } - return command; - } - - case req_addText: { - KFCSplitToken* command = new KFCSplitToken( i18n("Add Text"), container ); - TextRequest* tr = static_cast( request ); - IdentifierElement* id = creationStrategy->createIdentifierElement(); - command->addCursor( cursor ); - command->addToken( id ); - for ( uint i = 0; i < tr->text().length(); i++ ) { - TextElement* text = creationStrategy->createTextElement( tr->text()[i] ); - command->addContent( id, text ); - } - SequenceElement* parent = static_cast< SequenceElement* >( getParent() ); - if ( parent ) { - cursor->setTo( parent, parent->childPos( this ) + 1 ); - } - return command; - } - - case req_addOperator: { - KFCSplitToken* command = new KFCSplitToken( i18n("Add Operator"), container ); - OperatorRequest* opr = static_cast( request ); - OperatorElement* op = creationStrategy->createOperatorElement(); - TextElement* text = creationStrategy->createTextElement( opr->ch() ); - command->addCursor( cursor ); - command->addToken( op ); - command->addContent( op, text ); - SequenceElement* parent = static_cast< SequenceElement* >( getParent() ); - if ( parent ) { - cursor->setTo( parent, parent->childPos( this ) + 1 ); - } - return command; - } - case req_addEmptyBox: - case req_addNameSequence: - case req_addBracket: - case req_addSpace: - case req_addFraction: - case req_addRoot: - case req_addSymbol: - case req_addOneByTwoMatrix: - case req_addMatrix: { - SequenceElement* parent = static_cast( getParent() ); - if ( parent ) { - uint pos = parent->childPos( this ); - cursor->setTo( parent, pos + 1); - return parent->buildCommand( container, request ); - } - } - default: - return SequenceElement::buildCommand( container, request ); - } - return 0; -} - - -KFORMULA_NAMESPACE_END diff --git a/lib/kformula/numberelement.cpp b/lib/kformula/numberelement.cpp new file mode 100644 index 00000000..7705e3ab --- /dev/null +++ b/lib/kformula/numberelement.cpp @@ -0,0 +1,153 @@ +/* This file is part of the KDE project + Copyright (C) 2006 Alfredo Beaumont Sainz + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include + +#include "numberelement.h" +#include "kformuladefs.h" +#include "textelement.h" +#include "identifierelement.h" +#include "operatorelement.h" +#include "kformulacommand.h" +#include "kformulacontainer.h" +#include "formulaelement.h" +#include "creationstrategy.h" + +KFORMULA_NAMESPACE_BEGIN + +NumberElement::NumberElement( BasicElement* parent ) : TokenElement( parent ) {} + +/* + * Token elements' content has to be of homogeneous type. Every token element + * must (TODO: check this) appear inside a non-token sequence, and thus, if + * the command asks for a different content, a new element has to be created in + * parent sequence. + */ +KCommand* NumberElement::buildCommand( Container* container, Request* request ) +{ + FormulaCursor* cursor = container->activeCursor(); + if ( cursor->isReadOnly() ) { + formula()->tell( i18n( "write protection" ) ); + return 0; + } + + if ( *request == req_addNumber ) { + KFCReplace* command = new KFCReplace( i18n("Add Number"), container ); + NumberRequest* nr = static_cast( request ); + TextElement* element = creationStrategy->createTextElement( nr->ch(), false ); + command->addElement( element ); + return command; + } + + if ( countChildren() == 0 || cursor->getPos() == countChildren() ) { + // We are in the last position, so it's easy, call the parent to + // create a new child + SequenceElement* parent = static_cast( getParent() ); + if ( parent ) { + uint pos = parent->childPos( this ); + cursor->setTo( parent, pos + 1); + return parent->buildCommand( container, request ); + } + } + if ( cursor->getPos() == 0 ) { + SequenceElement* parent = static_cast( getParent() ); + if ( parent ) { + uint pos = parent->childPos( this ); + cursor->setTo( parent, pos ); + return parent->buildCommand( container, request ); + } + } + + // We are in the middle of a token, so: + // a) Cut from mark to the end + // b) Create a new token and add an element from key pressed + // c) Create a new token and add elements cut previously + // d) Move cursor to parent so that it command execution works fine + + switch( *request ) { + case req_addTextChar: { + KFCSplitToken* command = new KFCSplitToken( i18n("Add Text"), container ); + TextCharRequest* tr = static_cast( request ); + IdentifierElement* id = creationStrategy->createIdentifierElement(); + TextElement* text = creationStrategy->createTextElement( tr->ch() ); + command->addCursor( cursor ); + command->addToken( id ); + command->addContent( id, text ); + SequenceElement* parent = static_cast< SequenceElement* >( getParent() ); + if ( parent ) { + cursor->setTo( parent, parent->childPos( this ) + 1 ); + } + return command; + } + + case req_addText: { + KFCSplitToken* command = new KFCSplitToken( i18n("Add Text"), container ); + TextRequest* tr = static_cast( request ); + IdentifierElement* id = creationStrategy->createIdentifierElement(); + command->addCursor( cursor ); + command->addToken( id ); + for ( uint i = 0; i < tr->text().length(); i++ ) { + TextElement* text = creationStrategy->createTextElement( tr->text()[i] ); + command->addContent( id, text ); + } + SequenceElement* parent = static_cast< SequenceElement* >( getParent() ); + if ( parent ) { + cursor->setTo( parent, parent->childPos( this ) + 1 ); + } + return command; + } + + case req_addOperator: { + KFCSplitToken* command = new KFCSplitToken( i18n("Add Operator"), container ); + OperatorRequest* opr = static_cast( request ); + OperatorElement* op = creationStrategy->createOperatorElement(); + TextElement* text = creationStrategy->createTextElement( opr->ch() ); + command->addCursor( cursor ); + command->addToken( op ); + command->addContent( op, text ); + SequenceElement* parent = static_cast< SequenceElement* >( getParent() ); + if ( parent ) { + cursor->setTo( parent, parent->childPos( this ) + 1 ); + } + return command; + } + case req_addEmptyBox: + case req_addNameSequence: + case req_addBracket: + case req_addSpace: + case req_addFraction: + case req_addRoot: + case req_addSymbol: + case req_addOneByTwoMatrix: + case req_addMatrix: { + SequenceElement* parent = static_cast( getParent() ); + if ( parent ) { + uint pos = parent->childPos( this ); + cursor->setTo( parent, pos + 1); + return parent->buildCommand( container, request ); + } + } + default: + return SequenceElement::buildCommand( container, request ); + } + return 0; +} + + +KFORMULA_NAMESPACE_END diff --git a/lib/kformula/oasiscreationstrategy.cc b/lib/kformula/oasiscreationstrategy.cc deleted file mode 100644 index 7d7a65cc..00000000 --- a/lib/kformula/oasiscreationstrategy.cc +++ /dev/null @@ -1,210 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2006 Alfredo Beaumont Sainz - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - -#include - -#include "bracketelement.h" -#include "elementtype.h" -#include "fractionelement.h" -#include "indexelement.h" -#include "matrixelement.h" -#include "rootelement.h" -#include "sequenceelement.h" -#include "spaceelement.h" -#include "symbolelement.h" -#include "textelement.h" -#include "glyphelement.h" -#include "styleelement.h" -#include "numberelement.h" -#include "identifierelement.h" -#include "operatorelement.h" -#include "stringelement.h" -#include "paddedelement.h" -#include "errorelement.h" -#include "phantomelement.h" -#include "actionelement.h" -#include "encloseelement.h" - -#include "oasiscreationstrategy.h" - -KFORMULA_NAMESPACE_BEGIN - -BasicElement* OasisCreationStrategy::createElement( TQString type, const TQDomElement& element ) -{ - - // TODO - // mlabeledtr - // maligngroup - // malignmark - // Content elements - // mtr and mtd are currently managed inside MatrixElement - kdDebug( DEBUGID ) << type << endl; - - // Token Elements ( Section 3.1.6.1 ) - if ( type == "mi" ) return new IdentifierElement(); - else if ( type == "mo" ) return createOperatorElement( element ); - else if ( type == "mn" ) return new NumberElement(); - else if ( type == "mtext" ) return new TokenElement(); - else if ( type == "ms" ) return new StringElement(); - else if ( type == "mspace" ) return new SpaceElement(); - else if ( type == "mglyph" ) return new GlyphElement(); - - // General Layout Schemata ( Section 3.1.6.2 ) - else if ( type == "mrow" ) return new SequenceElement(); - else if ( type == "mfrac" ) return new FractionElement(); - else if ( type == "msqrt" - || type == "mroot" ) return new RootElement(); - else if ( type == "mstyle" ) return new StyleElement(); - else if ( type == "merror" ) return new ErrorElement(); - else if ( type == "mpadded" ) return new PaddedElement(); - else if ( type == "mphantom" ) return new PhantomElement(); - else if ( type == "mfenced" ) return new BracketElement(); - else if ( type == "menclose" ) return new EncloseElement(); - - // Script and Limit Schemata ( Section 3.1.6.3 ) - else if ( type == "msub" - || type == "msup" - || type == "msubsup" - || type == "munder" - || type == "mover" - || type == "munderover" - || type == "mmultiscripts" ) return new IndexElement(); - - // Tables and Matrices ( Section 3.1.6.4 ) - else if ( type == "mtable" ) return new MatrixElement(); - - // Enlivening Expressions ( Section 3.1.6.5 ) - else if ( type == "maction" ) return new ActionElement(); - return 0; -} - - -TextElement* OasisCreationStrategy::createTextElement( const TQChar& ch, bool symbol ) -{ - return new TextElement( ch, symbol ); -} - -EmptyElement* OasisCreationStrategy::createEmptyElement() -{ - return new EmptyElement; -} - -NameSequence* OasisCreationStrategy::createNameSequence() -{ - return new NameSequence; -} - -BracketElement* OasisCreationStrategy::createBracketElement( SymbolType lhs, SymbolType rhs ) -{ - return new BracketElement( lhs, rhs ); -} - -OverlineElement* OasisCreationStrategy::createOverlineElement() -{ - return new OverlineElement; -} - -UnderlineElement* OasisCreationStrategy::createUnderlineElement() -{ - return new UnderlineElement; -} - -MultilineElement* OasisCreationStrategy::createMultilineElement() -{ - return new MultilineElement; -} - -SpaceElement* OasisCreationStrategy::createSpaceElement( SpaceWidth width ) -{ - return new SpaceElement( width ); -} - -FractionElement* OasisCreationStrategy::createFractionElement() -{ - return new FractionElement; -} - -RootElement* OasisCreationStrategy::createRootElement() -{ - return new RootElement; -} - -SymbolElement* OasisCreationStrategy::createSymbolElement( SymbolType type ) -{ - return new SymbolElement( type ); -} - -MatrixElement* OasisCreationStrategy::createMatrixElement( uint rows, uint columns ) -{ - return new MatrixElement( rows, columns ); -} - -IndexElement* OasisCreationStrategy::createIndexElement() -{ - return new IndexElement; -} - -BasicElement* OasisCreationStrategy::createOperatorElement( const TQDomElement& element ) -{ - TQDomNode n = element.firstChild(); - if ( n.isNull() ) - return 0; - if ( n.isEntityReference() ) { - TQString name = n.nodeName(); - if ( name == "CloseCurlyDoubleQuote" - || name == "CloseCurlyQuote" - || name == "LeftAngleBracket" - || name == "LeftCeiling" - || name == "LeftDoubleBracket" - || name == "LeftFloor" - || name == "OpenCurlyDoubleQuote" - || name == "OpenCurlyQuote" - || name == "RightAngleBracket" - || name == "RightCeiling" - || name == "RightDoubleBracket" - || name == "RightFloor" ) { - return new BracketElement(); - } - return new OperatorElement(); - } - if ( n.isText() ) { - TQString text = n.toText().data(); - if ( text.length() == 1 && TQString("()[]{}").contains(text[0]) ) { - return new BracketElement(); - } - } - return new OperatorElement(); -} - -IdentifierElement* OasisCreationStrategy::createIdentifierElement() -{ - return new IdentifierElement(); -} - -OperatorElement* OasisCreationStrategy::createOperatorElement() -{ - return new OperatorElement(); -} - -NumberElement* OasisCreationStrategy::createNumberElement() -{ - return new NumberElement(); -} - -KFORMULA_NAMESPACE_END diff --git a/lib/kformula/oasiscreationstrategy.cpp b/lib/kformula/oasiscreationstrategy.cpp new file mode 100644 index 00000000..7d7a65cc --- /dev/null +++ b/lib/kformula/oasiscreationstrategy.cpp @@ -0,0 +1,210 @@ +/* This file is part of the KDE project + Copyright (C) 2006 Alfredo Beaumont Sainz + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include + +#include "bracketelement.h" +#include "elementtype.h" +#include "fractionelement.h" +#include "indexelement.h" +#include "matrixelement.h" +#include "rootelement.h" +#include "sequenceelement.h" +#include "spaceelement.h" +#include "symbolelement.h" +#include "textelement.h" +#include "glyphelement.h" +#include "styleelement.h" +#include "numberelement.h" +#include "identifierelement.h" +#include "operatorelement.h" +#include "stringelement.h" +#include "paddedelement.h" +#include "errorelement.h" +#include "phantomelement.h" +#include "actionelement.h" +#include "encloseelement.h" + +#include "oasiscreationstrategy.h" + +KFORMULA_NAMESPACE_BEGIN + +BasicElement* OasisCreationStrategy::createElement( TQString type, const TQDomElement& element ) +{ + + // TODO + // mlabeledtr + // maligngroup + // malignmark + // Content elements + // mtr and mtd are currently managed inside MatrixElement + kdDebug( DEBUGID ) << type << endl; + + // Token Elements ( Section 3.1.6.1 ) + if ( type == "mi" ) return new IdentifierElement(); + else if ( type == "mo" ) return createOperatorElement( element ); + else if ( type == "mn" ) return new NumberElement(); + else if ( type == "mtext" ) return new TokenElement(); + else if ( type == "ms" ) return new StringElement(); + else if ( type == "mspace" ) return new SpaceElement(); + else if ( type == "mglyph" ) return new GlyphElement(); + + // General Layout Schemata ( Section 3.1.6.2 ) + else if ( type == "mrow" ) return new SequenceElement(); + else if ( type == "mfrac" ) return new FractionElement(); + else if ( type == "msqrt" + || type == "mroot" ) return new RootElement(); + else if ( type == "mstyle" ) return new StyleElement(); + else if ( type == "merror" ) return new ErrorElement(); + else if ( type == "mpadded" ) return new PaddedElement(); + else if ( type == "mphantom" ) return new PhantomElement(); + else if ( type == "mfenced" ) return new BracketElement(); + else if ( type == "menclose" ) return new EncloseElement(); + + // Script and Limit Schemata ( Section 3.1.6.3 ) + else if ( type == "msub" + || type == "msup" + || type == "msubsup" + || type == "munder" + || type == "mover" + || type == "munderover" + || type == "mmultiscripts" ) return new IndexElement(); + + // Tables and Matrices ( Section 3.1.6.4 ) + else if ( type == "mtable" ) return new MatrixElement(); + + // Enlivening Expressions ( Section 3.1.6.5 ) + else if ( type == "maction" ) return new ActionElement(); + return 0; +} + + +TextElement* OasisCreationStrategy::createTextElement( const TQChar& ch, bool symbol ) +{ + return new TextElement( ch, symbol ); +} + +EmptyElement* OasisCreationStrategy::createEmptyElement() +{ + return new EmptyElement; +} + +NameSequence* OasisCreationStrategy::createNameSequence() +{ + return new NameSequence; +} + +BracketElement* OasisCreationStrategy::createBracketElement( SymbolType lhs, SymbolType rhs ) +{ + return new BracketElement( lhs, rhs ); +} + +OverlineElement* OasisCreationStrategy::createOverlineElement() +{ + return new OverlineElement; +} + +UnderlineElement* OasisCreationStrategy::createUnderlineElement() +{ + return new UnderlineElement; +} + +MultilineElement* OasisCreationStrategy::createMultilineElement() +{ + return new MultilineElement; +} + +SpaceElement* OasisCreationStrategy::createSpaceElement( SpaceWidth width ) +{ + return new SpaceElement( width ); +} + +FractionElement* OasisCreationStrategy::createFractionElement() +{ + return new FractionElement; +} + +RootElement* OasisCreationStrategy::createRootElement() +{ + return new RootElement; +} + +SymbolElement* OasisCreationStrategy::createSymbolElement( SymbolType type ) +{ + return new SymbolElement( type ); +} + +MatrixElement* OasisCreationStrategy::createMatrixElement( uint rows, uint columns ) +{ + return new MatrixElement( rows, columns ); +} + +IndexElement* OasisCreationStrategy::createIndexElement() +{ + return new IndexElement; +} + +BasicElement* OasisCreationStrategy::createOperatorElement( const TQDomElement& element ) +{ + TQDomNode n = element.firstChild(); + if ( n.isNull() ) + return 0; + if ( n.isEntityReference() ) { + TQString name = n.nodeName(); + if ( name == "CloseCurlyDoubleQuote" + || name == "CloseCurlyQuote" + || name == "LeftAngleBracket" + || name == "LeftCeiling" + || name == "LeftDoubleBracket" + || name == "LeftFloor" + || name == "OpenCurlyDoubleQuote" + || name == "OpenCurlyQuote" + || name == "RightAngleBracket" + || name == "RightCeiling" + || name == "RightDoubleBracket" + || name == "RightFloor" ) { + return new BracketElement(); + } + return new OperatorElement(); + } + if ( n.isText() ) { + TQString text = n.toText().data(); + if ( text.length() == 1 && TQString("()[]{}").contains(text[0]) ) { + return new BracketElement(); + } + } + return new OperatorElement(); +} + +IdentifierElement* OasisCreationStrategy::createIdentifierElement() +{ + return new IdentifierElement(); +} + +OperatorElement* OasisCreationStrategy::createOperatorElement() +{ + return new OperatorElement(); +} + +NumberElement* OasisCreationStrategy::createNumberElement() +{ + return new NumberElement(); +} + +KFORMULA_NAMESPACE_END diff --git a/lib/kformula/operatordictionary.cc b/lib/kformula/operatordictionary.cc deleted file mode 100644 index 787a58b5..00000000 --- a/lib/kformula/operatordictionary.cc +++ /dev/null @@ -1,4266 +0,0 @@ -// -// Created: Sat Aug 26 20:12:37 2006 -// by: oper-dict.py -// from: appendixf.html -// -// WARNING! All changes made in this file will be lost! - -/* This file is part of the KDE project - Copyright (C) 2006 Alfredo Beaumont Sainz - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - - -#include "operatordictionary.h" - -KFORMULA_NAMESPACE_BEGIN - -const OperatorDictionary operators[] = { - { {"!!", "postfix"}, - "verythinmathspace" , - "0em" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"!", "postfix"}, - "verythinmathspace" , - "0em" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"!", "prefix"}, - "0em" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"!=", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"&", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"&", "postfix"}, - "thickmathspace" , - "0em" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"&", "prefix"}, - "0em" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"&&", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"'", "postfix"}, - "verythinmathspace" , - "0em" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"(", "prefix"}, - "0em" , - "0em" , - "infinity" , - "1" , - true , - false , - true , - true , - false , - false , - false } , - - { {"(", "prefix"}, - "0em" , - "0em" , - "infinity" , - "1" , - true , - false , - true , - true , - false , - false , - false } , - - { {")", "postfix"}, - "0em" , - "0em" , - "infinity" , - "1" , - true , - false , - true , - true , - false , - false , - false } , - - { {"*", "infix"}, - "thinmathspace" , - "thinmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"**", "infix"}, - "verythinmathspace" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"*=", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"+", "infix"}, - "mediummathspace" , - "mediummathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"+", "prefix"}, - "0em" , - "veryverythinmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"++", "postfix"}, - "verythinmathspace" , - "0em" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"++", "prefix"}, - "0em" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"+=", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {",", "infix"}, - "0em" , - "verythickmathspace" , - "infinity" , - "1" , - false , - true , - false , - true , - false , - false , - false } , - - { {"-", "infix"}, - "mediummathspace" , - "mediummathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"-", "prefix"}, - "0em" , - "veryverythinmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"--", "postfix"}, - "verythinmathspace" , - "0em" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"--", "prefix"}, - "0em" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"-=", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"->", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {".", "infix"}, - "0em" , - "0em" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"..", "postfix"}, - "mediummathspace" , - "0em" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"...", "postfix"}, - "mediummathspace" , - "0em" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"/", "infix"}, - "thinmathspace" , - "thinmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"//", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"/=", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {":", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {":=", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {";", "infix"}, - "0em" , - "thickmathspace" , - "infinity" , - "1" , - false , - true , - false , - true , - false , - false , - false } , - - { {";", "postfix"}, - "0em" , - "0em" , - "infinity" , - "1" , - false , - true , - false , - true , - false , - false , - false } , - - { {"<", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"<=", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"<>", "infix"}, - "verythinmathspace" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"=", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"==", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {">", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {">=", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"?", "infix"}, - "verythinmathspace" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"@", "infix"}, - "verythinmathspace" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"[", "prefix"}, - "0em" , - "0em" , - "infinity" , - "1" , - true , - false , - true , - true , - false , - false , - false } , - - { {"]", "postfix"}, - "0em" , - "0em" , - "infinity" , - "1" , - true , - false , - true , - true , - false , - false , - false } , - - { {"^", "infix"}, - "verythinmathspace" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"^", "postfix"}, - "0em" , - "0em" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - true } , - - { {"_", "infix"}, - "verythinmathspace" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"`", "postfix"}, - "0em" , - "0em" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - true } , - - { {"lim", "prefix"}, - "0em" , - "thinmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - true , - false } , - - { {"max", "prefix"}, - "0em" , - "thinmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - true , - false } , - - { {"min", "prefix"}, - "0em" , - "thinmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - true , - false } , - - { {"{", "prefix"}, - "0em" , - "0em" , - "infinity" , - "1" , - true , - false , - true , - true , - false , - false , - false } , - - { {"|", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"|", "infix"}, - "0em" , - "0em" , - "infinity" , - "0" , - false , - false , - true , - true , - false , - false , - false } , - - { {"||", "infix"}, - "mediummathspace" , - "mediummathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"}", "postfix"}, - "0em" , - "0em" , - "infinity" , - "1" , - true , - false , - true , - true , - false , - false , - false } , - - { {"~", "infix"}, - "verythinmathspace" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"¨", "postfix"}, - "0em" , - "0em" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - true } , - - { {"¯", "postfix"}, - "0em" , - "0em" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - true } , - - { {"±", "infix"}, - "mediummathspace" , - "mediummathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"±", "prefix"}, - "0em" , - "veryverythinmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"´", "postfix"}, - "0em" , - "0em" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - true } , - - { {"·", "infix"}, - "thinmathspace" , - "thinmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"¸", "postfix"}, - "0em" , - "0em" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - true } , - - { {"ˇ", "postfix"}, - "0em" , - "0em" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - true } , - - { {"˘", "postfix"}, - "0em" , - "0em" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - true } , - - { {"˙", "postfix"}, - "0em" , - "0em" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - true } , - - { {"˜", "postfix"}, - "0em" , - "0em" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - true } , - - { {"˝", "postfix"}, - "0em" , - "0em" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - true } , - - { {"̑", "postfix"}, - "0em" , - "0em" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - true } , - - { {"̲", "postfix"}, - "0em" , - "0em" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - true } , - - { {"‘", "prefix"}, - "0em" , - "0em" , - "infinity" , - "1" , - true , - false , - false , - true , - false , - false , - false } , - - { {"’", "postfix"}, - "0em" , - "0em" , - "infinity" , - "1" , - true , - false , - false , - true , - false , - false , - false } , - - { {"“", "prefix"}, - "0em" , - "0em" , - "infinity" , - "1" , - true , - false , - false , - true , - false , - false , - false } , - - { {"”", "postfix"}, - "0em" , - "0em" , - "infinity" , - "1" , - true , - false , - false , - true , - false , - false , - false } , - - { {"⁡", "infix"}, - "0em" , - "0em" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⁢", "infix"}, - "0em" , - "0em" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⁣", "infix"}, - "0em" , - "0em" , - "infinity" , - "1" , - false , - true , - false , - true , - false , - false , - false } , - - { {"⃛", "postfix"}, - "0em" , - "0em" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - true } , - - { {"ⅅ", "prefix"}, - "0em" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"ⅆ", "prefix"}, - "0em" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"←", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"←", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"←", "postfix"}, - "0em" , - "0em" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - true } , - - { {"↑", "infix"}, - "verythinmathspace" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"↑", "infix"}, - "verythinmathspace" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"→", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"→", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"→", "postfix"}, - "0em" , - "0em" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - true } , - - { {"↓", "infix"}, - "verythinmathspace" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"↓", "infix"}, - "verythinmathspace" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"↔", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"↔", "postfix"}, - "0em" , - "0em" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - true } , - - { {"↕", "infix"}, - "verythinmathspace" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"↖", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"↗", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"↘", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"↙", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"↤", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"↥", "infix"}, - "verythinmathspace" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"↦", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"↧", "infix"}, - "verythinmathspace" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"↼", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"↼", "postfix"}, - "0em" , - "0em" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - true } , - - { {"↽", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"↾", "infix"}, - "verythinmathspace" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"↿", "infix"}, - "verythinmathspace" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⇀", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⇀", "postfix"}, - "0em" , - "0em" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - true } , - - { {"⇁", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⇂", "infix"}, - "verythinmathspace" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⇃", "infix"}, - "verythinmathspace" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⇄", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⇅", "infix"}, - "verythinmathspace" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⇆", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⇋", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⇌", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⇐", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⇑", "infix"}, - "verythinmathspace" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⇒", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⇒", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⇓", "infix"}, - "verythinmathspace" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⇔", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⇕", "infix"}, - "verythinmathspace" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⇤", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⇥", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⇵", "infix"}, - "verythinmathspace" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"∀", "prefix"}, - "0em" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"∂", "prefix"}, - "0em" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"∃", "prefix"}, - "0em" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"∄", "prefix"}, - "0em" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"∇", "prefix"}, - "0em" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"∈", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"∉", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"∋", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"∋", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"∌", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"∏", "prefix"}, - "0em" , - "thinmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - true , - true , - false } , - - { {"∐", "infix"}, - "thinmathspace" , - "thinmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"∐", "prefix"}, - "0em" , - "thinmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - true , - true , - false } , - - { {"∑", "prefix"}, - "0em" , - "thinmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - true , - true , - false } , - - { {"∓", "infix"}, - "mediummathspace" , - "mediummathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"∓", "prefix"}, - "0em" , - "veryverythinmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"∖", "infix"}, - "thinmathspace" , - "thinmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"∘", "infix"}, - "verythinmathspace" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"√", "prefix"}, - "0em" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"∝", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"∣", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"∤", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"∥", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"∦", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"∫", "prefix"}, - "0em" , - "0em" , - "infinity" , - "1" , - false , - false , - true , - true , - true , - false , - false } , - - { {"∮", "prefix"}, - "0em" , - "0em" , - "infinity" , - "1" , - false , - false , - true , - true , - true , - false , - false } , - - { {"∯", "prefix"}, - "0em" , - "0em" , - "infinity" , - "1" , - false , - false , - true , - true , - true , - false , - false } , - - { {"∲", "prefix"}, - "0em" , - "0em" , - "infinity" , - "1" , - false , - false , - true , - true , - true , - false , - false } , - - { {"∳", "prefix"}, - "0em" , - "0em" , - "infinity" , - "1" , - false , - false , - true , - true , - true , - false , - false } , - - { {"∴", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"∵", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"∷", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"∷", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"∼", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"≀", "infix"}, - "thinmathspace" , - "thinmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"≁", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"≂", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"≃", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"≄", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"≅", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"≇", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"≈", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"≉", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"≍", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"≎", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"≏", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"≐", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"≔", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"≠", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"≡", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"≢", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"≤", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"≥", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"≦", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"≧", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"≪", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"≫", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"≭", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"≮", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"≯", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"≰", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"≱", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"≲", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"≳", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"≴", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"≵", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"≶", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"≷", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"≸", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"≹", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"≺", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"≻", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"≼", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"≽", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"≾", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"≿", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⊀", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⊁", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⊃", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⊆", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⊇", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⊈", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⊉", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⊎", "infix"}, - "mediummathspace" , - "mediummathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⊎", "prefix"}, - "0em" , - "thinmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - true , - true , - false } , - - { {"⊏", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⊐", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⊑", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⊒", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⊓", "infix"}, - "mediummathspace" , - "mediummathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⊔", "infix"}, - "mediummathspace" , - "mediummathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⊕", "infix"}, - "thinmathspace" , - "thinmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⊕", "prefix"}, - "0em" , - "thinmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - true , - true , - false } , - - { {"⊖", "infix"}, - "thinmathspace" , - "thinmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⊖", "prefix"}, - "0em" , - "thinmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - true , - true , - false } , - - { {"⊗", "infix"}, - "thinmathspace" , - "thinmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⊗", "prefix"}, - "0em" , - "thinmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - true , - true , - false } , - - { {"⊙", "infix"}, - "verythinmathspace" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⊙", "prefix"}, - "0em" , - "thinmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - true , - true , - false } , - - { {"⊢", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⊣", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⊤", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⊥", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⊨", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⊲", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⊳", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⊴", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⊵", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⋀", "infix"}, - "thinmathspace" , - "thinmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⋀", "prefix"}, - "0em" , - "thinmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - true , - true , - false } , - - { {"⋁", "infix"}, - "thinmathspace" , - "thinmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⋁", "prefix"}, - "0em" , - "thinmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - true , - true , - false } , - - { {"⋂", "infix"}, - "mediummathspace" , - "mediummathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⋂", "prefix"}, - "0em" , - "thinmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - true , - true , - false } , - - { {"⋃", "infix"}, - "mediummathspace" , - "mediummathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⋃", "prefix"}, - "0em" , - "thinmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - true , - true , - false } , - - { {"⋄", "infix"}, - "thinmathspace" , - "thinmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⋆", "infix"}, - "thinmathspace" , - "thinmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⋐", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⋒", "infix"}, - "thinmathspace" , - "thinmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⋓", "infix"}, - "thinmathspace" , - "thinmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⋚", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⋛", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⋠", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⋡", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⋢", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⋣", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⋪", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⋫", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⋬", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⋭", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⌈", "prefix"}, - "0em" , - "0em" , - "infinity" , - "1" , - true , - false , - true , - true , - false , - false , - false } , - - { {"⌉", "postfix"}, - "0em" , - "0em" , - "infinity" , - "1" , - true , - false , - true , - true , - false , - false , - false } , - - { {"⌊", "prefix"}, - "0em" , - "0em" , - "infinity" , - "1" , - true , - false , - true , - true , - false , - false , - false } , - - { {"⌋", "postfix"}, - "0em" , - "0em" , - "infinity" , - "1" , - true , - false , - true , - true , - false , - false , - false } , - - { {"〈", "prefix"}, - "0em" , - "0em" , - "infinity" , - "1" , - true , - false , - true , - true , - false , - false , - false } , - - { {"〉", "postfix"}, - "0em" , - "0em" , - "infinity" , - "1" , - true , - false , - true , - true , - false , - false , - false } , - - { {"⎴", "postfix"}, - "0em" , - "0em" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - true } , - - { {"⎵", "postfix"}, - "0em" , - "0em" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - true } , - - { {"─", "infix"}, - "0em" , - "0em" , - "infinity" , - "0" , - false , - false , - true , - true , - false , - false , - false } , - - { {"□", "prefix"}, - "0em" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"❘", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⟵", "infix"}, - "verythinmathspace" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⟶", "infix"}, - "verythinmathspace" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⟷", "infix"}, - "verythinmathspace" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⟸", "infix"}, - "verythinmathspace" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⟹", "infix"}, - "verythinmathspace" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⟺", "infix"}, - "verythinmathspace" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⤒", "infix"}, - "verythinmathspace" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⤓", "infix"}, - "verythinmathspace" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⥎", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⥎", "postfix"}, - "0em" , - "0em" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - true } , - - { {"⥏", "infix"}, - "verythinmathspace" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⥐", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⥑", "infix"}, - "verythinmathspace" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⥒", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⥓", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⥔", "infix"}, - "verythinmathspace" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⥕", "infix"}, - "verythinmathspace" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⥖", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⥗", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⥘", "infix"}, - "verythinmathspace" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⥙", "infix"}, - "verythinmathspace" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⥚", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⥛", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⥜", "infix"}, - "verythinmathspace" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⥝", "infix"}, - "verythinmathspace" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⥞", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⥟", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⥠", "infix"}, - "verythinmathspace" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⥡", "infix"}, - "verythinmathspace" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⥮", "infix"}, - "verythinmathspace" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⥯", "infix"}, - "verythinmathspace" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⥰", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⧏", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⧐", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⨯", "infix"}, - "verythinmathspace" , - "verythinmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⩓", "infix"}, - "mediummathspace" , - "mediummathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⩔", "infix"}, - "mediummathspace" , - "mediummathspace" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - false } , - - { {"⩵", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⩽", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⩾", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⪡", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⪢", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⪯", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⪰", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⫤", "infix"}, - "thickmathspace" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"⫬", "prefix"}, - "0em" , - "thickmathspace" , - "infinity" , - "1" , - false , - false , - false , - true , - false , - false , - false } , - - { {"〚", "prefix"}, - "0em" , - "0em" , - "infinity" , - "1" , - true , - false , - true , - true , - false , - false , - false } , - - { {"〛", "postfix"}, - "0em" , - "0em" , - "infinity" , - "1" , - true , - false , - true , - true , - false , - false , - false } , - - { {"︵", "postfix"}, - "0em" , - "0em" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - true } , - - { {"︶", "postfix"}, - "0em" , - "0em" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - true } , - - { {"︷", "postfix"}, - "0em" , - "0em" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - true } , - - { {"︸", "postfix"}, - "0em" , - "0em" , - "infinity" , - "1" , - false , - false , - true , - true , - false , - false , - true } -}; - -// Needed since sizeof is a macro and we cannot be used until size is known -int OperatorDictionary::size() -{ - return sizeof( operators ) / sizeof( OperatorDictionary ); -} - -KFORMULA_NAMESPACE_END - diff --git a/lib/kformula/operatordictionary.cpp b/lib/kformula/operatordictionary.cpp new file mode 100644 index 00000000..787a58b5 --- /dev/null +++ b/lib/kformula/operatordictionary.cpp @@ -0,0 +1,4266 @@ +// +// Created: Sat Aug 26 20:12:37 2006 +// by: oper-dict.py +// from: appendixf.html +// +// WARNING! All changes made in this file will be lost! + +/* This file is part of the KDE project + Copyright (C) 2006 Alfredo Beaumont Sainz + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + + +#include "operatordictionary.h" + +KFORMULA_NAMESPACE_BEGIN + +const OperatorDictionary operators[] = { + { {"!!", "postfix"}, + "verythinmathspace" , + "0em" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"!", "postfix"}, + "verythinmathspace" , + "0em" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"!", "prefix"}, + "0em" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"!=", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"&", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"&", "postfix"}, + "thickmathspace" , + "0em" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"&", "prefix"}, + "0em" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"&&", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"'", "postfix"}, + "verythinmathspace" , + "0em" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"(", "prefix"}, + "0em" , + "0em" , + "infinity" , + "1" , + true , + false , + true , + true , + false , + false , + false } , + + { {"(", "prefix"}, + "0em" , + "0em" , + "infinity" , + "1" , + true , + false , + true , + true , + false , + false , + false } , + + { {")", "postfix"}, + "0em" , + "0em" , + "infinity" , + "1" , + true , + false , + true , + true , + false , + false , + false } , + + { {"*", "infix"}, + "thinmathspace" , + "thinmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"**", "infix"}, + "verythinmathspace" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"*=", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"+", "infix"}, + "mediummathspace" , + "mediummathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"+", "prefix"}, + "0em" , + "veryverythinmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"++", "postfix"}, + "verythinmathspace" , + "0em" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"++", "prefix"}, + "0em" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"+=", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {",", "infix"}, + "0em" , + "verythickmathspace" , + "infinity" , + "1" , + false , + true , + false , + true , + false , + false , + false } , + + { {"-", "infix"}, + "mediummathspace" , + "mediummathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"-", "prefix"}, + "0em" , + "veryverythinmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"--", "postfix"}, + "verythinmathspace" , + "0em" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"--", "prefix"}, + "0em" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"-=", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"->", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {".", "infix"}, + "0em" , + "0em" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"..", "postfix"}, + "mediummathspace" , + "0em" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"...", "postfix"}, + "mediummathspace" , + "0em" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"/", "infix"}, + "thinmathspace" , + "thinmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"//", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"/=", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {":", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {":=", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {";", "infix"}, + "0em" , + "thickmathspace" , + "infinity" , + "1" , + false , + true , + false , + true , + false , + false , + false } , + + { {";", "postfix"}, + "0em" , + "0em" , + "infinity" , + "1" , + false , + true , + false , + true , + false , + false , + false } , + + { {"<", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"<=", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"<>", "infix"}, + "verythinmathspace" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"=", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"==", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {">", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {">=", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"?", "infix"}, + "verythinmathspace" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"@", "infix"}, + "verythinmathspace" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"[", "prefix"}, + "0em" , + "0em" , + "infinity" , + "1" , + true , + false , + true , + true , + false , + false , + false } , + + { {"]", "postfix"}, + "0em" , + "0em" , + "infinity" , + "1" , + true , + false , + true , + true , + false , + false , + false } , + + { {"^", "infix"}, + "verythinmathspace" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"^", "postfix"}, + "0em" , + "0em" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + true } , + + { {"_", "infix"}, + "verythinmathspace" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"`", "postfix"}, + "0em" , + "0em" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + true } , + + { {"lim", "prefix"}, + "0em" , + "thinmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + true , + false } , + + { {"max", "prefix"}, + "0em" , + "thinmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + true , + false } , + + { {"min", "prefix"}, + "0em" , + "thinmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + true , + false } , + + { {"{", "prefix"}, + "0em" , + "0em" , + "infinity" , + "1" , + true , + false , + true , + true , + false , + false , + false } , + + { {"|", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"|", "infix"}, + "0em" , + "0em" , + "infinity" , + "0" , + false , + false , + true , + true , + false , + false , + false } , + + { {"||", "infix"}, + "mediummathspace" , + "mediummathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"}", "postfix"}, + "0em" , + "0em" , + "infinity" , + "1" , + true , + false , + true , + true , + false , + false , + false } , + + { {"~", "infix"}, + "verythinmathspace" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"¨", "postfix"}, + "0em" , + "0em" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + true } , + + { {"¯", "postfix"}, + "0em" , + "0em" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + true } , + + { {"±", "infix"}, + "mediummathspace" , + "mediummathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"±", "prefix"}, + "0em" , + "veryverythinmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"´", "postfix"}, + "0em" , + "0em" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + true } , + + { {"·", "infix"}, + "thinmathspace" , + "thinmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"¸", "postfix"}, + "0em" , + "0em" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + true } , + + { {"ˇ", "postfix"}, + "0em" , + "0em" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + true } , + + { {"˘", "postfix"}, + "0em" , + "0em" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + true } , + + { {"˙", "postfix"}, + "0em" , + "0em" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + true } , + + { {"˜", "postfix"}, + "0em" , + "0em" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + true } , + + { {"˝", "postfix"}, + "0em" , + "0em" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + true } , + + { {"̑", "postfix"}, + "0em" , + "0em" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + true } , + + { {"̲", "postfix"}, + "0em" , + "0em" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + true } , + + { {"‘", "prefix"}, + "0em" , + "0em" , + "infinity" , + "1" , + true , + false , + false , + true , + false , + false , + false } , + + { {"’", "postfix"}, + "0em" , + "0em" , + "infinity" , + "1" , + true , + false , + false , + true , + false , + false , + false } , + + { {"“", "prefix"}, + "0em" , + "0em" , + "infinity" , + "1" , + true , + false , + false , + true , + false , + false , + false } , + + { {"”", "postfix"}, + "0em" , + "0em" , + "infinity" , + "1" , + true , + false , + false , + true , + false , + false , + false } , + + { {"⁡", "infix"}, + "0em" , + "0em" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⁢", "infix"}, + "0em" , + "0em" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⁣", "infix"}, + "0em" , + "0em" , + "infinity" , + "1" , + false , + true , + false , + true , + false , + false , + false } , + + { {"⃛", "postfix"}, + "0em" , + "0em" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + true } , + + { {"ⅅ", "prefix"}, + "0em" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"ⅆ", "prefix"}, + "0em" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"←", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"←", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"←", "postfix"}, + "0em" , + "0em" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + true } , + + { {"↑", "infix"}, + "verythinmathspace" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"↑", "infix"}, + "verythinmathspace" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"→", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"→", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"→", "postfix"}, + "0em" , + "0em" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + true } , + + { {"↓", "infix"}, + "verythinmathspace" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"↓", "infix"}, + "verythinmathspace" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"↔", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"↔", "postfix"}, + "0em" , + "0em" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + true } , + + { {"↕", "infix"}, + "verythinmathspace" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"↖", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"↗", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"↘", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"↙", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"↤", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"↥", "infix"}, + "verythinmathspace" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"↦", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"↧", "infix"}, + "verythinmathspace" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"↼", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"↼", "postfix"}, + "0em" , + "0em" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + true } , + + { {"↽", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"↾", "infix"}, + "verythinmathspace" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"↿", "infix"}, + "verythinmathspace" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⇀", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⇀", "postfix"}, + "0em" , + "0em" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + true } , + + { {"⇁", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⇂", "infix"}, + "verythinmathspace" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⇃", "infix"}, + "verythinmathspace" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⇄", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⇅", "infix"}, + "verythinmathspace" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⇆", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⇋", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⇌", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⇐", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⇑", "infix"}, + "verythinmathspace" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⇒", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⇒", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⇓", "infix"}, + "verythinmathspace" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⇔", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⇕", "infix"}, + "verythinmathspace" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⇤", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⇥", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⇵", "infix"}, + "verythinmathspace" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"∀", "prefix"}, + "0em" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"∂", "prefix"}, + "0em" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"∃", "prefix"}, + "0em" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"∄", "prefix"}, + "0em" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"∇", "prefix"}, + "0em" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"∈", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"∉", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"∋", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"∋", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"∌", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"∏", "prefix"}, + "0em" , + "thinmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + true , + true , + false } , + + { {"∐", "infix"}, + "thinmathspace" , + "thinmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"∐", "prefix"}, + "0em" , + "thinmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + true , + true , + false } , + + { {"∑", "prefix"}, + "0em" , + "thinmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + true , + true , + false } , + + { {"∓", "infix"}, + "mediummathspace" , + "mediummathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"∓", "prefix"}, + "0em" , + "veryverythinmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"∖", "infix"}, + "thinmathspace" , + "thinmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"∘", "infix"}, + "verythinmathspace" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"√", "prefix"}, + "0em" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"∝", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"∣", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"∤", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"∥", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"∦", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"∫", "prefix"}, + "0em" , + "0em" , + "infinity" , + "1" , + false , + false , + true , + true , + true , + false , + false } , + + { {"∮", "prefix"}, + "0em" , + "0em" , + "infinity" , + "1" , + false , + false , + true , + true , + true , + false , + false } , + + { {"∯", "prefix"}, + "0em" , + "0em" , + "infinity" , + "1" , + false , + false , + true , + true , + true , + false , + false } , + + { {"∲", "prefix"}, + "0em" , + "0em" , + "infinity" , + "1" , + false , + false , + true , + true , + true , + false , + false } , + + { {"∳", "prefix"}, + "0em" , + "0em" , + "infinity" , + "1" , + false , + false , + true , + true , + true , + false , + false } , + + { {"∴", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"∵", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"∷", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"∷", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"∼", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"≀", "infix"}, + "thinmathspace" , + "thinmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"≁", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"≂", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"≃", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"≄", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"≅", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"≇", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"≈", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"≉", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"≍", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"≎", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"≏", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"≐", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"≔", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"≠", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"≡", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"≢", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"≤", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"≥", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"≦", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"≧", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"≪", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"≫", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"≭", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"≮", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"≯", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"≰", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"≱", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"≲", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"≳", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"≴", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"≵", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"≶", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"≷", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"≸", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"≹", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"≺", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"≻", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"≼", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"≽", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"≾", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"≿", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⊀", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⊁", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⊃", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⊆", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⊇", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⊈", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⊉", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⊎", "infix"}, + "mediummathspace" , + "mediummathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⊎", "prefix"}, + "0em" , + "thinmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + true , + true , + false } , + + { {"⊏", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⊐", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⊑", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⊒", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⊓", "infix"}, + "mediummathspace" , + "mediummathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⊔", "infix"}, + "mediummathspace" , + "mediummathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⊕", "infix"}, + "thinmathspace" , + "thinmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⊕", "prefix"}, + "0em" , + "thinmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + true , + true , + false } , + + { {"⊖", "infix"}, + "thinmathspace" , + "thinmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⊖", "prefix"}, + "0em" , + "thinmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + true , + true , + false } , + + { {"⊗", "infix"}, + "thinmathspace" , + "thinmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⊗", "prefix"}, + "0em" , + "thinmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + true , + true , + false } , + + { {"⊙", "infix"}, + "verythinmathspace" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⊙", "prefix"}, + "0em" , + "thinmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + true , + true , + false } , + + { {"⊢", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⊣", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⊤", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⊥", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⊨", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⊲", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⊳", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⊴", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⊵", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⋀", "infix"}, + "thinmathspace" , + "thinmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⋀", "prefix"}, + "0em" , + "thinmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + true , + true , + false } , + + { {"⋁", "infix"}, + "thinmathspace" , + "thinmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⋁", "prefix"}, + "0em" , + "thinmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + true , + true , + false } , + + { {"⋂", "infix"}, + "mediummathspace" , + "mediummathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⋂", "prefix"}, + "0em" , + "thinmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + true , + true , + false } , + + { {"⋃", "infix"}, + "mediummathspace" , + "mediummathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⋃", "prefix"}, + "0em" , + "thinmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + true , + true , + false } , + + { {"⋄", "infix"}, + "thinmathspace" , + "thinmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⋆", "infix"}, + "thinmathspace" , + "thinmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⋐", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⋒", "infix"}, + "thinmathspace" , + "thinmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⋓", "infix"}, + "thinmathspace" , + "thinmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⋚", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⋛", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⋠", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⋡", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⋢", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⋣", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⋪", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⋫", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⋬", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⋭", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⌈", "prefix"}, + "0em" , + "0em" , + "infinity" , + "1" , + true , + false , + true , + true , + false , + false , + false } , + + { {"⌉", "postfix"}, + "0em" , + "0em" , + "infinity" , + "1" , + true , + false , + true , + true , + false , + false , + false } , + + { {"⌊", "prefix"}, + "0em" , + "0em" , + "infinity" , + "1" , + true , + false , + true , + true , + false , + false , + false } , + + { {"⌋", "postfix"}, + "0em" , + "0em" , + "infinity" , + "1" , + true , + false , + true , + true , + false , + false , + false } , + + { {"〈", "prefix"}, + "0em" , + "0em" , + "infinity" , + "1" , + true , + false , + true , + true , + false , + false , + false } , + + { {"〉", "postfix"}, + "0em" , + "0em" , + "infinity" , + "1" , + true , + false , + true , + true , + false , + false , + false } , + + { {"⎴", "postfix"}, + "0em" , + "0em" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + true } , + + { {"⎵", "postfix"}, + "0em" , + "0em" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + true } , + + { {"─", "infix"}, + "0em" , + "0em" , + "infinity" , + "0" , + false , + false , + true , + true , + false , + false , + false } , + + { {"□", "prefix"}, + "0em" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"❘", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⟵", "infix"}, + "verythinmathspace" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⟶", "infix"}, + "verythinmathspace" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⟷", "infix"}, + "verythinmathspace" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⟸", "infix"}, + "verythinmathspace" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⟹", "infix"}, + "verythinmathspace" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⟺", "infix"}, + "verythinmathspace" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⤒", "infix"}, + "verythinmathspace" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⤓", "infix"}, + "verythinmathspace" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⥎", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⥎", "postfix"}, + "0em" , + "0em" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + true } , + + { {"⥏", "infix"}, + "verythinmathspace" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⥐", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⥑", "infix"}, + "verythinmathspace" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⥒", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⥓", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⥔", "infix"}, + "verythinmathspace" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⥕", "infix"}, + "verythinmathspace" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⥖", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⥗", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⥘", "infix"}, + "verythinmathspace" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⥙", "infix"}, + "verythinmathspace" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⥚", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⥛", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⥜", "infix"}, + "verythinmathspace" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⥝", "infix"}, + "verythinmathspace" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⥞", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⥟", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⥠", "infix"}, + "verythinmathspace" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⥡", "infix"}, + "verythinmathspace" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⥮", "infix"}, + "verythinmathspace" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⥯", "infix"}, + "verythinmathspace" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⥰", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⧏", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⧐", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⨯", "infix"}, + "verythinmathspace" , + "verythinmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⩓", "infix"}, + "mediummathspace" , + "mediummathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⩔", "infix"}, + "mediummathspace" , + "mediummathspace" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + false } , + + { {"⩵", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⩽", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⩾", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⪡", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⪢", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⪯", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⪰", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⫤", "infix"}, + "thickmathspace" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"⫬", "prefix"}, + "0em" , + "thickmathspace" , + "infinity" , + "1" , + false , + false , + false , + true , + false , + false , + false } , + + { {"〚", "prefix"}, + "0em" , + "0em" , + "infinity" , + "1" , + true , + false , + true , + true , + false , + false , + false } , + + { {"〛", "postfix"}, + "0em" , + "0em" , + "infinity" , + "1" , + true , + false , + true , + true , + false , + false , + false } , + + { {"︵", "postfix"}, + "0em" , + "0em" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + true } , + + { {"︶", "postfix"}, + "0em" , + "0em" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + true } , + + { {"︷", "postfix"}, + "0em" , + "0em" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + true } , + + { {"︸", "postfix"}, + "0em" , + "0em" , + "infinity" , + "1" , + false , + false , + true , + true , + false , + false , + true } +}; + +// Needed since sizeof is a macro and we cannot be used until size is known +int OperatorDictionary::size() +{ + return sizeof( operators ) / sizeof( OperatorDictionary ); +} + +KFORMULA_NAMESPACE_END + diff --git a/lib/kformula/operatorelement.cc b/lib/kformula/operatorelement.cc deleted file mode 100644 index 882eed01..00000000 --- a/lib/kformula/operatorelement.cc +++ /dev/null @@ -1,547 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2006 Alfredo Beaumont Sainz - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - -#include - -#include - -#include - -#include "elementtype.h" -#include "sequenceelement.h" -#include "textelement.h" -#include "fontstyle.h" -#include "operatordictionary.h" -#include "operatorelement.h" -#include "identifierelement.h" -#include "numberelement.h" -#include "kformulacommand.h" -#include "kformulacontainer.h" -#include "kformuladocument.h" -#include "formulaelement.h" -#include "creationstrategy.h" - -KFORMULA_NAMESPACE_BEGIN - -OperatorElement::OperatorElement( BasicElement* parent ) : TokenElement( parent ), - m_form( NoForm ), - m_lspaceType( ThickMathSpace ), - m_rspaceType( ThickMathSpace ), - m_maxSizeType( InfinitySize ), - m_minSizeType( RelativeSize ), - m_minSize( 1 ), - m_fence( false ), - m_separator( false ), - m_stretchy( false ), - m_symmetric( true ), - m_largeOp( false ), - m_movableLimits( false ), - m_accent( false ), - m_customForm( false ), - m_customFence( false ), - m_customSeparator( false ), - m_customLSpace( false ), - m_customRSpace( false ), - m_customStretchy( false ), - m_customSymmetric( false ), - m_customMaxSize( false ), - m_customMinSize( false ), - m_customLargeOp( false ), - m_customMovableLimits( false ), - m_customAccent( false ) -{ -} - -void OperatorElement::setForm( FormType type ) -{ - if ( ! m_customForm ) { // Set by an attribute has higher priority - m_form = type; - } - - if ( ! isTextOnly() ) { // Only text content can be dictionary keys - return; - } - TQString text; - for ( uint i = 0; i < countChildren(); i++ ) { - text.append( getChild( i )->getCharacter() ); - } - TQString form; - switch ( m_form ) { - case PrefixForm: - form = "prefix"; - break; - case InfixForm: - form = "infix"; - break; - case PostfixForm: - form = "postfix"; - break; - default: - // Should not happen - kdWarning( DEBUGID ) << "Invalid `form' attribute value\n"; - return; - } - DictionaryKey key = { text.utf8(), form.ascii() }; - const OperatorDictionary* begin = operators; - const OperatorDictionary* end = operators + OperatorDictionary::size(); - const OperatorDictionary* pos = std::lower_bound( begin, end, key ); - if ( pos != end && pos->key == key ) { // Entry found ! - if ( ! m_customFence ) { - m_fence = pos->fence; - } - if ( ! m_customSeparator ) { - m_separator = pos->separator; - } - if ( ! m_customLSpace ) { - m_lspace = getSize( pos->lspace, &m_lspaceType ); - if ( m_lspaceType == NoSize ) { - m_lspaceType = getSpace( pos->lspace ); - } - } - if ( ! m_customRSpace ) { - m_rspace = getSize( pos->rspace, &m_rspaceType ); - if ( m_rspaceType == NoSize ) { - m_rspaceType = getSpace( pos->rspace ); - } - } - if ( ! m_customStretchy ) { - m_stretchy = pos->stretchy; - } - if ( ! m_customSymmetric ) { - m_symmetric = pos->symmetric; - } - if ( ! m_customMaxSize ) { - if ( qstrcmp( pos->maxsize, "infinity" ) == 0 ) { - m_maxSizeType = InfinitySize; - } - else { - m_maxSize = getSize( pos->maxsize, &m_maxSizeType ); - if ( m_maxSizeType == NoSize ) { - m_maxSizeType = getSpace( pos->maxsize ); - } - } - } - if ( ! m_customMinSize ) { - m_minSize = getSize( pos->minsize, &m_minSizeType ); - if ( m_minSizeType == NoSize ) { - m_minSizeType = getSpace( pos->minsize ); - } - } - if ( ! m_customLargeOp ) { - m_largeOp = pos->largeop; - } - if ( ! m_customMovableLimits ) { - m_movableLimits = pos->movablelimits; - } - if ( ! m_customAccent ) { - m_accent = pos->accent; - } - } -} - -/* - * Token elements' content has to be of homogeneous type. Every token element - * must (TODO: check this) appear inside a non-token sequence, and thus, if - * the command asks for a different content, a new element has to be created in - * parent sequence. - */ -KCommand* OperatorElement::buildCommand( Container* container, Request* request ) -{ - FormulaCursor* cursor = container->activeCursor(); - if ( cursor->isReadOnly() ) { - formula()->tell( i18n( "write protection" ) ); - return 0; - } - - if ( *request == req_addOperator ) { - KFCReplace* command = new KFCReplace( i18n("Add Operator"), container ); - OperatorRequest* opr = static_cast( request ); - TextElement* element = creationStrategy->createTextElement( opr->ch(), true ); - command->addElement( element ); - return command; - } - - if ( countChildren() == 0 || cursor->getPos() == countChildren() ) { - // We are in the last position, so it's easy, call the parent to - // create a new child - SequenceElement* parent = static_cast( getParent() ); - if ( parent ) { - uint pos = parent->childPos( this ); - cursor->setTo( parent, pos + 1); - return parent->buildCommand( container, request ); - } - } - if ( cursor->getPos() == 0 ) { - SequenceElement* parent = static_cast( getParent() ); - if ( parent ) { - uint pos = parent->childPos( this ); - cursor->setTo( parent, pos ); - return parent->buildCommand( container, request ); - } - } - - // We are in the middle of a token, so: - // a) Cut from mark to the end - // b) Create a new token and add an element from key pressed - // c) Create a new token and add elements cut previously - // d) Move cursor to parent so that it command execution works fine - - switch( *request ) { - case req_addTextChar: { - KFCSplitToken* command = new KFCSplitToken( i18n("Add Text"), container ); - TextCharRequest* tr = static_cast( request ); - IdentifierElement* id = creationStrategy->createIdentifierElement(); - TextElement* text = creationStrategy->createTextElement( tr->ch() ); - command->addCursor( cursor ); - command->addToken( id ); - command->addContent( id, text ); - SequenceElement* parent = static_cast< SequenceElement* >( getParent() ); - if ( parent ) { - cursor->setTo( parent, parent->childPos( this ) + 1 ); - } - return command; - } - - case req_addText: { - KFCSplitToken* command = new KFCSplitToken( i18n("Add Text"), container ); - TextRequest* tr = static_cast( request ); - IdentifierElement* id = creationStrategy->createIdentifierElement(); - command->addCursor( cursor ); - command->addToken( id ); - for ( uint i = 0; i < tr->text().length(); i++ ) { - TextElement* text = creationStrategy->createTextElement( tr->text()[i] ); - command->addContent( id, text ); - } - SequenceElement* parent = static_cast< SequenceElement* >( getParent() ); - if ( parent ) { - cursor->setTo( parent, parent->childPos( this ) + 1 ); - } - return command; - } - - case req_addNumber: { - KFCSplitToken* command = new KFCSplitToken( i18n("Add Number"), container ); - NumberRequest* nr = static_cast( request ); - NumberElement* num = creationStrategy->createNumberElement(); - TextElement* text = creationStrategy->createTextElement( nr->ch() ); - command->addCursor( cursor ); - command->addToken( num ); - command->addContent( num, text ); - SequenceElement* parent = static_cast< SequenceElement* >( getParent() ); - if ( parent ) { - cursor->setTo( parent, parent->childPos( this ) + 1 ); - } - return command; - } - case req_addEmptyBox: - case req_addNameSequence: - case req_addBracket: - case req_addSpace: - case req_addFraction: - case req_addRoot: - case req_addSymbol: - case req_addOneByTwoMatrix: - case req_addMatrix: { - uint pos = static_cast(getParent())->childPos( this ); - cursor->setTo( getParent(), pos + 1); - return getParent()->buildCommand( container, request ); - } - default: - return SequenceElement::buildCommand( container, request ); - } - return 0; -} - - -bool OperatorElement::readAttributesFromMathMLDom( const TQDomElement &element ) -{ - if ( ! BasicElement::readAttributesFromMathMLDom( element ) ) { - return false; - } - - TQString formStr = element.attribute( "form" ).stripWhiteSpace().lower(); - if ( ! formStr.isNull() ) { - m_customForm = true; - if ( formStr == "prefix" ) { - m_form = PrefixForm; - } - else if ( formStr == "infix" ) { - m_form = InfixForm; - } - else if ( formStr == "postfix" ) { - m_form = PostfixForm; - } - else { - kdWarning( DEBUGID ) << "Invalid value for attribute `form': " << formStr << endl; - m_customForm = false; - } - } - TQString fenceStr = element.attribute( "fence" ).stripWhiteSpace().lower(); - if ( ! fenceStr.isNull() ) { - m_customFence = true; - if ( fenceStr == "true" ) { - m_fence = true; - } - else if ( fenceStr == "false" ) { - m_fence = false; - } - else { - kdWarning( DEBUGID ) << "Invalid value for attribute `fence': " << fenceStr << endl; - m_customFence = false; - } - } - TQString separatorStr = element.attribute( "separator" ).stripWhiteSpace().lower(); - if ( ! separatorStr.isNull() ) { - m_customSeparator = true; - if ( separatorStr == "true" ) { - m_separator = true; - } - else if ( separatorStr == "false" ) { - m_separator = false; - } - else { - kdWarning( DEBUGID ) << "Invalid value for attribute `separator': " << separatorStr << endl; - m_customSeparator = false; - } - } - TQString lspaceStr = element.attribute( "lspace" ).stripWhiteSpace().lower(); - if ( ! lspaceStr.isNull() ) { - m_customLSpace = true; - m_lspace = getSize( lspaceStr, &m_lspaceType ); - if ( m_lspaceType == NoSize ) { - m_lspaceType = getSpace( lspaceStr ); - } - } - TQString rspaceStr = element.attribute( "rspace" ).stripWhiteSpace().lower(); - if ( ! rspaceStr.isNull() ) { - m_customRSpace = true; - m_rspace = getSize( rspaceStr, &m_rspaceType ); - if ( m_rspaceType == NoSize ) { - m_rspaceType = getSpace( rspaceStr ); - } - } - TQString stretchyStr = element.attribute( "stretchy" ).stripWhiteSpace().lower(); - if ( ! stretchyStr.isNull() ) { - m_customStretchy = true; - if ( stretchyStr == "true" ) { - m_stretchy = true; - } - else if ( stretchyStr == "false" ) { - m_stretchy = false; - } - else { - kdWarning( DEBUGID ) << "Invalid value for attribute `stretchy': " << stretchyStr << endl; - m_customStretchy = false; - } - } - TQString symmetricStr = element.attribute( "symmetric" ).stripWhiteSpace().lower(); - if ( ! symmetricStr.isNull() ) { - m_customSymmetric = true; - if ( symmetricStr == "true" ) { - m_symmetric = true; - } - else if ( symmetricStr == "false" ) { - m_symmetric = false; - } - else { - kdWarning( DEBUGID ) << "Invalid value for attribute `symmetric': " << symmetricStr << endl; - m_customSymmetric = false; - } - } - TQString maxsizeStr = element.attribute( "maxsize" ).stripWhiteSpace().lower(); - if ( ! maxsizeStr.isNull() ) { - m_customMaxSize = true; - if ( maxsizeStr == "infinity" ) { - m_maxSizeType = InfinitySize; - } - else { - m_maxSize = getSize( maxsizeStr, &m_maxSizeType ); - if ( m_maxSizeType == NoSize ) { - m_maxSizeType = getSpace( maxsizeStr ); - } - } - } - TQString minsizeStr = element.attribute( "minsize" ).stripWhiteSpace().lower(); - if ( ! minsizeStr.isNull() ) { - m_customMinSize = true; - m_minSize = getSize( minsizeStr, &m_minSizeType ); - if ( m_minSizeType == NoSize ) { - m_minSizeType = getSpace( minsizeStr ); - } - } - TQString largeopStr = element.attribute( "largeop" ).stripWhiteSpace().lower(); - if ( ! largeopStr.isNull() ) { - m_customLargeOp = true; - if ( largeopStr == "true" ) { - m_largeOp = true; - } - else if ( largeopStr == "false" ) { - m_largeOp = false; - } - else { - kdWarning( DEBUGID ) << "Invalid value for attribute `largeop': " << largeopStr << endl; - m_customLargeOp = false; - } - } - TQString movablelimitsStr = element.attribute( "movablelimits" ).stripWhiteSpace().lower(); - if ( ! movablelimitsStr.isNull() ) { - m_customMovableLimits = true; - if ( movablelimitsStr == "true" ) { - m_movableLimits = true; - } - else if ( movablelimitsStr == "false" ) { - m_movableLimits = false; - } - else { - kdWarning( DEBUGID ) << "Invalid value for attribute `movablelimits': " << movablelimitsStr << endl; - m_customMovableLimits = false; - } - } - TQString accentStr = element.attribute( "accent" ).stripWhiteSpace().lower(); - if ( ! accentStr.isNull() ) { - m_customAccent = true; - if ( accentStr == "true" ) { - m_accent = true; - } - else if ( accentStr == "false" ) { - m_accent = false; - } - else { - kdWarning( DEBUGID ) << "Invalid value for attribute `accent': " << accentStr << endl; - m_customAccent = false; - } - } - return true; -} - -void OperatorElement::writeMathMLAttributes( TQDomElement& element ) const -{ - if ( m_customForm ) { - switch ( m_form ) { - case PrefixForm: - element.setAttribute( "form", "prefix" ); - break; - case InfixForm: - element.setAttribute( "form", "infix" ); - break; - case PostfixForm: - element.setAttribute( "form", "postfix" ); - default: - break; - } - } - if ( m_customFence ) { - element.setAttribute( "fence", m_fence ? "true" : "false" ); - } - if ( m_customSeparator ) { - element.setAttribute( "separator", m_separator ? "true" : "false" ); - } - if ( m_customLSpace ) { - writeSizeAttribute( element, "lspace", m_lspaceType, m_lspace ); - } - if ( m_customRSpace ) { - writeSizeAttribute( element, "rspace", m_rspaceType, m_rspace ); - } - if ( m_customStretchy ) { - element.setAttribute( "stretchy", m_stretchy ? "true" : "false" ); - } - if ( m_customSymmetric ) { - element.setAttribute( "symmetric", m_symmetric ? "true" : "false" ); - } - if ( m_customMaxSize ) { - writeSizeAttribute( element, "maxsize", m_maxSizeType, m_maxSize ); - } - if ( m_customMinSize ) { - writeSizeAttribute( element, "minsize", m_minSizeType, m_minSize ); - } - if ( m_customLargeOp ) { - element.setAttribute( "largeop", m_largeOp ? "true" : "false" ); - } - if ( m_customMovableLimits ) { - element.setAttribute( "movablelimits", m_movableLimits ? "true" : "false" ); - } - if ( m_customAccent ) { - element.setAttribute( "accent", m_accent ? "true" : "false" ); - } -} - -void OperatorElement::writeSizeAttribute( TQDomElement& element, const TQString &attr, SizeType type, double length ) const -{ - switch ( type ) { - case InfinitySize: - element.setAttribute( attr, "infinity" ); - break; - case AbsoluteSize: - element.setAttribute( attr, TQString( "%1pt" ).arg( length ) ); - break; - case RelativeSize: - element.setAttribute( attr, TQString( "%1% " ).arg( length * 100.0 ) ); - break; - case PixelSize: - element.setAttribute( attr, TQString( "%1px " ).arg( length ) ); - break; - case NegativeVeryVeryThinMathSpace: - element.setAttribute( attr, "negativeveryverythinmathspace" ); - break; - case NegativeVeryThinMathSpace: - element.setAttribute( attr, "negativeverythinmathspace" ); - break; - case NegativeThinMathSpace: - element.setAttribute( attr, "negativethinmathspace" ); - break; - case NegativeMediumMathSpace: - element.setAttribute( attr, "negativemediummathspace" ); - break; - case NegativeThickMathSpace: - element.setAttribute( attr, "negativethickmathspace" ); - break; - case NegativeVeryThickMathSpace: - element.setAttribute( attr, "negativeverythickmathspace" ); - break; - case NegativeVeryVeryThickMathSpace: - element.setAttribute( attr, "negativeveryverythickmathspace" ); - break; - case VeryVeryThinMathSpace: - element.setAttribute( attr, "veryverythinmathspace" ); - break; - case VeryThinMathSpace: - element.setAttribute( attr, "verythinmathspace" ); - break; - case ThinMathSpace: - element.setAttribute( attr, "thinmathspace" ); - break; - case MediumMathSpace: - element.setAttribute( attr, "mediummathspace" ); - break; - case ThickMathSpace: - element.setAttribute( attr, "thickmathspace" ); - break; - case VeryThickMathSpace: - element.setAttribute( attr, "verythickmathspace" ); - break; - case VeryVeryThickMathSpace: - element.setAttribute( attr, "veryverythickmathspace" ); - break; - default: - break; - } -} - - -KFORMULA_NAMESPACE_END diff --git a/lib/kformula/operatorelement.cpp b/lib/kformula/operatorelement.cpp new file mode 100644 index 00000000..882eed01 --- /dev/null +++ b/lib/kformula/operatorelement.cpp @@ -0,0 +1,547 @@ +/* This file is part of the KDE project + Copyright (C) 2006 Alfredo Beaumont Sainz + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include + +#include + +#include + +#include "elementtype.h" +#include "sequenceelement.h" +#include "textelement.h" +#include "fontstyle.h" +#include "operatordictionary.h" +#include "operatorelement.h" +#include "identifierelement.h" +#include "numberelement.h" +#include "kformulacommand.h" +#include "kformulacontainer.h" +#include "kformuladocument.h" +#include "formulaelement.h" +#include "creationstrategy.h" + +KFORMULA_NAMESPACE_BEGIN + +OperatorElement::OperatorElement( BasicElement* parent ) : TokenElement( parent ), + m_form( NoForm ), + m_lspaceType( ThickMathSpace ), + m_rspaceType( ThickMathSpace ), + m_maxSizeType( InfinitySize ), + m_minSizeType( RelativeSize ), + m_minSize( 1 ), + m_fence( false ), + m_separator( false ), + m_stretchy( false ), + m_symmetric( true ), + m_largeOp( false ), + m_movableLimits( false ), + m_accent( false ), + m_customForm( false ), + m_customFence( false ), + m_customSeparator( false ), + m_customLSpace( false ), + m_customRSpace( false ), + m_customStretchy( false ), + m_customSymmetric( false ), + m_customMaxSize( false ), + m_customMinSize( false ), + m_customLargeOp( false ), + m_customMovableLimits( false ), + m_customAccent( false ) +{ +} + +void OperatorElement::setForm( FormType type ) +{ + if ( ! m_customForm ) { // Set by an attribute has higher priority + m_form = type; + } + + if ( ! isTextOnly() ) { // Only text content can be dictionary keys + return; + } + TQString text; + for ( uint i = 0; i < countChildren(); i++ ) { + text.append( getChild( i )->getCharacter() ); + } + TQString form; + switch ( m_form ) { + case PrefixForm: + form = "prefix"; + break; + case InfixForm: + form = "infix"; + break; + case PostfixForm: + form = "postfix"; + break; + default: + // Should not happen + kdWarning( DEBUGID ) << "Invalid `form' attribute value\n"; + return; + } + DictionaryKey key = { text.utf8(), form.ascii() }; + const OperatorDictionary* begin = operators; + const OperatorDictionary* end = operators + OperatorDictionary::size(); + const OperatorDictionary* pos = std::lower_bound( begin, end, key ); + if ( pos != end && pos->key == key ) { // Entry found ! + if ( ! m_customFence ) { + m_fence = pos->fence; + } + if ( ! m_customSeparator ) { + m_separator = pos->separator; + } + if ( ! m_customLSpace ) { + m_lspace = getSize( pos->lspace, &m_lspaceType ); + if ( m_lspaceType == NoSize ) { + m_lspaceType = getSpace( pos->lspace ); + } + } + if ( ! m_customRSpace ) { + m_rspace = getSize( pos->rspace, &m_rspaceType ); + if ( m_rspaceType == NoSize ) { + m_rspaceType = getSpace( pos->rspace ); + } + } + if ( ! m_customStretchy ) { + m_stretchy = pos->stretchy; + } + if ( ! m_customSymmetric ) { + m_symmetric = pos->symmetric; + } + if ( ! m_customMaxSize ) { + if ( qstrcmp( pos->maxsize, "infinity" ) == 0 ) { + m_maxSizeType = InfinitySize; + } + else { + m_maxSize = getSize( pos->maxsize, &m_maxSizeType ); + if ( m_maxSizeType == NoSize ) { + m_maxSizeType = getSpace( pos->maxsize ); + } + } + } + if ( ! m_customMinSize ) { + m_minSize = getSize( pos->minsize, &m_minSizeType ); + if ( m_minSizeType == NoSize ) { + m_minSizeType = getSpace( pos->minsize ); + } + } + if ( ! m_customLargeOp ) { + m_largeOp = pos->largeop; + } + if ( ! m_customMovableLimits ) { + m_movableLimits = pos->movablelimits; + } + if ( ! m_customAccent ) { + m_accent = pos->accent; + } + } +} + +/* + * Token elements' content has to be of homogeneous type. Every token element + * must (TODO: check this) appear inside a non-token sequence, and thus, if + * the command asks for a different content, a new element has to be created in + * parent sequence. + */ +KCommand* OperatorElement::buildCommand( Container* container, Request* request ) +{ + FormulaCursor* cursor = container->activeCursor(); + if ( cursor->isReadOnly() ) { + formula()->tell( i18n( "write protection" ) ); + return 0; + } + + if ( *request == req_addOperator ) { + KFCReplace* command = new KFCReplace( i18n("Add Operator"), container ); + OperatorRequest* opr = static_cast( request ); + TextElement* element = creationStrategy->createTextElement( opr->ch(), true ); + command->addElement( element ); + return command; + } + + if ( countChildren() == 0 || cursor->getPos() == countChildren() ) { + // We are in the last position, so it's easy, call the parent to + // create a new child + SequenceElement* parent = static_cast( getParent() ); + if ( parent ) { + uint pos = parent->childPos( this ); + cursor->setTo( parent, pos + 1); + return parent->buildCommand( container, request ); + } + } + if ( cursor->getPos() == 0 ) { + SequenceElement* parent = static_cast( getParent() ); + if ( parent ) { + uint pos = parent->childPos( this ); + cursor->setTo( parent, pos ); + return parent->buildCommand( container, request ); + } + } + + // We are in the middle of a token, so: + // a) Cut from mark to the end + // b) Create a new token and add an element from key pressed + // c) Create a new token and add elements cut previously + // d) Move cursor to parent so that it command execution works fine + + switch( *request ) { + case req_addTextChar: { + KFCSplitToken* command = new KFCSplitToken( i18n("Add Text"), container ); + TextCharRequest* tr = static_cast( request ); + IdentifierElement* id = creationStrategy->createIdentifierElement(); + TextElement* text = creationStrategy->createTextElement( tr->ch() ); + command->addCursor( cursor ); + command->addToken( id ); + command->addContent( id, text ); + SequenceElement* parent = static_cast< SequenceElement* >( getParent() ); + if ( parent ) { + cursor->setTo( parent, parent->childPos( this ) + 1 ); + } + return command; + } + + case req_addText: { + KFCSplitToken* command = new KFCSplitToken( i18n("Add Text"), container ); + TextRequest* tr = static_cast( request ); + IdentifierElement* id = creationStrategy->createIdentifierElement(); + command->addCursor( cursor ); + command->addToken( id ); + for ( uint i = 0; i < tr->text().length(); i++ ) { + TextElement* text = creationStrategy->createTextElement( tr->text()[i] ); + command->addContent( id, text ); + } + SequenceElement* parent = static_cast< SequenceElement* >( getParent() ); + if ( parent ) { + cursor->setTo( parent, parent->childPos( this ) + 1 ); + } + return command; + } + + case req_addNumber: { + KFCSplitToken* command = new KFCSplitToken( i18n("Add Number"), container ); + NumberRequest* nr = static_cast( request ); + NumberElement* num = creationStrategy->createNumberElement(); + TextElement* text = creationStrategy->createTextElement( nr->ch() ); + command->addCursor( cursor ); + command->addToken( num ); + command->addContent( num, text ); + SequenceElement* parent = static_cast< SequenceElement* >( getParent() ); + if ( parent ) { + cursor->setTo( parent, parent->childPos( this ) + 1 ); + } + return command; + } + case req_addEmptyBox: + case req_addNameSequence: + case req_addBracket: + case req_addSpace: + case req_addFraction: + case req_addRoot: + case req_addSymbol: + case req_addOneByTwoMatrix: + case req_addMatrix: { + uint pos = static_cast(getParent())->childPos( this ); + cursor->setTo( getParent(), pos + 1); + return getParent()->buildCommand( container, request ); + } + default: + return SequenceElement::buildCommand( container, request ); + } + return 0; +} + + +bool OperatorElement::readAttributesFromMathMLDom( const TQDomElement &element ) +{ + if ( ! BasicElement::readAttributesFromMathMLDom( element ) ) { + return false; + } + + TQString formStr = element.attribute( "form" ).stripWhiteSpace().lower(); + if ( ! formStr.isNull() ) { + m_customForm = true; + if ( formStr == "prefix" ) { + m_form = PrefixForm; + } + else if ( formStr == "infix" ) { + m_form = InfixForm; + } + else if ( formStr == "postfix" ) { + m_form = PostfixForm; + } + else { + kdWarning( DEBUGID ) << "Invalid value for attribute `form': " << formStr << endl; + m_customForm = false; + } + } + TQString fenceStr = element.attribute( "fence" ).stripWhiteSpace().lower(); + if ( ! fenceStr.isNull() ) { + m_customFence = true; + if ( fenceStr == "true" ) { + m_fence = true; + } + else if ( fenceStr == "false" ) { + m_fence = false; + } + else { + kdWarning( DEBUGID ) << "Invalid value for attribute `fence': " << fenceStr << endl; + m_customFence = false; + } + } + TQString separatorStr = element.attribute( "separator" ).stripWhiteSpace().lower(); + if ( ! separatorStr.isNull() ) { + m_customSeparator = true; + if ( separatorStr == "true" ) { + m_separator = true; + } + else if ( separatorStr == "false" ) { + m_separator = false; + } + else { + kdWarning( DEBUGID ) << "Invalid value for attribute `separator': " << separatorStr << endl; + m_customSeparator = false; + } + } + TQString lspaceStr = element.attribute( "lspace" ).stripWhiteSpace().lower(); + if ( ! lspaceStr.isNull() ) { + m_customLSpace = true; + m_lspace = getSize( lspaceStr, &m_lspaceType ); + if ( m_lspaceType == NoSize ) { + m_lspaceType = getSpace( lspaceStr ); + } + } + TQString rspaceStr = element.attribute( "rspace" ).stripWhiteSpace().lower(); + if ( ! rspaceStr.isNull() ) { + m_customRSpace = true; + m_rspace = getSize( rspaceStr, &m_rspaceType ); + if ( m_rspaceType == NoSize ) { + m_rspaceType = getSpace( rspaceStr ); + } + } + TQString stretchyStr = element.attribute( "stretchy" ).stripWhiteSpace().lower(); + if ( ! stretchyStr.isNull() ) { + m_customStretchy = true; + if ( stretchyStr == "true" ) { + m_stretchy = true; + } + else if ( stretchyStr == "false" ) { + m_stretchy = false; + } + else { + kdWarning( DEBUGID ) << "Invalid value for attribute `stretchy': " << stretchyStr << endl; + m_customStretchy = false; + } + } + TQString symmetricStr = element.attribute( "symmetric" ).stripWhiteSpace().lower(); + if ( ! symmetricStr.isNull() ) { + m_customSymmetric = true; + if ( symmetricStr == "true" ) { + m_symmetric = true; + } + else if ( symmetricStr == "false" ) { + m_symmetric = false; + } + else { + kdWarning( DEBUGID ) << "Invalid value for attribute `symmetric': " << symmetricStr << endl; + m_customSymmetric = false; + } + } + TQString maxsizeStr = element.attribute( "maxsize" ).stripWhiteSpace().lower(); + if ( ! maxsizeStr.isNull() ) { + m_customMaxSize = true; + if ( maxsizeStr == "infinity" ) { + m_maxSizeType = InfinitySize; + } + else { + m_maxSize = getSize( maxsizeStr, &m_maxSizeType ); + if ( m_maxSizeType == NoSize ) { + m_maxSizeType = getSpace( maxsizeStr ); + } + } + } + TQString minsizeStr = element.attribute( "minsize" ).stripWhiteSpace().lower(); + if ( ! minsizeStr.isNull() ) { + m_customMinSize = true; + m_minSize = getSize( minsizeStr, &m_minSizeType ); + if ( m_minSizeType == NoSize ) { + m_minSizeType = getSpace( minsizeStr ); + } + } + TQString largeopStr = element.attribute( "largeop" ).stripWhiteSpace().lower(); + if ( ! largeopStr.isNull() ) { + m_customLargeOp = true; + if ( largeopStr == "true" ) { + m_largeOp = true; + } + else if ( largeopStr == "false" ) { + m_largeOp = false; + } + else { + kdWarning( DEBUGID ) << "Invalid value for attribute `largeop': " << largeopStr << endl; + m_customLargeOp = false; + } + } + TQString movablelimitsStr = element.attribute( "movablelimits" ).stripWhiteSpace().lower(); + if ( ! movablelimitsStr.isNull() ) { + m_customMovableLimits = true; + if ( movablelimitsStr == "true" ) { + m_movableLimits = true; + } + else if ( movablelimitsStr == "false" ) { + m_movableLimits = false; + } + else { + kdWarning( DEBUGID ) << "Invalid value for attribute `movablelimits': " << movablelimitsStr << endl; + m_customMovableLimits = false; + } + } + TQString accentStr = element.attribute( "accent" ).stripWhiteSpace().lower(); + if ( ! accentStr.isNull() ) { + m_customAccent = true; + if ( accentStr == "true" ) { + m_accent = true; + } + else if ( accentStr == "false" ) { + m_accent = false; + } + else { + kdWarning( DEBUGID ) << "Invalid value for attribute `accent': " << accentStr << endl; + m_customAccent = false; + } + } + return true; +} + +void OperatorElement::writeMathMLAttributes( TQDomElement& element ) const +{ + if ( m_customForm ) { + switch ( m_form ) { + case PrefixForm: + element.setAttribute( "form", "prefix" ); + break; + case InfixForm: + element.setAttribute( "form", "infix" ); + break; + case PostfixForm: + element.setAttribute( "form", "postfix" ); + default: + break; + } + } + if ( m_customFence ) { + element.setAttribute( "fence", m_fence ? "true" : "false" ); + } + if ( m_customSeparator ) { + element.setAttribute( "separator", m_separator ? "true" : "false" ); + } + if ( m_customLSpace ) { + writeSizeAttribute( element, "lspace", m_lspaceType, m_lspace ); + } + if ( m_customRSpace ) { + writeSizeAttribute( element, "rspace", m_rspaceType, m_rspace ); + } + if ( m_customStretchy ) { + element.setAttribute( "stretchy", m_stretchy ? "true" : "false" ); + } + if ( m_customSymmetric ) { + element.setAttribute( "symmetric", m_symmetric ? "true" : "false" ); + } + if ( m_customMaxSize ) { + writeSizeAttribute( element, "maxsize", m_maxSizeType, m_maxSize ); + } + if ( m_customMinSize ) { + writeSizeAttribute( element, "minsize", m_minSizeType, m_minSize ); + } + if ( m_customLargeOp ) { + element.setAttribute( "largeop", m_largeOp ? "true" : "false" ); + } + if ( m_customMovableLimits ) { + element.setAttribute( "movablelimits", m_movableLimits ? "true" : "false" ); + } + if ( m_customAccent ) { + element.setAttribute( "accent", m_accent ? "true" : "false" ); + } +} + +void OperatorElement::writeSizeAttribute( TQDomElement& element, const TQString &attr, SizeType type, double length ) const +{ + switch ( type ) { + case InfinitySize: + element.setAttribute( attr, "infinity" ); + break; + case AbsoluteSize: + element.setAttribute( attr, TQString( "%1pt" ).arg( length ) ); + break; + case RelativeSize: + element.setAttribute( attr, TQString( "%1% " ).arg( length * 100.0 ) ); + break; + case PixelSize: + element.setAttribute( attr, TQString( "%1px " ).arg( length ) ); + break; + case NegativeVeryVeryThinMathSpace: + element.setAttribute( attr, "negativeveryverythinmathspace" ); + break; + case NegativeVeryThinMathSpace: + element.setAttribute( attr, "negativeverythinmathspace" ); + break; + case NegativeThinMathSpace: + element.setAttribute( attr, "negativethinmathspace" ); + break; + case NegativeMediumMathSpace: + element.setAttribute( attr, "negativemediummathspace" ); + break; + case NegativeThickMathSpace: + element.setAttribute( attr, "negativethickmathspace" ); + break; + case NegativeVeryThickMathSpace: + element.setAttribute( attr, "negativeverythickmathspace" ); + break; + case NegativeVeryVeryThickMathSpace: + element.setAttribute( attr, "negativeveryverythickmathspace" ); + break; + case VeryVeryThinMathSpace: + element.setAttribute( attr, "veryverythinmathspace" ); + break; + case VeryThinMathSpace: + element.setAttribute( attr, "verythinmathspace" ); + break; + case ThinMathSpace: + element.setAttribute( attr, "thinmathspace" ); + break; + case MediumMathSpace: + element.setAttribute( attr, "mediummathspace" ); + break; + case ThickMathSpace: + element.setAttribute( attr, "thickmathspace" ); + break; + case VeryThickMathSpace: + element.setAttribute( attr, "verythickmathspace" ); + break; + case VeryVeryThickMathSpace: + element.setAttribute( attr, "veryverythickmathspace" ); + break; + default: + break; + } +} + + +KFORMULA_NAMESPACE_END diff --git a/lib/kformula/paddedelement.cc b/lib/kformula/paddedelement.cc deleted file mode 100644 index e4f28ce7..00000000 --- a/lib/kformula/paddedelement.cc +++ /dev/null @@ -1,296 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2006 Alfredo Beaumont Sainz - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - -#include "elementtype.h" -#include "paddedelement.h" - -KFORMULA_NAMESPACE_BEGIN - -PaddedElement::PaddedElement( BasicElement* parent ) : SequenceElement( parent ), - m_widthType( NoSize ), - m_lspaceType( NoSize ), - m_heightType( NoSize ), - m_depthType( NoSize ), - m_widthRelative( false ), - m_lspaceRelative( false ), - m_heightRelative( false ), - m_depthRelative( false ) -{ -} - -/** - * Calculates our width and height and - * our children's parentPosition. - */ -void PaddedElement::calcSizes( const ContextStyle& context, - ContextStyle::TextStyle tstyle, - ContextStyle::IndexStyle istyle, - StyleAttributes& style ) -{ - double factor = style.sizeFactor(); - - luPixel width = 0; - luPixel height = 0; - luPixel depth = 0; - - if ( !isEmpty() ) { - // First, get content height and width - for ( iterator it = begin(); it != end(); ++it ) { - luPixel spaceBefore = 0; - if ( it == begin() ) { - spaceBefore = context.ptToPixelX( getSpaceBefore( context, tstyle, factor ) ); - } - it->calcSizes( context, tstyle, istyle, style ); - width += it->getWidth() + spaceBefore; - luPixel baseline = it->getBaseline(); - if ( baseline > -1 ) { - height = TQMAX( height, baseline ); - depth = TQMAX( depth, it->getHeight() - baseline ); - } - else { - luPixel bl = it->getHeight()/2 + context.axisHeight( tstyle, factor ); - height = TQMAX( height, bl ); - depth = TQMAX( depth, it->getHeight() - bl ); - } - } - } - else { - width = context.getEmptyRectWidth( factor ); - height = context.getEmptyRectHeight( factor ); - depth = 0; - } - - luPixel left = calcSize( context, m_lspaceType, m_lspaceRelative, m_lspace, width, height, 0 ); - luPixel right = calcSize( context, m_widthType, m_widthRelative, m_width, width, height, width ) + left; - luPixel down = calcSize( context, m_depthType, m_depthRelative, m_depth, width, height, depth ); - luPixel up = calcSize( context, m_heightType, m_heightRelative, m_height, width, height, height ); - - // Check borders - if ( right < 0 ) right = 0; - if ( up + down < 0 ) up = down = 0; - - if ( ! isEmpty() ) { - width = left; - // Let's do all normal elements that have a base line. - for ( iterator it = begin(); it != end(); ++it ) { - luPixel spaceBefore = 0; - if ( it == begin() ) { - spaceBefore = context.ptToPixelX( getSpaceBefore( context, tstyle, factor ) ); - } - it->calcSizes( context, tstyle, istyle, style ); - it->setX( width + spaceBefore ); - width += it->getWidth() + spaceBefore; - } - - setWidth( right ); - setHeight( up + down ); - setBaseline( up ); - setChildrenPositions(); - } - else { - setWidth( right ); - setHeight( up + down ); - setBaseline( up ); - } -} - -bool PaddedElement::readAttributesFromMathMLDom(const TQDomElement& element) -{ - if ( ! BasicElement::readAttributesFromMathMLDom( element ) ) { - return false; - } - - TQString widthStr = element.attribute( "width" ).stripWhiteSpace().lower(); - if ( ! widthStr.isNull() ) { - m_width = readSizeAttribute( widthStr, &m_widthType, &m_widthRelative ); - } - TQString lspaceStr = element.attribute( "lspace" ).stripWhiteSpace().lower(); - if ( ! lspaceStr.isNull() ) { - m_lspace = readSizeAttribute( lspaceStr, &m_lspaceType, &m_lspaceRelative ); - } - TQString heightStr = element.attribute( "height" ).stripWhiteSpace().lower(); - if ( ! heightStr.isNull() ) { - m_height = readSizeAttribute( heightStr, &m_heightType, &m_heightRelative ); - } - TQString depthStr = element.attribute( "depth" ).stripWhiteSpace().lower(); - if ( ! depthStr.isNull() ) { - m_depth = readSizeAttribute( depthStr, &m_depthType, &m_depthRelative ); - } - - return true; -} - -void PaddedElement::writeMathMLAttributes( TQDomElement& element ) const -{ - writeSizeAttribute( element, "width", m_widthType, m_width, m_widthRelative ); - writeSizeAttribute( element, "lspace", m_lspaceType, m_lspace, m_lspaceRelative ); - writeSizeAttribute( element, "height", m_heightType, m_height, m_heightRelative ); - writeSizeAttribute( element, "depth", m_depthType, m_depth, m_depthRelative ); -} - -double PaddedElement::readSizeAttribute( const TQString& str, SizeType* st, bool* relative ) -{ - if ( st == 0 ){ - return -1; - } - if ( str[0] == '+' || str[0] == '-' ) { - *relative = true; - } - int index = str.find( "width" ); - if ( index != -1 ) { - int index2 = str.find( "%" ); - if ( index2 != -1 ) { - return str2size( str.left( index2 ).stripWhiteSpace(), st, WidthRelativeSize ) / 100.0; - } - return str2size( str.left( index ).stripWhiteSpace(), st, WidthRelativeSize ); - } - index = str.find( "height" ); - if ( index != -1 ) { - int index2 = str.find( "%" ); - if ( index2 != -1 ) { - return str2size( str.left( index2 ).stripWhiteSpace(), st, HeightRelativeSize ) / 100.0; - } - return str2size( str.left( index ).stripWhiteSpace(), st, HeightRelativeSize ); - } - index = str.find( "%" ); - if ( index != -1 ) { - return str2size( str.left( index ).stripWhiteSpace(), st, RelativeSize ) / 100.0; - } - index = str.find( "pt", 0, false ); - if ( index != -1 ) { - return str2size( str.left( index ).stripWhiteSpace(), st, AbsoluteSize ); - } - index = str.find( "mm", 0, false ); - if ( index != -1 ) { - return str2size( str.left( index ).stripWhiteSpace(), st, AbsoluteSize ) * 72.0 / 20.54; - } - index = str.find( "cm", 0, false ); - if ( index != -1 ) { - return str2size( str.left( index ).stripWhiteSpace(), st, AbsoluteSize ) * 72.0 / 2.54; - } - index = str.find( "in", 0, false ); - if ( index != -1 ) { - return str2size( str.left( index ).stripWhiteSpace(), st, AbsoluteSize ) * 72.0; - } - index = str.find( "em", 0, false ); - if ( index != -1 ) { - return str2size( str.left( index ).stripWhiteSpace(), st, RelativeSize ); - } - index = str.find( "ex", 0, false ); - if ( index != -1 ) { - return str2size( str.left( index ).stripWhiteSpace(), st, RelativeSize ); - } - index = str.find( "pc", 0, false ); - if ( index != -1 ) { - return str2size( str.left( index ).stripWhiteSpace(), st, AbsoluteSize ) * 12.0; - } - index = str.find( "px", 0, false ); - if ( index != -1 ) { - return str2size( str.left( index ).stripWhiteSpace(), st, PixelSize ); - } - // If there's no unit, assume 'pt' - return str2size( str, st, AbsoluteSize ); -} - -double PaddedElement::str2size( const TQString& str, SizeType *st, SizeType type ) -{ - bool ok; - double size = str.toDouble( &ok ); - if ( ok ) { - if ( st ) { - *st = type; - } - return size; - } - if ( st ) { - *st = NoSize; - } - return -1; -} - -void PaddedElement::writeSizeAttribute( TQDomElement element, const TQString& str, - SizeType st, bool relative, double s ) const -{ - TQString prefix; - if ( relative ) { - s < 0 ? prefix = "-" : prefix = "+" ; - } - switch ( st ) { - case WidthRelativeSize: - element.setAttribute( str, prefix + TQString( "%1 width" ).arg( s ) ); - break; - case HeightRelativeSize: - element.setAttribute( str, prefix + TQString( "%1 height" ).arg( s ) ); - case AbsoluteSize: - element.setAttribute( str, prefix + TQString( "%1pt" ).arg( s ) ); - break; - case RelativeSize: - element.setAttribute( str, prefix + TQString( "%1%" ).arg( s * 100.0 ) ); - break; - case PixelSize: - element.setAttribute( str, prefix + TQString( "%1px" ).arg( s ) ); - break; - default: - break; - } -} - -luPixel PaddedElement::calcSize( const ContextStyle& context, SizeType type, - bool relative, double length, luPixel width, - luPixel height, luPixel defvalue ) -{ - luPixel value = defvalue; - switch ( type ) { - case AbsoluteSize: - if ( relative ) - value += context.ptToLayoutUnitPt ( length ); - else - value = context.ptToLayoutUnitPt( length ); - break; - case RelativeSize: - if ( relative ) - value += length * value; - else - value *= length; - break; - case WidthRelativeSize: - if ( relative ) - value += length * width; - else - value = length * width; - break; - case HeightRelativeSize: - if ( relative ) - value += length * height; - else - value = length * height; - break; - case PixelSize: - if ( relative ) - value += context.pixelToLayoutUnitX( length ); - else - value = context.pixelToLayoutUnitX( length ); - break; - default: - break; - } - return value; -} - -KFORMULA_NAMESPACE_END diff --git a/lib/kformula/paddedelement.cpp b/lib/kformula/paddedelement.cpp new file mode 100644 index 00000000..e4f28ce7 --- /dev/null +++ b/lib/kformula/paddedelement.cpp @@ -0,0 +1,296 @@ +/* This file is part of the KDE project + Copyright (C) 2006 Alfredo Beaumont Sainz + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "elementtype.h" +#include "paddedelement.h" + +KFORMULA_NAMESPACE_BEGIN + +PaddedElement::PaddedElement( BasicElement* parent ) : SequenceElement( parent ), + m_widthType( NoSize ), + m_lspaceType( NoSize ), + m_heightType( NoSize ), + m_depthType( NoSize ), + m_widthRelative( false ), + m_lspaceRelative( false ), + m_heightRelative( false ), + m_depthRelative( false ) +{ +} + +/** + * Calculates our width and height and + * our children's parentPosition. + */ +void PaddedElement::calcSizes( const ContextStyle& context, + ContextStyle::TextStyle tstyle, + ContextStyle::IndexStyle istyle, + StyleAttributes& style ) +{ + double factor = style.sizeFactor(); + + luPixel width = 0; + luPixel height = 0; + luPixel depth = 0; + + if ( !isEmpty() ) { + // First, get content height and width + for ( iterator it = begin(); it != end(); ++it ) { + luPixel spaceBefore = 0; + if ( it == begin() ) { + spaceBefore = context.ptToPixelX( getSpaceBefore( context, tstyle, factor ) ); + } + it->calcSizes( context, tstyle, istyle, style ); + width += it->getWidth() + spaceBefore; + luPixel baseline = it->getBaseline(); + if ( baseline > -1 ) { + height = TQMAX( height, baseline ); + depth = TQMAX( depth, it->getHeight() - baseline ); + } + else { + luPixel bl = it->getHeight()/2 + context.axisHeight( tstyle, factor ); + height = TQMAX( height, bl ); + depth = TQMAX( depth, it->getHeight() - bl ); + } + } + } + else { + width = context.getEmptyRectWidth( factor ); + height = context.getEmptyRectHeight( factor ); + depth = 0; + } + + luPixel left = calcSize( context, m_lspaceType, m_lspaceRelative, m_lspace, width, height, 0 ); + luPixel right = calcSize( context, m_widthType, m_widthRelative, m_width, width, height, width ) + left; + luPixel down = calcSize( context, m_depthType, m_depthRelative, m_depth, width, height, depth ); + luPixel up = calcSize( context, m_heightType, m_heightRelative, m_height, width, height, height ); + + // Check borders + if ( right < 0 ) right = 0; + if ( up + down < 0 ) up = down = 0; + + if ( ! isEmpty() ) { + width = left; + // Let's do all normal elements that have a base line. + for ( iterator it = begin(); it != end(); ++it ) { + luPixel spaceBefore = 0; + if ( it == begin() ) { + spaceBefore = context.ptToPixelX( getSpaceBefore( context, tstyle, factor ) ); + } + it->calcSizes( context, tstyle, istyle, style ); + it->setX( width + spaceBefore ); + width += it->getWidth() + spaceBefore; + } + + setWidth( right ); + setHeight( up + down ); + setBaseline( up ); + setChildrenPositions(); + } + else { + setWidth( right ); + setHeight( up + down ); + setBaseline( up ); + } +} + +bool PaddedElement::readAttributesFromMathMLDom(const TQDomElement& element) +{ + if ( ! BasicElement::readAttributesFromMathMLDom( element ) ) { + return false; + } + + TQString widthStr = element.attribute( "width" ).stripWhiteSpace().lower(); + if ( ! widthStr.isNull() ) { + m_width = readSizeAttribute( widthStr, &m_widthType, &m_widthRelative ); + } + TQString lspaceStr = element.attribute( "lspace" ).stripWhiteSpace().lower(); + if ( ! lspaceStr.isNull() ) { + m_lspace = readSizeAttribute( lspaceStr, &m_lspaceType, &m_lspaceRelative ); + } + TQString heightStr = element.attribute( "height" ).stripWhiteSpace().lower(); + if ( ! heightStr.isNull() ) { + m_height = readSizeAttribute( heightStr, &m_heightType, &m_heightRelative ); + } + TQString depthStr = element.attribute( "depth" ).stripWhiteSpace().lower(); + if ( ! depthStr.isNull() ) { + m_depth = readSizeAttribute( depthStr, &m_depthType, &m_depthRelative ); + } + + return true; +} + +void PaddedElement::writeMathMLAttributes( TQDomElement& element ) const +{ + writeSizeAttribute( element, "width", m_widthType, m_width, m_widthRelative ); + writeSizeAttribute( element, "lspace", m_lspaceType, m_lspace, m_lspaceRelative ); + writeSizeAttribute( element, "height", m_heightType, m_height, m_heightRelative ); + writeSizeAttribute( element, "depth", m_depthType, m_depth, m_depthRelative ); +} + +double PaddedElement::readSizeAttribute( const TQString& str, SizeType* st, bool* relative ) +{ + if ( st == 0 ){ + return -1; + } + if ( str[0] == '+' || str[0] == '-' ) { + *relative = true; + } + int index = str.find( "width" ); + if ( index != -1 ) { + int index2 = str.find( "%" ); + if ( index2 != -1 ) { + return str2size( str.left( index2 ).stripWhiteSpace(), st, WidthRelativeSize ) / 100.0; + } + return str2size( str.left( index ).stripWhiteSpace(), st, WidthRelativeSize ); + } + index = str.find( "height" ); + if ( index != -1 ) { + int index2 = str.find( "%" ); + if ( index2 != -1 ) { + return str2size( str.left( index2 ).stripWhiteSpace(), st, HeightRelativeSize ) / 100.0; + } + return str2size( str.left( index ).stripWhiteSpace(), st, HeightRelativeSize ); + } + index = str.find( "%" ); + if ( index != -1 ) { + return str2size( str.left( index ).stripWhiteSpace(), st, RelativeSize ) / 100.0; + } + index = str.find( "pt", 0, false ); + if ( index != -1 ) { + return str2size( str.left( index ).stripWhiteSpace(), st, AbsoluteSize ); + } + index = str.find( "mm", 0, false ); + if ( index != -1 ) { + return str2size( str.left( index ).stripWhiteSpace(), st, AbsoluteSize ) * 72.0 / 20.54; + } + index = str.find( "cm", 0, false ); + if ( index != -1 ) { + return str2size( str.left( index ).stripWhiteSpace(), st, AbsoluteSize ) * 72.0 / 2.54; + } + index = str.find( "in", 0, false ); + if ( index != -1 ) { + return str2size( str.left( index ).stripWhiteSpace(), st, AbsoluteSize ) * 72.0; + } + index = str.find( "em", 0, false ); + if ( index != -1 ) { + return str2size( str.left( index ).stripWhiteSpace(), st, RelativeSize ); + } + index = str.find( "ex", 0, false ); + if ( index != -1 ) { + return str2size( str.left( index ).stripWhiteSpace(), st, RelativeSize ); + } + index = str.find( "pc", 0, false ); + if ( index != -1 ) { + return str2size( str.left( index ).stripWhiteSpace(), st, AbsoluteSize ) * 12.0; + } + index = str.find( "px", 0, false ); + if ( index != -1 ) { + return str2size( str.left( index ).stripWhiteSpace(), st, PixelSize ); + } + // If there's no unit, assume 'pt' + return str2size( str, st, AbsoluteSize ); +} + +double PaddedElement::str2size( const TQString& str, SizeType *st, SizeType type ) +{ + bool ok; + double size = str.toDouble( &ok ); + if ( ok ) { + if ( st ) { + *st = type; + } + return size; + } + if ( st ) { + *st = NoSize; + } + return -1; +} + +void PaddedElement::writeSizeAttribute( TQDomElement element, const TQString& str, + SizeType st, bool relative, double s ) const +{ + TQString prefix; + if ( relative ) { + s < 0 ? prefix = "-" : prefix = "+" ; + } + switch ( st ) { + case WidthRelativeSize: + element.setAttribute( str, prefix + TQString( "%1 width" ).arg( s ) ); + break; + case HeightRelativeSize: + element.setAttribute( str, prefix + TQString( "%1 height" ).arg( s ) ); + case AbsoluteSize: + element.setAttribute( str, prefix + TQString( "%1pt" ).arg( s ) ); + break; + case RelativeSize: + element.setAttribute( str, prefix + TQString( "%1%" ).arg( s * 100.0 ) ); + break; + case PixelSize: + element.setAttribute( str, prefix + TQString( "%1px" ).arg( s ) ); + break; + default: + break; + } +} + +luPixel PaddedElement::calcSize( const ContextStyle& context, SizeType type, + bool relative, double length, luPixel width, + luPixel height, luPixel defvalue ) +{ + luPixel value = defvalue; + switch ( type ) { + case AbsoluteSize: + if ( relative ) + value += context.ptToLayoutUnitPt ( length ); + else + value = context.ptToLayoutUnitPt( length ); + break; + case RelativeSize: + if ( relative ) + value += length * value; + else + value *= length; + break; + case WidthRelativeSize: + if ( relative ) + value += length * width; + else + value = length * width; + break; + case HeightRelativeSize: + if ( relative ) + value += length * height; + else + value = length * height; + break; + case PixelSize: + if ( relative ) + value += context.pixelToLayoutUnitX( length ); + else + value = context.pixelToLayoutUnitX( length ); + break; + default: + break; + } + return value; +} + +KFORMULA_NAMESPACE_END diff --git a/lib/kformula/phantomelement.cc b/lib/kformula/phantomelement.cc deleted file mode 100644 index 78b0a1cb..00000000 --- a/lib/kformula/phantomelement.cc +++ /dev/null @@ -1,39 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2006 Alfredo Beaumont Sainz - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - -#include "phantomelement.h" - -KFORMULA_NAMESPACE_BEGIN - -PhantomElement::PhantomElement( BasicElement* parent ) : SequenceElement( parent ) -{ -} - -/** - * Draws the whole element including its children. - * The `parentOrigin' is the point this element's parent starts. - * We can use our parentPosition to get our own origin then. - */ -void PhantomElement::draw( TQPainter&, const LuPixelRect&, const ContextStyle&, - ContextStyle::TextStyle, ContextStyle::IndexStyle, - StyleAttributes&, const LuPixelPoint& ) -{ -} - -KFORMULA_NAMESPACE_END diff --git a/lib/kformula/phantomelement.cpp b/lib/kformula/phantomelement.cpp new file mode 100644 index 00000000..78b0a1cb --- /dev/null +++ b/lib/kformula/phantomelement.cpp @@ -0,0 +1,39 @@ +/* This file is part of the KDE project + Copyright (C) 2006 Alfredo Beaumont Sainz + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "phantomelement.h" + +KFORMULA_NAMESPACE_BEGIN + +PhantomElement::PhantomElement( BasicElement* parent ) : SequenceElement( parent ) +{ +} + +/** + * Draws the whole element including its children. + * The `parentOrigin' is the point this element's parent starts. + * We can use our parentPosition to get our own origin then. + */ +void PhantomElement::draw( TQPainter&, const LuPixelRect&, const ContextStyle&, + ContextStyle::TextStyle, ContextStyle::IndexStyle, + StyleAttributes&, const LuPixelPoint& ) +{ +} + +KFORMULA_NAMESPACE_END diff --git a/lib/kformula/prototype/gensymbolfontmap.py b/lib/kformula/prototype/gensymbolfontmap.py index a1373815..df06eeed 100644 --- a/lib/kformula/prototype/gensymbolfontmap.py +++ b/lib/kformula/prototype/gensymbolfontmap.py @@ -62,12 +62,12 @@ def write_header(f): ''' def main(): - f = open('../symbolfontmapping.cc', 'w') + f = open('../symbolfontmapping.cpp', 'w') write_header(f) writeFontTable("symbol", f) f.close() - f = open('../esstixfontmapping.cc', 'w') + f = open('../esstixfontmapping.cpp', 'w') write_header(f) fontnames = [ "esstixnine", "esstixthirteen", @@ -90,7 +90,7 @@ def main(): writeFontTable(fn, f) f.close() - f = open('../cmmapping.cc', 'w') + f = open('../cmmapping.cpp', 'w') write_header(f) fontnames = [ "cmbx10", "cmex10", @@ -107,7 +107,7 @@ def main(): writeFontTable(fn, f) f.close() - f = open('../unicodenames.cc', 'w') + f = open('../unicodenames.cpp', 'w') write_header(f) print >>f, 'struct UnicodeNameTable { short unicode; const char* name; };' print >>f, 'static UnicodeNameTable nameTable[] = {' diff --git a/lib/kformula/rootelement.cc b/lib/kformula/rootelement.cc deleted file mode 100644 index 5e511cbe..00000000 --- a/lib/kformula/rootelement.cc +++ /dev/null @@ -1,680 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2001 Andrea Rizzi - Ulrich Kuettler - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - -#include -#include - -#include -#include - -#include "elementvisitor.h" -#include "formulacursor.h" -#include "formulaelement.h" -#include "kformulacommand.h" -#include "rootelement.h" -#include "sequenceelement.h" - -KFORMULA_NAMESPACE_BEGIN - - -class RootSequenceElement : public SequenceElement { - typedef SequenceElement inherited; -public: - - RootSequenceElement( BasicElement* parent = 0 ) : SequenceElement( parent ) {} - virtual RootSequenceElement* clone() { - return new RootSequenceElement( *this ); - } - - /** - * This is called by the container to get a command depending on - * the current cursor position (this is how the element gets chosen) - * and the request. - * - * @returns the command that performs the requested action with - * the containers active cursor. - */ - virtual KCommand* buildCommand( Container*, Request* ); -}; - - -KCommand* RootSequenceElement::buildCommand( Container* container, Request* request ) -{ - FormulaCursor* cursor = container->activeCursor(); - if ( cursor->isReadOnly() ) { - return 0; - } - - switch ( *request ) { - case req_addIndex: { - FormulaCursor* cursor = container->activeCursor(); - if ( cursor->isSelection() || - ( cursor->getPos() > 0 && cursor->getPos() < countChildren() ) ) { - break; - } - IndexRequest* ir = static_cast( request ); - if ( ir->index() == upperLeftPos ) { - RootElement* element = static_cast( getParent() ); - ElementIndexPtr index = element->getIndex(); - if ( !index->hasIndex() ) { - KFCAddGenericIndex* command = new KFCAddGenericIndex( container, index ); - return command; - } - else { - index->moveToIndex( cursor, afterCursor ); - cursor->setSelection( false ); - formula()->cursorHasMoved( cursor ); - return 0; - } - } - } - default: - break; - } - return inherited::buildCommand( container, request ); -} - - -RootElement::RootElement(BasicElement* parent) - : BasicElement(parent) -{ - content = new RootSequenceElement( this ); - index = 0; -} - -RootElement::~RootElement() -{ - delete index; - delete content; -} - - -RootElement::RootElement( const RootElement& other ) - : BasicElement( other ) -{ - content = new RootSequenceElement( *dynamic_cast( other.content ) ); - if ( other.index ) { - index = new SequenceElement( *( other.index ) ); - index->setParent( this ); - } - else { - index = 0; - } -} - - -bool RootElement::accept( ElementVisitor* visitor ) -{ - return visitor->visit( this ); -} - - -void RootElement::entered( SequenceElement* child ) -{ - if ( child == content ) { - formula()->tell( i18n( "Main list of root" ) ); - } - else { - formula()->tell( i18n( "Index" ) ); - } -} - - -BasicElement* RootElement::goToPos( FormulaCursor* cursor, bool& handled, - const LuPixelPoint& point, const LuPixelPoint& parentOrigin) -{ - BasicElement* e = BasicElement::goToPos(cursor, handled, point, parentOrigin); - if (e != 0) { - LuPixelPoint myPos(parentOrigin.x() + getX(), - parentOrigin.y() + getY()); - - e = content->goToPos(cursor, handled, point, myPos); - if (e != 0) { - return e; - } - if (hasIndex()) { - e = index->goToPos(cursor, handled, point, myPos); - if (e != 0) { - return e; - } - } - - //int dx = point.x() - myPos.x(); - luPixel dy = point.y() - myPos.y(); - - // the position after the index - if (hasIndex()) { - if (dy < index->getHeight()) { - index->moveLeft(cursor, this); - handled = true; - return index; - } - } - - return this; - } - return 0; -} - - -/** - * Calculates our width and height and - * our children's parentPosition. - */ -void RootElement::calcSizes( const ContextStyle& context, - ContextStyle::TextStyle tstyle, - ContextStyle::IndexStyle istyle, - StyleAttributes& style ) -{ - content->calcSizes( context, tstyle, - context.convertIndexStyleLower(istyle), style ); - - luPixel indexWidth = 0; - luPixel indexHeight = 0; - if (hasIndex()) { - index->calcSizes( context, - context.convertTextStyleIndex(tstyle), - context.convertIndexStyleUpper(istyle), - style ); - indexWidth = index->getWidth(); - indexHeight = index->getHeight(); - } - - double factor = style.sizeFactor(); - luPixel distX = context.ptToPixelX( context.getThinSpace( tstyle, factor ) ); - luPixel distY = context.ptToPixelY( context.getThinSpace( tstyle, factor ) ); - luPixel unit = (content->getHeight() + distY)/ 3; - - if (hasIndex()) { - if (indexWidth > unit) { - index->setX(0); - rootOffset.setX( indexWidth - unit ); - } - else { - index->setX( ( unit - indexWidth )/2 ); - rootOffset.setX(0); - } - if (indexHeight > unit) { - index->setY(0); - rootOffset.setY( indexHeight - unit ); - } - else { - index->setY( unit - indexHeight ); - rootOffset.setY(0); - } - } - else { - rootOffset.setX(0); - rootOffset.setY(0); - } - - setWidth( content->getWidth() + unit+unit/3+ rootOffset.x() + distX/2 ); - setHeight( content->getHeight() + distY*2 + rootOffset.y() ); - - content->setX( rootOffset.x() + unit+unit/3 ); - content->setY( rootOffset.y() + distY ); - setBaseline(content->getBaseline() + content->getY()); -} - -/** - * Draws the whole element including its children. - * The `parentOrigin' is the point this element's parent starts. - * We can use our parentPosition to get our own origin then. - */ -void RootElement::draw( TQPainter& painter, const LuPixelRect& r, - const ContextStyle& context, - ContextStyle::TextStyle tstyle, - ContextStyle::IndexStyle istyle, - StyleAttributes& style, - const LuPixelPoint& parentOrigin ) -{ - LuPixelPoint myPos( parentOrigin.x()+getX(), parentOrigin.y()+getY() ); - //if ( !LuPixelRect( myPos.x(), myPos.y(), getWidth(), getHeight() ).intersects( r ) ) - // return; - - content->draw( painter, r, context, tstyle, - context.convertIndexStyleLower(istyle), style, myPos); - if (hasIndex()) { - index->draw(painter, r, context, - context.convertTextStyleIndex(tstyle), - context.convertIndexStyleUpper(istyle), style, myPos); - } - - luPixel x = myPos.x() + rootOffset.x(); - luPixel y = myPos.y() + rootOffset.y(); - //int distX = context.getDistanceX(tstyle); - double factor = style.sizeFactor(); - luPixel distY = context.ptToPixelY( context.getThinSpace( tstyle, factor ) ); - luPixel unit = (content->getHeight() + distY)/ 3; - - painter.setPen( TQPen( style.color(), - context.layoutUnitToPixelX( 2*context.getLineWidth( factor ) ) ) ); - painter.drawLine( context.layoutUnitToPixelX( x+unit/3 ), - context.layoutUnitToPixelY( y+unit+distY/3 ), - context.layoutUnitToPixelX( x+unit/2+unit/3 ), - context.layoutUnitToPixelY( myPos.y()+getHeight() ) ); - - painter.setPen( TQPen( style.color(), - context.layoutUnitToPixelY( context.getLineWidth( factor ) ) ) ); - - painter.drawLine( context.layoutUnitToPixelX( x+unit+unit/3 ), - context.layoutUnitToPixelY( y+distY/3 ), - context.layoutUnitToPixelX( x+unit/2+unit/3 ), - context.layoutUnitToPixelY( myPos.y()+getHeight() ) ); - painter.drawLine( context.layoutUnitToPixelX( x+unit+unit/3 ), - context.layoutUnitToPixelY( y+distY/3 ), - context.layoutUnitToPixelX( x+unit+unit/3+content->getWidth() ), - context.layoutUnitToPixelY( y+distY/3 ) ); - painter.drawLine( context.layoutUnitToPixelX( x+unit/3 ), - context.layoutUnitToPixelY( y+unit+distY/2 ), - context.layoutUnitToPixelX( x ), - context.layoutUnitToPixelY( y+unit+unit/2 ) ); -} - - -void RootElement::dispatchFontCommand( FontCommand* cmd ) -{ - content->dispatchFontCommand( cmd ); - if (hasIndex()) { - index->dispatchFontCommand( cmd ); - } -} - -/** - * Enters this element while moving to the left starting inside - * the element `from'. Searches for a cursor position inside - * this element or to the left of it. - */ -void RootElement::moveLeft(FormulaCursor* cursor, BasicElement* from) -{ - if (cursor->isSelectionMode()) { - getParent()->moveLeft(cursor, this); - } - else { - bool linear = cursor->getLinearMovement(); - if (from == getParent()) { - content->moveLeft(cursor, this); - } - else if (from == content) { - if (linear && hasIndex()) { - index->moveLeft(cursor, this); - } - else { - getParent()->moveLeft(cursor, this); - } - } - else { - getParent()->moveLeft(cursor, this); - } - } -} - -/** - * Enters this element while moving to the right starting inside - * the element `from'. Searches for a cursor position inside - * this element or to the right of it. - */ -void RootElement::moveRight(FormulaCursor* cursor, BasicElement* from) -{ - if (cursor->isSelectionMode()) { - getParent()->moveRight(cursor, this); - } - else { - bool linear = cursor->getLinearMovement(); - if (from == getParent()) { - if (linear && hasIndex()) { - index->moveRight(cursor, this); - } - else { - content->moveRight(cursor, this); - } - } - else if (from == index) { - content->moveRight(cursor, this); - } - else { - getParent()->moveRight(cursor, this); - } - } -} - -/** - * Enters this element while moving up starting inside - * the element `from'. Searches for a cursor position inside - * this element or above it. - */ -void RootElement::moveUp(FormulaCursor* cursor, BasicElement* from) -{ - if (cursor->isSelectionMode()) { - getParent()->moveUp(cursor, this); - } - else { - if (from == getParent()) { - content->moveRight(cursor, this); - } - else if (from == content) { - if (hasIndex()) { - index->moveRight(cursor, this); - } - else { - getParent()->moveUp(cursor, this); - } - } - else { - getParent()->moveUp(cursor, this); - } - } -} - -/** - * Enters this element while moving down starting inside - * the element `from'. Searches for a cursor position inside - * this element or below it. - */ -void RootElement::moveDown(FormulaCursor* cursor, BasicElement* from) -{ - if (cursor->isSelectionMode()) { - getParent()->moveDown(cursor, this); - } - else { - if (from == getParent()) { - if (hasIndex()) { - index->moveRight(cursor, this); - } - else { - content->moveRight(cursor, this); - } - } - else if (from == index) { - content->moveRight(cursor, this); - } - else { - getParent()->moveDown(cursor, this); - } - } -} - -/** - * Reinserts the index if it has been removed. - */ -void RootElement::insert(FormulaCursor* cursor, - TQPtrList& newChildren, - Direction direction) -{ - if (cursor->getPos() == upperLeftPos) { - index = static_cast(newChildren.take(0)); - index->setParent(this); - - if (direction == beforeCursor) { - index->moveLeft(cursor, this); - } - else { - index->moveRight(cursor, this); - } - cursor->setSelection(false); - formula()->changed(); - } -} - -/** - * Removes all selected children and returns them. Places the - * cursor to where the children have been. - * - * We remove ourselve if we are requested to remove our content. - */ -void RootElement::remove(FormulaCursor* cursor, - TQPtrList& removedChildren, - Direction direction) -{ - switch (cursor->getPos()) { - case contentPos: - getParent()->selectChild(cursor, this); - getParent()->remove(cursor, removedChildren, direction); - break; - case upperLeftPos: - removedChildren.append(index); - formula()->elementRemoval(index); - index = 0; - cursor->setTo(this, upperLeftPos); - formula()->changed(); - break; - } -} - - -/** - * Moves the cursor to a normal place where new elements - * might be inserted. - */ -void RootElement::normalize(FormulaCursor* cursor, Direction direction) -{ - if (direction == beforeCursor) { - content->moveLeft(cursor, this); - } - else { - content->moveRight(cursor, this); - } -} - - -// main child -// -// If an element has children one has to become the main one. - -SequenceElement* RootElement::getMainChild() -{ - return content; -} - -// void RootElement::setMainChild(SequenceElement* child) -// { -// formula()->elementRemoval(content); -// content = child; -// content->setParent(this); -// formula()->changed(); -// } - - -/** - * Sets the cursor to select the child. The mark is placed before, - * the position behind it. - */ -void RootElement::selectChild(FormulaCursor* cursor, BasicElement* child) -{ - if (child == content) { - cursor->setTo(this, contentPos); - } - else if (child == index) { - cursor->setTo(this, upperLeftPos); - } -} - - -void RootElement::moveToIndex(FormulaCursor* cursor, Direction direction) -{ - if (hasIndex()) { - if (direction == beforeCursor) { - index->moveLeft(cursor, this); - } - else { - index->moveRight(cursor, this); - } - } -} - -void RootElement::setToIndex(FormulaCursor* cursor) -{ - cursor->setTo(this, upperLeftPos); -} - - -/** - * Appends our attributes to the dom element. - */ -void RootElement::writeDom(TQDomElement element) -{ - BasicElement::writeDom(element); - - TQDomDocument doc = element.ownerDocument(); - - TQDomElement con = doc.createElement("CONTENT"); - con.appendChild(content->getElementDom(doc)); - element.appendChild(con); - - if(hasIndex()) { - TQDomElement ind = doc.createElement("ROOTINDEX"); - ind.appendChild(index->getElementDom(doc)); - element.appendChild(ind); - } -} - -/** - * Reads our attributes from the element. - * Returns false if it failed. - */ -bool RootElement::readAttributesFromDom(TQDomElement element) -{ - return BasicElement::readAttributesFromDom(element); -} - -/** - * Reads our content from the node. Sets the node to the next node - * that needs to be read. - * Returns false if it failed. - */ -bool RootElement::readContentFromDom(TQDomNode& node) -{ - if (!BasicElement::readContentFromDom(node)) { - return false; - } - - if ( !buildChild( content, node, "CONTENT" ) ) { - kdWarning( DEBUGID ) << "Empty content in RootElement." << endl; - return false; - } - node = node.nextSibling(); - - if ( node.nodeName().upper() == "ROOTINDEX" ) { - if ( !buildChild( index=new SequenceElement( this ), node, "ROOTINDEX" ) ) { - return false; - } - } - // backward compatibility - else if ( node.nodeName().upper() == "INDEX" ) { - if ( !buildChild( index=new SequenceElement( this ), node, "INDEX" ) ) { - return false; - } - } - node = node.nextSibling(); - - return true; -} - -/** - * Reads our attributes from the MathML element. - * Also checks whether it's a msqrt or mroot. - * Returns false if it failed. - */ -bool RootElement::readAttributesFromMathMLDom(const TQDomElement& element) -{ - if ( element.tagName().lower() == "mroot" ) - square = false; - else - square = true; - return true; -} - - -/** - * Reads our content from the MathML node. Sets the node to the next node - * that needs to be read. - * Returns false if it failed. - */ -int RootElement::readContentFromMathMLDom(TQDomNode& node) -{ - if ( BasicElement::readContentFromMathMLDom( node ) == -1 ) { - return -1; - } - - if ( square ) { - // Any number of arguments are allowed - if ( content->readContentFromMathMLDom( node ) == -1 ) { - kdWarning( DEBUGID ) << "Empty content in RootElement." << endl; - return -1; - } - } - else { - // Exactly two arguments are required - int contentNumber = content->buildMathMLChild( node ); - if ( contentNumber == -1 ) { - kdWarning( DEBUGID ) << "Empty content in RootElement." << endl; - return -1; - } - for (int i = 0; i < contentNumber; i++ ) { - if ( node.isNull() ) { - return -1; - } - node = node.nextSibling(); - } - - index = new SequenceElement( this ); - if ( index->buildMathMLChild( node ) == -1 ) { - kdWarning( DEBUGID ) << "Empty index in RootElement." << endl; - return -1; - } - } - - return 1; -} - -TQString RootElement::toLatex() -{ - TQString root; - root="\\sqrt"; - if(hasIndex()) { - root+="["; - root+=index->toLatex(); - root+="]"; - } - root+="{"; - root+=content->toLatex(); - root+="}"; - - return root; -} - -TQString RootElement::formulaString() -{ - if ( hasIndex() ) { - return "(" + content->formulaString() + ")**(1.0/(" + index->formulaString() + "))"; - } - return "sqrt(" + content->formulaString() + ")"; -} - -void RootElement::writeMathMLContent( TQDomDocument& doc, TQDomElement& element, bool oasisFormat ) const -{ - content->writeMathML( doc, element, oasisFormat ); - if( hasIndex() ) - { - index->writeMathML( doc, element, oasisFormat ); - } -} - -KFORMULA_NAMESPACE_END diff --git a/lib/kformula/rootelement.cpp b/lib/kformula/rootelement.cpp new file mode 100644 index 00000000..5e511cbe --- /dev/null +++ b/lib/kformula/rootelement.cpp @@ -0,0 +1,680 @@ +/* This file is part of the KDE project + Copyright (C) 2001 Andrea Rizzi + Ulrich Kuettler + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include + +#include +#include + +#include "elementvisitor.h" +#include "formulacursor.h" +#include "formulaelement.h" +#include "kformulacommand.h" +#include "rootelement.h" +#include "sequenceelement.h" + +KFORMULA_NAMESPACE_BEGIN + + +class RootSequenceElement : public SequenceElement { + typedef SequenceElement inherited; +public: + + RootSequenceElement( BasicElement* parent = 0 ) : SequenceElement( parent ) {} + virtual RootSequenceElement* clone() { + return new RootSequenceElement( *this ); + } + + /** + * This is called by the container to get a command depending on + * the current cursor position (this is how the element gets chosen) + * and the request. + * + * @returns the command that performs the requested action with + * the containers active cursor. + */ + virtual KCommand* buildCommand( Container*, Request* ); +}; + + +KCommand* RootSequenceElement::buildCommand( Container* container, Request* request ) +{ + FormulaCursor* cursor = container->activeCursor(); + if ( cursor->isReadOnly() ) { + return 0; + } + + switch ( *request ) { + case req_addIndex: { + FormulaCursor* cursor = container->activeCursor(); + if ( cursor->isSelection() || + ( cursor->getPos() > 0 && cursor->getPos() < countChildren() ) ) { + break; + } + IndexRequest* ir = static_cast( request ); + if ( ir->index() == upperLeftPos ) { + RootElement* element = static_cast( getParent() ); + ElementIndexPtr index = element->getIndex(); + if ( !index->hasIndex() ) { + KFCAddGenericIndex* command = new KFCAddGenericIndex( container, index ); + return command; + } + else { + index->moveToIndex( cursor, afterCursor ); + cursor->setSelection( false ); + formula()->cursorHasMoved( cursor ); + return 0; + } + } + } + default: + break; + } + return inherited::buildCommand( container, request ); +} + + +RootElement::RootElement(BasicElement* parent) + : BasicElement(parent) +{ + content = new RootSequenceElement( this ); + index = 0; +} + +RootElement::~RootElement() +{ + delete index; + delete content; +} + + +RootElement::RootElement( const RootElement& other ) + : BasicElement( other ) +{ + content = new RootSequenceElement( *dynamic_cast( other.content ) ); + if ( other.index ) { + index = new SequenceElement( *( other.index ) ); + index->setParent( this ); + } + else { + index = 0; + } +} + + +bool RootElement::accept( ElementVisitor* visitor ) +{ + return visitor->visit( this ); +} + + +void RootElement::entered( SequenceElement* child ) +{ + if ( child == content ) { + formula()->tell( i18n( "Main list of root" ) ); + } + else { + formula()->tell( i18n( "Index" ) ); + } +} + + +BasicElement* RootElement::goToPos( FormulaCursor* cursor, bool& handled, + const LuPixelPoint& point, const LuPixelPoint& parentOrigin) +{ + BasicElement* e = BasicElement::goToPos(cursor, handled, point, parentOrigin); + if (e != 0) { + LuPixelPoint myPos(parentOrigin.x() + getX(), + parentOrigin.y() + getY()); + + e = content->goToPos(cursor, handled, point, myPos); + if (e != 0) { + return e; + } + if (hasIndex()) { + e = index->goToPos(cursor, handled, point, myPos); + if (e != 0) { + return e; + } + } + + //int dx = point.x() - myPos.x(); + luPixel dy = point.y() - myPos.y(); + + // the position after the index + if (hasIndex()) { + if (dy < index->getHeight()) { + index->moveLeft(cursor, this); + handled = true; + return index; + } + } + + return this; + } + return 0; +} + + +/** + * Calculates our width and height and + * our children's parentPosition. + */ +void RootElement::calcSizes( const ContextStyle& context, + ContextStyle::TextStyle tstyle, + ContextStyle::IndexStyle istyle, + StyleAttributes& style ) +{ + content->calcSizes( context, tstyle, + context.convertIndexStyleLower(istyle), style ); + + luPixel indexWidth = 0; + luPixel indexHeight = 0; + if (hasIndex()) { + index->calcSizes( context, + context.convertTextStyleIndex(tstyle), + context.convertIndexStyleUpper(istyle), + style ); + indexWidth = index->getWidth(); + indexHeight = index->getHeight(); + } + + double factor = style.sizeFactor(); + luPixel distX = context.ptToPixelX( context.getThinSpace( tstyle, factor ) ); + luPixel distY = context.ptToPixelY( context.getThinSpace( tstyle, factor ) ); + luPixel unit = (content->getHeight() + distY)/ 3; + + if (hasIndex()) { + if (indexWidth > unit) { + index->setX(0); + rootOffset.setX( indexWidth - unit ); + } + else { + index->setX( ( unit - indexWidth )/2 ); + rootOffset.setX(0); + } + if (indexHeight > unit) { + index->setY(0); + rootOffset.setY( indexHeight - unit ); + } + else { + index->setY( unit - indexHeight ); + rootOffset.setY(0); + } + } + else { + rootOffset.setX(0); + rootOffset.setY(0); + } + + setWidth( content->getWidth() + unit+unit/3+ rootOffset.x() + distX/2 ); + setHeight( content->getHeight() + distY*2 + rootOffset.y() ); + + content->setX( rootOffset.x() + unit+unit/3 ); + content->setY( rootOffset.y() + distY ); + setBaseline(content->getBaseline() + content->getY()); +} + +/** + * Draws the whole element including its children. + * The `parentOrigin' is the point this element's parent starts. + * We can use our parentPosition to get our own origin then. + */ +void RootElement::draw( TQPainter& painter, const LuPixelRect& r, + const ContextStyle& context, + ContextStyle::TextStyle tstyle, + ContextStyle::IndexStyle istyle, + StyleAttributes& style, + const LuPixelPoint& parentOrigin ) +{ + LuPixelPoint myPos( parentOrigin.x()+getX(), parentOrigin.y()+getY() ); + //if ( !LuPixelRect( myPos.x(), myPos.y(), getWidth(), getHeight() ).intersects( r ) ) + // return; + + content->draw( painter, r, context, tstyle, + context.convertIndexStyleLower(istyle), style, myPos); + if (hasIndex()) { + index->draw(painter, r, context, + context.convertTextStyleIndex(tstyle), + context.convertIndexStyleUpper(istyle), style, myPos); + } + + luPixel x = myPos.x() + rootOffset.x(); + luPixel y = myPos.y() + rootOffset.y(); + //int distX = context.getDistanceX(tstyle); + double factor = style.sizeFactor(); + luPixel distY = context.ptToPixelY( context.getThinSpace( tstyle, factor ) ); + luPixel unit = (content->getHeight() + distY)/ 3; + + painter.setPen( TQPen( style.color(), + context.layoutUnitToPixelX( 2*context.getLineWidth( factor ) ) ) ); + painter.drawLine( context.layoutUnitToPixelX( x+unit/3 ), + context.layoutUnitToPixelY( y+unit+distY/3 ), + context.layoutUnitToPixelX( x+unit/2+unit/3 ), + context.layoutUnitToPixelY( myPos.y()+getHeight() ) ); + + painter.setPen( TQPen( style.color(), + context.layoutUnitToPixelY( context.getLineWidth( factor ) ) ) ); + + painter.drawLine( context.layoutUnitToPixelX( x+unit+unit/3 ), + context.layoutUnitToPixelY( y+distY/3 ), + context.layoutUnitToPixelX( x+unit/2+unit/3 ), + context.layoutUnitToPixelY( myPos.y()+getHeight() ) ); + painter.drawLine( context.layoutUnitToPixelX( x+unit+unit/3 ), + context.layoutUnitToPixelY( y+distY/3 ), + context.layoutUnitToPixelX( x+unit+unit/3+content->getWidth() ), + context.layoutUnitToPixelY( y+distY/3 ) ); + painter.drawLine( context.layoutUnitToPixelX( x+unit/3 ), + context.layoutUnitToPixelY( y+unit+distY/2 ), + context.layoutUnitToPixelX( x ), + context.layoutUnitToPixelY( y+unit+unit/2 ) ); +} + + +void RootElement::dispatchFontCommand( FontCommand* cmd ) +{ + content->dispatchFontCommand( cmd ); + if (hasIndex()) { + index->dispatchFontCommand( cmd ); + } +} + +/** + * Enters this element while moving to the left starting inside + * the element `from'. Searches for a cursor position inside + * this element or to the left of it. + */ +void RootElement::moveLeft(FormulaCursor* cursor, BasicElement* from) +{ + if (cursor->isSelectionMode()) { + getParent()->moveLeft(cursor, this); + } + else { + bool linear = cursor->getLinearMovement(); + if (from == getParent()) { + content->moveLeft(cursor, this); + } + else if (from == content) { + if (linear && hasIndex()) { + index->moveLeft(cursor, this); + } + else { + getParent()->moveLeft(cursor, this); + } + } + else { + getParent()->moveLeft(cursor, this); + } + } +} + +/** + * Enters this element while moving to the right starting inside + * the element `from'. Searches for a cursor position inside + * this element or to the right of it. + */ +void RootElement::moveRight(FormulaCursor* cursor, BasicElement* from) +{ + if (cursor->isSelectionMode()) { + getParent()->moveRight(cursor, this); + } + else { + bool linear = cursor->getLinearMovement(); + if (from == getParent()) { + if (linear && hasIndex()) { + index->moveRight(cursor, this); + } + else { + content->moveRight(cursor, this); + } + } + else if (from == index) { + content->moveRight(cursor, this); + } + else { + getParent()->moveRight(cursor, this); + } + } +} + +/** + * Enters this element while moving up starting inside + * the element `from'. Searches for a cursor position inside + * this element or above it. + */ +void RootElement::moveUp(FormulaCursor* cursor, BasicElement* from) +{ + if (cursor->isSelectionMode()) { + getParent()->moveUp(cursor, this); + } + else { + if (from == getParent()) { + content->moveRight(cursor, this); + } + else if (from == content) { + if (hasIndex()) { + index->moveRight(cursor, this); + } + else { + getParent()->moveUp(cursor, this); + } + } + else { + getParent()->moveUp(cursor, this); + } + } +} + +/** + * Enters this element while moving down starting inside + * the element `from'. Searches for a cursor position inside + * this element or below it. + */ +void RootElement::moveDown(FormulaCursor* cursor, BasicElement* from) +{ + if (cursor->isSelectionMode()) { + getParent()->moveDown(cursor, this); + } + else { + if (from == getParent()) { + if (hasIndex()) { + index->moveRight(cursor, this); + } + else { + content->moveRight(cursor, this); + } + } + else if (from == index) { + content->moveRight(cursor, this); + } + else { + getParent()->moveDown(cursor, this); + } + } +} + +/** + * Reinserts the index if it has been removed. + */ +void RootElement::insert(FormulaCursor* cursor, + TQPtrList& newChildren, + Direction direction) +{ + if (cursor->getPos() == upperLeftPos) { + index = static_cast(newChildren.take(0)); + index->setParent(this); + + if (direction == beforeCursor) { + index->moveLeft(cursor, this); + } + else { + index->moveRight(cursor, this); + } + cursor->setSelection(false); + formula()->changed(); + } +} + +/** + * Removes all selected children and returns them. Places the + * cursor to where the children have been. + * + * We remove ourselve if we are requested to remove our content. + */ +void RootElement::remove(FormulaCursor* cursor, + TQPtrList& removedChildren, + Direction direction) +{ + switch (cursor->getPos()) { + case contentPos: + getParent()->selectChild(cursor, this); + getParent()->remove(cursor, removedChildren, direction); + break; + case upperLeftPos: + removedChildren.append(index); + formula()->elementRemoval(index); + index = 0; + cursor->setTo(this, upperLeftPos); + formula()->changed(); + break; + } +} + + +/** + * Moves the cursor to a normal place where new elements + * might be inserted. + */ +void RootElement::normalize(FormulaCursor* cursor, Direction direction) +{ + if (direction == beforeCursor) { + content->moveLeft(cursor, this); + } + else { + content->moveRight(cursor, this); + } +} + + +// main child +// +// If an element has children one has to become the main one. + +SequenceElement* RootElement::getMainChild() +{ + return content; +} + +// void RootElement::setMainChild(SequenceElement* child) +// { +// formula()->elementRemoval(content); +// content = child; +// content->setParent(this); +// formula()->changed(); +// } + + +/** + * Sets the cursor to select the child. The mark is placed before, + * the position behind it. + */ +void RootElement::selectChild(FormulaCursor* cursor, BasicElement* child) +{ + if (child == content) { + cursor->setTo(this, contentPos); + } + else if (child == index) { + cursor->setTo(this, upperLeftPos); + } +} + + +void RootElement::moveToIndex(FormulaCursor* cursor, Direction direction) +{ + if (hasIndex()) { + if (direction == beforeCursor) { + index->moveLeft(cursor, this); + } + else { + index->moveRight(cursor, this); + } + } +} + +void RootElement::setToIndex(FormulaCursor* cursor) +{ + cursor->setTo(this, upperLeftPos); +} + + +/** + * Appends our attributes to the dom element. + */ +void RootElement::writeDom(TQDomElement element) +{ + BasicElement::writeDom(element); + + TQDomDocument doc = element.ownerDocument(); + + TQDomElement con = doc.createElement("CONTENT"); + con.appendChild(content->getElementDom(doc)); + element.appendChild(con); + + if(hasIndex()) { + TQDomElement ind = doc.createElement("ROOTINDEX"); + ind.appendChild(index->getElementDom(doc)); + element.appendChild(ind); + } +} + +/** + * Reads our attributes from the element. + * Returns false if it failed. + */ +bool RootElement::readAttributesFromDom(TQDomElement element) +{ + return BasicElement::readAttributesFromDom(element); +} + +/** + * Reads our content from the node. Sets the node to the next node + * that needs to be read. + * Returns false if it failed. + */ +bool RootElement::readContentFromDom(TQDomNode& node) +{ + if (!BasicElement::readContentFromDom(node)) { + return false; + } + + if ( !buildChild( content, node, "CONTENT" ) ) { + kdWarning( DEBUGID ) << "Empty content in RootElement." << endl; + return false; + } + node = node.nextSibling(); + + if ( node.nodeName().upper() == "ROOTINDEX" ) { + if ( !buildChild( index=new SequenceElement( this ), node, "ROOTINDEX" ) ) { + return false; + } + } + // backward compatibility + else if ( node.nodeName().upper() == "INDEX" ) { + if ( !buildChild( index=new SequenceElement( this ), node, "INDEX" ) ) { + return false; + } + } + node = node.nextSibling(); + + return true; +} + +/** + * Reads our attributes from the MathML element. + * Also checks whether it's a msqrt or mroot. + * Returns false if it failed. + */ +bool RootElement::readAttributesFromMathMLDom(const TQDomElement& element) +{ + if ( element.tagName().lower() == "mroot" ) + square = false; + else + square = true; + return true; +} + + +/** + * Reads our content from the MathML node. Sets the node to the next node + * that needs to be read. + * Returns false if it failed. + */ +int RootElement::readContentFromMathMLDom(TQDomNode& node) +{ + if ( BasicElement::readContentFromMathMLDom( node ) == -1 ) { + return -1; + } + + if ( square ) { + // Any number of arguments are allowed + if ( content->readContentFromMathMLDom( node ) == -1 ) { + kdWarning( DEBUGID ) << "Empty content in RootElement." << endl; + return -1; + } + } + else { + // Exactly two arguments are required + int contentNumber = content->buildMathMLChild( node ); + if ( contentNumber == -1 ) { + kdWarning( DEBUGID ) << "Empty content in RootElement." << endl; + return -1; + } + for (int i = 0; i < contentNumber; i++ ) { + if ( node.isNull() ) { + return -1; + } + node = node.nextSibling(); + } + + index = new SequenceElement( this ); + if ( index->buildMathMLChild( node ) == -1 ) { + kdWarning( DEBUGID ) << "Empty index in RootElement." << endl; + return -1; + } + } + + return 1; +} + +TQString RootElement::toLatex() +{ + TQString root; + root="\\sqrt"; + if(hasIndex()) { + root+="["; + root+=index->toLatex(); + root+="]"; + } + root+="{"; + root+=content->toLatex(); + root+="}"; + + return root; +} + +TQString RootElement::formulaString() +{ + if ( hasIndex() ) { + return "(" + content->formulaString() + ")**(1.0/(" + index->formulaString() + "))"; + } + return "sqrt(" + content->formulaString() + ")"; +} + +void RootElement::writeMathMLContent( TQDomDocument& doc, TQDomElement& element, bool oasisFormat ) const +{ + content->writeMathML( doc, element, oasisFormat ); + if( hasIndex() ) + { + index->writeMathML( doc, element, oasisFormat ); + } +} + +KFORMULA_NAMESPACE_END diff --git a/lib/kformula/scripts/bynames.py b/lib/kformula/scripts/bynames.py index afb9ece5..6b8c1d7a 100755 --- a/lib/kformula/scripts/bynames.py +++ b/lib/kformula/scripts/bynames.py @@ -144,7 +144,7 @@ if __name__ == '__main__': write_header( fh ) write_h( fh ) fh.close() - fcc = open( '../entities.cc', 'w' ) + fcc = open( '../entities.cpp', 'w' ) write_header( fcc ) fr = open( sys.argv[1] ) write_cc( fr , fcc ) diff --git a/lib/kformula/scripts/oper-dict.py b/lib/kformula/scripts/oper-dict.py index 49191ef6..e9e10550 100755 --- a/lib/kformula/scripts/oper-dict.py +++ b/lib/kformula/scripts/oper-dict.py @@ -247,7 +247,7 @@ if __name__ == '__main__': write_header( fh ) write_h( fh ) fh.close() - fcc = codecs.open( '../operatordictionary.cc', 'w', 'utf-8' ) + fcc = codecs.open( '../operatordictionary.cpp', 'w', 'utf-8' ) write_header( fcc ) fr = open( sys.argv[1] ) write_cc( fr , fcc ) diff --git a/lib/kformula/sequenceelement.cc b/lib/kformula/sequenceelement.cc deleted file mode 100644 index 187bcd65..00000000 --- a/lib/kformula/sequenceelement.cc +++ /dev/null @@ -1,1934 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2001 Andrea Rizzi - Ulrich Kuettler - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - -#include -#include - -#include -#include -#include - -#include -#include -#include - -//#include - -#include "MatrixDialog.h" -#include "bracketelement.h" -#include "creationstrategy.h" -#include "elementtype.h" -#include "elementvisitor.h" -#include "formulacursor.h" -#include "formulaelement.h" -#include "fractionelement.h" -#include "indexelement.h" -#include "kformulacommand.h" -#include "kformulacontainer.h" -#include "kformuladocument.h" -#include "matrixelement.h" -#include "rootelement.h" -#include "sequenceelement.h" -#include "sequenceparser.h" -#include "spaceelement.h" -#include "symbolelement.h" -#include "symboltable.h" -#include "textelement.h" -#include "numberelement.h" -#include "identifierelement.h" -#include "operatorelement.h" - -#include - -KFORMULA_NAMESPACE_BEGIN -//using namespace std; - -ElementCreationStrategy* SequenceElement::creationStrategy = 0; - -void SequenceElement::setCreationStrategy( ElementCreationStrategy* strategy ) -{ - creationStrategy = strategy; -} - -void SequenceElement::setStyle( StyleElement *st ) -{ - style = st; -} - -SequenceElement::SequenceElement(BasicElement* parent) - : BasicElement(parent), parseTree(0), textSequence(true),singlePipe(true), style(0) -{ - assert( creationStrategy != 0 ); - children.setAutoDelete(true); -} - - -SequenceElement::~SequenceElement() -{ - delete parseTree; -} - -SequenceElement::SequenceElement( const SequenceElement& other ) - : BasicElement( other ) -{ - children.setAutoDelete(true); - uint count = other.children.count(); - for (uint i = 0; i < count; i++) { - BasicElement* child = children.at(i)->clone(); - child->setParent( this ); - children.append( child ); - } -} - - -bool SequenceElement::accept( ElementVisitor* visitor ) -{ - return visitor->visit( this ); -} - - -bool SequenceElement::readOnly( const FormulaCursor* ) const -{ - return getParent()->readOnly( this ); -} - - -/** - * Returns the element the point is in. - */ -BasicElement* SequenceElement::goToPos( FormulaCursor* cursor, bool& handled, - const LuPixelPoint& point, const LuPixelPoint& parentOrigin ) -{ - BasicElement* e = BasicElement::goToPos(cursor, handled, point, parentOrigin); - if (e != 0) { - LuPixelPoint myPos(parentOrigin.x() + getX(), - parentOrigin.y() + getY()); - - uint count = children.count(); - for (uint i = 0; i < count; i++) { - BasicElement* child = children.at(i); - e = child->goToPos(cursor, handled, point, myPos); - if (e != 0) { - if (!handled) { - handled = true; - if ((point.x() - myPos.x()) < (e->getX() + e->getWidth()*2/3)) { - cursor->setTo(this, children.find(e)); - } - else { - cursor->setTo(this, children.find(e)+1); - } - } - return e; - } - } - - luPixel dx = point.x() - myPos.x(); - //int dy = point.y() - myPos.y(); - - for (uint i = 0; i < count; i++) { - BasicElement* child = children.at(i); - if (dx < child->getX()) { - cursor->setTo( this, i ); - handled = true; - return children.at( i ); - } - } - - cursor->setTo(this, countChildren()); - handled = true; - return this; - } - return 0; -} - - -bool SequenceElement::isEmpty() -{ - uint count = children.count(); - for (uint i = 0; i < count; i++) { - BasicElement* child = children.at(i); - if (!child->isInvisible()) { - return false; - } - } - return true; -} - - -/** - * Calculates our width and height and - * our children's parentPosition. - */ -void SequenceElement::calcSizes( const ContextStyle& context, - ContextStyle::TextStyle tstyle, - ContextStyle::IndexStyle istyle, - StyleAttributes& style ) -{ - double factor = style.sizeFactor(); - if (!isEmpty()) { - luPixel width = 0; - luPixel toBaseline = 0; - luPixel fromBaseline = 0; - - width += context.ptToPixelX( getSpaceBefore( context, tstyle, factor ) ); - - // Let's do all normal elements that have a base line. - TQPtrListIterator it( children ); - for ( ; it.current(); ++it ) { - BasicElement* child = it.current(); - - if ( !child->isInvisible() ) { - child->calcSizes( context, tstyle, istyle, style ); - child->setX( width ); - width += child->getWidth(); - - luPixel childBaseline = child->getBaseline(); - if ( childBaseline > -1 ) { - toBaseline = TQMAX( toBaseline, childBaseline ); - fromBaseline = TQMAX( fromBaseline, - child->getHeight() - childBaseline ); - } - else { - luPixel bl = child->getHeight()/2 + context.axisHeight( tstyle, factor ); - toBaseline = TQMAX( toBaseline, bl ); - fromBaseline = TQMAX( fromBaseline, child->getHeight() - bl ); - } - } - else { - child->setX( width ); - } - } - - width += context.ptToPixelX( getSpaceAfter( context, tstyle, factor ) ); - - setWidth(width); - setHeight(toBaseline+fromBaseline); - setBaseline(toBaseline); - - setChildrenPositions(); - } - else { - luPixel w = context.getEmptyRectWidth( factor ); - luPixel h = context.getEmptyRectHeight( factor ); - setWidth( w ); - setHeight( h ); - setBaseline( h ); - //setMidline( h*.5 ); - } -} - - -void SequenceElement::setChildrenPositions() -{ - TQPtrListIterator it( children ); - for ( ; it.current(); ++it ) { - BasicElement* child = it.current(); - child->setY(getBaseline() - child->getBaseline()); - } -} - - -/** - * Draws the whole element including its children. - * The `parentOrigin' is the point this element's parent starts. - * We can use our parentPosition to get our own origin then. - */ -void SequenceElement::draw( TQPainter& painter, const LuPixelRect& r, - const ContextStyle& context, - ContextStyle::TextStyle tstyle, - ContextStyle::IndexStyle istyle, - StyleAttributes& style, - const LuPixelPoint& parentOrigin ) -{ - LuPixelPoint myPos( parentOrigin.x() + getX(), parentOrigin.y() + getY() ); - // There might be zero sized elements that still want to be drawn at least - // in edit mode. (EmptyElement) - //if ( !LuPixelRect( myPos.x(), myPos.y(), getWidth(), getHeight() ).intersects( r ) ) - // return; - - if (!isEmpty()) { - TQPtrListIterator it( children ); - for (int i = 0 ; it.current(); i++) { - BasicElement* child = it.current(); - if (!child->isInvisible()) { - child->draw(painter, r, context, tstyle, istyle, style, myPos); - - // Each starting element draws the whole token - // This only concerns TextElements. - /* - ElementType* token = child->getElementType(); - if ( token != 0 ) { - it += token->end() - token->start(); - } - else { - ++it; - } - */ - } -// else { - ++it; -// } - } - } - else { - drawEmptyRect( painter, context, style.sizeFactor(), myPos ); - } - // Debug - //painter.setPen(TQt::green); - //painter.drawRect(parentOrigin.x() + getX(), parentOrigin.y() + getY(), - // getWidth(), getHeight()); -// painter.drawLine( context.layoutUnitToPixelX( parentOrigin.x() + getX() ), -// context.layoutUnitToPixelY( parentOrigin.y() + getY() + axis( context, tstyle ) ), -// context.layoutUnitToPixelX( parentOrigin.x() + getX() + getWidth() ), -// context.layoutUnitToPixelY( parentOrigin.y() + getY() + axis( context, tstyle ) ) ); -// painter.setPen(TQt::red); -// painter.drawLine( context.layoutUnitToPixelX( parentOrigin.x() + getX() ), -// context.layoutUnitToPixelY( parentOrigin.y() + getY() + getBaseline() ), -// context.layoutUnitToPixelX( parentOrigin.x() + getX() + getWidth() ), -// context.layoutUnitToPixelY( parentOrigin.y() + getY() + getBaseline() ) ); -} - - -void SequenceElement::dispatchFontCommand( FontCommand* cmd ) -{ - TQPtrListIterator it( children ); - for ( ; it.current(); ++it ) { - BasicElement* child = it.current(); - child->dispatchFontCommand( cmd ); - } -} - - -void SequenceElement::drawEmptyRect( TQPainter& painter, const ContextStyle& context, - double factor, const LuPixelPoint& upperLeft ) -{ - if ( context.edit() ) { - painter.setBrush(TQt::NoBrush); - painter.setPen( TQPen( context.getEmptyColor(), - context.layoutUnitToPixelX( context.getLineWidth( factor ) ) ) ); - painter.drawRect( context.layoutUnitToPixelX( upperLeft.x() ), - context.layoutUnitToPixelY( upperLeft.y() ), - context.layoutUnitToPixelX( getWidth() ), - context.layoutUnitToPixelY( getHeight() ) ); - } -} - -void SequenceElement::calcCursorSize( const ContextStyle& context, - FormulaCursor* cursor, bool smallCursor ) -{ - LuPixelPoint point = widgetPos(); - uint pos = cursor->getPos(); - - luPixel posX = getChildPosition( context, pos ); - luPixel height = getHeight(); - - luPixel unitX = context.ptToLayoutUnitPixX( 1 ); - luPixel unitY = context.ptToLayoutUnitPixY( 1 ); - - // Here are those evil constants that describe the cursor size. - - if ( cursor->isSelection() ) { - uint mark = cursor->getMark(); - luPixel markX = getChildPosition( context, mark ); - luPixel x = TQMIN(posX, markX); - luPixel width = abs(posX - markX); - - if ( smallCursor ) { - cursor->cursorSize.setRect( point.x()+x, point.y(), width, height ); - } - else { - cursor->cursorSize.setRect( point.x()+x, point.y() - 2*unitY, - width + unitX, height + 4*unitY ); - } - } - else { - if ( smallCursor ) { - cursor->cursorSize.setRect( point.x()+posX, point.y(), - unitX, height ); - } - else { - cursor->cursorSize.setRect( point.x(), point.y() - 2*unitY, - getWidth() + unitX, height + 4*unitY ); - } - } - - cursor->cursorPoint.setX( point.x()+posX ); - cursor->cursorPoint.setY( point.y()+getHeight()/2 ); -} - - -/** - * If the cursor is inside a sequence it needs to be drawn. - */ -void SequenceElement::drawCursor( TQPainter& painter, const ContextStyle& context, - StyleAttributes& style, FormulaCursor* cursor, - bool smallCursor, bool activeCursor ) -{ - painter.setRasterOp( TQt::XorROP ); - if ( cursor->isSelection() ) { - const LuPixelRect& r = cursor->cursorSize; - painter.fillRect( context.layoutUnitToPixelX( r.x() ), - context.layoutUnitToPixelY( r.y() ), - context.layoutUnitToPixelX( r.width() ), - context.layoutUnitToPixelY( r.height() ), - TQt::white ); - } - painter.setPen( TQPen( TQt::white, - context.layoutUnitToPixelX( context.getLineWidth( style.sizeFactor() )/2 ) ) ); - const LuPixelPoint& point = cursor->getCursorPoint(); - const LuPixelRect& size = cursor->getCursorSize(); - if ( activeCursor ) - { - int offset = 0; - if ( cursor->isSelection() && cursor->getPos() > cursor->getMark() ) - offset = -1; - painter.drawLine( context.layoutUnitToPixelX( point.x() ) + offset, - context.layoutUnitToPixelY( size.top() ), - context.layoutUnitToPixelX( point.x() ) + offset, - context.layoutUnitToPixelY( size.bottom() )-1 ); - painter.drawLine( context.layoutUnitToPixelX( point.x() ) + offset + 1, - context.layoutUnitToPixelY( size.top() ), - context.layoutUnitToPixelX( point.x() ) + offset + 1, - context.layoutUnitToPixelY( size.bottom() )-1 ); - } - if ( !smallCursor && !cursor->isSelection() ) - painter.drawLine( context.layoutUnitToPixelX( size.left() ), - context.layoutUnitToPixelY( size.bottom() )-1, - context.layoutUnitToPixelX( size.right() )-1, - context.layoutUnitToPixelY( size.bottom() )-1 ); - // This might be wrong but probably isn't. - painter.setRasterOp( TQt::CopyROP ); -} - - -luPixel SequenceElement::getChildPosition( const ContextStyle& context, uint child ) -{ - if (child < children.count()) { - return children.at(child)->getX(); - } - else { - if (children.count() > 0) { - return children.at(child-1)->getX() + children.at(child-1)->getWidth(); - } - else { - return context.ptToLayoutUnitPixX( 2 ); - } - } -} - - -// navigation -// -// The elements are responsible to handle cursor movement themselves. -// To do this they need to know the direction the cursor moves and -// the element it comes from. -// -// The cursor might be in normal or in selection mode. - -/** - * Enters this element while moving to the left starting inside - * the element `from'. Searches for a cursor position inside - * this element or to the left of it. - */ -void SequenceElement::moveLeft(FormulaCursor* cursor, BasicElement* from) -{ - // Our parent asks us for a cursor position. Found. - if (from == getParent()) { - cursor->setTo(this, children.count()); - if ( cursor->isSelectionMode() ) { - cursor->setMark( children.count() ); - } - from->entered( this ); - } - - // We already owned the cursor. Ask next child then. - else if (from == this) { - if (cursor->getPos() > 0) { - cursor->setTo(this, cursor->getPos()-1); - - // invisible elements are not visible so we move on. - if (children.at(cursor->getPos())->isInvisible()) { - moveLeft(cursor, this); - } - } - else { - // Needed because FormulaElement derives this. - if (getParent() != 0) { - getParent()->moveLeft(cursor, this); - } - else { - formula()->moveOutLeft( cursor ); - } - } - } - - // The cursor came from one of our children or - // something is wrong. - else { - int fromPos = children.find(from); - if ( fromPos > 0 ) { - children.at( fromPos - 1)->moveLeft( cursor, this ); - } - - // invisible elements are not visible so we move on. - if (from->isInvisible()) { - moveLeft(cursor, this); - } - formula()->tell( "" ); - } -} - -/** - * Enters this element while moving to the right starting inside - * the element `from'. Searches for a cursor position inside - * this element or to the right of it. - */ -void SequenceElement::moveRight(FormulaCursor* cursor, BasicElement* from) -{ - // Our parent asks us for a cursor position. Found. - if (from == getParent()) { - cursor->setTo(this, 0); - from->entered( this ); - } - - // We already owned the cursor. Ask next child then. - else if (from == this) { - uint pos = cursor->getPos(); - if (pos < children.count()) { - cursor->setTo(this, pos+1); - - // invisible elements are not visible so we move on. - if (children.at(pos)->isInvisible()) { - moveRight(cursor, this); - } - } - else { - // Needed because FormulaElement derives this. - if (getParent() != 0) { - getParent()->moveRight(cursor, this); - } - else { - formula()->moveOutRight( cursor ); - } - } - } - - // The cursor came from one of our children or - // something is wrong. - else { - int fromPos = children.find(from); - if ( fromPos < children.count() - 1 ) { - children.at( fromPos + 1 )->moveDown( cursor, this ); - } - else { - cursor->setTo(this, fromPos+1); - } - if (cursor->isSelectionMode()) { - cursor->setMark(fromPos); - } - - // invisible elements are not visible so we move on. - if (from->isInvisible()) { - moveRight(cursor, this); - } - formula()->tell( "" ); - } -} - - -void SequenceElement::moveWordLeft(FormulaCursor* cursor) -{ - uint pos = cursor->getPos(); - if (pos > 0) { - ElementType* type = children.at(pos-1)->getElementType(); - if (type != 0) { - cursor->setTo(this, type->start()); - } - } - else { - moveLeft(cursor, this); - } -} - - -void SequenceElement::moveWordRight(FormulaCursor* cursor) -{ - uint pos = cursor->getPos(); - if (pos < children.count()) { - ElementType* type = children.at(pos)->getElementType(); - if (type != 0) { - cursor->setTo(this, type->end()); - } - } - else { - moveRight(cursor, this); - } -} - - -/** - * Enters this element while moving up starting inside - * the element `from'. Searches for a cursor position inside - * this element or above it. - */ -void SequenceElement::moveUp(FormulaCursor* cursor, BasicElement* from) -{ - if (from == getParent()) { - moveRight(cursor, this); - } - else if ( from == this ) { - if ( getParent() != 0 ) { - uint pos = cursor->getPos(); - if ( pos < (children.count() - 1) / 2 ) { - getParent()->moveLeft( cursor, this ); - } - else { - getParent()->moveRight( cursor, this ); - } - } - else { - formula()->moveOutAbove( cursor ); - } - } - else { - if (getParent() != 0) { - getParent()->moveUp(cursor, this); - } - else { - formula()->moveOutAbove( cursor ); - } - } -} - -/** - * Enters this element while moving down starting inside - * the element `from'. Searches for a cursor position inside - * this element or below it. - */ -void SequenceElement::moveDown(FormulaCursor* cursor, BasicElement* from) -{ - if (from == getParent()) { - cursor->setTo(this, 0); - from->entered( this ); - } - else if (from == this) { - uint pos = cursor->getPos(); - if (pos < children.count()) { - children.at(pos)->moveDown(cursor, this); - } - } - else { - if (getParent() != 0) { - getParent()->moveDown(cursor, this); - } - else { - cursor->setTo( this, children.count() ); - from->entered( this ); -// formula()->moveOutBelow( cursor ); - } - } -} - -/** - * Moves the cursor to the first position in this sequence. - * (That is before the first child.) - */ -void SequenceElement::moveHome(FormulaCursor* cursor) -{ - if (cursor->isSelectionMode()) { - BasicElement* element = cursor->getElement(); - if (element != this) { - while (element->getParent() != this) { - element = element->getParent(); - } - cursor->setMark(children.find(element)+1); - } - } - cursor->setTo(this, 0); -} - -/** - * Moves the cursor to the last position in this sequence. - * (That is behind the last child.) - */ -void SequenceElement::moveEnd(FormulaCursor* cursor) -{ - if (cursor->isSelectionMode()) { - BasicElement* element = cursor->getElement(); - if (element != this) { - while (element->getParent() != this) { - element = element->getParent(); - if (element == 0) { - cursor->setMark(children.count()); - break; - } - } - if (element != 0) { - cursor->setMark(children.find(element)); - } - } - } - cursor->setTo(this, children.count()); -} - -/** - * Sets the cursor inside this element to its start position. - * For most elements that is the main child. - */ -void SequenceElement::goInside(FormulaCursor* cursor) -{ - cursor->setSelection(false); - cursor->setTo(this, 0); -} - -/** - * Sets the cursor inside this element to its end position. - * For most elements that is the main child. - */ -void SequenceElement::goInsideLast(FormulaCursor* cursor) -{ - cursor->setSelection(false); - cursor->setTo(this, children.count()); -} - - -// children - - /** - * Insert a new child in the sequence - * - * @returns true if succesful, i.e. if index is in range, otherwise returns - * false. The valid range is 0 to count(). The child is appended if index == count(). - * - * @param index position in the sequence to insert the child - * @param child the child to insert in the sequence - */ - -bool SequenceElement::insert( uint index, BasicElement *child ) -{ - return children.insert( index, child ); -} - -/** - * Removes the child. If this was the main child this element might - * request its own removal. - * The cursor is the one that caused the removal. It has to be moved - * to the place any user expects the cursor after that particular - * element has been removed. - */ -// void SequenceElement::removeChild(FormulaCursor* cursor, BasicElement* child) -// { -// int pos = children.find(child); -// formula()->elementRemoval(child, pos); -// cursor->setTo(this, pos); -// children.remove(pos); -// /* -// if len(self.children) == 0: -// if self.parent != None: -// self.parent.removeChild(cursor, self) -// return -// */ -// formula()->changed(); -// } - - -/** - * Inserts all new children at the cursor position. Places the - * cursor according to the direction. The inserted elements will - * be selected. - * - * The list will be emptied but stays the property of the caller. - */ -void SequenceElement::insert(FormulaCursor* cursor, - TQPtrList& newChildren, - Direction direction) -{ - int pos = cursor->getPos(); - uint count = newChildren.count(); - for (uint i = 0; i < count; i++) { - BasicElement* child = newChildren.take(0); - child->setParent(this); - children.insert(pos+i, child); - } - if (direction == beforeCursor) { - cursor->setTo(this, pos+count, pos); - } - else { - cursor->setTo(this, pos, pos+count); - } - - formula()->changed(); - parse(); -} - - -/** - * Removes all selected children and returns them. Places the - * cursor to where the children have been. - * - * The ownership of the list is passed to the caller. - */ -void SequenceElement::remove(FormulaCursor* cursor, - TQPtrList& removedChildren, - Direction direction) -{ - if (cursor->isSelection()) { - int from = cursor->getSelectionStart(); - int to = cursor->getSelectionEnd(); - for (int i = from; i < to; i++) { - removeChild(removedChildren, from); - } - cursor->setTo(this, from); - cursor->setSelection(false); - } - else { - if (direction == beforeCursor) { - int pos = cursor->getPos() - 1; - if (pos >= 0) { - while (pos >= 0) { - BasicElement* child = children.at(pos); - formula()->elementRemoval(child); - children.take(pos); - removedChildren.prepend(child); - if (!child->isInvisible()) { - break; - } - pos--; - } - cursor->setTo(this, pos); - formula()->changed(); - } - } - else { - uint pos = cursor->getPos(); - if (pos < children.count()) { - while (pos < children.count()) { - BasicElement* child = children.at(pos); - formula()->elementRemoval(child); - children.take(pos); - removedChildren.append(child); - if (!child->isInvisible()) { - break; - } - } - // It is necessary to set the cursor to its old - // position because it got a notification and - // moved to the beginning of this sequence. - cursor->setTo(this, pos); - formula()->changed(); - } - } - } - parse(); -} - - -/** - * Removes the children at pos and appends it to the list. - */ -void SequenceElement::removeChild(TQPtrList& removedChildren, int pos) -{ - BasicElement* child = children.at(pos); - formula()->elementRemoval(child); - children.take(pos); - removedChildren.append(child); - //cerr << *removedChildren.at(0) << endl; - formula()->changed(); -} - - -/** - * Moves the cursor to a normal place where new elements - * might be inserted. - */ -void SequenceElement::normalize(FormulaCursor* cursor, Direction) -{ - cursor->setSelection(false); -} - - -/** - * Returns the child at the cursor. - * Does not care about the selection. - */ -BasicElement* SequenceElement::getChild( FormulaCursor* cursor, Direction direction ) -{ - if ( direction == beforeCursor ) { - if ( cursor->getPos() > 0 ) { - return children.at( cursor->getPos() - 1 ); - } - } - else { - if ( cursor->getPos() < tqRound( children.count() ) ) { - return children.at( cursor->getPos() ); - } - } - return 0; -} - - -/** - * Sets the cursor to select the child. The mark is placed before, - * the position behind it. - */ -void SequenceElement::selectChild(FormulaCursor* cursor, BasicElement* child) -{ - int pos = children.find(child); - if (pos > -1) { - cursor->setTo(this, pos+1, pos); - } -} - -void SequenceElement::childWillVanish(FormulaCursor* cursor, BasicElement* child) -{ - int childPos = children.find(child); - if (childPos > -1) { - int pos = cursor->getPos(); - if (pos > childPos) { - pos--; - } - int mark = cursor->getMark(); - if (mark > childPos) { - mark--; - } - cursor->setTo(this, pos, mark); - } -} - - -/** - * Selects all children. The cursor is put behind, the mark before them. - */ -void SequenceElement::selectAllChildren(FormulaCursor* cursor) -{ - cursor->setTo(this, children.count(), 0); -} - -bool SequenceElement::onlyTextSelected( FormulaCursor* cursor ) -{ - if ( cursor->isSelection() ) { - uint from = TQMIN( cursor->getPos(), cursor->getMark() ); - uint to = TQMAX( cursor->getPos(), cursor->getMark() ); - for ( uint i = from; i < to; i++ ) { - BasicElement* element = getChild( i ); - if ( element->getCharacter() == TQChar::null ) { - return false; - } - } - } - return true; -} - - -KCommand* SequenceElement::buildCommand( Container* container, Request* request ) -{ - FormulaCursor* cursor = container->activeCursor(); - if ( cursor->isReadOnly() ) { - formula()->tell( i18n( "write protection" ) ); - return 0; - } - - switch ( *request ) { - case req_addText: { - KFCReplaceToken* command = new KFCReplaceToken( i18n("Add Text"), container ); - TextRequest* tr = static_cast( request ); - IdentifierElement* id = creationStrategy->createIdentifierElement(); - command->addToken( id ); - for ( uint i = 0; i < tr->text().length(); i++ ) { - TextElement* text = creationStrategy->createTextElement( tr->text()[i] ); - command->addContent( id, text ); - } - return command; - } - case req_addTextChar: { - KFCReplaceToken* command = new KFCReplaceToken( i18n("Add Text"), container ); - TextCharRequest* tr = static_cast( request ); - IdentifierElement* id = creationStrategy->createIdentifierElement(); - TextElement* text = creationStrategy->createTextElement( tr->ch() ); - command->addToken( id ); - command->addContent( id, text ); - return command; - } - - case req_addOperator: { - KFCReplaceToken* command = new KFCReplaceToken( i18n("Add Operator"), container ); - OperatorRequest* opr = static_cast( request ); - OperatorElement* op = creationStrategy->createOperatorElement(); - TextElement* text = creationStrategy->createTextElement( opr->ch() ); - command->addToken( op ); - command->addContent( op, text ); - return command; - } - - case req_addNumber: { - KFCReplaceToken* command = new KFCReplaceToken( i18n("Add Number"), container ); - NumberRequest* nr = static_cast( request ); - NumberElement* num = creationStrategy->createNumberElement(); - num->setParent( this ); - TextElement* text = creationStrategy->createTextElement( nr->ch() ); - text->setParent( num ); - command->addToken( num ); - command->addContent( num, text ); - return command; - } - - case req_addEmptyBox: { - EmptyElement* element = creationStrategy->createEmptyElement(); - if ( element != 0 ) { - KFCReplace* command = new KFCReplace( i18n("Add Empty Box"), container ); - command->addElement( element ); - return command; - } - break; - } - case req_addNameSequence: - if ( onlyTextSelected( container->activeCursor() ) ) { - NameSequence* nameSequence = creationStrategy->createNameSequence(); - if ( nameSequence != 0 ) { - KFCAddReplacing* command = new KFCAddReplacing( i18n( "Add Name" ), container ); - command->setElement( nameSequence ); - return command; - } - } - break; - case req_addBracket: { - BracketRequest* br = static_cast( request ); - BracketElement* bracketElement = - creationStrategy->createBracketElement( br->left(), br->right() ); - if ( bracketElement != 0 ) { - KFCAddReplacing* command = new KFCAddReplacing(i18n("Add Bracket"), container); - command->setElement( bracketElement ); - return command; - } - break; - } - case req_addOverline: { - OverlineElement* overline = creationStrategy->createOverlineElement(); - if ( overline != 0 ) { - KFCAddReplacing* command = new KFCAddReplacing(i18n("Add Overline"), container); - command->setElement( overline ); - return command; - } - break; - } - case req_addUnderline: { - UnderlineElement* underline = creationStrategy->createUnderlineElement(); - if ( underline != 0 ) { - KFCAddReplacing* command = new KFCAddReplacing(i18n("Add Underline"), container); - command->setElement( underline ); - return command; - } - break; - } - case req_addMultiline: { - MultilineElement* multiline = creationStrategy->createMultilineElement(); - if ( multiline != 0 ) { - KFCAddReplacing* command = new KFCAddReplacing(i18n("Add Multiline"), container); - command->setElement( multiline ); - return command; - } - break; - } - case req_addSpace: { - SpaceRequest* sr = static_cast( request ); - SpaceElement* element = creationStrategy->createSpaceElement( sr->space() ); - if ( element != 0 ) { - KFCReplace* command = new KFCReplace( i18n("Add Space"), container ); - command->addElement( element ); - return command; - } - break; - } - case req_addFraction: { - FractionElement* fraction = creationStrategy->createFractionElement(); - if ( fraction != 0 ) { - KFCAddReplacing* command = new KFCAddReplacing(i18n("Add Fraction"), container); - command->setElement( fraction ); - return command; - } - break; - } - case req_addRoot: { - RootElement* root = creationStrategy->createRootElement(); - if ( root != 0 ) { - KFCAddReplacing* command = new KFCAddReplacing(i18n("Add Root"), container); - command->setElement( root ); - return command; - } - break; - } - case req_addSymbol: { - SymbolRequest* sr = static_cast( request ); - SymbolElement* symbol = creationStrategy->createSymbolElement( sr->type() ); - if ( symbol != 0 ) { - KFCAddReplacing* command = new KFCAddReplacing( i18n( "Add Symbol" ), container ); - command->setElement( symbol ); - return command; - } - break; - } - case req_addOneByTwoMatrix: { - FractionElement* element = creationStrategy->createFractionElement(); - if ( element != 0 ) { - KFCAddReplacing* command = new KFCAddReplacing( i18n("Add 1x2 Matrix"), container ); - element->showLine(false); - command->setElement(element); - return command; - } - } - case req_addMatrix: { - MatrixRequest* mr = static_cast( request ); - uint rows = mr->rows(), cols = mr->columns(); - if ( ( rows == 0 ) || ( cols == 0 ) ) { - MatrixDialog* dialog = new MatrixDialog( 0 ); - if ( dialog->exec() ) { - rows = dialog->h; - cols = dialog->w; - } - delete dialog; - } - - if ( ( rows != 0 ) && ( cols != 0 ) ) { - KFCAddReplacing* command = new KFCAddReplacing( i18n( "Add Matrix" ), container ); - command->setElement( creationStrategy->createMatrixElement( rows, cols ) ); - return command; - } - else - return 0L; - } - case req_addIndex: { - if ( cursor->getPos() > 0 && !cursor->isSelection() ) { - IndexElement* element = - dynamic_cast( children.at( cursor->getPos()-1 ) ); - if ( element != 0 ) { - element->goInside( cursor ); - return element->buildCommand( container, request ); - } - } - IndexElement* element = creationStrategy->createIndexElement(); - if ( element != 0 ) { - if ( !cursor->isSelection() ) { - cursor->moveLeft( SelectMovement | WordMovement ); - } - IndexRequest* ir = static_cast( request ); - KFCAddIndex* command = new KFCAddIndex( container, element, - element->getIndex( ir->index() ) ); - return command; - } - break; - } - case req_removeEnclosing: { - if ( !cursor->isSelection() ) { - DirectedRemove* dr = static_cast( request ); - KFCRemoveEnclosing* command = new KFCRemoveEnclosing( container, dr->direction() ); - return command; - } - } - case req_remove: { - SequenceElement* sequence = cursor->normal(); - if ( sequence && - ( sequence == sequence->formula() ) && - ( sequence->countChildren() == 0 ) ) { - sequence->formula()->removeFormula( cursor ); - return 0; - } - else { - DirectedRemove* dr = static_cast( request ); - - // empty removes are not legal! - if ( !cursor->isSelection() ) { - if ( countChildren() > 0 ) { - if ( ( cursor->getPos() == 0 ) && ( dr->direction() == beforeCursor ) ) { - return 0; - } - if ( ( cursor->getPos() == countChildren() ) && ( dr->direction() == afterCursor ) ) { - return 0; - } - } - else if ( getParent() == 0 ) { - return 0; - } - } - - KFCRemove* command = new KFCRemove( container, dr->direction() ); - return command; - } - } - case req_compactExpression: { - cursor->moveEnd(); - cursor->moveRight(); - formula()->cursorHasMoved( cursor ); - break; - } - case req_makeGreek: { - TextElement* element = cursor->getActiveTextElement(); - if ((element != 0) && !element->isSymbol()) { - cursor->selectActiveElement(); - const SymbolTable& table = container->document()->getSymbolTable(); - if (table.greekLetters().find(element->getCharacter()) != -1) { - KFCReplace* command = new KFCReplace( i18n( "Change Char to Symbol" ), container ); - TextElement* symbol = creationStrategy->createTextElement( table.unicodeFromSymbolFont( element->getCharacter() ), true ); - command->addElement( symbol ); - return command; - } - cursor->setSelection( false ); - } - break; - } - case req_paste: - case req_copy: - case req_cut: - break; - case req_formatBold: - case req_formatItalic: { - if ( cursor->isSelection() ) { - CharStyleRequest* csr = static_cast( request ); - CharStyle cs = normalChar; - if ( csr->bold() ) cs = static_cast( cs | boldChar ); - if ( csr->italic() ) cs = static_cast( cs | italicChar ); - CharStyleCommand* cmd = new CharStyleCommand( cs, i18n( "Change Char Style" ), container ); - int end = cursor->getSelectionEnd(); - for ( int i = cursor->getSelectionStart(); iaddElement( children.at( i ) ); - } - return cmd; - } - break; - } - case req_formatFamily: { - if ( cursor->isSelection() ) { - CharFamilyRequest* cfr = static_cast( request ); - CharFamily cf = cfr->charFamily(); - CharFamilyCommand* cmd = new CharFamilyCommand( cf, i18n( "Change Char Family" ), container ); - int end = cursor->getSelectionEnd(); - for ( int i = cursor->getSelectionStart(); iaddElement( children.at( i ) ); - } - return cmd; - } - break; - } - default: - break; - } - return 0; -} - - -KCommand* SequenceElement::input( Container* container, TQKeyEvent* event ) -{ - TQChar ch = event->text().at( 0 ); - if ( ch.isPrint() ) { - return input( container, ch ); - } - else { - int action = event->key(); - int state = event->state(); - MoveFlag flag = movementFlag(state); - - switch ( action ) { - case TQt::Key_BackSpace: { - DirectedRemove r( req_remove, beforeCursor ); - return buildCommand( container, &r ); - } - case TQt::Key_Delete: { - DirectedRemove r( req_remove, afterCursor ); - return buildCommand( container, &r ); - } - case TQt::Key_Left: { - FormulaCursor* cursor = container->activeCursor(); - cursor->moveLeft( flag ); - formula()->cursorHasMoved( cursor ); - break; - } - case TQt::Key_Right: { - FormulaCursor* cursor = container->activeCursor(); - cursor->moveRight( flag ); - formula()->cursorHasMoved( cursor ); - break; - } - case TQt::Key_Up: { - FormulaCursor* cursor = container->activeCursor(); - cursor->moveUp( flag ); - formula()->cursorHasMoved( cursor ); - break; - } - case TQt::Key_Down: { - FormulaCursor* cursor = container->activeCursor(); - cursor->moveDown( flag ); - formula()->cursorHasMoved( cursor ); - break; - } - case TQt::Key_Home: { - FormulaCursor* cursor = container->activeCursor(); - cursor->moveHome( flag ); - formula()->cursorHasMoved( cursor ); - break; - } - case TQt::Key_End: { - FormulaCursor* cursor = container->activeCursor(); - cursor->moveEnd( flag ); - formula()->cursorHasMoved( cursor ); - break; - } - default: - if ( state & TQt::ControlButton ) { - switch ( event->key() ) { - case TQt::Key_AsciiCircum: { - IndexRequest r( upperLeftPos ); - return buildCommand( container, &r ); - } - case TQt::Key_Underscore: { - IndexRequest r( lowerLeftPos ); - return buildCommand( container, &r ); - } - default: - break; - } - } - } - } - return 0; -} - - -KCommand* SequenceElement::input( Container* container, TQChar ch ) -{ - int unicode = ch.unicode(); - switch (unicode) { - case '(': { - BracketRequest r( container->document()->leftBracketChar(), - container->document()->rightBracketChar() ); - singlePipe = true; - return buildCommand( container, &r ); - } - case '[': { - BracketRequest r( LeftSquareBracket, RightSquareBracket ); - singlePipe = true; - return buildCommand( container, &r ); - } - case '{': { - BracketRequest r( LeftCurlyBracket, RightCurlyBracket ); - singlePipe = true; - return buildCommand( container, &r ); - } - case '|': { - if (!singlePipe) { // We have had 2 '|' in a row so we want brackets - - DirectedRemove rDelete( req_remove, beforeCursor ); //Delete the previous '|' we dont need it any more - KCommand* command = buildCommand( container, &rDelete ); - command->execute(); - - BracketRequest rBracket( LeftLineBracket , RightLineBracket); - singlePipe = true; //the next '|' will be a single pipe again - return buildCommand( container, &rBracket ); - } - else { // We really do only want 1 '|' - TextCharRequest r(ch); - - //in case another '|' character is entered right after this one, '| |' brackets are made; see above - singlePipe = false; - - return buildCommand( container, &r ); - } - } - case '^': { - IndexRequest r( upperRightPos ); - singlePipe = true; - return buildCommand( container, &r ); - } - case '_': { - IndexRequest r( lowerRightPos ); - singlePipe = true; - return buildCommand( container, &r ); - } - /* - case ' ': { - Request r( req_compactExpression ); - singlePipe = true; - return buildCommand( container, &r ); - }*/ - case '}': { - Request r( req_addEmptyBox ); - singlePipe = true; - return buildCommand( container, &r ); - } - case ']': - case ')': - singlePipe = true; - break; - case '\\': { - Request r( req_addNameSequence ); - singlePipe = true; - return buildCommand( container, &r ); - } - default: { - singlePipe = true; - if ( ch.isPunct() || ch.isSymbol() ) { - OperatorRequest r( ch ); - return buildCommand( container, &r ); - } - if ( ch.isNumber() ) { - NumberRequest r( ch ); - return buildCommand( container, &r ); - } - TextCharRequest r( ch ); - return buildCommand( container, &r ); - } - } - return 0; -} - -/** - * Stores the given childrens dom in the element. - */ -void SequenceElement::getChildrenDom( TQDomDocument& doc, TQDomElement elem, - uint from, uint to) -{ - for (uint i = from; i < to; i++) { - TQDomElement tmpEleDom=children.at(i)->getElementDom(doc); - elem.appendChild(tmpEleDom); - } -} - -/** - * Stores the given childrens MathML dom in the element. - */ -void SequenceElement::getChildrenMathMLDom( TQDomDocument& doc, TQDomNode& parent, - uint from, uint to) -{ - for ( uint i = from; i < to; i++ ) { - children.at( i )->writeMathML( doc, parent, false ); - } -} - - -/** - * Builds elements from the given node and its siblings and - * puts them into the list. - * Returns false if an error occures. - */ -bool SequenceElement::buildChildrenFromDom(TQPtrList& list, TQDomNode n) -{ - while (!n.isNull()) { - if (n.isElement()) { - TQDomElement e = n.toElement(); - BasicElement* child = 0; - TQString tag = e.tagName().upper(); - - child = createElement(tag, e); - if (child != 0) { - child->setParent(this); - if (child->buildFromDom(e)) { - list.append(child); - } - else { - delete child; - return false; - } - } - else { - return false; - } - } - n = n.nextSibling(); - } - parse(); - return true; -} - - -BasicElement* SequenceElement::createElement( TQString type, const TQDomElement& element ) -{ - return creationStrategy->createElement( type, element ); -} - -/** - * Appends our attributes to the dom element. - */ -void SequenceElement::writeDom(TQDomElement element) -{ - BasicElement::writeDom(element); - - uint count = children.count(); - TQDomDocument doc = element.ownerDocument(); - getChildrenDom(doc, element, 0, count); -} - -/** - * Reads our attributes from the element. - * Returns false if it failed. - */ -bool SequenceElement::readAttributesFromDom(TQDomElement element) -{ - if (!BasicElement::readAttributesFromDom(element)) { - return false; - } - return true; -} - -/** - * Reads our content from the node. Sets the node to the next node - * that needs to be read. - * Returns false if it failed. - */ -bool SequenceElement::readContentFromDom(TQDomNode& node) -{ - if (!BasicElement::readContentFromDom(node)) { - return false; - } - - return buildChildrenFromDom(children, node); -} - - -void SequenceElement::parse() -{ - delete parseTree; - - textSequence = true; - for (BasicElement* element = children.first(); - element != 0; - element = children.next()) { - - // Those types are gone. Make sure they won't - // be used. - element->setElementType(0); - - if (element->getCharacter().isNull()) { - textSequence = false; - } - } - - const SymbolTable& symbols = formula()->getSymbolTable(); - SequenceParser parser(symbols); - parseTree = parser.parse(children); - - // With the IndexElement dynamically changing its text/non-text - // behaviour we need to reparse your parent, too. Hacky! - BasicElement* p = getParent(); - if ( p != 0 ) { - SequenceElement* seq = dynamic_cast( p->getParent() ); - if ( seq != 0 ) { - seq->parse(); - } - } - // debug - //parseTree->output(); -} - - -bool SequenceElement::isFirstOfToken( BasicElement* child ) -{ - return ( child->getElementType() != 0 ) && isChildNumber( child->getElementType()->start(), child ); -} - - -TQString SequenceElement::toLatex() -{ - TQString content; - uint count = children.count(); - for ( uint i = 0; i < count; i++ ) { - BasicElement* child = children.at( i ); -// if ( isFirstOfToken( child ) ) { -// content += ""; -// } - content += child->toLatex(); - } - return content; -} - - -TQString SequenceElement::formulaString() -{ - TQString content; - uint count = children.count(); - for ( uint i = 0; i < count; i++ ) { - BasicElement* child = children.at( i ); - //if ( isFirstOfToken( child ) ) { - // content += " "; - //} - content += child->formulaString(); - } - return content; -} - - -void SequenceElement::writeMathMLContent( TQDomDocument& doc, TQDomElement& element, bool oasisFormat ) const -{ - for ( TQPtrListIterator it( children ); it.current(); ++it ) { - it.current()->writeMathML( doc, element, oasisFormat ); - } -} - - -const BasicElement* SequenceElement::getChild( uint i ) const -{ - TQPtrListIterator it( children ); - it += i; - return it.current(); -} - - -int SequenceElement::childPos( const BasicElement* child ) const -{ - TQPtrListIterator it( children ); - uint count = it.count(); - for ( uint i=0; ivisit( this ); -} - - -void NameSequence::calcCursorSize( const ContextStyle& context, - FormulaCursor* cursor, bool smallCursor ) -{ - inherited::calcCursorSize( context, cursor, smallCursor ); - LuPixelPoint point = widgetPos(); - luPixel unitX = context.ptToLayoutUnitPixX( 1 ); - luPixel unitY = context.ptToLayoutUnitPixY( 1 ); - cursor->addCursorSize( LuPixelRect( point.x()-unitX, point.y()-unitY, - getWidth()+2*unitX, getHeight()+2*unitY ) ); -} - -void NameSequence::drawCursor( TQPainter& painter, const ContextStyle& context, - StyleAttributes& style, FormulaCursor* cursor, - bool smallCursor, bool activeCursor ) -{ - LuPixelPoint point = widgetPos(); - painter.setPen( TQPen( context.getEmptyColor(), - context.layoutUnitToPixelX( context.getLineWidth( style.sizeFactor() )/2 ) ) ); - luPixel unitX = context.ptToLayoutUnitPixX( 1 ); - luPixel unitY = context.ptToLayoutUnitPixY( 1 ); - painter.drawRect( context.layoutUnitToPixelX( point.x()-unitX ), - context.layoutUnitToPixelY( point.y()-unitY ), - context.layoutUnitToPixelX( getWidth()+2*unitX ), - context.layoutUnitToPixelY( getHeight()+2*unitY ) ); - - inherited::drawCursor( painter, context, style, cursor, smallCursor, activeCursor ); -} - -void NameSequence::moveWordLeft( FormulaCursor* cursor ) -{ - uint pos = cursor->getPos(); - if ( pos > 0 ) { - cursor->setTo( this, 0 ); - } - else { - moveLeft( cursor, this ); - } -} - -void NameSequence::moveWordRight( FormulaCursor* cursor ) -{ - int pos = cursor->getPos(); - if ( pos < countChildren() ) { - cursor->setTo( this, countChildren() ); - } - else { - moveRight( cursor, this ); - } -} - - -KCommand* NameSequence::compactExpressionCmd( Container* container ) -{ - BasicElement* element = replaceElement( container->document()->getSymbolTable() ); - if ( element != 0 ) { - getParent()->selectChild( container->activeCursor(), this ); - - KFCReplace* command = new KFCReplace( i18n( "Add Element" ), container ); - command->addElement( element ); - return command; - } - return 0; -} - -KCommand* NameSequence::buildCommand( Container* container, Request* request ) -{ - switch ( *request ) { - case req_compactExpression: - return compactExpressionCmd( container ); - case req_addSpace: - case req_addIndex: - case req_addMatrix: - case req_addOneByTwoMatrix: - case req_addSymbol: - case req_addRoot: - case req_addFraction: - case req_addBracket: - case req_addNameSequence: - return 0; - default: - break; - } - return inherited::buildCommand( container, request ); -} - - -KCommand* NameSequence::input( Container* container, TQChar ch ) -{ - int unicode = ch.unicode(); - switch (unicode) { - case '(': - case '[': - case '|': - case '^': - case '_': - case '}': - case ']': - case ')': - case '\\': { -// KCommand* compact = compactExpressionCmd( container ); -// KCommand* cmd = static_cast( getParent() )->input( container, ch ); -// if ( compact != 0 ) { -// KMacroCommand* macro = new KMacroCommand( cmd->name() ); -// macro->addCommand( compact ); -// macro->addCommand( cmd ); -// return macro; -// } -// else { -// return cmd; -// } - break; - } - case '{': - case ' ': { - Request r( req_compactExpression ); - return buildCommand( container, &r ); - } - default: { - TextCharRequest r( ch ); - return buildCommand( container, &r ); - } - } - return 0; -} - -void NameSequence::setElementType( ElementType* t ) -{ - inherited::setElementType( t ); - parse(); -} - -BasicElement* NameSequence::replaceElement( const SymbolTable& table ) -{ - TQString name = buildName(); - TQChar ch = table.unicode( name ); - if ( !ch.isNull() ) { - return new TextElement( ch, true ); - } - else { - ch = table.unicode( i18n( name.latin1() ) ); - if ( !ch.isNull() ) { - return new TextElement( ch, true ); - } - } - - if ( name == "!" ) return new SpaceElement( NEGTHIN ); - if ( name == "," ) return new SpaceElement( THIN ); - if ( name == ">" ) return new SpaceElement( MEDIUM ); - if ( name == ";" ) return new SpaceElement( THICK ); - if ( name == "quad" ) return new SpaceElement( QUAD ); - - if ( name == "frac" ) return new FractionElement(); - if ( name == "atop" ) { - FractionElement* frac = new FractionElement(); - frac->showLine( false ); - return frac; - } - if ( name == "sqrt" ) return new RootElement(); - - return 0; -} - -BasicElement* NameSequence::createElement( TQString type ) -{ - if ( type == "TEXT" ) return new TextElement(); - return 0; -} - -// void NameSequence::parse() -// { -// // A name sequence is known as name and so are its children. -// // Caution: this is fake! -// for ( int i = 0; i < countChildren(); i++ ) { -// getChild( i )->setElementType( getElementType() ); -// } -// } - -TQString NameSequence::buildName() -{ - TQString name; - for ( uint i = 0; i < countChildren(); i++ ) { - name += getChild( i )->getCharacter(); - } - return name; -} - -bool NameSequence::isValidSelection( FormulaCursor* cursor ) -{ - SequenceElement* sequence = cursor->normal(); - if ( sequence == 0 ) { - return false; - } - return sequence->onlyTextSelected( cursor ); -} - -int SequenceElement::buildChildrenFromMathMLDom(TQPtrList& list, TQDomNode n) -{ - while (!n.isNull()) { - int nodeNumber = 1; - if (n.isElement()) { - TQDomElement e = n.toElement(); - BasicElement* child = 0; - TQString tag = e.tagName().lower(); - - kdDebug( DEBUGID ) << "Sequence Tag: " << tag << endl; - if ( tag == "semantics" ) { // Special case, just pick the first child - TQDomNode node = e.firstChild(); - while( ! node.isElement() ) { - node = node.nextSibling(); - if ( node.isNull() ) { - return -1; - } - } - e = node.toElement(); - tag = e.tagName().lower(); - } - child = creationStrategy->createElement(tag, e); - if (child != 0) { - child->setParent(this); - if (style != 0) { - child->setStyle(style); - } - nodeNumber = child->buildFromMathMLDom( e ); - if ( nodeNumber != -1 ) { - list.append(child); - } - else { - delete child; - return -1; - } - } - else { - kdWarning() << "Unsupported MathML element: " << tag << endl; - } - } - for (int i = 0; i < nodeNumber; i++ ) { - if ( n.isNull() ) { - return -1; - } - n = n.nextSibling(); - } - } - // Operator elements inside a sequence have to be parsed to get proper form - // value. Form value is needed to access operator dictionary and has to be - // obtained after sequence parsing since its value depends on position - // inside the sequence. - - // If the sequence contains more than one element, if the first or last - // element are operators, they have to be marked differently - if ( list.count() > 1 ) { - if ( list.getFirst()->getElementName() == "mo" ) { - static_cast( list.getFirst() )->setForm( PrefixForm ); - } - if ( list.getLast()->getElementName() == "mo" ) { - static_cast( list.getLast() )->setForm( PostfixForm ); - } - for ( uint i = 1; i < list.count() - 1; i++ ) { - if ( list.at( i )->getElementName() == "mo" ) { - static_cast( list.at( i ) )->setForm( InfixForm ); - } - } - } - else if ( list.count() == 1 ) { - if ( list.getFirst()->getElementName() == "mo" ) { - static_cast( list.getFirst() )->setForm( InfixForm ); - } - } - parse(); - return 1; -} - -/** - */ -int SequenceElement::readContentFromMathMLDom(TQDomNode& node) -{ - if ( BasicElement::readContentFromMathMLDom(node) == -1 ) { - return -1; - } - - return buildChildrenFromMathMLDom(children, node); -} - -int SequenceElement::buildMathMLChild( TQDomNode node ) -{ - int nodeCounter = 1; - while ( ! node.isElement() ) { - node = node.nextSibling(); - nodeCounter++; - if ( node.isNull() ) { - return -1; - } - } - TQDomElement e = node.toElement(); - BasicElement* child = 0; - TQString tag = e.tagName().lower(); - - child = creationStrategy->createElement(tag, e); - if (child != 0) { - child->setParent(this); - if (style != 0) { - child->setStyle(style); - } - if (child->buildFromMathMLDom(e) != -1) { - children.append(child); - } - else { - delete child; - return -1; - } - } - else { - return -1; - } - parse(); - return nodeCounter; -} - - - -KFORMULA_NAMESPACE_END diff --git a/lib/kformula/sequenceelement.cpp b/lib/kformula/sequenceelement.cpp new file mode 100644 index 00000000..187bcd65 --- /dev/null +++ b/lib/kformula/sequenceelement.cpp @@ -0,0 +1,1934 @@ +/* This file is part of the KDE project + Copyright (C) 2001 Andrea Rizzi + Ulrich Kuettler + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include + +#include +#include +#include + +#include +#include +#include + +//#include + +#include "MatrixDialog.h" +#include "bracketelement.h" +#include "creationstrategy.h" +#include "elementtype.h" +#include "elementvisitor.h" +#include "formulacursor.h" +#include "formulaelement.h" +#include "fractionelement.h" +#include "indexelement.h" +#include "kformulacommand.h" +#include "kformulacontainer.h" +#include "kformuladocument.h" +#include "matrixelement.h" +#include "rootelement.h" +#include "sequenceelement.h" +#include "sequenceparser.h" +#include "spaceelement.h" +#include "symbolelement.h" +#include "symboltable.h" +#include "textelement.h" +#include "numberelement.h" +#include "identifierelement.h" +#include "operatorelement.h" + +#include + +KFORMULA_NAMESPACE_BEGIN +//using namespace std; + +ElementCreationStrategy* SequenceElement::creationStrategy = 0; + +void SequenceElement::setCreationStrategy( ElementCreationStrategy* strategy ) +{ + creationStrategy = strategy; +} + +void SequenceElement::setStyle( StyleElement *st ) +{ + style = st; +} + +SequenceElement::SequenceElement(BasicElement* parent) + : BasicElement(parent), parseTree(0), textSequence(true),singlePipe(true), style(0) +{ + assert( creationStrategy != 0 ); + children.setAutoDelete(true); +} + + +SequenceElement::~SequenceElement() +{ + delete parseTree; +} + +SequenceElement::SequenceElement( const SequenceElement& other ) + : BasicElement( other ) +{ + children.setAutoDelete(true); + uint count = other.children.count(); + for (uint i = 0; i < count; i++) { + BasicElement* child = children.at(i)->clone(); + child->setParent( this ); + children.append( child ); + } +} + + +bool SequenceElement::accept( ElementVisitor* visitor ) +{ + return visitor->visit( this ); +} + + +bool SequenceElement::readOnly( const FormulaCursor* ) const +{ + return getParent()->readOnly( this ); +} + + +/** + * Returns the element the point is in. + */ +BasicElement* SequenceElement::goToPos( FormulaCursor* cursor, bool& handled, + const LuPixelPoint& point, const LuPixelPoint& parentOrigin ) +{ + BasicElement* e = BasicElement::goToPos(cursor, handled, point, parentOrigin); + if (e != 0) { + LuPixelPoint myPos(parentOrigin.x() + getX(), + parentOrigin.y() + getY()); + + uint count = children.count(); + for (uint i = 0; i < count; i++) { + BasicElement* child = children.at(i); + e = child->goToPos(cursor, handled, point, myPos); + if (e != 0) { + if (!handled) { + handled = true; + if ((point.x() - myPos.x()) < (e->getX() + e->getWidth()*2/3)) { + cursor->setTo(this, children.find(e)); + } + else { + cursor->setTo(this, children.find(e)+1); + } + } + return e; + } + } + + luPixel dx = point.x() - myPos.x(); + //int dy = point.y() - myPos.y(); + + for (uint i = 0; i < count; i++) { + BasicElement* child = children.at(i); + if (dx < child->getX()) { + cursor->setTo( this, i ); + handled = true; + return children.at( i ); + } + } + + cursor->setTo(this, countChildren()); + handled = true; + return this; + } + return 0; +} + + +bool SequenceElement::isEmpty() +{ + uint count = children.count(); + for (uint i = 0; i < count; i++) { + BasicElement* child = children.at(i); + if (!child->isInvisible()) { + return false; + } + } + return true; +} + + +/** + * Calculates our width and height and + * our children's parentPosition. + */ +void SequenceElement::calcSizes( const ContextStyle& context, + ContextStyle::TextStyle tstyle, + ContextStyle::IndexStyle istyle, + StyleAttributes& style ) +{ + double factor = style.sizeFactor(); + if (!isEmpty()) { + luPixel width = 0; + luPixel toBaseline = 0; + luPixel fromBaseline = 0; + + width += context.ptToPixelX( getSpaceBefore( context, tstyle, factor ) ); + + // Let's do all normal elements that have a base line. + TQPtrListIterator it( children ); + for ( ; it.current(); ++it ) { + BasicElement* child = it.current(); + + if ( !child->isInvisible() ) { + child->calcSizes( context, tstyle, istyle, style ); + child->setX( width ); + width += child->getWidth(); + + luPixel childBaseline = child->getBaseline(); + if ( childBaseline > -1 ) { + toBaseline = TQMAX( toBaseline, childBaseline ); + fromBaseline = TQMAX( fromBaseline, + child->getHeight() - childBaseline ); + } + else { + luPixel bl = child->getHeight()/2 + context.axisHeight( tstyle, factor ); + toBaseline = TQMAX( toBaseline, bl ); + fromBaseline = TQMAX( fromBaseline, child->getHeight() - bl ); + } + } + else { + child->setX( width ); + } + } + + width += context.ptToPixelX( getSpaceAfter( context, tstyle, factor ) ); + + setWidth(width); + setHeight(toBaseline+fromBaseline); + setBaseline(toBaseline); + + setChildrenPositions(); + } + else { + luPixel w = context.getEmptyRectWidth( factor ); + luPixel h = context.getEmptyRectHeight( factor ); + setWidth( w ); + setHeight( h ); + setBaseline( h ); + //setMidline( h*.5 ); + } +} + + +void SequenceElement::setChildrenPositions() +{ + TQPtrListIterator it( children ); + for ( ; it.current(); ++it ) { + BasicElement* child = it.current(); + child->setY(getBaseline() - child->getBaseline()); + } +} + + +/** + * Draws the whole element including its children. + * The `parentOrigin' is the point this element's parent starts. + * We can use our parentPosition to get our own origin then. + */ +void SequenceElement::draw( TQPainter& painter, const LuPixelRect& r, + const ContextStyle& context, + ContextStyle::TextStyle tstyle, + ContextStyle::IndexStyle istyle, + StyleAttributes& style, + const LuPixelPoint& parentOrigin ) +{ + LuPixelPoint myPos( parentOrigin.x() + getX(), parentOrigin.y() + getY() ); + // There might be zero sized elements that still want to be drawn at least + // in edit mode. (EmptyElement) + //if ( !LuPixelRect( myPos.x(), myPos.y(), getWidth(), getHeight() ).intersects( r ) ) + // return; + + if (!isEmpty()) { + TQPtrListIterator it( children ); + for (int i = 0 ; it.current(); i++) { + BasicElement* child = it.current(); + if (!child->isInvisible()) { + child->draw(painter, r, context, tstyle, istyle, style, myPos); + + // Each starting element draws the whole token + // This only concerns TextElements. + /* + ElementType* token = child->getElementType(); + if ( token != 0 ) { + it += token->end() - token->start(); + } + else { + ++it; + } + */ + } +// else { + ++it; +// } + } + } + else { + drawEmptyRect( painter, context, style.sizeFactor(), myPos ); + } + // Debug + //painter.setPen(TQt::green); + //painter.drawRect(parentOrigin.x() + getX(), parentOrigin.y() + getY(), + // getWidth(), getHeight()); +// painter.drawLine( context.layoutUnitToPixelX( parentOrigin.x() + getX() ), +// context.layoutUnitToPixelY( parentOrigin.y() + getY() + axis( context, tstyle ) ), +// context.layoutUnitToPixelX( parentOrigin.x() + getX() + getWidth() ), +// context.layoutUnitToPixelY( parentOrigin.y() + getY() + axis( context, tstyle ) ) ); +// painter.setPen(TQt::red); +// painter.drawLine( context.layoutUnitToPixelX( parentOrigin.x() + getX() ), +// context.layoutUnitToPixelY( parentOrigin.y() + getY() + getBaseline() ), +// context.layoutUnitToPixelX( parentOrigin.x() + getX() + getWidth() ), +// context.layoutUnitToPixelY( parentOrigin.y() + getY() + getBaseline() ) ); +} + + +void SequenceElement::dispatchFontCommand( FontCommand* cmd ) +{ + TQPtrListIterator it( children ); + for ( ; it.current(); ++it ) { + BasicElement* child = it.current(); + child->dispatchFontCommand( cmd ); + } +} + + +void SequenceElement::drawEmptyRect( TQPainter& painter, const ContextStyle& context, + double factor, const LuPixelPoint& upperLeft ) +{ + if ( context.edit() ) { + painter.setBrush(TQt::NoBrush); + painter.setPen( TQPen( context.getEmptyColor(), + context.layoutUnitToPixelX( context.getLineWidth( factor ) ) ) ); + painter.drawRect( context.layoutUnitToPixelX( upperLeft.x() ), + context.layoutUnitToPixelY( upperLeft.y() ), + context.layoutUnitToPixelX( getWidth() ), + context.layoutUnitToPixelY( getHeight() ) ); + } +} + +void SequenceElement::calcCursorSize( const ContextStyle& context, + FormulaCursor* cursor, bool smallCursor ) +{ + LuPixelPoint point = widgetPos(); + uint pos = cursor->getPos(); + + luPixel posX = getChildPosition( context, pos ); + luPixel height = getHeight(); + + luPixel unitX = context.ptToLayoutUnitPixX( 1 ); + luPixel unitY = context.ptToLayoutUnitPixY( 1 ); + + // Here are those evil constants that describe the cursor size. + + if ( cursor->isSelection() ) { + uint mark = cursor->getMark(); + luPixel markX = getChildPosition( context, mark ); + luPixel x = TQMIN(posX, markX); + luPixel width = abs(posX - markX); + + if ( smallCursor ) { + cursor->cursorSize.setRect( point.x()+x, point.y(), width, height ); + } + else { + cursor->cursorSize.setRect( point.x()+x, point.y() - 2*unitY, + width + unitX, height + 4*unitY ); + } + } + else { + if ( smallCursor ) { + cursor->cursorSize.setRect( point.x()+posX, point.y(), + unitX, height ); + } + else { + cursor->cursorSize.setRect( point.x(), point.y() - 2*unitY, + getWidth() + unitX, height + 4*unitY ); + } + } + + cursor->cursorPoint.setX( point.x()+posX ); + cursor->cursorPoint.setY( point.y()+getHeight()/2 ); +} + + +/** + * If the cursor is inside a sequence it needs to be drawn. + */ +void SequenceElement::drawCursor( TQPainter& painter, const ContextStyle& context, + StyleAttributes& style, FormulaCursor* cursor, + bool smallCursor, bool activeCursor ) +{ + painter.setRasterOp( TQt::XorROP ); + if ( cursor->isSelection() ) { + const LuPixelRect& r = cursor->cursorSize; + painter.fillRect( context.layoutUnitToPixelX( r.x() ), + context.layoutUnitToPixelY( r.y() ), + context.layoutUnitToPixelX( r.width() ), + context.layoutUnitToPixelY( r.height() ), + TQt::white ); + } + painter.setPen( TQPen( TQt::white, + context.layoutUnitToPixelX( context.getLineWidth( style.sizeFactor() )/2 ) ) ); + const LuPixelPoint& point = cursor->getCursorPoint(); + const LuPixelRect& size = cursor->getCursorSize(); + if ( activeCursor ) + { + int offset = 0; + if ( cursor->isSelection() && cursor->getPos() > cursor->getMark() ) + offset = -1; + painter.drawLine( context.layoutUnitToPixelX( point.x() ) + offset, + context.layoutUnitToPixelY( size.top() ), + context.layoutUnitToPixelX( point.x() ) + offset, + context.layoutUnitToPixelY( size.bottom() )-1 ); + painter.drawLine( context.layoutUnitToPixelX( point.x() ) + offset + 1, + context.layoutUnitToPixelY( size.top() ), + context.layoutUnitToPixelX( point.x() ) + offset + 1, + context.layoutUnitToPixelY( size.bottom() )-1 ); + } + if ( !smallCursor && !cursor->isSelection() ) + painter.drawLine( context.layoutUnitToPixelX( size.left() ), + context.layoutUnitToPixelY( size.bottom() )-1, + context.layoutUnitToPixelX( size.right() )-1, + context.layoutUnitToPixelY( size.bottom() )-1 ); + // This might be wrong but probably isn't. + painter.setRasterOp( TQt::CopyROP ); +} + + +luPixel SequenceElement::getChildPosition( const ContextStyle& context, uint child ) +{ + if (child < children.count()) { + return children.at(child)->getX(); + } + else { + if (children.count() > 0) { + return children.at(child-1)->getX() + children.at(child-1)->getWidth(); + } + else { + return context.ptToLayoutUnitPixX( 2 ); + } + } +} + + +// navigation +// +// The elements are responsible to handle cursor movement themselves. +// To do this they need to know the direction the cursor moves and +// the element it comes from. +// +// The cursor might be in normal or in selection mode. + +/** + * Enters this element while moving to the left starting inside + * the element `from'. Searches for a cursor position inside + * this element or to the left of it. + */ +void SequenceElement::moveLeft(FormulaCursor* cursor, BasicElement* from) +{ + // Our parent asks us for a cursor position. Found. + if (from == getParent()) { + cursor->setTo(this, children.count()); + if ( cursor->isSelectionMode() ) { + cursor->setMark( children.count() ); + } + from->entered( this ); + } + + // We already owned the cursor. Ask next child then. + else if (from == this) { + if (cursor->getPos() > 0) { + cursor->setTo(this, cursor->getPos()-1); + + // invisible elements are not visible so we move on. + if (children.at(cursor->getPos())->isInvisible()) { + moveLeft(cursor, this); + } + } + else { + // Needed because FormulaElement derives this. + if (getParent() != 0) { + getParent()->moveLeft(cursor, this); + } + else { + formula()->moveOutLeft( cursor ); + } + } + } + + // The cursor came from one of our children or + // something is wrong. + else { + int fromPos = children.find(from); + if ( fromPos > 0 ) { + children.at( fromPos - 1)->moveLeft( cursor, this ); + } + + // invisible elements are not visible so we move on. + if (from->isInvisible()) { + moveLeft(cursor, this); + } + formula()->tell( "" ); + } +} + +/** + * Enters this element while moving to the right starting inside + * the element `from'. Searches for a cursor position inside + * this element or to the right of it. + */ +void SequenceElement::moveRight(FormulaCursor* cursor, BasicElement* from) +{ + // Our parent asks us for a cursor position. Found. + if (from == getParent()) { + cursor->setTo(this, 0); + from->entered( this ); + } + + // We already owned the cursor. Ask next child then. + else if (from == this) { + uint pos = cursor->getPos(); + if (pos < children.count()) { + cursor->setTo(this, pos+1); + + // invisible elements are not visible so we move on. + if (children.at(pos)->isInvisible()) { + moveRight(cursor, this); + } + } + else { + // Needed because FormulaElement derives this. + if (getParent() != 0) { + getParent()->moveRight(cursor, this); + } + else { + formula()->moveOutRight( cursor ); + } + } + } + + // The cursor came from one of our children or + // something is wrong. + else { + int fromPos = children.find(from); + if ( fromPos < children.count() - 1 ) { + children.at( fromPos + 1 )->moveDown( cursor, this ); + } + else { + cursor->setTo(this, fromPos+1); + } + if (cursor->isSelectionMode()) { + cursor->setMark(fromPos); + } + + // invisible elements are not visible so we move on. + if (from->isInvisible()) { + moveRight(cursor, this); + } + formula()->tell( "" ); + } +} + + +void SequenceElement::moveWordLeft(FormulaCursor* cursor) +{ + uint pos = cursor->getPos(); + if (pos > 0) { + ElementType* type = children.at(pos-1)->getElementType(); + if (type != 0) { + cursor->setTo(this, type->start()); + } + } + else { + moveLeft(cursor, this); + } +} + + +void SequenceElement::moveWordRight(FormulaCursor* cursor) +{ + uint pos = cursor->getPos(); + if (pos < children.count()) { + ElementType* type = children.at(pos)->getElementType(); + if (type != 0) { + cursor->setTo(this, type->end()); + } + } + else { + moveRight(cursor, this); + } +} + + +/** + * Enters this element while moving up starting inside + * the element `from'. Searches for a cursor position inside + * this element or above it. + */ +void SequenceElement::moveUp(FormulaCursor* cursor, BasicElement* from) +{ + if (from == getParent()) { + moveRight(cursor, this); + } + else if ( from == this ) { + if ( getParent() != 0 ) { + uint pos = cursor->getPos(); + if ( pos < (children.count() - 1) / 2 ) { + getParent()->moveLeft( cursor, this ); + } + else { + getParent()->moveRight( cursor, this ); + } + } + else { + formula()->moveOutAbove( cursor ); + } + } + else { + if (getParent() != 0) { + getParent()->moveUp(cursor, this); + } + else { + formula()->moveOutAbove( cursor ); + } + } +} + +/** + * Enters this element while moving down starting inside + * the element `from'. Searches for a cursor position inside + * this element or below it. + */ +void SequenceElement::moveDown(FormulaCursor* cursor, BasicElement* from) +{ + if (from == getParent()) { + cursor->setTo(this, 0); + from->entered( this ); + } + else if (from == this) { + uint pos = cursor->getPos(); + if (pos < children.count()) { + children.at(pos)->moveDown(cursor, this); + } + } + else { + if (getParent() != 0) { + getParent()->moveDown(cursor, this); + } + else { + cursor->setTo( this, children.count() ); + from->entered( this ); +// formula()->moveOutBelow( cursor ); + } + } +} + +/** + * Moves the cursor to the first position in this sequence. + * (That is before the first child.) + */ +void SequenceElement::moveHome(FormulaCursor* cursor) +{ + if (cursor->isSelectionMode()) { + BasicElement* element = cursor->getElement(); + if (element != this) { + while (element->getParent() != this) { + element = element->getParent(); + } + cursor->setMark(children.find(element)+1); + } + } + cursor->setTo(this, 0); +} + +/** + * Moves the cursor to the last position in this sequence. + * (That is behind the last child.) + */ +void SequenceElement::moveEnd(FormulaCursor* cursor) +{ + if (cursor->isSelectionMode()) { + BasicElement* element = cursor->getElement(); + if (element != this) { + while (element->getParent() != this) { + element = element->getParent(); + if (element == 0) { + cursor->setMark(children.count()); + break; + } + } + if (element != 0) { + cursor->setMark(children.find(element)); + } + } + } + cursor->setTo(this, children.count()); +} + +/** + * Sets the cursor inside this element to its start position. + * For most elements that is the main child. + */ +void SequenceElement::goInside(FormulaCursor* cursor) +{ + cursor->setSelection(false); + cursor->setTo(this, 0); +} + +/** + * Sets the cursor inside this element to its end position. + * For most elements that is the main child. + */ +void SequenceElement::goInsideLast(FormulaCursor* cursor) +{ + cursor->setSelection(false); + cursor->setTo(this, children.count()); +} + + +// children + + /** + * Insert a new child in the sequence + * + * @returns true if succesful, i.e. if index is in range, otherwise returns + * false. The valid range is 0 to count(). The child is appended if index == count(). + * + * @param index position in the sequence to insert the child + * @param child the child to insert in the sequence + */ + +bool SequenceElement::insert( uint index, BasicElement *child ) +{ + return children.insert( index, child ); +} + +/** + * Removes the child. If this was the main child this element might + * request its own removal. + * The cursor is the one that caused the removal. It has to be moved + * to the place any user expects the cursor after that particular + * element has been removed. + */ +// void SequenceElement::removeChild(FormulaCursor* cursor, BasicElement* child) +// { +// int pos = children.find(child); +// formula()->elementRemoval(child, pos); +// cursor->setTo(this, pos); +// children.remove(pos); +// /* +// if len(self.children) == 0: +// if self.parent != None: +// self.parent.removeChild(cursor, self) +// return +// */ +// formula()->changed(); +// } + + +/** + * Inserts all new children at the cursor position. Places the + * cursor according to the direction. The inserted elements will + * be selected. + * + * The list will be emptied but stays the property of the caller. + */ +void SequenceElement::insert(FormulaCursor* cursor, + TQPtrList& newChildren, + Direction direction) +{ + int pos = cursor->getPos(); + uint count = newChildren.count(); + for (uint i = 0; i < count; i++) { + BasicElement* child = newChildren.take(0); + child->setParent(this); + children.insert(pos+i, child); + } + if (direction == beforeCursor) { + cursor->setTo(this, pos+count, pos); + } + else { + cursor->setTo(this, pos, pos+count); + } + + formula()->changed(); + parse(); +} + + +/** + * Removes all selected children and returns them. Places the + * cursor to where the children have been. + * + * The ownership of the list is passed to the caller. + */ +void SequenceElement::remove(FormulaCursor* cursor, + TQPtrList& removedChildren, + Direction direction) +{ + if (cursor->isSelection()) { + int from = cursor->getSelectionStart(); + int to = cursor->getSelectionEnd(); + for (int i = from; i < to; i++) { + removeChild(removedChildren, from); + } + cursor->setTo(this, from); + cursor->setSelection(false); + } + else { + if (direction == beforeCursor) { + int pos = cursor->getPos() - 1; + if (pos >= 0) { + while (pos >= 0) { + BasicElement* child = children.at(pos); + formula()->elementRemoval(child); + children.take(pos); + removedChildren.prepend(child); + if (!child->isInvisible()) { + break; + } + pos--; + } + cursor->setTo(this, pos); + formula()->changed(); + } + } + else { + uint pos = cursor->getPos(); + if (pos < children.count()) { + while (pos < children.count()) { + BasicElement* child = children.at(pos); + formula()->elementRemoval(child); + children.take(pos); + removedChildren.append(child); + if (!child->isInvisible()) { + break; + } + } + // It is necessary to set the cursor to its old + // position because it got a notification and + // moved to the beginning of this sequence. + cursor->setTo(this, pos); + formula()->changed(); + } + } + } + parse(); +} + + +/** + * Removes the children at pos and appends it to the list. + */ +void SequenceElement::removeChild(TQPtrList& removedChildren, int pos) +{ + BasicElement* child = children.at(pos); + formula()->elementRemoval(child); + children.take(pos); + removedChildren.append(child); + //cerr << *removedChildren.at(0) << endl; + formula()->changed(); +} + + +/** + * Moves the cursor to a normal place where new elements + * might be inserted. + */ +void SequenceElement::normalize(FormulaCursor* cursor, Direction) +{ + cursor->setSelection(false); +} + + +/** + * Returns the child at the cursor. + * Does not care about the selection. + */ +BasicElement* SequenceElement::getChild( FormulaCursor* cursor, Direction direction ) +{ + if ( direction == beforeCursor ) { + if ( cursor->getPos() > 0 ) { + return children.at( cursor->getPos() - 1 ); + } + } + else { + if ( cursor->getPos() < tqRound( children.count() ) ) { + return children.at( cursor->getPos() ); + } + } + return 0; +} + + +/** + * Sets the cursor to select the child. The mark is placed before, + * the position behind it. + */ +void SequenceElement::selectChild(FormulaCursor* cursor, BasicElement* child) +{ + int pos = children.find(child); + if (pos > -1) { + cursor->setTo(this, pos+1, pos); + } +} + +void SequenceElement::childWillVanish(FormulaCursor* cursor, BasicElement* child) +{ + int childPos = children.find(child); + if (childPos > -1) { + int pos = cursor->getPos(); + if (pos > childPos) { + pos--; + } + int mark = cursor->getMark(); + if (mark > childPos) { + mark--; + } + cursor->setTo(this, pos, mark); + } +} + + +/** + * Selects all children. The cursor is put behind, the mark before them. + */ +void SequenceElement::selectAllChildren(FormulaCursor* cursor) +{ + cursor->setTo(this, children.count(), 0); +} + +bool SequenceElement::onlyTextSelected( FormulaCursor* cursor ) +{ + if ( cursor->isSelection() ) { + uint from = TQMIN( cursor->getPos(), cursor->getMark() ); + uint to = TQMAX( cursor->getPos(), cursor->getMark() ); + for ( uint i = from; i < to; i++ ) { + BasicElement* element = getChild( i ); + if ( element->getCharacter() == TQChar::null ) { + return false; + } + } + } + return true; +} + + +KCommand* SequenceElement::buildCommand( Container* container, Request* request ) +{ + FormulaCursor* cursor = container->activeCursor(); + if ( cursor->isReadOnly() ) { + formula()->tell( i18n( "write protection" ) ); + return 0; + } + + switch ( *request ) { + case req_addText: { + KFCReplaceToken* command = new KFCReplaceToken( i18n("Add Text"), container ); + TextRequest* tr = static_cast( request ); + IdentifierElement* id = creationStrategy->createIdentifierElement(); + command->addToken( id ); + for ( uint i = 0; i < tr->text().length(); i++ ) { + TextElement* text = creationStrategy->createTextElement( tr->text()[i] ); + command->addContent( id, text ); + } + return command; + } + case req_addTextChar: { + KFCReplaceToken* command = new KFCReplaceToken( i18n("Add Text"), container ); + TextCharRequest* tr = static_cast( request ); + IdentifierElement* id = creationStrategy->createIdentifierElement(); + TextElement* text = creationStrategy->createTextElement( tr->ch() ); + command->addToken( id ); + command->addContent( id, text ); + return command; + } + + case req_addOperator: { + KFCReplaceToken* command = new KFCReplaceToken( i18n("Add Operator"), container ); + OperatorRequest* opr = static_cast( request ); + OperatorElement* op = creationStrategy->createOperatorElement(); + TextElement* text = creationStrategy->createTextElement( opr->ch() ); + command->addToken( op ); + command->addContent( op, text ); + return command; + } + + case req_addNumber: { + KFCReplaceToken* command = new KFCReplaceToken( i18n("Add Number"), container ); + NumberRequest* nr = static_cast( request ); + NumberElement* num = creationStrategy->createNumberElement(); + num->setParent( this ); + TextElement* text = creationStrategy->createTextElement( nr->ch() ); + text->setParent( num ); + command->addToken( num ); + command->addContent( num, text ); + return command; + } + + case req_addEmptyBox: { + EmptyElement* element = creationStrategy->createEmptyElement(); + if ( element != 0 ) { + KFCReplace* command = new KFCReplace( i18n("Add Empty Box"), container ); + command->addElement( element ); + return command; + } + break; + } + case req_addNameSequence: + if ( onlyTextSelected( container->activeCursor() ) ) { + NameSequence* nameSequence = creationStrategy->createNameSequence(); + if ( nameSequence != 0 ) { + KFCAddReplacing* command = new KFCAddReplacing( i18n( "Add Name" ), container ); + command->setElement( nameSequence ); + return command; + } + } + break; + case req_addBracket: { + BracketRequest* br = static_cast( request ); + BracketElement* bracketElement = + creationStrategy->createBracketElement( br->left(), br->right() ); + if ( bracketElement != 0 ) { + KFCAddReplacing* command = new KFCAddReplacing(i18n("Add Bracket"), container); + command->setElement( bracketElement ); + return command; + } + break; + } + case req_addOverline: { + OverlineElement* overline = creationStrategy->createOverlineElement(); + if ( overline != 0 ) { + KFCAddReplacing* command = new KFCAddReplacing(i18n("Add Overline"), container); + command->setElement( overline ); + return command; + } + break; + } + case req_addUnderline: { + UnderlineElement* underline = creationStrategy->createUnderlineElement(); + if ( underline != 0 ) { + KFCAddReplacing* command = new KFCAddReplacing(i18n("Add Underline"), container); + command->setElement( underline ); + return command; + } + break; + } + case req_addMultiline: { + MultilineElement* multiline = creationStrategy->createMultilineElement(); + if ( multiline != 0 ) { + KFCAddReplacing* command = new KFCAddReplacing(i18n("Add Multiline"), container); + command->setElement( multiline ); + return command; + } + break; + } + case req_addSpace: { + SpaceRequest* sr = static_cast( request ); + SpaceElement* element = creationStrategy->createSpaceElement( sr->space() ); + if ( element != 0 ) { + KFCReplace* command = new KFCReplace( i18n("Add Space"), container ); + command->addElement( element ); + return command; + } + break; + } + case req_addFraction: { + FractionElement* fraction = creationStrategy->createFractionElement(); + if ( fraction != 0 ) { + KFCAddReplacing* command = new KFCAddReplacing(i18n("Add Fraction"), container); + command->setElement( fraction ); + return command; + } + break; + } + case req_addRoot: { + RootElement* root = creationStrategy->createRootElement(); + if ( root != 0 ) { + KFCAddReplacing* command = new KFCAddReplacing(i18n("Add Root"), container); + command->setElement( root ); + return command; + } + break; + } + case req_addSymbol: { + SymbolRequest* sr = static_cast( request ); + SymbolElement* symbol = creationStrategy->createSymbolElement( sr->type() ); + if ( symbol != 0 ) { + KFCAddReplacing* command = new KFCAddReplacing( i18n( "Add Symbol" ), container ); + command->setElement( symbol ); + return command; + } + break; + } + case req_addOneByTwoMatrix: { + FractionElement* element = creationStrategy->createFractionElement(); + if ( element != 0 ) { + KFCAddReplacing* command = new KFCAddReplacing( i18n("Add 1x2 Matrix"), container ); + element->showLine(false); + command->setElement(element); + return command; + } + } + case req_addMatrix: { + MatrixRequest* mr = static_cast( request ); + uint rows = mr->rows(), cols = mr->columns(); + if ( ( rows == 0 ) || ( cols == 0 ) ) { + MatrixDialog* dialog = new MatrixDialog( 0 ); + if ( dialog->exec() ) { + rows = dialog->h; + cols = dialog->w; + } + delete dialog; + } + + if ( ( rows != 0 ) && ( cols != 0 ) ) { + KFCAddReplacing* command = new KFCAddReplacing( i18n( "Add Matrix" ), container ); + command->setElement( creationStrategy->createMatrixElement( rows, cols ) ); + return command; + } + else + return 0L; + } + case req_addIndex: { + if ( cursor->getPos() > 0 && !cursor->isSelection() ) { + IndexElement* element = + dynamic_cast( children.at( cursor->getPos()-1 ) ); + if ( element != 0 ) { + element->goInside( cursor ); + return element->buildCommand( container, request ); + } + } + IndexElement* element = creationStrategy->createIndexElement(); + if ( element != 0 ) { + if ( !cursor->isSelection() ) { + cursor->moveLeft( SelectMovement | WordMovement ); + } + IndexRequest* ir = static_cast( request ); + KFCAddIndex* command = new KFCAddIndex( container, element, + element->getIndex( ir->index() ) ); + return command; + } + break; + } + case req_removeEnclosing: { + if ( !cursor->isSelection() ) { + DirectedRemove* dr = static_cast( request ); + KFCRemoveEnclosing* command = new KFCRemoveEnclosing( container, dr->direction() ); + return command; + } + } + case req_remove: { + SequenceElement* sequence = cursor->normal(); + if ( sequence && + ( sequence == sequence->formula() ) && + ( sequence->countChildren() == 0 ) ) { + sequence->formula()->removeFormula( cursor ); + return 0; + } + else { + DirectedRemove* dr = static_cast( request ); + + // empty removes are not legal! + if ( !cursor->isSelection() ) { + if ( countChildren() > 0 ) { + if ( ( cursor->getPos() == 0 ) && ( dr->direction() == beforeCursor ) ) { + return 0; + } + if ( ( cursor->getPos() == countChildren() ) && ( dr->direction() == afterCursor ) ) { + return 0; + } + } + else if ( getParent() == 0 ) { + return 0; + } + } + + KFCRemove* command = new KFCRemove( container, dr->direction() ); + return command; + } + } + case req_compactExpression: { + cursor->moveEnd(); + cursor->moveRight(); + formula()->cursorHasMoved( cursor ); + break; + } + case req_makeGreek: { + TextElement* element = cursor->getActiveTextElement(); + if ((element != 0) && !element->isSymbol()) { + cursor->selectActiveElement(); + const SymbolTable& table = container->document()->getSymbolTable(); + if (table.greekLetters().find(element->getCharacter()) != -1) { + KFCReplace* command = new KFCReplace( i18n( "Change Char to Symbol" ), container ); + TextElement* symbol = creationStrategy->createTextElement( table.unicodeFromSymbolFont( element->getCharacter() ), true ); + command->addElement( symbol ); + return command; + } + cursor->setSelection( false ); + } + break; + } + case req_paste: + case req_copy: + case req_cut: + break; + case req_formatBold: + case req_formatItalic: { + if ( cursor->isSelection() ) { + CharStyleRequest* csr = static_cast( request ); + CharStyle cs = normalChar; + if ( csr->bold() ) cs = static_cast( cs | boldChar ); + if ( csr->italic() ) cs = static_cast( cs | italicChar ); + CharStyleCommand* cmd = new CharStyleCommand( cs, i18n( "Change Char Style" ), container ); + int end = cursor->getSelectionEnd(); + for ( int i = cursor->getSelectionStart(); iaddElement( children.at( i ) ); + } + return cmd; + } + break; + } + case req_formatFamily: { + if ( cursor->isSelection() ) { + CharFamilyRequest* cfr = static_cast( request ); + CharFamily cf = cfr->charFamily(); + CharFamilyCommand* cmd = new CharFamilyCommand( cf, i18n( "Change Char Family" ), container ); + int end = cursor->getSelectionEnd(); + for ( int i = cursor->getSelectionStart(); iaddElement( children.at( i ) ); + } + return cmd; + } + break; + } + default: + break; + } + return 0; +} + + +KCommand* SequenceElement::input( Container* container, TQKeyEvent* event ) +{ + TQChar ch = event->text().at( 0 ); + if ( ch.isPrint() ) { + return input( container, ch ); + } + else { + int action = event->key(); + int state = event->state(); + MoveFlag flag = movementFlag(state); + + switch ( action ) { + case TQt::Key_BackSpace: { + DirectedRemove r( req_remove, beforeCursor ); + return buildCommand( container, &r ); + } + case TQt::Key_Delete: { + DirectedRemove r( req_remove, afterCursor ); + return buildCommand( container, &r ); + } + case TQt::Key_Left: { + FormulaCursor* cursor = container->activeCursor(); + cursor->moveLeft( flag ); + formula()->cursorHasMoved( cursor ); + break; + } + case TQt::Key_Right: { + FormulaCursor* cursor = container->activeCursor(); + cursor->moveRight( flag ); + formula()->cursorHasMoved( cursor ); + break; + } + case TQt::Key_Up: { + FormulaCursor* cursor = container->activeCursor(); + cursor->moveUp( flag ); + formula()->cursorHasMoved( cursor ); + break; + } + case TQt::Key_Down: { + FormulaCursor* cursor = container->activeCursor(); + cursor->moveDown( flag ); + formula()->cursorHasMoved( cursor ); + break; + } + case TQt::Key_Home: { + FormulaCursor* cursor = container->activeCursor(); + cursor->moveHome( flag ); + formula()->cursorHasMoved( cursor ); + break; + } + case TQt::Key_End: { + FormulaCursor* cursor = container->activeCursor(); + cursor->moveEnd( flag ); + formula()->cursorHasMoved( cursor ); + break; + } + default: + if ( state & TQt::ControlButton ) { + switch ( event->key() ) { + case TQt::Key_AsciiCircum: { + IndexRequest r( upperLeftPos ); + return buildCommand( container, &r ); + } + case TQt::Key_Underscore: { + IndexRequest r( lowerLeftPos ); + return buildCommand( container, &r ); + } + default: + break; + } + } + } + } + return 0; +} + + +KCommand* SequenceElement::input( Container* container, TQChar ch ) +{ + int unicode = ch.unicode(); + switch (unicode) { + case '(': { + BracketRequest r( container->document()->leftBracketChar(), + container->document()->rightBracketChar() ); + singlePipe = true; + return buildCommand( container, &r ); + } + case '[': { + BracketRequest r( LeftSquareBracket, RightSquareBracket ); + singlePipe = true; + return buildCommand( container, &r ); + } + case '{': { + BracketRequest r( LeftCurlyBracket, RightCurlyBracket ); + singlePipe = true; + return buildCommand( container, &r ); + } + case '|': { + if (!singlePipe) { // We have had 2 '|' in a row so we want brackets + + DirectedRemove rDelete( req_remove, beforeCursor ); //Delete the previous '|' we dont need it any more + KCommand* command = buildCommand( container, &rDelete ); + command->execute(); + + BracketRequest rBracket( LeftLineBracket , RightLineBracket); + singlePipe = true; //the next '|' will be a single pipe again + return buildCommand( container, &rBracket ); + } + else { // We really do only want 1 '|' + TextCharRequest r(ch); + + //in case another '|' character is entered right after this one, '| |' brackets are made; see above + singlePipe = false; + + return buildCommand( container, &r ); + } + } + case '^': { + IndexRequest r( upperRightPos ); + singlePipe = true; + return buildCommand( container, &r ); + } + case '_': { + IndexRequest r( lowerRightPos ); + singlePipe = true; + return buildCommand( container, &r ); + } + /* + case ' ': { + Request r( req_compactExpression ); + singlePipe = true; + return buildCommand( container, &r ); + }*/ + case '}': { + Request r( req_addEmptyBox ); + singlePipe = true; + return buildCommand( container, &r ); + } + case ']': + case ')': + singlePipe = true; + break; + case '\\': { + Request r( req_addNameSequence ); + singlePipe = true; + return buildCommand( container, &r ); + } + default: { + singlePipe = true; + if ( ch.isPunct() || ch.isSymbol() ) { + OperatorRequest r( ch ); + return buildCommand( container, &r ); + } + if ( ch.isNumber() ) { + NumberRequest r( ch ); + return buildCommand( container, &r ); + } + TextCharRequest r( ch ); + return buildCommand( container, &r ); + } + } + return 0; +} + +/** + * Stores the given childrens dom in the element. + */ +void SequenceElement::getChildrenDom( TQDomDocument& doc, TQDomElement elem, + uint from, uint to) +{ + for (uint i = from; i < to; i++) { + TQDomElement tmpEleDom=children.at(i)->getElementDom(doc); + elem.appendChild(tmpEleDom); + } +} + +/** + * Stores the given childrens MathML dom in the element. + */ +void SequenceElement::getChildrenMathMLDom( TQDomDocument& doc, TQDomNode& parent, + uint from, uint to) +{ + for ( uint i = from; i < to; i++ ) { + children.at( i )->writeMathML( doc, parent, false ); + } +} + + +/** + * Builds elements from the given node and its siblings and + * puts them into the list. + * Returns false if an error occures. + */ +bool SequenceElement::buildChildrenFromDom(TQPtrList& list, TQDomNode n) +{ + while (!n.isNull()) { + if (n.isElement()) { + TQDomElement e = n.toElement(); + BasicElement* child = 0; + TQString tag = e.tagName().upper(); + + child = createElement(tag, e); + if (child != 0) { + child->setParent(this); + if (child->buildFromDom(e)) { + list.append(child); + } + else { + delete child; + return false; + } + } + else { + return false; + } + } + n = n.nextSibling(); + } + parse(); + return true; +} + + +BasicElement* SequenceElement::createElement( TQString type, const TQDomElement& element ) +{ + return creationStrategy->createElement( type, element ); +} + +/** + * Appends our attributes to the dom element. + */ +void SequenceElement::writeDom(TQDomElement element) +{ + BasicElement::writeDom(element); + + uint count = children.count(); + TQDomDocument doc = element.ownerDocument(); + getChildrenDom(doc, element, 0, count); +} + +/** + * Reads our attributes from the element. + * Returns false if it failed. + */ +bool SequenceElement::readAttributesFromDom(TQDomElement element) +{ + if (!BasicElement::readAttributesFromDom(element)) { + return false; + } + return true; +} + +/** + * Reads our content from the node. Sets the node to the next node + * that needs to be read. + * Returns false if it failed. + */ +bool SequenceElement::readContentFromDom(TQDomNode& node) +{ + if (!BasicElement::readContentFromDom(node)) { + return false; + } + + return buildChildrenFromDom(children, node); +} + + +void SequenceElement::parse() +{ + delete parseTree; + + textSequence = true; + for (BasicElement* element = children.first(); + element != 0; + element = children.next()) { + + // Those types are gone. Make sure they won't + // be used. + element->setElementType(0); + + if (element->getCharacter().isNull()) { + textSequence = false; + } + } + + const SymbolTable& symbols = formula()->getSymbolTable(); + SequenceParser parser(symbols); + parseTree = parser.parse(children); + + // With the IndexElement dynamically changing its text/non-text + // behaviour we need to reparse your parent, too. Hacky! + BasicElement* p = getParent(); + if ( p != 0 ) { + SequenceElement* seq = dynamic_cast( p->getParent() ); + if ( seq != 0 ) { + seq->parse(); + } + } + // debug + //parseTree->output(); +} + + +bool SequenceElement::isFirstOfToken( BasicElement* child ) +{ + return ( child->getElementType() != 0 ) && isChildNumber( child->getElementType()->start(), child ); +} + + +TQString SequenceElement::toLatex() +{ + TQString content; + uint count = children.count(); + for ( uint i = 0; i < count; i++ ) { + BasicElement* child = children.at( i ); +// if ( isFirstOfToken( child ) ) { +// content += ""; +// } + content += child->toLatex(); + } + return content; +} + + +TQString SequenceElement::formulaString() +{ + TQString content; + uint count = children.count(); + for ( uint i = 0; i < count; i++ ) { + BasicElement* child = children.at( i ); + //if ( isFirstOfToken( child ) ) { + // content += " "; + //} + content += child->formulaString(); + } + return content; +} + + +void SequenceElement::writeMathMLContent( TQDomDocument& doc, TQDomElement& element, bool oasisFormat ) const +{ + for ( TQPtrListIterator it( children ); it.current(); ++it ) { + it.current()->writeMathML( doc, element, oasisFormat ); + } +} + + +const BasicElement* SequenceElement::getChild( uint i ) const +{ + TQPtrListIterator it( children ); + it += i; + return it.current(); +} + + +int SequenceElement::childPos( const BasicElement* child ) const +{ + TQPtrListIterator it( children ); + uint count = it.count(); + for ( uint i=0; ivisit( this ); +} + + +void NameSequence::calcCursorSize( const ContextStyle& context, + FormulaCursor* cursor, bool smallCursor ) +{ + inherited::calcCursorSize( context, cursor, smallCursor ); + LuPixelPoint point = widgetPos(); + luPixel unitX = context.ptToLayoutUnitPixX( 1 ); + luPixel unitY = context.ptToLayoutUnitPixY( 1 ); + cursor->addCursorSize( LuPixelRect( point.x()-unitX, point.y()-unitY, + getWidth()+2*unitX, getHeight()+2*unitY ) ); +} + +void NameSequence::drawCursor( TQPainter& painter, const ContextStyle& context, + StyleAttributes& style, FormulaCursor* cursor, + bool smallCursor, bool activeCursor ) +{ + LuPixelPoint point = widgetPos(); + painter.setPen( TQPen( context.getEmptyColor(), + context.layoutUnitToPixelX( context.getLineWidth( style.sizeFactor() )/2 ) ) ); + luPixel unitX = context.ptToLayoutUnitPixX( 1 ); + luPixel unitY = context.ptToLayoutUnitPixY( 1 ); + painter.drawRect( context.layoutUnitToPixelX( point.x()-unitX ), + context.layoutUnitToPixelY( point.y()-unitY ), + context.layoutUnitToPixelX( getWidth()+2*unitX ), + context.layoutUnitToPixelY( getHeight()+2*unitY ) ); + + inherited::drawCursor( painter, context, style, cursor, smallCursor, activeCursor ); +} + +void NameSequence::moveWordLeft( FormulaCursor* cursor ) +{ + uint pos = cursor->getPos(); + if ( pos > 0 ) { + cursor->setTo( this, 0 ); + } + else { + moveLeft( cursor, this ); + } +} + +void NameSequence::moveWordRight( FormulaCursor* cursor ) +{ + int pos = cursor->getPos(); + if ( pos < countChildren() ) { + cursor->setTo( this, countChildren() ); + } + else { + moveRight( cursor, this ); + } +} + + +KCommand* NameSequence::compactExpressionCmd( Container* container ) +{ + BasicElement* element = replaceElement( container->document()->getSymbolTable() ); + if ( element != 0 ) { + getParent()->selectChild( container->activeCursor(), this ); + + KFCReplace* command = new KFCReplace( i18n( "Add Element" ), container ); + command->addElement( element ); + return command; + } + return 0; +} + +KCommand* NameSequence::buildCommand( Container* container, Request* request ) +{ + switch ( *request ) { + case req_compactExpression: + return compactExpressionCmd( container ); + case req_addSpace: + case req_addIndex: + case req_addMatrix: + case req_addOneByTwoMatrix: + case req_addSymbol: + case req_addRoot: + case req_addFraction: + case req_addBracket: + case req_addNameSequence: + return 0; + default: + break; + } + return inherited::buildCommand( container, request ); +} + + +KCommand* NameSequence::input( Container* container, TQChar ch ) +{ + int unicode = ch.unicode(); + switch (unicode) { + case '(': + case '[': + case '|': + case '^': + case '_': + case '}': + case ']': + case ')': + case '\\': { +// KCommand* compact = compactExpressionCmd( container ); +// KCommand* cmd = static_cast( getParent() )->input( container, ch ); +// if ( compact != 0 ) { +// KMacroCommand* macro = new KMacroCommand( cmd->name() ); +// macro->addCommand( compact ); +// macro->addCommand( cmd ); +// return macro; +// } +// else { +// return cmd; +// } + break; + } + case '{': + case ' ': { + Request r( req_compactExpression ); + return buildCommand( container, &r ); + } + default: { + TextCharRequest r( ch ); + return buildCommand( container, &r ); + } + } + return 0; +} + +void NameSequence::setElementType( ElementType* t ) +{ + inherited::setElementType( t ); + parse(); +} + +BasicElement* NameSequence::replaceElement( const SymbolTable& table ) +{ + TQString name = buildName(); + TQChar ch = table.unicode( name ); + if ( !ch.isNull() ) { + return new TextElement( ch, true ); + } + else { + ch = table.unicode( i18n( name.latin1() ) ); + if ( !ch.isNull() ) { + return new TextElement( ch, true ); + } + } + + if ( name == "!" ) return new SpaceElement( NEGTHIN ); + if ( name == "," ) return new SpaceElement( THIN ); + if ( name == ">" ) return new SpaceElement( MEDIUM ); + if ( name == ";" ) return new SpaceElement( THICK ); + if ( name == "quad" ) return new SpaceElement( QUAD ); + + if ( name == "frac" ) return new FractionElement(); + if ( name == "atop" ) { + FractionElement* frac = new FractionElement(); + frac->showLine( false ); + return frac; + } + if ( name == "sqrt" ) return new RootElement(); + + return 0; +} + +BasicElement* NameSequence::createElement( TQString type ) +{ + if ( type == "TEXT" ) return new TextElement(); + return 0; +} + +// void NameSequence::parse() +// { +// // A name sequence is known as name and so are its children. +// // Caution: this is fake! +// for ( int i = 0; i < countChildren(); i++ ) { +// getChild( i )->setElementType( getElementType() ); +// } +// } + +TQString NameSequence::buildName() +{ + TQString name; + for ( uint i = 0; i < countChildren(); i++ ) { + name += getChild( i )->getCharacter(); + } + return name; +} + +bool NameSequence::isValidSelection( FormulaCursor* cursor ) +{ + SequenceElement* sequence = cursor->normal(); + if ( sequence == 0 ) { + return false; + } + return sequence->onlyTextSelected( cursor ); +} + +int SequenceElement::buildChildrenFromMathMLDom(TQPtrList& list, TQDomNode n) +{ + while (!n.isNull()) { + int nodeNumber = 1; + if (n.isElement()) { + TQDomElement e = n.toElement(); + BasicElement* child = 0; + TQString tag = e.tagName().lower(); + + kdDebug( DEBUGID ) << "Sequence Tag: " << tag << endl; + if ( tag == "semantics" ) { // Special case, just pick the first child + TQDomNode node = e.firstChild(); + while( ! node.isElement() ) { + node = node.nextSibling(); + if ( node.isNull() ) { + return -1; + } + } + e = node.toElement(); + tag = e.tagName().lower(); + } + child = creationStrategy->createElement(tag, e); + if (child != 0) { + child->setParent(this); + if (style != 0) { + child->setStyle(style); + } + nodeNumber = child->buildFromMathMLDom( e ); + if ( nodeNumber != -1 ) { + list.append(child); + } + else { + delete child; + return -1; + } + } + else { + kdWarning() << "Unsupported MathML element: " << tag << endl; + } + } + for (int i = 0; i < nodeNumber; i++ ) { + if ( n.isNull() ) { + return -1; + } + n = n.nextSibling(); + } + } + // Operator elements inside a sequence have to be parsed to get proper form + // value. Form value is needed to access operator dictionary and has to be + // obtained after sequence parsing since its value depends on position + // inside the sequence. + + // If the sequence contains more than one element, if the first or last + // element are operators, they have to be marked differently + if ( list.count() > 1 ) { + if ( list.getFirst()->getElementName() == "mo" ) { + static_cast( list.getFirst() )->setForm( PrefixForm ); + } + if ( list.getLast()->getElementName() == "mo" ) { + static_cast( list.getLast() )->setForm( PostfixForm ); + } + for ( uint i = 1; i < list.count() - 1; i++ ) { + if ( list.at( i )->getElementName() == "mo" ) { + static_cast( list.at( i ) )->setForm( InfixForm ); + } + } + } + else if ( list.count() == 1 ) { + if ( list.getFirst()->getElementName() == "mo" ) { + static_cast( list.getFirst() )->setForm( InfixForm ); + } + } + parse(); + return 1; +} + +/** + */ +int SequenceElement::readContentFromMathMLDom(TQDomNode& node) +{ + if ( BasicElement::readContentFromMathMLDom(node) == -1 ) { + return -1; + } + + return buildChildrenFromMathMLDom(children, node); +} + +int SequenceElement::buildMathMLChild( TQDomNode node ) +{ + int nodeCounter = 1; + while ( ! node.isElement() ) { + node = node.nextSibling(); + nodeCounter++; + if ( node.isNull() ) { + return -1; + } + } + TQDomElement e = node.toElement(); + BasicElement* child = 0; + TQString tag = e.tagName().lower(); + + child = creationStrategy->createElement(tag, e); + if (child != 0) { + child->setParent(this); + if (style != 0) { + child->setStyle(style); + } + if (child->buildFromMathMLDom(e) != -1) { + children.append(child); + } + else { + delete child; + return -1; + } + } + else { + return -1; + } + parse(); + return nodeCounter; +} + + + +KFORMULA_NAMESPACE_END diff --git a/lib/kformula/sequenceparser.cc b/lib/kformula/sequenceparser.cc deleted file mode 100644 index bbc2f0b1..00000000 --- a/lib/kformula/sequenceparser.cc +++ /dev/null @@ -1,241 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2001 Andrea Rizzi - Ulrich Kuettler - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - -#include "basicelement.h" -#include "elementtype.h" -#include "sequenceparser.h" -#include "symboltable.h" -#include "textelement.h" - - -KFORMULA_NAMESPACE_BEGIN - - -SequenceParser::SequenceParser( const SymbolTable& t ) - : tokenStart( 0 ), tokenEnd( 0 ), type( SEQUENCE ), - binOpAllowed( false ), table( t ) -{ -} - - -void SequenceParser::setElementType( uint pos, ElementType* type ) -{ - list.at( pos )->setElementType( type ); -} - - -ElementType* SequenceParser::parse( TQPtrList& elements ) -{ - list = elements; - return new SequenceType( this ); -} - - -void SequenceParser::nextToken() -{ - tokenStart = tokenEnd; - if ( tokenStart >= list.count() ) { - type = END; - return; - } - tokenEnd++; - BasicElement* element = list.at( tokenStart ); - type = element->getTokenType(); - if ( type == SEPARATOR ) { - if ( tokenEnd < list.count() ) { - TQChar ch = getEndChar(); - switch ( ch ) { - case ',': - case '>': - case ';': - type = NAME; - tokenEnd++; - break; - default: - readText(); - } - } - } - else if ( type == ORDINARY ) { - readText(); - } - else if ( type == NUMBER ) { - readNumber(); - } - if ( !binOpAllowed && ( type == BINOP ) ) { - type = ORDINARY; - } - binOpAllowed = ( type == ORDINARY ) || ( type == NUMBER ) || ( type == NAME ) || - ( type == ELEMENT ) || ( type == BRACKET ) || ( type == INNER ); - - //cerr << "SequenceParser::nextToken(): " << type << " " - // << tokenStart << " " << tokenEnd << endl; -} - - -void SequenceParser::readNumber() -{ - type = NUMBER; - readDigits(); - if ( tokenEnd < list.count()-1 ) { - TQChar ch = getEndChar(); - - // Look for a dot. - if ( ch == '.' ) { - tokenEnd++; - ch = getEndChar(); - if ( ch.isNumber() ) { - readDigits(); - } -// else { -// tokenEnd--; -// return; -// } - } - - // there might as well be an exponent - if ( tokenEnd < list.count()-1 ) { - BasicElement* element = list.at(tokenEnd); - ch = getEndChar(); - if ( ( element->getTokenType() == ORDINARY ) && - ( ( ch == 'E' ) || ( ch == 'e' ) ) ) { - tokenEnd++; - ch = getEndChar(); - - // signs are allowed after the exponent - if ( ( ( ch == '+' ) || ( ch == '-' ) ) && - ( tokenEnd < list.count()-1 ) ) { - tokenEnd++; - ch = getEndChar(); - if ( ch.isNumber() ) { - readDigits(); - } - else { - tokenEnd -= 2; - return; - } - } - else if ( ch.isNumber() ) { - readDigits(); - } - else { - tokenEnd--; - } - } - } - } -} - - -void SequenceParser::readDigits() -{ - for ( ; tokenEnd < list.count(); tokenEnd++ ) { - TQChar ch = getEndChar(); - if ( !ch.isNumber() ) { - break; - } - } -} - - -void SequenceParser::readText() -{ - BasicElement* element = list.at( tokenStart ); - TextElement* beginText = static_cast( element ); - if ( beginText->isSymbol() || - ( beginText->getCharacter() == '/' ) ) { - return; - } - char format = beginText->format(); - type = ORDINARY; - for ( ; tokenEnd < list.count(); tokenEnd++ ) { - element = list.at( tokenEnd ); - TokenType tt = element->getTokenType(); - if ( ( ( tt != ORDINARY ) || - ( element->getCharacter() == '/' ) ) && - ( tt != NUMBER ) ) { - return; - } - if ( static_cast( element )->format() != format ) { - return; - } - if ( static_cast( element )->isSymbol() ) { - return; - } - } -} - -TQChar SequenceParser::getEndChar() -{ - BasicElement* element = list.at( tokenEnd ); - return element->getCharacter(); -} - - -ElementType* SequenceParser::getPrimitive() -{ - //cerr << "SequenceParser::getPrimitive(): " << type << " " - // << tokenStart << " " << tokenEnd << endl; - switch ( type ) { - case ORDINARY: { -// TQString text = getText(); -// if ( table.contains( text ) || ( text == "\\quad" ) ) { -// return new NameType( this, text ); -// } -// else { - return new TextType( this ); -// } - } - case NAME: - return new NameType( this ); - case NUMBER: - return new NumberType( this ); - case ELEMENT: - return new ComplexElementType( this ); - case INNER: - return new InnerElementType( this ); - case BINOP: - return new OperatorType( this ); - case RELATION: - return new RelationType( this ); - case PUNCTUATION: - return new PunctuationType( this ); - case BRACKET: - return new BracketType( this ); - case SEQUENCE: - case SEPARATOR: - case END: - return 0; - } - return 0; -} - - -TQString SequenceParser::text() -{ - TQString text; - for ( uint i = tokenStart; i < tokenEnd; i++ ) { - BasicElement* element = list.at( i ); - text.append( element->getCharacter() ); - } - return text; -} - -KFORMULA_NAMESPACE_END diff --git a/lib/kformula/sequenceparser.cpp b/lib/kformula/sequenceparser.cpp new file mode 100644 index 00000000..bbc2f0b1 --- /dev/null +++ b/lib/kformula/sequenceparser.cpp @@ -0,0 +1,241 @@ +/* This file is part of the KDE project + Copyright (C) 2001 Andrea Rizzi + Ulrich Kuettler + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "basicelement.h" +#include "elementtype.h" +#include "sequenceparser.h" +#include "symboltable.h" +#include "textelement.h" + + +KFORMULA_NAMESPACE_BEGIN + + +SequenceParser::SequenceParser( const SymbolTable& t ) + : tokenStart( 0 ), tokenEnd( 0 ), type( SEQUENCE ), + binOpAllowed( false ), table( t ) +{ +} + + +void SequenceParser::setElementType( uint pos, ElementType* type ) +{ + list.at( pos )->setElementType( type ); +} + + +ElementType* SequenceParser::parse( TQPtrList& elements ) +{ + list = elements; + return new SequenceType( this ); +} + + +void SequenceParser::nextToken() +{ + tokenStart = tokenEnd; + if ( tokenStart >= list.count() ) { + type = END; + return; + } + tokenEnd++; + BasicElement* element = list.at( tokenStart ); + type = element->getTokenType(); + if ( type == SEPARATOR ) { + if ( tokenEnd < list.count() ) { + TQChar ch = getEndChar(); + switch ( ch ) { + case ',': + case '>': + case ';': + type = NAME; + tokenEnd++; + break; + default: + readText(); + } + } + } + else if ( type == ORDINARY ) { + readText(); + } + else if ( type == NUMBER ) { + readNumber(); + } + if ( !binOpAllowed && ( type == BINOP ) ) { + type = ORDINARY; + } + binOpAllowed = ( type == ORDINARY ) || ( type == NUMBER ) || ( type == NAME ) || + ( type == ELEMENT ) || ( type == BRACKET ) || ( type == INNER ); + + //cerr << "SequenceParser::nextToken(): " << type << " " + // << tokenStart << " " << tokenEnd << endl; +} + + +void SequenceParser::readNumber() +{ + type = NUMBER; + readDigits(); + if ( tokenEnd < list.count()-1 ) { + TQChar ch = getEndChar(); + + // Look for a dot. + if ( ch == '.' ) { + tokenEnd++; + ch = getEndChar(); + if ( ch.isNumber() ) { + readDigits(); + } +// else { +// tokenEnd--; +// return; +// } + } + + // there might as well be an exponent + if ( tokenEnd < list.count()-1 ) { + BasicElement* element = list.at(tokenEnd); + ch = getEndChar(); + if ( ( element->getTokenType() == ORDINARY ) && + ( ( ch == 'E' ) || ( ch == 'e' ) ) ) { + tokenEnd++; + ch = getEndChar(); + + // signs are allowed after the exponent + if ( ( ( ch == '+' ) || ( ch == '-' ) ) && + ( tokenEnd < list.count()-1 ) ) { + tokenEnd++; + ch = getEndChar(); + if ( ch.isNumber() ) { + readDigits(); + } + else { + tokenEnd -= 2; + return; + } + } + else if ( ch.isNumber() ) { + readDigits(); + } + else { + tokenEnd--; + } + } + } + } +} + + +void SequenceParser::readDigits() +{ + for ( ; tokenEnd < list.count(); tokenEnd++ ) { + TQChar ch = getEndChar(); + if ( !ch.isNumber() ) { + break; + } + } +} + + +void SequenceParser::readText() +{ + BasicElement* element = list.at( tokenStart ); + TextElement* beginText = static_cast( element ); + if ( beginText->isSymbol() || + ( beginText->getCharacter() == '/' ) ) { + return; + } + char format = beginText->format(); + type = ORDINARY; + for ( ; tokenEnd < list.count(); tokenEnd++ ) { + element = list.at( tokenEnd ); + TokenType tt = element->getTokenType(); + if ( ( ( tt != ORDINARY ) || + ( element->getCharacter() == '/' ) ) && + ( tt != NUMBER ) ) { + return; + } + if ( static_cast( element )->format() != format ) { + return; + } + if ( static_cast( element )->isSymbol() ) { + return; + } + } +} + +TQChar SequenceParser::getEndChar() +{ + BasicElement* element = list.at( tokenEnd ); + return element->getCharacter(); +} + + +ElementType* SequenceParser::getPrimitive() +{ + //cerr << "SequenceParser::getPrimitive(): " << type << " " + // << tokenStart << " " << tokenEnd << endl; + switch ( type ) { + case ORDINARY: { +// TQString text = getText(); +// if ( table.contains( text ) || ( text == "\\quad" ) ) { +// return new NameType( this, text ); +// } +// else { + return new TextType( this ); +// } + } + case NAME: + return new NameType( this ); + case NUMBER: + return new NumberType( this ); + case ELEMENT: + return new ComplexElementType( this ); + case INNER: + return new InnerElementType( this ); + case BINOP: + return new OperatorType( this ); + case RELATION: + return new RelationType( this ); + case PUNCTUATION: + return new PunctuationType( this ); + case BRACKET: + return new BracketType( this ); + case SEQUENCE: + case SEPARATOR: + case END: + return 0; + } + return 0; +} + + +TQString SequenceParser::text() +{ + TQString text; + for ( uint i = tokenStart; i < tokenEnd; i++ ) { + BasicElement* element = list.at( i ); + text.append( element->getCharacter() ); + } + return text; +} + +KFORMULA_NAMESPACE_END diff --git a/lib/kformula/spaceelement.cc b/lib/kformula/spaceelement.cc deleted file mode 100644 index 7d372360..00000000 --- a/lib/kformula/spaceelement.cc +++ /dev/null @@ -1,431 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2001 Andrea Rizzi - Ulrich Kuettler - Copyright (C) 2006 Alfredo Beaumont Sainz - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - -#include -#include - -#include -#include - -#include "contextstyle.h" -#include "elementvisitor.h" -#include "spaceelement.h" - - -KFORMULA_NAMESPACE_BEGIN - - -SpaceElement::SpaceElement( SpaceWidth space, bool tab, BasicElement* parent ) - : BasicElement( parent ), - m_tab( tab ), - m_widthType( NoSize ), - m_heightType( NoSize ), - m_depthType( NoSize ), - m_lineBreak( NoBreakType ) -{ - // Backwards compatibility with KFO format - switch ( space ) { - case NEGTHIN: - m_widthType = NegativeThinMathSpace; - break; - case THIN: - m_widthType = ThinMathSpace; - break; - case MEDIUM: - m_widthType = MediumMathSpace; - break; - case THICK: - m_widthType = ThickMathSpace; - break; - case QUAD: - m_widthType = VeryVeryThickMathSpace; - break; - } -} - - -SpaceElement::SpaceElement( const SpaceElement& other ) - : BasicElement( other ), - m_widthType( other.m_widthType ), - m_width( other.m_width ), - m_heightType( other.m_heightType ), - m_height( other.m_height ), - m_depthType( other.m_depthType ), - m_depth( other.m_depth ), - m_lineBreak( other.m_lineBreak ) -{ -} - - -bool SpaceElement::accept( ElementVisitor* visitor ) -{ - return visitor->visit( this ); -} - - -void SpaceElement::calcSizes( const ContextStyle& context, - ContextStyle::TextStyle tstyle, - ContextStyle::IndexStyle /*istyle*/, - StyleAttributes& style ) -{ - double factor = style.sizeFactor(); - luPt mySize = context.getAdjustedSize( tstyle, factor ); - TQFont font = context.getDefaultFont(); - font.setPointSize( mySize ); - - TQFontMetrics fm( font ); - TQChar w = 'M'; - LuPixelRect hbound = fm.boundingRect( w ); - TQChar h = 'x'; - LuPixelRect vbound = fm.boundingRect( h ); - - double width = style.getSpace( m_widthType, m_width ); - if ( m_widthType == AbsoluteSize ) { - width = m_width / context.layoutUnitPtToPt( context.getBaseSize() ); - } - else if ( m_widthType == PixelSize ) { - width = context.pixelYToPt( m_width ) / context.layoutUnitPtToPt( context.getBaseSize() ); - } - double height = style.getSpace( m_heightType, m_height ); - if ( m_heightType == AbsoluteSize ) { - height = m_height / context.layoutUnitPtToPt( context.getBaseSize() ); - } - else if ( m_heightType == PixelSize ) { - height = context.pixelYToPt( m_height ) / context.layoutUnitPtToPt( context.getBaseSize() ); - } - double depth = style.getSpace( m_depthType, m_depth ); - if ( m_depthType == AbsoluteSize ) { - depth = m_depth / context.layoutUnitPtToPt( context.getBaseSize() ); - } - else if ( m_depthType == PixelSize ) { - depth = context.pixelYToPt( m_depth ) / context.layoutUnitPtToPt( context.getBaseSize() ); - } - - setWidth( hbound.width() * width ); - setHeight( vbound.height() * height + vbound.height() * depth ); - setBaseline( vbound.height() * height ); - - if ( m_tab ) { - getParent()->registerTab( this ); - } -} - -void SpaceElement::draw( TQPainter& painter, const LuPixelRect& /*r*/, - const ContextStyle& context, - ContextStyle::TextStyle /*tstyle*/, - ContextStyle::IndexStyle /*istyle*/, - StyleAttributes& /*style*/, - const LuPixelPoint& parentOrigin ) -{ - LuPixelPoint myPos(parentOrigin.x()+getX(), parentOrigin.y()+getY()); - // there is such a thing as negative space! - //if ( !LuPixelRect( myPos.x(), myPos.y(), getWidth(), getHeight() ).intersects( r ) ) - // return; - - if ( context.edit() ) { - painter.setPen( context.getEmptyColor() ); - painter.drawLine( context.layoutUnitToPixelX( myPos.x() ), - context.layoutUnitToPixelY( myPos.y()+getHeight() ), - context.layoutUnitToPixelX( myPos.x()+getWidth()-1 ), - context.layoutUnitToPixelY( myPos.y()+getHeight() ) ); - painter.drawLine( context.layoutUnitToPixelX( myPos.x() ), - context.layoutUnitToPixelY( myPos.y()+getHeight() ), - context.layoutUnitToPixelX( myPos.x() ), - context.layoutUnitToPixelY( myPos.y()+getHeight()-getHeight()/5 ) ); - painter.drawLine( context.layoutUnitToPixelX( myPos.x()+getWidth()-1 ), - context.layoutUnitToPixelY( myPos.y()+getHeight() ), - context.layoutUnitToPixelX( myPos.x()+getWidth()-1 ), - context.layoutUnitToPixelY( myPos.y()+getHeight()-getHeight()/5 ) ); - } -} - - -void SpaceElement::writeDom(TQDomElement element) -{ - BasicElement::writeDom(element); - switch ( m_widthType ) { - case NegativeVeryVeryThinMathSpace: - case NegativeVeryThinMathSpace: - case NegativeThinMathSpace: - case NegativeMediumMathSpace: - case NegativeThickMathSpace: - case NegativeVeryThickMathSpace: - case NegativeVeryVeryThickMathSpace: - element.setAttribute( "WIDTH", "negthin" ); - break; - case VeryVeryThinMathSpace: - case VeryThinMathSpace: - case ThinMathSpace: - element.setAttribute( "WIDTH", "thin" ); - break; - case MediumMathSpace: - element.setAttribute( "WIDTH", "medium" ); - break; - case ThickMathSpace: - element.setAttribute( "WIDTH", "thick" ); - break; - case VeryThickMathSpace: - case VeryVeryThickMathSpace: - element.setAttribute( "WIDTH", "quad" ); - break; - case AbsoluteSize: - case RelativeSize: - case PixelSize: - if ( m_width < 0 ) { - element.setAttribute( "WIDTH", "negthin" ); - } - else { - element.setAttribute( "WIDTH", "thin" ); - } - default: - break; - } - if ( m_tab ) { - element.setAttribute( "TAB", "true" ); - } -} - -bool SpaceElement::readAttributesFromDom( TQDomElement element ) -{ - if ( !BasicElement::readAttributesFromDom( element ) ) { - return false; - } - TQString widthStr = element.attribute( "WIDTH" ); - if( !widthStr.isNull() ) { - if ( widthStr.lower() == "quad" ) { - m_widthType = VeryVeryThickMathSpace; - } - else if ( widthStr.lower() == "thick" ) { - m_widthType = ThickMathSpace; - } - else if ( widthStr.lower() == "medium" ) { - m_widthType = MediumMathSpace; - } - else if ( widthStr.lower() == "negthin" ) { - m_widthType = NegativeThinMathSpace; - } - else { - m_widthType = ThinMathSpace; - } - } - else { - return false; - } - TQString tabStr = element.attribute( "TAB" ); - m_tab = !tabStr.isNull(); - return true; -} - -bool SpaceElement::readContentFromDom(TQDomNode& node) -{ - return BasicElement::readContentFromDom( node ); -} - -bool SpaceElement::readAttributesFromMathMLDom(const TQDomElement& element) -{ - if ( ! BasicElement::readAttributesFromMathMLDom( element ) ) { - return false; - } - - TQString widthStr = element.attribute( "width" ).stripWhiteSpace().lower(); - if ( ! widthStr.isNull() ) { - m_width = getSize( widthStr, &m_widthType ); - if ( m_widthType == NoSize ) { - m_widthType = getSpace( widthStr ); - } - } - TQString heightStr = element.attribute( "height" ).stripWhiteSpace().lower(); - if ( ! heightStr.isNull() ) { - m_height = getSize( heightStr, &m_heightType ); - } - TQString depthStr = element.attribute( "depth" ).stripWhiteSpace().lower(); - if ( ! depthStr.isNull() ) { - m_depth = getSize( depthStr, &m_depthType ); - } - TQString linebreakStr = element.attribute( "linebreak" ).stripWhiteSpace().lower(); - if ( ! linebreakStr.isNull() ) { - if ( linebreakStr == "auto" ) { - m_lineBreak = AutoBreak; - } - else if ( linebreakStr == "newline" ) { - m_lineBreak = NewLineBreak; - } - else if ( linebreakStr == "indentingnewline" ) { - m_lineBreak = IndentingNewLineBreak; - } - else if ( linebreakStr == "nobreak" ) { - m_lineBreak = NoBreak; - } - else if ( linebreakStr == "goodbreak" ) { - m_lineBreak = GoodBreak; - } - else if ( linebreakStr == "badbreak" ) { - m_lineBreak = BadBreak; - } - } - return true; -} - -void SpaceElement::writeMathMLAttributes( TQDomElement& element ) const -{ - switch ( m_widthType ) { - case AbsoluteSize: - element.setAttribute( "width", TQString( "%1pt" ).arg( m_width ) ); - break; - case RelativeSize: - element.setAttribute( "width", TQString( "%1%" ).arg( m_width * 100.0 ) ); - break; - case PixelSize: - element.setAttribute( "width", TQString( "%1px" ).arg( m_width ) ); - break; - case NegativeVeryVeryThinMathSpace: - element.setAttribute( "width", "negativeveryverythinmathspace" ); - break; - case NegativeVeryThinMathSpace: - element.setAttribute( "width", "negativeverythinmathspace" ); - break; - case NegativeThinMathSpace: - element.setAttribute( "width", "negativethinmathspace" ); - break; - case NegativeMediumMathSpace: - element.setAttribute( "width", "negativemediummathspace" ); - break; - case NegativeThickMathSpace: - element.setAttribute( "width", "negativethickmathspace" ); - break; - case NegativeVeryThickMathSpace: - element.setAttribute( "width", "negativeverythickmathspace" ); - break; - case NegativeVeryVeryThickMathSpace: - element.setAttribute( "width", "negativeveryverythickmathspace" ); - break; - case VeryVeryThinMathSpace: - element.setAttribute( "width", "veryverythinmathspace" ); - break; - case VeryThinMathSpace: - element.setAttribute( "width", "verythinmathspace" ); - break; - case ThinMathSpace: - element.setAttribute( "width", "thinmathspace" ); - break; - case MediumMathSpace: - element.setAttribute( "width", "mediummathspace" ); - break; - case ThickMathSpace: - element.setAttribute( "width", "thickmathspace" ); - break; - case VeryThickMathSpace: - element.setAttribute( "width", "verythickmathspace" ); - break; - case VeryVeryThickMathSpace: - element.setAttribute( "width", "veryverythickmathspace" ); - break; - default: - break; - } - switch ( m_heightType ) { - case AbsoluteSize: - element.setAttribute( "height", TQString( "%1pt" ).arg( m_height ) ); - break; - case RelativeSize: - element.setAttribute( "height", TQString( "%1%" ).arg( m_height * 100.0 ) ); - break; - case PixelSize: - element.setAttribute( "height", TQString( "%1px" ).arg( m_height ) ); - break; - default: - break; - } - switch ( m_depthType ) { - case AbsoluteSize: - element.setAttribute( "depth", TQString( "%1pt" ).arg( m_depth ) ); - break; - case RelativeSize: - element.setAttribute( "depth", TQString( "%1%" ).arg( m_depth * 100.0 ) ); - break; - case PixelSize: - element.setAttribute( "depth", TQString( "%1px" ).arg( m_depth ) ); - break; - default: - break; - } - switch ( m_lineBreak ) { - case AutoBreak: - element.setAttribute( "linebreak", "auto" ); - break; - case NewLineBreak: - element.setAttribute( "linebreak", "newline" ); - break; - case IndentingNewLineBreak: - element.setAttribute( "linebreak", "indentingnewline" ); - break; - case NoBreak: - element.setAttribute( "linebreak", "nobreak" ); - break; - case GoodBreak: - element.setAttribute( "linebreak", "goodbreak" ); - break; - case BadBreak: - element.setAttribute( "linebreak", "badbreak" ); - break; - default: - break; - } -} - -TQString SpaceElement::toLatex() -{ - switch ( m_widthType ) { - case NegativeVeryVeryThinMathSpace: - case NegativeVeryThinMathSpace: - case NegativeThinMathSpace: - case NegativeMediumMathSpace: - case NegativeThickMathSpace: - case NegativeVeryThickMathSpace: - case NegativeVeryVeryThickMathSpace: - return "\\!"; - case VeryVeryThinMathSpace: - case VeryThinMathSpace: - case ThinMathSpace: - return "\\,"; - case MediumMathSpace: - return "\\>"; - case ThickMathSpace: - return "\\;"; - case VeryThickMathSpace: - case VeryVeryThickMathSpace: - return "\\quad "; - case AbsoluteSize: - case RelativeSize: - case PixelSize: - if ( m_width < 0 ) { - return "\\!"; - } - else { - return "\\,"; - } - default: - break; - } - return ""; -} - -KFORMULA_NAMESPACE_END diff --git a/lib/kformula/spaceelement.cpp b/lib/kformula/spaceelement.cpp new file mode 100644 index 00000000..7d372360 --- /dev/null +++ b/lib/kformula/spaceelement.cpp @@ -0,0 +1,431 @@ +/* This file is part of the KDE project + Copyright (C) 2001 Andrea Rizzi + Ulrich Kuettler + Copyright (C) 2006 Alfredo Beaumont Sainz + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include + +#include +#include + +#include "contextstyle.h" +#include "elementvisitor.h" +#include "spaceelement.h" + + +KFORMULA_NAMESPACE_BEGIN + + +SpaceElement::SpaceElement( SpaceWidth space, bool tab, BasicElement* parent ) + : BasicElement( parent ), + m_tab( tab ), + m_widthType( NoSize ), + m_heightType( NoSize ), + m_depthType( NoSize ), + m_lineBreak( NoBreakType ) +{ + // Backwards compatibility with KFO format + switch ( space ) { + case NEGTHIN: + m_widthType = NegativeThinMathSpace; + break; + case THIN: + m_widthType = ThinMathSpace; + break; + case MEDIUM: + m_widthType = MediumMathSpace; + break; + case THICK: + m_widthType = ThickMathSpace; + break; + case QUAD: + m_widthType = VeryVeryThickMathSpace; + break; + } +} + + +SpaceElement::SpaceElement( const SpaceElement& other ) + : BasicElement( other ), + m_widthType( other.m_widthType ), + m_width( other.m_width ), + m_heightType( other.m_heightType ), + m_height( other.m_height ), + m_depthType( other.m_depthType ), + m_depth( other.m_depth ), + m_lineBreak( other.m_lineBreak ) +{ +} + + +bool SpaceElement::accept( ElementVisitor* visitor ) +{ + return visitor->visit( this ); +} + + +void SpaceElement::calcSizes( const ContextStyle& context, + ContextStyle::TextStyle tstyle, + ContextStyle::IndexStyle /*istyle*/, + StyleAttributes& style ) +{ + double factor = style.sizeFactor(); + luPt mySize = context.getAdjustedSize( tstyle, factor ); + TQFont font = context.getDefaultFont(); + font.setPointSize( mySize ); + + TQFontMetrics fm( font ); + TQChar w = 'M'; + LuPixelRect hbound = fm.boundingRect( w ); + TQChar h = 'x'; + LuPixelRect vbound = fm.boundingRect( h ); + + double width = style.getSpace( m_widthType, m_width ); + if ( m_widthType == AbsoluteSize ) { + width = m_width / context.layoutUnitPtToPt( context.getBaseSize() ); + } + else if ( m_widthType == PixelSize ) { + width = context.pixelYToPt( m_width ) / context.layoutUnitPtToPt( context.getBaseSize() ); + } + double height = style.getSpace( m_heightType, m_height ); + if ( m_heightType == AbsoluteSize ) { + height = m_height / context.layoutUnitPtToPt( context.getBaseSize() ); + } + else if ( m_heightType == PixelSize ) { + height = context.pixelYToPt( m_height ) / context.layoutUnitPtToPt( context.getBaseSize() ); + } + double depth = style.getSpace( m_depthType, m_depth ); + if ( m_depthType == AbsoluteSize ) { + depth = m_depth / context.layoutUnitPtToPt( context.getBaseSize() ); + } + else if ( m_depthType == PixelSize ) { + depth = context.pixelYToPt( m_depth ) / context.layoutUnitPtToPt( context.getBaseSize() ); + } + + setWidth( hbound.width() * width ); + setHeight( vbound.height() * height + vbound.height() * depth ); + setBaseline( vbound.height() * height ); + + if ( m_tab ) { + getParent()->registerTab( this ); + } +} + +void SpaceElement::draw( TQPainter& painter, const LuPixelRect& /*r*/, + const ContextStyle& context, + ContextStyle::TextStyle /*tstyle*/, + ContextStyle::IndexStyle /*istyle*/, + StyleAttributes& /*style*/, + const LuPixelPoint& parentOrigin ) +{ + LuPixelPoint myPos(parentOrigin.x()+getX(), parentOrigin.y()+getY()); + // there is such a thing as negative space! + //if ( !LuPixelRect( myPos.x(), myPos.y(), getWidth(), getHeight() ).intersects( r ) ) + // return; + + if ( context.edit() ) { + painter.setPen( context.getEmptyColor() ); + painter.drawLine( context.layoutUnitToPixelX( myPos.x() ), + context.layoutUnitToPixelY( myPos.y()+getHeight() ), + context.layoutUnitToPixelX( myPos.x()+getWidth()-1 ), + context.layoutUnitToPixelY( myPos.y()+getHeight() ) ); + painter.drawLine( context.layoutUnitToPixelX( myPos.x() ), + context.layoutUnitToPixelY( myPos.y()+getHeight() ), + context.layoutUnitToPixelX( myPos.x() ), + context.layoutUnitToPixelY( myPos.y()+getHeight()-getHeight()/5 ) ); + painter.drawLine( context.layoutUnitToPixelX( myPos.x()+getWidth()-1 ), + context.layoutUnitToPixelY( myPos.y()+getHeight() ), + context.layoutUnitToPixelX( myPos.x()+getWidth()-1 ), + context.layoutUnitToPixelY( myPos.y()+getHeight()-getHeight()/5 ) ); + } +} + + +void SpaceElement::writeDom(TQDomElement element) +{ + BasicElement::writeDom(element); + switch ( m_widthType ) { + case NegativeVeryVeryThinMathSpace: + case NegativeVeryThinMathSpace: + case NegativeThinMathSpace: + case NegativeMediumMathSpace: + case NegativeThickMathSpace: + case NegativeVeryThickMathSpace: + case NegativeVeryVeryThickMathSpace: + element.setAttribute( "WIDTH", "negthin" ); + break; + case VeryVeryThinMathSpace: + case VeryThinMathSpace: + case ThinMathSpace: + element.setAttribute( "WIDTH", "thin" ); + break; + case MediumMathSpace: + element.setAttribute( "WIDTH", "medium" ); + break; + case ThickMathSpace: + element.setAttribute( "WIDTH", "thick" ); + break; + case VeryThickMathSpace: + case VeryVeryThickMathSpace: + element.setAttribute( "WIDTH", "quad" ); + break; + case AbsoluteSize: + case RelativeSize: + case PixelSize: + if ( m_width < 0 ) { + element.setAttribute( "WIDTH", "negthin" ); + } + else { + element.setAttribute( "WIDTH", "thin" ); + } + default: + break; + } + if ( m_tab ) { + element.setAttribute( "TAB", "true" ); + } +} + +bool SpaceElement::readAttributesFromDom( TQDomElement element ) +{ + if ( !BasicElement::readAttributesFromDom( element ) ) { + return false; + } + TQString widthStr = element.attribute( "WIDTH" ); + if( !widthStr.isNull() ) { + if ( widthStr.lower() == "quad" ) { + m_widthType = VeryVeryThickMathSpace; + } + else if ( widthStr.lower() == "thick" ) { + m_widthType = ThickMathSpace; + } + else if ( widthStr.lower() == "medium" ) { + m_widthType = MediumMathSpace; + } + else if ( widthStr.lower() == "negthin" ) { + m_widthType = NegativeThinMathSpace; + } + else { + m_widthType = ThinMathSpace; + } + } + else { + return false; + } + TQString tabStr = element.attribute( "TAB" ); + m_tab = !tabStr.isNull(); + return true; +} + +bool SpaceElement::readContentFromDom(TQDomNode& node) +{ + return BasicElement::readContentFromDom( node ); +} + +bool SpaceElement::readAttributesFromMathMLDom(const TQDomElement& element) +{ + if ( ! BasicElement::readAttributesFromMathMLDom( element ) ) { + return false; + } + + TQString widthStr = element.attribute( "width" ).stripWhiteSpace().lower(); + if ( ! widthStr.isNull() ) { + m_width = getSize( widthStr, &m_widthType ); + if ( m_widthType == NoSize ) { + m_widthType = getSpace( widthStr ); + } + } + TQString heightStr = element.attribute( "height" ).stripWhiteSpace().lower(); + if ( ! heightStr.isNull() ) { + m_height = getSize( heightStr, &m_heightType ); + } + TQString depthStr = element.attribute( "depth" ).stripWhiteSpace().lower(); + if ( ! depthStr.isNull() ) { + m_depth = getSize( depthStr, &m_depthType ); + } + TQString linebreakStr = element.attribute( "linebreak" ).stripWhiteSpace().lower(); + if ( ! linebreakStr.isNull() ) { + if ( linebreakStr == "auto" ) { + m_lineBreak = AutoBreak; + } + else if ( linebreakStr == "newline" ) { + m_lineBreak = NewLineBreak; + } + else if ( linebreakStr == "indentingnewline" ) { + m_lineBreak = IndentingNewLineBreak; + } + else if ( linebreakStr == "nobreak" ) { + m_lineBreak = NoBreak; + } + else if ( linebreakStr == "goodbreak" ) { + m_lineBreak = GoodBreak; + } + else if ( linebreakStr == "badbreak" ) { + m_lineBreak = BadBreak; + } + } + return true; +} + +void SpaceElement::writeMathMLAttributes( TQDomElement& element ) const +{ + switch ( m_widthType ) { + case AbsoluteSize: + element.setAttribute( "width", TQString( "%1pt" ).arg( m_width ) ); + break; + case RelativeSize: + element.setAttribute( "width", TQString( "%1%" ).arg( m_width * 100.0 ) ); + break; + case PixelSize: + element.setAttribute( "width", TQString( "%1px" ).arg( m_width ) ); + break; + case NegativeVeryVeryThinMathSpace: + element.setAttribute( "width", "negativeveryverythinmathspace" ); + break; + case NegativeVeryThinMathSpace: + element.setAttribute( "width", "negativeverythinmathspace" ); + break; + case NegativeThinMathSpace: + element.setAttribute( "width", "negativethinmathspace" ); + break; + case NegativeMediumMathSpace: + element.setAttribute( "width", "negativemediummathspace" ); + break; + case NegativeThickMathSpace: + element.setAttribute( "width", "negativethickmathspace" ); + break; + case NegativeVeryThickMathSpace: + element.setAttribute( "width", "negativeverythickmathspace" ); + break; + case NegativeVeryVeryThickMathSpace: + element.setAttribute( "width", "negativeveryverythickmathspace" ); + break; + case VeryVeryThinMathSpace: + element.setAttribute( "width", "veryverythinmathspace" ); + break; + case VeryThinMathSpace: + element.setAttribute( "width", "verythinmathspace" ); + break; + case ThinMathSpace: + element.setAttribute( "width", "thinmathspace" ); + break; + case MediumMathSpace: + element.setAttribute( "width", "mediummathspace" ); + break; + case ThickMathSpace: + element.setAttribute( "width", "thickmathspace" ); + break; + case VeryThickMathSpace: + element.setAttribute( "width", "verythickmathspace" ); + break; + case VeryVeryThickMathSpace: + element.setAttribute( "width", "veryverythickmathspace" ); + break; + default: + break; + } + switch ( m_heightType ) { + case AbsoluteSize: + element.setAttribute( "height", TQString( "%1pt" ).arg( m_height ) ); + break; + case RelativeSize: + element.setAttribute( "height", TQString( "%1%" ).arg( m_height * 100.0 ) ); + break; + case PixelSize: + element.setAttribute( "height", TQString( "%1px" ).arg( m_height ) ); + break; + default: + break; + } + switch ( m_depthType ) { + case AbsoluteSize: + element.setAttribute( "depth", TQString( "%1pt" ).arg( m_depth ) ); + break; + case RelativeSize: + element.setAttribute( "depth", TQString( "%1%" ).arg( m_depth * 100.0 ) ); + break; + case PixelSize: + element.setAttribute( "depth", TQString( "%1px" ).arg( m_depth ) ); + break; + default: + break; + } + switch ( m_lineBreak ) { + case AutoBreak: + element.setAttribute( "linebreak", "auto" ); + break; + case NewLineBreak: + element.setAttribute( "linebreak", "newline" ); + break; + case IndentingNewLineBreak: + element.setAttribute( "linebreak", "indentingnewline" ); + break; + case NoBreak: + element.setAttribute( "linebreak", "nobreak" ); + break; + case GoodBreak: + element.setAttribute( "linebreak", "goodbreak" ); + break; + case BadBreak: + element.setAttribute( "linebreak", "badbreak" ); + break; + default: + break; + } +} + +TQString SpaceElement::toLatex() +{ + switch ( m_widthType ) { + case NegativeVeryVeryThinMathSpace: + case NegativeVeryThinMathSpace: + case NegativeThinMathSpace: + case NegativeMediumMathSpace: + case NegativeThickMathSpace: + case NegativeVeryThickMathSpace: + case NegativeVeryVeryThickMathSpace: + return "\\!"; + case VeryVeryThinMathSpace: + case VeryThinMathSpace: + case ThinMathSpace: + return "\\,"; + case MediumMathSpace: + return "\\>"; + case ThickMathSpace: + return "\\;"; + case VeryThickMathSpace: + case VeryVeryThickMathSpace: + return "\\quad "; + case AbsoluteSize: + case RelativeSize: + case PixelSize: + if ( m_width < 0 ) { + return "\\!"; + } + else { + return "\\,"; + } + default: + break; + } + return ""; +} + +KFORMULA_NAMESPACE_END diff --git a/lib/kformula/stringelement.cc b/lib/kformula/stringelement.cc deleted file mode 100644 index e9851033..00000000 --- a/lib/kformula/stringelement.cc +++ /dev/null @@ -1,88 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2006 Alfredo Beaumont Sainz - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - -#include "textelement.h" -#include "stringelement.h" - -KFORMULA_NAMESPACE_BEGIN - -StringElement::StringElement( BasicElement* parent ) : TokenElement( parent ) -{ -} - -bool StringElement::readAttributesFromMathMLDom(const TQDomElement& element) -{ - if ( ! BasicElement::readAttributesFromMathMLDom( element ) ) { - return false; - } - - if ( ! inherited::readAttributesFromMathMLDom( element ) ) { - return false; - } - - m_lquote = element.attribute( "lquote" ); - if ( ! m_lquote.isNull() ) { - m_customLquote = true; - } - m_rquote = element.attribute( "rquote" ); - if ( ! m_rquote.isNull() ) { - m_customRquote = true; - } - - return true; -} - -int StringElement::buildChildrenFromMathMLDom(TQPtrList& list, TQDomNode n) -{ - int count = inherited::buildChildrenFromMathMLDom( list, n ); - if ( count == -1 ) - return -1; - TextElement* child = new TextElement( '"' ); - child->setParent( this ); - child->setCharFamily( charFamily() ); - child->setCharStyle( charStyle() ); - insert( 0, child ); - child = new TextElement( '"' ); - child->setParent( this ); - child->setCharFamily( charFamily() ); - child->setCharStyle( charStyle() ); - insert( countChildren(), child ); - return count; -} - -void StringElement::writeMathMLAttributes( TQDomElement& element ) const -{ - inherited::writeMathMLAttributes( element ); - if ( m_customLquote ) { - element.setAttribute( "lquote", m_lquote ); - } - if ( m_customRquote ) { - element.setAttribute( "rquote", m_rquote ); - } -} - -void StringElement::writeMathMLContent( TQDomDocument& doc, TQDomElement& element, bool oasisFormat ) const -{ - for ( uint i = 1; i < countChildren() - 1; ++i ) { - const BasicElement* e = getChild( i ); - e->writeMathML( doc, element, oasisFormat ); - } -} - -KFORMULA_NAMESPACE_END diff --git a/lib/kformula/stringelement.cpp b/lib/kformula/stringelement.cpp new file mode 100644 index 00000000..e9851033 --- /dev/null +++ b/lib/kformula/stringelement.cpp @@ -0,0 +1,88 @@ +/* This file is part of the KDE project + Copyright (C) 2006 Alfredo Beaumont Sainz + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "textelement.h" +#include "stringelement.h" + +KFORMULA_NAMESPACE_BEGIN + +StringElement::StringElement( BasicElement* parent ) : TokenElement( parent ) +{ +} + +bool StringElement::readAttributesFromMathMLDom(const TQDomElement& element) +{ + if ( ! BasicElement::readAttributesFromMathMLDom( element ) ) { + return false; + } + + if ( ! inherited::readAttributesFromMathMLDom( element ) ) { + return false; + } + + m_lquote = element.attribute( "lquote" ); + if ( ! m_lquote.isNull() ) { + m_customLquote = true; + } + m_rquote = element.attribute( "rquote" ); + if ( ! m_rquote.isNull() ) { + m_customRquote = true; + } + + return true; +} + +int StringElement::buildChildrenFromMathMLDom(TQPtrList& list, TQDomNode n) +{ + int count = inherited::buildChildrenFromMathMLDom( list, n ); + if ( count == -1 ) + return -1; + TextElement* child = new TextElement( '"' ); + child->setParent( this ); + child->setCharFamily( charFamily() ); + child->setCharStyle( charStyle() ); + insert( 0, child ); + child = new TextElement( '"' ); + child->setParent( this ); + child->setCharFamily( charFamily() ); + child->setCharStyle( charStyle() ); + insert( countChildren(), child ); + return count; +} + +void StringElement::writeMathMLAttributes( TQDomElement& element ) const +{ + inherited::writeMathMLAttributes( element ); + if ( m_customLquote ) { + element.setAttribute( "lquote", m_lquote ); + } + if ( m_customRquote ) { + element.setAttribute( "rquote", m_rquote ); + } +} + +void StringElement::writeMathMLContent( TQDomDocument& doc, TQDomElement& element, bool oasisFormat ) const +{ + for ( uint i = 1; i < countChildren() - 1; ++i ) { + const BasicElement* e = getChild( i ); + e->writeMathML( doc, element, oasisFormat ); + } +} + +KFORMULA_NAMESPACE_END diff --git a/lib/kformula/styleelement.cc b/lib/kformula/styleelement.cc deleted file mode 100644 index de760453..00000000 --- a/lib/kformula/styleelement.cc +++ /dev/null @@ -1,390 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2006 Alfredo Beaumont Sainz - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - -#include "basicelement.h" -#include "styleelement.h" - -KFORMULA_NAMESPACE_BEGIN - -StyleElement::StyleElement( BasicElement* parent ) : TokenStyleElement( parent ), - m_scriptMinSizeType( NoSize ), - m_veryVeryThinMathSpaceType( NoSize ), - m_veryThinMathSpaceType( NoSize ), - m_thinMathSpaceType( NoSize ), - m_mediumMathSpaceType( NoSize ), - m_thickMathSpaceType( NoSize ), - m_veryThickMathSpaceType( NoSize ), - m_veryVeryThickMathSpaceType( NoSize ), - m_customScriptLevel( false ), - m_relativeScriptLevel( false ), - m_customDisplayStyle( false ), - m_customScriptSizeMultiplier( false ), - m_customBackground( false ) -{ -} - -bool StyleElement::readAttributesFromMathMLDom( const TQDomElement& element ) -{ - if ( !BasicElement::readAttributesFromMathMLDom( element ) ) { - return false; - } - - TQString scriptlevelStr = element.attribute( "scriptlevel" ); - if ( ! scriptlevelStr.isNull() ) { - if ( scriptlevelStr[0] == '+' || scriptlevelStr[0] == '-' ) { - m_relativeScriptLevel = true; - } - bool ok; - m_scriptLevel = scriptlevelStr.toInt( &ok ); - if ( ! ok ) { - kdWarning( DEBUGID ) << "Invalid scriptlevel attribute value: " - << scriptlevelStr << endl; - } - else { - m_customScriptLevel = true; - } - } - TQString displaystyleStr = element.attribute( "displaystyle" ); - if ( ! displaystyleStr.isNull() ) { - if ( displaystyleStr.lower() == "true" ) { - m_displayStyle = true; - } - else { - m_displayStyle = false; - } - m_customDisplayStyle = true; - } - TQString scriptsizemultiplierStr = element.attribute( "scriptsizemultiplier" ); - if ( ! scriptsizemultiplierStr.isNull() ) { - bool ok; - m_scriptSizeMultiplier = scriptsizemultiplierStr.toDouble( &ok ); - if ( ! ok ) { - kdWarning( DEBUGID ) << "Invalid scriptsizemultiplier attribute value: " - << scriptsizemultiplierStr << endl; - } - else { - m_customScriptSizeMultiplier = true; - } - } - TQString scriptminsizeStr = element.attribute( "scriptminsize" ); - if ( ! scriptminsizeStr.isNull() ) { - readSizeAttribute( scriptminsizeStr, &m_scriptMinSizeType, &m_scriptMinSize ); - } - TQString backgroundStr = element.attribute( "background" ); - if ( ! backgroundStr.isNull() ) { - // TODO: tranparent background - m_customBackground = true; - if ( backgroundStr[0] != '#' ) { - m_background = TQColor( getHtmlColor( backgroundStr ) ); - } - else { - m_background = TQColor( backgroundStr ); - } - } - TQString veryverythinmathspaceStr = element.attribute( "veryverythinmathspace" ); - if ( ! veryverythinmathspaceStr.isNull() ) { - readSizeAttribute( veryverythinmathspaceStr, &m_veryVeryThinMathSpaceType, &m_veryVeryThinMathSpace ); - } - TQString verythinmathspaceStr = element.attribute( "verythinmathspace" ); - if ( ! verythinmathspaceStr.isNull() ) { - readSizeAttribute( verythinmathspaceStr, &m_veryThinMathSpaceType, &m_veryThinMathSpace ); - } - TQString thinmathspaceStr = element.attribute( "thinmathspace" ); - if ( ! thinmathspaceStr.isNull() ) { - readSizeAttribute( thinmathspaceStr, &m_thinMathSpaceType, &m_thinMathSpace ); - } - TQString mediummathspaceStr = element.attribute( "mediummathspace" ); - if ( ! mediummathspaceStr.isNull() ) { - readSizeAttribute( mediummathspaceStr, &m_mediumMathSpaceType, &m_mediumMathSpace ); - } - TQString thickmathspaceStr = element.attribute( "thickmathspace" ); - if ( ! thickmathspaceStr.isNull() ) { - readSizeAttribute( thickmathspaceStr, &m_thickMathSpaceType, &m_thickMathSpace ); - } - TQString verythickmathspaceStr = element.attribute( "verythickmathspace" ); - if ( ! verythickmathspaceStr.isNull() ) { - readSizeAttribute( verythickmathspaceStr, &m_veryThickMathSpaceType, &m_veryThickMathSpace ); - } - TQString veryverythickmathspaceStr = element.attribute( "veryverythickmathspace" ); - if ( ! veryverythickmathspaceStr.isNull() ) { - readSizeAttribute( veryverythickmathspaceStr, &m_veryVeryThickMathSpaceType, &m_veryVeryThickMathSpace ); - } - return inherited::readAttributesFromMathMLDom( element ); -} - -void StyleElement::writeMathMLAttributes( TQDomElement& element ) const -{ - if ( m_customScriptLevel ) { - TQString prefix; - if ( m_relativeScriptLevel && m_scriptLevel >= 0 ) { - prefix = "+"; - } - element.setAttribute( "scriptlevel", prefix + TQString( "%1" ).arg( m_scriptLevel ) ); - } - if ( m_customDisplayStyle ) { - element.setAttribute( "displaystyle", m_displayStyle ? "true" : "false" ); - } - if ( m_customScriptSizeMultiplier ) { - element.setAttribute( "scriptsizemultiplier", TQString( "%1" ).arg( m_scriptSizeMultiplier ) ); - } - writeSizeAttribute( element, "scriptminsize", m_scriptMinSizeType, m_scriptMinSize ); - if ( m_customBackground ) { - element.setAttribute( "background", m_background.name() ); - } - writeSizeAttribute( element, "veryverythinmathspace", m_veryVeryThinMathSpaceType, m_veryVeryThinMathSpace ); - writeSizeAttribute( element, "verythinmathspace", m_veryThinMathSpaceType, m_veryThinMathSpace ); - writeSizeAttribute( element, "thinmathspace", m_thinMathSpaceType, m_thinMathSpace ); - writeSizeAttribute( element, "mediummathspace", m_mediumMathSpaceType, m_mediumMathSpace ); - writeSizeAttribute( element, "thickmathspace", m_thickMathSpaceType, m_thickMathSpace ); - writeSizeAttribute( element, "verythickmathspace", m_veryThickMathSpaceType, m_veryThickMathSpace ); - writeSizeAttribute( element, "veryverythickmathspace", m_veryVeryThickMathSpaceType, m_veryVeryThickMathSpace ); - - inherited::writeMathMLAttributes( element ); -} - - -void StyleElement::setStyleSize( const ContextStyle& context, StyleAttributes& style ) -{ - if ( m_customScriptLevel ) { - if ( m_relativeScriptLevel ) { - style.setScriptLevel( style.scriptLevel() + m_scriptLevel ); - } - else { - style.setScriptLevel( m_scriptLevel ); - } - } - else { - style.setScriptLevel( style.scriptLevel() ); - } - if ( m_customDisplayStyle || style.customDisplayStyle() ) { - style.setCustomDisplayStyle( true ); - if ( m_customDisplayStyle ) { - style.setDisplayStyle( m_displayStyle ); - } - else { - style.setDisplayStyle( style.displayStyle() ); - } - } - else { - style.setCustomDisplayStyle( false ); - } - if ( m_customScriptSizeMultiplier ) { - style.setScriptSizeMultiplier( m_scriptSizeMultiplier ); - } - else { - style.setScriptSizeMultiplier( style.scriptSizeMultiplier() ); - } - - // Get scriptminsize attribute in absolute units, so we don't depend on - // context to get the default value - double basesize = context.layoutUnitPtToPt( context.getBaseSize() ); - double size = style.scriptMinSize(); - switch ( m_scriptMinSizeType ) { - case AbsoluteSize: - size = m_scriptMinSize; - case RelativeSize: - size = m_scriptMinSize * basesize; - case PixelSize: - size = context.pixelXToPt( m_scriptMinSize ); - default: - break; - } - style.setScriptMinSize( size ); - - style.setVeryVeryThinMathSpace( sizeFactor( context, - m_veryVeryThinMathSpaceType, - m_veryVeryThinMathSpace, - style.veryVeryThinMathSpace() )); - style.setVeryThinMathSpace( sizeFactor( context, m_veryThinMathSpaceType, - m_veryThinMathSpace, - style.veryThinMathSpace() )); - style.setThinMathSpace( sizeFactor( context, m_thinMathSpaceType, - m_thinMathSpace, - style.thinMathSpace() )); - style.setMediumMathSpace( sizeFactor( context, m_mediumMathSpaceType, - m_mediumMathSpace, - style.mediumMathSpace() )); - style.setThickMathSpace( sizeFactor( context, m_thickMathSpaceType, - m_thickMathSpace, - style.thickMathSpace() )); - style.setVeryThickMathSpace( sizeFactor( context, m_veryThickMathSpaceType, - m_veryThickMathSpace, - style.veryThickMathSpace() )); - style.setVeryVeryThickMathSpace( sizeFactor( context, - m_veryVeryThickMathSpaceType, - m_veryVeryThickMathSpace, - style.veryVeryThickMathSpace() )); - inherited::setStyleSize( context, style ); -} - -double StyleElement::sizeFactor( const ContextStyle& context, SizeType st, - double length, double defvalue ) -{ - double basesize = context.layoutUnitPtToPt( context.getBaseSize() ); - switch ( st ) { - case AbsoluteSize: - return length / basesize; - case RelativeSize: - return length; - case PixelSize: - return context.pixelXToPt( length ) / basesize; - default: - break; - } - return defvalue; -} - -void StyleElement::setStyleVariant( StyleAttributes& style ) -{ - if ( customMathVariant() ) { - style.setCustomMathVariant ( true ); - style.setCustomFontWeight( false ); - style.setCustomFontStyle( false ); - style.setCustomFont( false ); - if ( customMathVariant() ) { - style.setCharFamily ( charFamily() ); - style.setCharStyle( charStyle() ); - } - else { - style.setCharFamily( style.charFamily() ); - style.setCharStyle( style.charStyle() ); - } - } - else { - style.setCustomMathVariant( false ); - if ( customFontFamily() ) { - style.setCustomFont( true ); - style.setFont( TQFont(fontFamily()) ); - } - - bool fontweight = false; - if ( customFontWeight() || style.customFontWeight() ) { - style.setCustomFontWeight( true ); - if ( customFontWeight() ) { - fontweight = fontWeight(); - } - else { - fontweight = style.fontWeight(); - } - style.setFontWeight( fontweight ); - } - else { - style.setCustomFontWeight( false ); - } - - bool fontstyle = false; - if ( customFontStyle() || style.customFontStyle() ) { - style.setCustomFontStyle( true ); - if ( customFontStyle() ) { - fontstyle = fontStyle(); - } - else { - fontstyle = style.fontStyle(); - } - style.setFontStyle( fontstyle ); - } - else { - style.setCustomFontStyle( false ); - } - - if ( fontweight && fontstyle ) { - style.setCharStyle( boldItalicChar ); - } - else if ( fontweight && ! fontstyle ) { - style.setCharStyle( boldChar ); - } - else if ( ! fontweight && fontstyle ) { - style.setCharStyle( italicChar ); - } - else { - style.setCharStyle( normalChar ); - } - } -} - -void StyleElement::setStyleBackground( StyleAttributes& style ) -{ - if ( customMathBackground() ) { - style.setBackground( mathBackground() ); - } - else if ( m_customBackground ) { - style.setBackground( m_background ); - } - else { - style.setBackground( style.background() ); - } -} - -void StyleElement::resetStyle( StyleAttributes& style ) -{ - inherited::resetStyle( style ); - style.resetScriptLevel(); - style.resetScriptSizeMultiplier(); - style.resetScriptMinSize(); - style.resetVeryVeryThinMathSpace(); - style.resetVeryThinMathSpace(); - style.resetThinMathSpace(); - style.resetMediumMathSpace(); - style.resetThickMathSpace(); - style.resetVeryThickMathSpace(); - style.resetVeryVeryThickMathSpace(); - style.resetDisplayStyle(); -} - -void StyleElement::readSizeAttribute( const TQString& str, SizeType* st, double* s ) -{ - if ( st == 0 || s == 0 ){ - return; - } - if ( str == "small" ) { - *st = RelativeSize; - *s = 0.8; // ### Arbitrary size - } - else if ( str == "normal" ) { - *st = RelativeSize; - *s = 1.0; - } - else if ( str == "big" ) { - *st = RelativeSize; - *s = 1.2; // ### Arbitrary size - } - else { - *s = getSize( str, st ); - } -} - -void StyleElement::writeSizeAttribute( TQDomElement element, const TQString& str, SizeType st, double s ) const -{ - switch ( st ) { - case AbsoluteSize: - element.setAttribute( str, TQString( "%1pt" ).arg( s ) ); - break; - case RelativeSize: - element.setAttribute( str, TQString( "%1%" ).arg( s * 100.0 ) ); - break; - case PixelSize: - element.setAttribute( str, TQString( "%1px" ).arg( s ) ); - break; - default: - break; - } -} - - -KFORMULA_NAMESPACE_END diff --git a/lib/kformula/styleelement.cpp b/lib/kformula/styleelement.cpp new file mode 100644 index 00000000..de760453 --- /dev/null +++ b/lib/kformula/styleelement.cpp @@ -0,0 +1,390 @@ +/* This file is part of the KDE project + Copyright (C) 2006 Alfredo Beaumont Sainz + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "basicelement.h" +#include "styleelement.h" + +KFORMULA_NAMESPACE_BEGIN + +StyleElement::StyleElement( BasicElement* parent ) : TokenStyleElement( parent ), + m_scriptMinSizeType( NoSize ), + m_veryVeryThinMathSpaceType( NoSize ), + m_veryThinMathSpaceType( NoSize ), + m_thinMathSpaceType( NoSize ), + m_mediumMathSpaceType( NoSize ), + m_thickMathSpaceType( NoSize ), + m_veryThickMathSpaceType( NoSize ), + m_veryVeryThickMathSpaceType( NoSize ), + m_customScriptLevel( false ), + m_relativeScriptLevel( false ), + m_customDisplayStyle( false ), + m_customScriptSizeMultiplier( false ), + m_customBackground( false ) +{ +} + +bool StyleElement::readAttributesFromMathMLDom( const TQDomElement& element ) +{ + if ( !BasicElement::readAttributesFromMathMLDom( element ) ) { + return false; + } + + TQString scriptlevelStr = element.attribute( "scriptlevel" ); + if ( ! scriptlevelStr.isNull() ) { + if ( scriptlevelStr[0] == '+' || scriptlevelStr[0] == '-' ) { + m_relativeScriptLevel = true; + } + bool ok; + m_scriptLevel = scriptlevelStr.toInt( &ok ); + if ( ! ok ) { + kdWarning( DEBUGID ) << "Invalid scriptlevel attribute value: " + << scriptlevelStr << endl; + } + else { + m_customScriptLevel = true; + } + } + TQString displaystyleStr = element.attribute( "displaystyle" ); + if ( ! displaystyleStr.isNull() ) { + if ( displaystyleStr.lower() == "true" ) { + m_displayStyle = true; + } + else { + m_displayStyle = false; + } + m_customDisplayStyle = true; + } + TQString scriptsizemultiplierStr = element.attribute( "scriptsizemultiplier" ); + if ( ! scriptsizemultiplierStr.isNull() ) { + bool ok; + m_scriptSizeMultiplier = scriptsizemultiplierStr.toDouble( &ok ); + if ( ! ok ) { + kdWarning( DEBUGID ) << "Invalid scriptsizemultiplier attribute value: " + << scriptsizemultiplierStr << endl; + } + else { + m_customScriptSizeMultiplier = true; + } + } + TQString scriptminsizeStr = element.attribute( "scriptminsize" ); + if ( ! scriptminsizeStr.isNull() ) { + readSizeAttribute( scriptminsizeStr, &m_scriptMinSizeType, &m_scriptMinSize ); + } + TQString backgroundStr = element.attribute( "background" ); + if ( ! backgroundStr.isNull() ) { + // TODO: tranparent background + m_customBackground = true; + if ( backgroundStr[0] != '#' ) { + m_background = TQColor( getHtmlColor( backgroundStr ) ); + } + else { + m_background = TQColor( backgroundStr ); + } + } + TQString veryverythinmathspaceStr = element.attribute( "veryverythinmathspace" ); + if ( ! veryverythinmathspaceStr.isNull() ) { + readSizeAttribute( veryverythinmathspaceStr, &m_veryVeryThinMathSpaceType, &m_veryVeryThinMathSpace ); + } + TQString verythinmathspaceStr = element.attribute( "verythinmathspace" ); + if ( ! verythinmathspaceStr.isNull() ) { + readSizeAttribute( verythinmathspaceStr, &m_veryThinMathSpaceType, &m_veryThinMathSpace ); + } + TQString thinmathspaceStr = element.attribute( "thinmathspace" ); + if ( ! thinmathspaceStr.isNull() ) { + readSizeAttribute( thinmathspaceStr, &m_thinMathSpaceType, &m_thinMathSpace ); + } + TQString mediummathspaceStr = element.attribute( "mediummathspace" ); + if ( ! mediummathspaceStr.isNull() ) { + readSizeAttribute( mediummathspaceStr, &m_mediumMathSpaceType, &m_mediumMathSpace ); + } + TQString thickmathspaceStr = element.attribute( "thickmathspace" ); + if ( ! thickmathspaceStr.isNull() ) { + readSizeAttribute( thickmathspaceStr, &m_thickMathSpaceType, &m_thickMathSpace ); + } + TQString verythickmathspaceStr = element.attribute( "verythickmathspace" ); + if ( ! verythickmathspaceStr.isNull() ) { + readSizeAttribute( verythickmathspaceStr, &m_veryThickMathSpaceType, &m_veryThickMathSpace ); + } + TQString veryverythickmathspaceStr = element.attribute( "veryverythickmathspace" ); + if ( ! veryverythickmathspaceStr.isNull() ) { + readSizeAttribute( veryverythickmathspaceStr, &m_veryVeryThickMathSpaceType, &m_veryVeryThickMathSpace ); + } + return inherited::readAttributesFromMathMLDom( element ); +} + +void StyleElement::writeMathMLAttributes( TQDomElement& element ) const +{ + if ( m_customScriptLevel ) { + TQString prefix; + if ( m_relativeScriptLevel && m_scriptLevel >= 0 ) { + prefix = "+"; + } + element.setAttribute( "scriptlevel", prefix + TQString( "%1" ).arg( m_scriptLevel ) ); + } + if ( m_customDisplayStyle ) { + element.setAttribute( "displaystyle", m_displayStyle ? "true" : "false" ); + } + if ( m_customScriptSizeMultiplier ) { + element.setAttribute( "scriptsizemultiplier", TQString( "%1" ).arg( m_scriptSizeMultiplier ) ); + } + writeSizeAttribute( element, "scriptminsize", m_scriptMinSizeType, m_scriptMinSize ); + if ( m_customBackground ) { + element.setAttribute( "background", m_background.name() ); + } + writeSizeAttribute( element, "veryverythinmathspace", m_veryVeryThinMathSpaceType, m_veryVeryThinMathSpace ); + writeSizeAttribute( element, "verythinmathspace", m_veryThinMathSpaceType, m_veryThinMathSpace ); + writeSizeAttribute( element, "thinmathspace", m_thinMathSpaceType, m_thinMathSpace ); + writeSizeAttribute( element, "mediummathspace", m_mediumMathSpaceType, m_mediumMathSpace ); + writeSizeAttribute( element, "thickmathspace", m_thickMathSpaceType, m_thickMathSpace ); + writeSizeAttribute( element, "verythickmathspace", m_veryThickMathSpaceType, m_veryThickMathSpace ); + writeSizeAttribute( element, "veryverythickmathspace", m_veryVeryThickMathSpaceType, m_veryVeryThickMathSpace ); + + inherited::writeMathMLAttributes( element ); +} + + +void StyleElement::setStyleSize( const ContextStyle& context, StyleAttributes& style ) +{ + if ( m_customScriptLevel ) { + if ( m_relativeScriptLevel ) { + style.setScriptLevel( style.scriptLevel() + m_scriptLevel ); + } + else { + style.setScriptLevel( m_scriptLevel ); + } + } + else { + style.setScriptLevel( style.scriptLevel() ); + } + if ( m_customDisplayStyle || style.customDisplayStyle() ) { + style.setCustomDisplayStyle( true ); + if ( m_customDisplayStyle ) { + style.setDisplayStyle( m_displayStyle ); + } + else { + style.setDisplayStyle( style.displayStyle() ); + } + } + else { + style.setCustomDisplayStyle( false ); + } + if ( m_customScriptSizeMultiplier ) { + style.setScriptSizeMultiplier( m_scriptSizeMultiplier ); + } + else { + style.setScriptSizeMultiplier( style.scriptSizeMultiplier() ); + } + + // Get scriptminsize attribute in absolute units, so we don't depend on + // context to get the default value + double basesize = context.layoutUnitPtToPt( context.getBaseSize() ); + double size = style.scriptMinSize(); + switch ( m_scriptMinSizeType ) { + case AbsoluteSize: + size = m_scriptMinSize; + case RelativeSize: + size = m_scriptMinSize * basesize; + case PixelSize: + size = context.pixelXToPt( m_scriptMinSize ); + default: + break; + } + style.setScriptMinSize( size ); + + style.setVeryVeryThinMathSpace( sizeFactor( context, + m_veryVeryThinMathSpaceType, + m_veryVeryThinMathSpace, + style.veryVeryThinMathSpace() )); + style.setVeryThinMathSpace( sizeFactor( context, m_veryThinMathSpaceType, + m_veryThinMathSpace, + style.veryThinMathSpace() )); + style.setThinMathSpace( sizeFactor( context, m_thinMathSpaceType, + m_thinMathSpace, + style.thinMathSpace() )); + style.setMediumMathSpace( sizeFactor( context, m_mediumMathSpaceType, + m_mediumMathSpace, + style.mediumMathSpace() )); + style.setThickMathSpace( sizeFactor( context, m_thickMathSpaceType, + m_thickMathSpace, + style.thickMathSpace() )); + style.setVeryThickMathSpace( sizeFactor( context, m_veryThickMathSpaceType, + m_veryThickMathSpace, + style.veryThickMathSpace() )); + style.setVeryVeryThickMathSpace( sizeFactor( context, + m_veryVeryThickMathSpaceType, + m_veryVeryThickMathSpace, + style.veryVeryThickMathSpace() )); + inherited::setStyleSize( context, style ); +} + +double StyleElement::sizeFactor( const ContextStyle& context, SizeType st, + double length, double defvalue ) +{ + double basesize = context.layoutUnitPtToPt( context.getBaseSize() ); + switch ( st ) { + case AbsoluteSize: + return length / basesize; + case RelativeSize: + return length; + case PixelSize: + return context.pixelXToPt( length ) / basesize; + default: + break; + } + return defvalue; +} + +void StyleElement::setStyleVariant( StyleAttributes& style ) +{ + if ( customMathVariant() ) { + style.setCustomMathVariant ( true ); + style.setCustomFontWeight( false ); + style.setCustomFontStyle( false ); + style.setCustomFont( false ); + if ( customMathVariant() ) { + style.setCharFamily ( charFamily() ); + style.setCharStyle( charStyle() ); + } + else { + style.setCharFamily( style.charFamily() ); + style.setCharStyle( style.charStyle() ); + } + } + else { + style.setCustomMathVariant( false ); + if ( customFontFamily() ) { + style.setCustomFont( true ); + style.setFont( TQFont(fontFamily()) ); + } + + bool fontweight = false; + if ( customFontWeight() || style.customFontWeight() ) { + style.setCustomFontWeight( true ); + if ( customFontWeight() ) { + fontweight = fontWeight(); + } + else { + fontweight = style.fontWeight(); + } + style.setFontWeight( fontweight ); + } + else { + style.setCustomFontWeight( false ); + } + + bool fontstyle = false; + if ( customFontStyle() || style.customFontStyle() ) { + style.setCustomFontStyle( true ); + if ( customFontStyle() ) { + fontstyle = fontStyle(); + } + else { + fontstyle = style.fontStyle(); + } + style.setFontStyle( fontstyle ); + } + else { + style.setCustomFontStyle( false ); + } + + if ( fontweight && fontstyle ) { + style.setCharStyle( boldItalicChar ); + } + else if ( fontweight && ! fontstyle ) { + style.setCharStyle( boldChar ); + } + else if ( ! fontweight && fontstyle ) { + style.setCharStyle( italicChar ); + } + else { + style.setCharStyle( normalChar ); + } + } +} + +void StyleElement::setStyleBackground( StyleAttributes& style ) +{ + if ( customMathBackground() ) { + style.setBackground( mathBackground() ); + } + else if ( m_customBackground ) { + style.setBackground( m_background ); + } + else { + style.setBackground( style.background() ); + } +} + +void StyleElement::resetStyle( StyleAttributes& style ) +{ + inherited::resetStyle( style ); + style.resetScriptLevel(); + style.resetScriptSizeMultiplier(); + style.resetScriptMinSize(); + style.resetVeryVeryThinMathSpace(); + style.resetVeryThinMathSpace(); + style.resetThinMathSpace(); + style.resetMediumMathSpace(); + style.resetThickMathSpace(); + style.resetVeryThickMathSpace(); + style.resetVeryVeryThickMathSpace(); + style.resetDisplayStyle(); +} + +void StyleElement::readSizeAttribute( const TQString& str, SizeType* st, double* s ) +{ + if ( st == 0 || s == 0 ){ + return; + } + if ( str == "small" ) { + *st = RelativeSize; + *s = 0.8; // ### Arbitrary size + } + else if ( str == "normal" ) { + *st = RelativeSize; + *s = 1.0; + } + else if ( str == "big" ) { + *st = RelativeSize; + *s = 1.2; // ### Arbitrary size + } + else { + *s = getSize( str, st ); + } +} + +void StyleElement::writeSizeAttribute( TQDomElement element, const TQString& str, SizeType st, double s ) const +{ + switch ( st ) { + case AbsoluteSize: + element.setAttribute( str, TQString( "%1pt" ).arg( s ) ); + break; + case RelativeSize: + element.setAttribute( str, TQString( "%1%" ).arg( s * 100.0 ) ); + break; + case PixelSize: + element.setAttribute( str, TQString( "%1px" ).arg( s ) ); + break; + default: + break; + } +} + + +KFORMULA_NAMESPACE_END diff --git a/lib/kformula/symbolaction.cc b/lib/kformula/symbolaction.cc deleted file mode 100644 index 8fe3d8f8..00000000 --- a/lib/kformula/symbolaction.cc +++ /dev/null @@ -1,174 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2002 Heinrich Kuettler - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - -#include -#include - -#include -#include -#include -#include -#include - -#include "symbolaction.h" - -/* - * The items for the SymbolCombos. * - */ - -KFORMULA_NAMESPACE_BEGIN - -class SymbolComboItem : public TQListBoxItem -{ -public: - SymbolComboItem( const TQString&, const TQFont& , TQChar, TQComboBox* combo ); - virtual ~SymbolComboItem(); - - virtual int width( const TQListBox* ) const; - virtual int height( const TQListBox* ) const; - -protected: - virtual void paint( TQPainter *p ); - -private: - TQComboBox *m_combo; - TQString m_name; - TQFont m_font; - TQChar m_symbol; - - static int widest; -}; - -int SymbolComboItem::widest = 0; - -SymbolComboItem::SymbolComboItem( const TQString &name, const TQFont& font, - TQChar symbol, TQComboBox *combo ) - : TQListBoxItem( combo->listBox() ), - m_combo( combo ), - m_name( name ), - m_font( font ), - m_symbol( symbol ) -{ - setText( name ); - int charWidth = TQFontMetrics( m_font ).width( TQChar( m_symbol ) ); - widest = TQMAX( widest, charWidth ); -} - -SymbolComboItem::~SymbolComboItem() -{ -} - -int SymbolComboItem::width( const TQListBox * /*lb*/ ) const -{ - return widest + TQFontMetrics( TDEGlobalSettings::generalFont() ).width( text() ) + 12; -} - -int SymbolComboItem::height( const TQListBox * /*lb*/ ) const -{ - int generalHeight = TQFontMetrics( TDEGlobalSettings::generalFont() ).lineSpacing(); - int fontHeight = TQFontMetrics( m_font ).lineSpacing(); - return TQMAX( generalHeight, fontHeight ) + 2; -} - -void SymbolComboItem::paint( TQPainter *p ) -{ - p->setFont( m_font ); - TQFontMetrics fm( p->fontMetrics() ); - p->drawText( 3, fm.ascent() + fm.leading() / 2, - TQString( "%1" ).arg( TQChar( m_symbol ) ) ); - - p->setFont( TDEGlobalSettings::generalFont() ); - fm = p->fontMetrics(); - p->drawText( widest + 6, height( m_combo->listBox() ) / 2 + fm.strikeOutPos(), m_name ); -} - -/* - * The symbol action * - */ -SymbolAction::SymbolAction( TQObject* parent, const char* name ) - : TDESelectAction( parent, name ) -{ - setEditable( FALSE ); -} - -SymbolAction::SymbolAction( const TQString& text, const TDEShortcut& cut, - const TQObject* receiver, const char* slot, - TQObject* parent, const char* name ) - : TDESelectAction( text, cut, receiver, slot, parent, name ) -{ - setEditable( FALSE ); -} - -int SymbolAction::plug( TQWidget* w, int index ) -{ - if (kapp && !kapp->authorizeTDEAction(name())) - return -1; - if ( w->inherits( "TDEToolBar" ) ) - { - TDEToolBar* bar = static_cast( w ); - int id_ = TDEAction::getToolButtonID(); - KComboBox *cb = new KComboBox( bar ); - connect( cb, TQT_SIGNAL( activated( const TQString & ) ), - TQT_SLOT( slotActivated( const TQString & ) ) ); - cb->setEnabled( isEnabled() ); - bar->insertWidget( id_, comboWidth(), cb, index ); - cb->setMinimumWidth( cb->sizeHint().width() ); - - addContainer( bar, id_ ); - - connect( bar, TQT_SIGNAL( destroyed() ), this, TQT_SLOT( slotDestroyed() ) ); - - updateItems( containerCount() - 1 ); - - return containerCount() - 1; - } - else return TDESelectAction::plug( w, index ); -} - -void SymbolAction::setSymbols( const TQStringList &names, - const TQFont& font, - const TQMemArray& chars ) -{ - m_chars = chars; - m_font = font; - setItems( names ); - - int len = containerCount(); - for ( int i = 0; i < len; ++i ) - updateItems( i ); -} - -void SymbolAction::updateItems( int id ) -{ - TQWidget *w = container( id ); - if ( w->inherits( "TDEToolBar" ) ) { - TQWidget *r = static_cast( w )->getWidget( itemId( id ) ); - if ( r->inherits( TQCOMBOBOX_OBJECT_NAME_STRING ) ) { - TQComboBox *cb = static_cast( r ); - cb->clear(); - - for( uint i = 0; i < items().count(); ++i ) { - new SymbolComboItem( *items().at( i ), m_font, m_chars.at( i ), cb ); - } - cb->setMinimumWidth( cb->sizeHint().width() ); - } - } -} - -KFORMULA_NAMESPACE_END diff --git a/lib/kformula/symbolaction.cpp b/lib/kformula/symbolaction.cpp new file mode 100644 index 00000000..8fe3d8f8 --- /dev/null +++ b/lib/kformula/symbolaction.cpp @@ -0,0 +1,174 @@ +/* This file is part of the KDE project + Copyright (C) 2002 Heinrich Kuettler + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include + +#include +#include +#include +#include +#include + +#include "symbolaction.h" + +/* + * The items for the SymbolCombos. * + */ + +KFORMULA_NAMESPACE_BEGIN + +class SymbolComboItem : public TQListBoxItem +{ +public: + SymbolComboItem( const TQString&, const TQFont& , TQChar, TQComboBox* combo ); + virtual ~SymbolComboItem(); + + virtual int width( const TQListBox* ) const; + virtual int height( const TQListBox* ) const; + +protected: + virtual void paint( TQPainter *p ); + +private: + TQComboBox *m_combo; + TQString m_name; + TQFont m_font; + TQChar m_symbol; + + static int widest; +}; + +int SymbolComboItem::widest = 0; + +SymbolComboItem::SymbolComboItem( const TQString &name, const TQFont& font, + TQChar symbol, TQComboBox *combo ) + : TQListBoxItem( combo->listBox() ), + m_combo( combo ), + m_name( name ), + m_font( font ), + m_symbol( symbol ) +{ + setText( name ); + int charWidth = TQFontMetrics( m_font ).width( TQChar( m_symbol ) ); + widest = TQMAX( widest, charWidth ); +} + +SymbolComboItem::~SymbolComboItem() +{ +} + +int SymbolComboItem::width( const TQListBox * /*lb*/ ) const +{ + return widest + TQFontMetrics( TDEGlobalSettings::generalFont() ).width( text() ) + 12; +} + +int SymbolComboItem::height( const TQListBox * /*lb*/ ) const +{ + int generalHeight = TQFontMetrics( TDEGlobalSettings::generalFont() ).lineSpacing(); + int fontHeight = TQFontMetrics( m_font ).lineSpacing(); + return TQMAX( generalHeight, fontHeight ) + 2; +} + +void SymbolComboItem::paint( TQPainter *p ) +{ + p->setFont( m_font ); + TQFontMetrics fm( p->fontMetrics() ); + p->drawText( 3, fm.ascent() + fm.leading() / 2, + TQString( "%1" ).arg( TQChar( m_symbol ) ) ); + + p->setFont( TDEGlobalSettings::generalFont() ); + fm = p->fontMetrics(); + p->drawText( widest + 6, height( m_combo->listBox() ) / 2 + fm.strikeOutPos(), m_name ); +} + +/* + * The symbol action * + */ +SymbolAction::SymbolAction( TQObject* parent, const char* name ) + : TDESelectAction( parent, name ) +{ + setEditable( FALSE ); +} + +SymbolAction::SymbolAction( const TQString& text, const TDEShortcut& cut, + const TQObject* receiver, const char* slot, + TQObject* parent, const char* name ) + : TDESelectAction( text, cut, receiver, slot, parent, name ) +{ + setEditable( FALSE ); +} + +int SymbolAction::plug( TQWidget* w, int index ) +{ + if (kapp && !kapp->authorizeTDEAction(name())) + return -1; + if ( w->inherits( "TDEToolBar" ) ) + { + TDEToolBar* bar = static_cast( w ); + int id_ = TDEAction::getToolButtonID(); + KComboBox *cb = new KComboBox( bar ); + connect( cb, TQT_SIGNAL( activated( const TQString & ) ), + TQT_SLOT( slotActivated( const TQString & ) ) ); + cb->setEnabled( isEnabled() ); + bar->insertWidget( id_, comboWidth(), cb, index ); + cb->setMinimumWidth( cb->sizeHint().width() ); + + addContainer( bar, id_ ); + + connect( bar, TQT_SIGNAL( destroyed() ), this, TQT_SLOT( slotDestroyed() ) ); + + updateItems( containerCount() - 1 ); + + return containerCount() - 1; + } + else return TDESelectAction::plug( w, index ); +} + +void SymbolAction::setSymbols( const TQStringList &names, + const TQFont& font, + const TQMemArray& chars ) +{ + m_chars = chars; + m_font = font; + setItems( names ); + + int len = containerCount(); + for ( int i = 0; i < len; ++i ) + updateItems( i ); +} + +void SymbolAction::updateItems( int id ) +{ + TQWidget *w = container( id ); + if ( w->inherits( "TDEToolBar" ) ) { + TQWidget *r = static_cast( w )->getWidget( itemId( id ) ); + if ( r->inherits( TQCOMBOBOX_OBJECT_NAME_STRING ) ) { + TQComboBox *cb = static_cast( r ); + cb->clear(); + + for( uint i = 0; i < items().count(); ++i ) { + new SymbolComboItem( *items().at( i ), m_font, m_chars.at( i ), cb ); + } + cb->setMinimumWidth( cb->sizeHint().width() ); + } + } +} + +KFORMULA_NAMESPACE_END diff --git a/lib/kformula/symbolelement.cc b/lib/kformula/symbolelement.cc deleted file mode 100644 index 31787b16..00000000 --- a/lib/kformula/symbolelement.cc +++ /dev/null @@ -1,906 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2001 Andrea Rizzi - Ulrich Kuettler - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - -#include - -#include - -#include "elementvisitor.h" -#include "formulacursor.h" -#include "formulaelement.h" -#include "kformulacommand.h" -#include "sequenceelement.h" -#include "symbolelement.h" - -KFORMULA_NAMESPACE_BEGIN - - -class SymbolSequenceElement : public SequenceElement { - typedef SequenceElement inherited; -public: - - SymbolSequenceElement( BasicElement* parent = 0 ) : SequenceElement( parent ) {} - - /** - * This is called by the container to get a command depending on - * the current cursor position (this is how the element gets chosen) - * and the request. - * - * @returns the command that performs the requested action with - * the containers active cursor. - */ - virtual KCommand* buildCommand( Container*, Request* ); -}; - - -KCommand* SymbolSequenceElement::buildCommand( Container* container, Request* request ) -{ - FormulaCursor* cursor = container->activeCursor(); - if ( cursor->isReadOnly() ) { - return 0; - } - - switch ( *request ) { - case req_addIndex: { - FormulaCursor* cursor = container->activeCursor(); - if ( cursor->isSelection() || - ( cursor->getPos() > 0 && cursor->getPos() < countChildren() ) ) { - break; - } - IndexRequest* ir = static_cast( request ); - if ( ( ir->index() == upperMiddlePos ) || ( ir->index() == lowerMiddlePos ) ) { - SymbolElement* element = static_cast( getParent() ); - ElementIndexPtr index = element->getIndex( ir->index() ); - if ( !index->hasIndex() ) { - KFCAddGenericIndex* command = new KFCAddGenericIndex( container, index ); - return command; - } - else { - index->moveToIndex( cursor, afterCursor ); - cursor->setSelection( false ); - formula()->cursorHasMoved( cursor ); - return 0; - } - } - } - default: - break; - } - return inherited::buildCommand( container, request ); -} - - -SymbolElement::SymbolElement(SymbolType type, BasicElement* parent) - : BasicElement(parent), symbol( 0 ), symbolType( type ) -{ - content = new SymbolSequenceElement( this ); - upper = 0; - lower = 0; -} - -SymbolElement::~SymbolElement() -{ - delete lower; - delete upper; - delete content; - delete symbol; -} - - -SymbolElement::SymbolElement( const SymbolElement& other ) - : BasicElement( other ), symbol( 0 ), symbolType( other.symbolType ) -{ - content = new SymbolSequenceElement( *dynamic_cast( other.content ) ); - content->setParent( this ); - - if ( other.upper ) { - upper = new SequenceElement( *( other.upper ) ); - upper->setParent( this ); - } - else { - upper = 0; - } - if ( other.lower ) { - lower = new SequenceElement( *( other.lower ) ); - lower->setParent( this ); - } - else { - lower = 0; - } -} - - -bool SymbolElement::accept( ElementVisitor* visitor ) -{ - return visitor->visit( this ); -} - - -BasicElement* SymbolElement::goToPos( FormulaCursor* cursor, bool& handled, - const LuPixelPoint& point, const LuPixelPoint& parentOrigin ) -{ - BasicElement* e = BasicElement::goToPos(cursor, handled, point, parentOrigin); - if (e != 0) { - LuPixelPoint myPos(parentOrigin.x() + getX(), - parentOrigin.y() + getY()); - - e = content->goToPos(cursor, handled, point, myPos); - if (e != 0) { - return e; - } - if (hasLower()) { - e = lower->goToPos(cursor, handled, point, myPos); - if (e != 0) { - return e; - } - } - if (hasUpper()) { - e = upper->goToPos(cursor, handled, point, myPos); - if (e != 0) { - return e; - } - } - - // the positions after the indexes. - luPixel dx = point.x() - myPos.x(); - luPixel dy = point.y() - myPos.y(); - if (dy < symbol->getY()) { - if (hasUpper() && (dx > upper->getX())) { - upper->moveLeft(cursor, this); - handled = true; - return upper; - } - } - else if (dy > symbol->getY()+symbol->getHeight()) { - if (hasLower() && (dx > lower->getX())) { - lower->moveLeft(cursor, this); - handled = true; - return lower; - } - } - - // Have the cursor jump behind the integral. - if ( ( dx < symbol->getX()+symbol->getWidth() ) && - ( dx > symbol->getX()+symbol->getWidth()/2 ) ) { - content->moveRight( cursor, this ); - handled = true; - return content; - } - - return this; - } - return 0; -} - - -/** - * Calculates our width and height and - * our children's parentPosition. - */ -void SymbolElement::calcSizes( const ContextStyle& context, - ContextStyle::TextStyle tstyle, - ContextStyle::IndexStyle istyle, - StyleAttributes& style ) -{ - double factor = style.sizeFactor(); - luPt mySize = context.getAdjustedSize( tstyle, factor ); - luPixel distX = context.ptToPixelX( context.getThinSpace( tstyle, factor ) ); - luPixel distY = context.ptToPixelY( context.getThinSpace( tstyle, factor ) ); - - //if ( symbol == 0 ) { - delete symbol; - symbol = context.fontStyle().createArtwork( symbolType ); - //} - - symbol->calcSizes(context, tstyle, factor, mySize); - content->calcSizes( context, tstyle, istyle, style ); - - //symbol->scale(((double)parentSize)/symbol->getHeight()*2); - - luPixel upperWidth = 0; - luPixel upperHeight = 0; - if (hasUpper()) { - upper->calcSizes( context, context.convertTextStyleIndex( tstyle ), - context.convertIndexStyleUpper( istyle ), style ); - upperWidth = upper->getWidth(); - upperHeight = upper->getHeight() + distY; - } - - luPixel lowerWidth = 0; - luPixel lowerHeight = 0; - if (hasLower()) { - lower->calcSizes( context, context.convertTextStyleIndex( tstyle ), - context.convertIndexStyleLower( istyle ), style ); - lowerWidth = lower->getWidth(); - lowerHeight = lower->getHeight() + distY; - } - - // widths - luPixel xOffset = TQMAX(symbol->getWidth(), TQMAX(upperWidth, lowerWidth)); - if (context.getCenterSymbol()) { - symbol->setX((xOffset - symbol->getWidth()) / 2); - } - else { - symbol->setX(xOffset - symbol->getWidth()); - } - // ??? - content->setX(xOffset + - static_cast( symbol->slant()*symbol->getHeight()/2 ) + - distX/2); - - setWidth(TQMAX(content->getX() + content->getWidth(), - TQMAX(upperWidth, lowerWidth))); - - // heights - //int toMidline = TQMAX(content->getHeight() / 2, - luPixel toMidline = TQMAX(content->axis( context, tstyle, factor ), - upperHeight + symbol->getHeight()/2); - //int fromMidline = TQMAX(content->getHeight() / 2, - luPixel fromMidline = TQMAX(content->getHeight() - content->axis( context, tstyle, factor ), - lowerHeight + symbol->getHeight()/2); - setHeight(toMidline + fromMidline); - //setMidline(toMidline); - - symbol->setY(toMidline - symbol->getHeight()/2); - //content->setY(toMidline - content->getHeight()/2); - content->setY(toMidline - content->axis( context, tstyle, factor )); - - if (hasUpper()) { - luPixel slant = - static_cast( symbol->slant()*( symbol->getHeight()+distY ) ); - if (context.getCenterSymbol()) { - upper->setX((xOffset - upperWidth) / 2 + slant ); - } - else { - if (upperWidth < symbol->getWidth()) { - upper->setX(symbol->getX() + - (symbol->getWidth() - upperWidth) / 2 + slant ); - } - else { - upper->setX(xOffset - upperWidth); - } - } - upper->setY(toMidline - upperHeight - symbol->getHeight()/2); - } - if (hasLower()) { - luPixel slant = static_cast( -symbol->slant()*distY ); - if (context.getCenterSymbol()) { - lower->setX((xOffset - lowerWidth) / 2 + slant); - } - else { - if (lowerWidth < symbol->getWidth()) { - lower->setX(symbol->getX() + - (symbol->getWidth() - lowerWidth) / 2 + slant ); - } - else { - lower->setX(xOffset - lowerWidth); - } - } - lower->setY(toMidline + symbol->getHeight()/2 + distY); - } - setBaseline(content->getBaseline() + content->getY()); -} - -/** - * Draws the whole element including its children. - * The `parentOrigin' is the point this element's parent starts. - * We can use our parentPosition to get our own origin then. - */ -void SymbolElement::draw( TQPainter& painter, const LuPixelRect& r, - const ContextStyle& context, - ContextStyle::TextStyle tstyle, - ContextStyle::IndexStyle istyle, - StyleAttributes& style, - const LuPixelPoint& parentOrigin ) -{ - LuPixelPoint myPos( parentOrigin.x()+getX(), parentOrigin.y()+getY() ); - //if ( !LuPixelRect( myPos.x(), myPos.y(), getWidth(), getHeight() ).intersects( r ) ) - // return; - - luPt mySize = context.getAdjustedSize( tstyle, style.sizeFactor() ); - symbol->draw( painter, r, context, tstyle, style, mySize, myPos ); - content->draw( painter, r, context, tstyle, istyle, style, myPos ); - if ( hasUpper() ) { - upper->draw( painter, r, context, context.convertTextStyleIndex( tstyle ), - context.convertIndexStyleUpper( istyle ), style, myPos ); - } - if ( hasLower() ) { - lower->draw( painter, r, context, context.convertTextStyleIndex( tstyle ), - context.convertIndexStyleLower( istyle ), style, myPos ); - } - - // Debug -#if 0 - painter.setBrush(TQt::NoBrush); - painter.setPen(TQt::red); -// painter.drawRect( context.layoutUnitToPixelX( myPos.x() ), -// context.layoutUnitToPixelY( myPos.y() ), -// context.layoutUnitToPixelX( getWidth() ), -// context.layoutUnitToPixelY( getHeight() ) ); - painter.drawRect( context.layoutUnitToPixelX( myPos.x()+symbol->getX() ), - context.layoutUnitToPixelY( myPos.y()+symbol->getY() ), - context.layoutUnitToPixelX( symbol->getWidth() ), - context.layoutUnitToPixelY( symbol->getHeight() ) ); - painter.setPen(TQt::green); - painter.drawLine( context.layoutUnitToPixelX( myPos.x() ), - context.layoutUnitToPixelY( myPos.y()+axis(context, tstyle) ), - context.layoutUnitToPixelX( myPos.x()+getWidth() ), - context.layoutUnitToPixelY( myPos.y()+axis(context, tstyle) ) ); -#endif -} - - -void SymbolElement::dispatchFontCommand( FontCommand* cmd ) -{ - content->dispatchFontCommand( cmd ); - if ( hasUpper() ) { - upper->dispatchFontCommand( cmd ); - } - if ( hasLower() ) { - lower->dispatchFontCommand( cmd ); - } -} - -// navigation -// -// The elements are responsible to handle cursor movement themselves. -// To do this they need to know the direction the cursor moves and -// the element it comes from. -// -// The cursor might be in normal or in selection mode. - -/** - * Enters this element while moving to the left starting inside - * the element `from'. Searches for a cursor position inside - * this element or to the left of it. - */ -void SymbolElement::moveLeft(FormulaCursor* cursor, BasicElement* from) -{ - if (cursor->isSelectionMode()) { - getParent()->moveLeft(cursor, this); - } - else { - bool linear = cursor->getLinearMovement(); - if (from == getParent()) { - content->moveLeft(cursor, this); - } - else if (from == content) { - if (linear && hasLower()) { - lower->moveLeft(cursor, this); - } - else if (linear && hasUpper()) { - upper->moveLeft(cursor, this); - } - else { - getParent()->moveLeft(cursor, this); - } - } - else if (from == lower) { - if (linear && hasUpper()) { - upper->moveLeft(cursor, this); - } - else { - getParent()->moveLeft(cursor, this); - } - } - else if (from == upper) { - getParent()->moveLeft(cursor, this); - } - } -} - -/** - * Enters this element while moving to the right starting inside - * the element `from'. Searches for a cursor position inside - * this element or to the right of it. - */ -void SymbolElement::moveRight(FormulaCursor* cursor, BasicElement* from) -{ - if (cursor->isSelectionMode()) { - getParent()->moveRight(cursor, this); - } - else { - bool linear = cursor->getLinearMovement(); - if (from == getParent()) { - if (linear && hasUpper()) { - upper->moveRight(cursor, this); - } - else if (linear && hasLower()) { - lower->moveRight(cursor, this); - } - else { - content->moveRight(cursor, this); - } - } - else if (from == upper) { - if (linear && hasLower()) { - lower->moveRight(cursor, this); - } - else { - content->moveRight(cursor, this); - } - } - else if (from == lower) { - content->moveRight(cursor, this); - } - else if (from == content) { - getParent()->moveRight(cursor, this); - } - } -} - -/** - * Enters this element while moving up starting inside - * the element `from'. Searches for a cursor position inside - * this element or above it. - */ -void SymbolElement::moveUp(FormulaCursor* cursor, BasicElement* from) -{ - if (cursor->isSelectionMode()) { - getParent()->moveUp(cursor, this); - } - else { - if (from == content) { - if (hasUpper()) { - upper->moveLeft(cursor, this); - } - else { - getParent()->moveUp(cursor, this); - } - } - else if (from == upper) { - getParent()->moveUp(cursor, this); - } - else if ((from == getParent()) || (from == lower)) { - content->moveRight(cursor, this); - } - } -} - -/** - * Enters this element while moving down starting inside - * the element `from'. Searches for a cursor position inside - * this element or below it. - */ -void SymbolElement::moveDown(FormulaCursor* cursor, BasicElement* from) -{ - if (cursor->isSelectionMode()) { - getParent()->moveDown(cursor, this); - } - else { - if (from == content) { - if (hasLower()) { - lower->moveLeft(cursor, this); - } - else { - getParent()->moveDown(cursor, this); - } - } - else if (from == lower) { - getParent()->moveDown(cursor, this); - } - else if ((from == getParent()) || (from == upper)) { - content->moveRight(cursor, this); - } - } -} - -// children - -// main child -// -// If an element has children one has to become the main one. - -// void SymbolElement::setMainChild(SequenceElement* child) -// { -// formula()->elementRemoval(content); -// content = child; -// content->setParent(this); -// formula()->changed(); -// } - - -/** - * Inserts all new children at the cursor position. Places the - * cursor according to the direction. - * - * You only can insert one index at a time. So the list must contain - * exactly on SequenceElement. And the index you want to insert - * must not exist already. - * - * The list will be emptied but stays the property of the caller. - */ -void SymbolElement::insert(FormulaCursor* cursor, - TQPtrList& newChildren, - Direction direction) -{ - SequenceElement* index = static_cast(newChildren.take(0)); - index->setParent(this); - - switch (cursor->getPos()) { - case upperMiddlePos: - upper = index; - break; - case lowerMiddlePos: - lower = index; - break; - default: - // this is an error! - return; - } - - if (direction == beforeCursor) { - index->moveLeft(cursor, this); - } - else { - index->moveRight(cursor, this); - } - cursor->setSelection(false); - formula()->changed(); -} - -/** - * Removes all selected children and returns them. Places the - * cursor to where the children have been. - * - * The cursor has to be inside one of our indexes which is supposed - * to be empty. The index will be removed and the cursor will - * be placed to the removed index so it can be inserted again. - * This methode is called by SequenceElement::remove only. - * - * The ownership of the list is passed to the caller. - */ -void SymbolElement::remove(FormulaCursor* cursor, - TQPtrList& removedChildren, - Direction direction) -{ - int pos = cursor->getPos(); - switch (pos) { - case upperMiddlePos: - removedChildren.append(upper); - formula()->elementRemoval(upper); - upper = 0; - setToUpper(cursor); - break; - case lowerMiddlePos: - removedChildren.append(lower); - formula()->elementRemoval(lower); - lower = 0; - setToLower(cursor); - break; - case contentPos: { - BasicElement* parent = getParent(); - parent->selectChild(cursor, this); - parent->remove(cursor, removedChildren, direction); - break; - } - } - formula()->changed(); -} - -/** - * Moves the cursor to a normal place where new elements - * might be inserted. - */ -void SymbolElement::normalize(FormulaCursor* cursor, Direction direction) -{ - if (direction == beforeCursor) { - content->moveLeft(cursor, this); - } - else { - content->moveRight(cursor, this); - } -} - -/** - * Returns the child at the cursor. - */ -BasicElement* SymbolElement::getChild(FormulaCursor* cursor, Direction) -{ - int pos = cursor->getPos(); - switch (pos) { - case contentPos: - return content; - case upperMiddlePos: - return upper; - case lowerMiddlePos: - return lower; - } - return 0; -} - -/** - * Sets the cursor to select the child. The mark is placed before, - * the position behind it. - */ -void SymbolElement::selectChild(FormulaCursor* cursor, BasicElement* child) -{ - if (child == content) { - setToContent(cursor); - } - else if (child == upper) { - setToUpper(cursor); - } - else if (child == lower) { - setToLower(cursor); - } -} - -void SymbolElement::setToUpper(FormulaCursor* cursor) -{ - cursor->setTo(this, upperMiddlePos); -} - -void SymbolElement::setToLower(FormulaCursor* cursor) -{ - cursor->setTo(this, lowerMiddlePos); -} - -/** - * Sets the cursor to point to the place where the content is. - * There always is a content so this is not a useful place. - * No insertion or removal will succeed as long as the cursor is - * there. - */ -void SymbolElement::setToContent(FormulaCursor* cursor) -{ - cursor->setTo(this, contentPos); -} - - -void SymbolElement::moveToUpper(FormulaCursor* cursor, Direction direction) -{ - if (hasUpper()) { - if (direction == beforeCursor) { - upper->moveLeft(cursor, this); - } - else { - upper->moveRight(cursor, this); - } - } -} - -void SymbolElement::moveToLower(FormulaCursor* cursor, Direction direction) -{ - if (hasLower()) { - if (direction == beforeCursor) { - lower->moveLeft(cursor, this); - } - else { - lower->moveRight(cursor, this); - } - } -} - - -ElementIndexPtr SymbolElement::getIndex( int position ) -{ - switch ( position ) { - case lowerMiddlePos: - return getLowerIndex(); - case upperMiddlePos: - return getUpperIndex(); - } - return getUpperIndex(); -} - - -/** - * Appends our attributes to the dom element. - */ -void SymbolElement::writeDom(TQDomElement element) -{ - BasicElement::writeDom(element); - - element.setAttribute("TYPE", symbolType); - - TQDomDocument doc = element.ownerDocument(); - - TQDomElement con = doc.createElement("CONTENT"); - con.appendChild(content->getElementDom(doc)); - element.appendChild(con); - - if(hasLower()) { - TQDomElement ind = doc.createElement("LOWER"); - ind.appendChild(lower->getElementDom(doc)); - element.appendChild(ind); - } - if(hasUpper()) { - TQDomElement ind = doc.createElement("UPPER"); - ind.appendChild(upper->getElementDom(doc)); - element.appendChild(ind); - } -} - -/** - * Reads our attributes from the element. - * Returns false if it failed. - */ -bool SymbolElement::readAttributesFromDom(TQDomElement element) -{ - if (!BasicElement::readAttributesFromDom(element)) { - return false; - } - - TQString typeStr = element.attribute("TYPE"); - if(!typeStr.isNull()) { - symbolType = static_cast(typeStr.toInt()); - } - - return true; -} - -/** - * Reads our content from the node. Sets the node to the next node - * that needs to be read. - * Returns false if it failed. - */ -bool SymbolElement::readContentFromDom(TQDomNode& node) -{ - if (!BasicElement::readContentFromDom(node)) { - return false; - } - - if ( !buildChild( content, node, "CONTENT" ) ) { - kdWarning( DEBUGID ) << "Empty content in SymbolElement." << endl; - return false; - } - node = node.nextSibling(); - - bool lowerRead = false; - bool upperRead = false; - - while (!node.isNull() && !(upperRead && lowerRead)) { - - if (!lowerRead && (node.nodeName().upper() == "LOWER")) { - lowerRead = buildChild( lower=new SequenceElement( this ), node, "LOWER" ); - if ( !lowerRead ) return false; - } - - if (!upperRead && (node.nodeName().upper() == "UPPER")) { - upperRead = buildChild( upper=new SequenceElement( this ), node, "UPPER" ); - if ( !upperRead ) return false; - } - - node = node.nextSibling(); - } - return true; -} - -TQString SymbolElement::toLatex() -{ - TQString sym; - - switch(symbolType) { - - case 1001: - sym="\\int"; - break; - case 1002: - sym="\\sum"; - break; - case 1003: - sym="\\prod"; - break; - - default: - sym=" "; - - } - - - if(hasLower()) { - sym+="_{"; - sym+=lower->toLatex(); - sym+="}"; - } - - if(hasUpper()) { - sym+="^{"; - sym+=upper->toLatex(); - sym+="} "; - } - - sym += " "; - - sym+=content->toLatex(); - - - return sym; -} - -TQString SymbolElement::formulaString() -{ - TQString sym; - switch ( symbolType ) { - case 1001: - sym="int("; - break; - case 1002: - sym="sum("; - break; - case 1003: - sym="prod("; - break; - default: - sym="("; - } - sym += content->formulaString(); - if ( hasLower() ) { - sym += ", " + lower->formulaString(); - } - if ( hasUpper() ) { - sym += ", " + upper->formulaString(); - } - return sym + ")"; -} - -void SymbolElement::writeMathML( TQDomDocument& doc, TQDomNode& parent, bool oasisFormat ) const -{ - TQDomElement de = doc.createElement( oasisFormat ? "math:mrow" : "mrow" ); - TQDomElement mo = doc.createElement( oasisFormat ? "math:mo" : "mo" ); - - TQString value; - - switch( symbolType ) - { - case EmptyBracket: break; - case LeftLineBracket: case RightLineBracket: - mo.appendChild( doc.createTextNode( "|" ) ); break; - case Integral: - mo.appendChild( doc.createEntityReference( "int" ) ); break; - case Sum: - mo.appendChild( doc.createEntityReference( "sum" ) ); break; - case Product: - mo.appendChild( doc.createEntityReference( "prod" ) ); break; - default: - mo.appendChild( doc.createTextNode( TQChar( symbolType ) ) ); - } - - TQDomElement between; - if ( hasUpper() && hasLower() ) - { - between = doc.createElement( oasisFormat ? "math:msubsup" : "msubsup" ); - between.appendChild( mo ); - lower->writeMathML( doc, between, oasisFormat ); - upper->writeMathML( doc, between, oasisFormat ); - } - else if ( hasUpper() ) - { - between = doc.createElement( oasisFormat ? "math:msup" : "msup" ); - between.appendChild( mo ); - upper->writeMathML( doc, between, oasisFormat ); - } - else if ( hasLower() ) - { - between = doc.createElement( oasisFormat ? "math:msub" : "msub" ); - between.appendChild( mo ); - lower->writeMathML( doc, between, oasisFormat ); - } - else - between = mo; - - de.appendChild( between ); - content->writeMathML( doc, de, oasisFormat ); - - parent.appendChild( de ); -} - -KFORMULA_NAMESPACE_END diff --git a/lib/kformula/symbolelement.cpp b/lib/kformula/symbolelement.cpp new file mode 100644 index 00000000..31787b16 --- /dev/null +++ b/lib/kformula/symbolelement.cpp @@ -0,0 +1,906 @@ +/* This file is part of the KDE project + Copyright (C) 2001 Andrea Rizzi + Ulrich Kuettler + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include + +#include + +#include "elementvisitor.h" +#include "formulacursor.h" +#include "formulaelement.h" +#include "kformulacommand.h" +#include "sequenceelement.h" +#include "symbolelement.h" + +KFORMULA_NAMESPACE_BEGIN + + +class SymbolSequenceElement : public SequenceElement { + typedef SequenceElement inherited; +public: + + SymbolSequenceElement( BasicElement* parent = 0 ) : SequenceElement( parent ) {} + + /** + * This is called by the container to get a command depending on + * the current cursor position (this is how the element gets chosen) + * and the request. + * + * @returns the command that performs the requested action with + * the containers active cursor. + */ + virtual KCommand* buildCommand( Container*, Request* ); +}; + + +KCommand* SymbolSequenceElement::buildCommand( Container* container, Request* request ) +{ + FormulaCursor* cursor = container->activeCursor(); + if ( cursor->isReadOnly() ) { + return 0; + } + + switch ( *request ) { + case req_addIndex: { + FormulaCursor* cursor = container->activeCursor(); + if ( cursor->isSelection() || + ( cursor->getPos() > 0 && cursor->getPos() < countChildren() ) ) { + break; + } + IndexRequest* ir = static_cast( request ); + if ( ( ir->index() == upperMiddlePos ) || ( ir->index() == lowerMiddlePos ) ) { + SymbolElement* element = static_cast( getParent() ); + ElementIndexPtr index = element->getIndex( ir->index() ); + if ( !index->hasIndex() ) { + KFCAddGenericIndex* command = new KFCAddGenericIndex( container, index ); + return command; + } + else { + index->moveToIndex( cursor, afterCursor ); + cursor->setSelection( false ); + formula()->cursorHasMoved( cursor ); + return 0; + } + } + } + default: + break; + } + return inherited::buildCommand( container, request ); +} + + +SymbolElement::SymbolElement(SymbolType type, BasicElement* parent) + : BasicElement(parent), symbol( 0 ), symbolType( type ) +{ + content = new SymbolSequenceElement( this ); + upper = 0; + lower = 0; +} + +SymbolElement::~SymbolElement() +{ + delete lower; + delete upper; + delete content; + delete symbol; +} + + +SymbolElement::SymbolElement( const SymbolElement& other ) + : BasicElement( other ), symbol( 0 ), symbolType( other.symbolType ) +{ + content = new SymbolSequenceElement( *dynamic_cast( other.content ) ); + content->setParent( this ); + + if ( other.upper ) { + upper = new SequenceElement( *( other.upper ) ); + upper->setParent( this ); + } + else { + upper = 0; + } + if ( other.lower ) { + lower = new SequenceElement( *( other.lower ) ); + lower->setParent( this ); + } + else { + lower = 0; + } +} + + +bool SymbolElement::accept( ElementVisitor* visitor ) +{ + return visitor->visit( this ); +} + + +BasicElement* SymbolElement::goToPos( FormulaCursor* cursor, bool& handled, + const LuPixelPoint& point, const LuPixelPoint& parentOrigin ) +{ + BasicElement* e = BasicElement::goToPos(cursor, handled, point, parentOrigin); + if (e != 0) { + LuPixelPoint myPos(parentOrigin.x() + getX(), + parentOrigin.y() + getY()); + + e = content->goToPos(cursor, handled, point, myPos); + if (e != 0) { + return e; + } + if (hasLower()) { + e = lower->goToPos(cursor, handled, point, myPos); + if (e != 0) { + return e; + } + } + if (hasUpper()) { + e = upper->goToPos(cursor, handled, point, myPos); + if (e != 0) { + return e; + } + } + + // the positions after the indexes. + luPixel dx = point.x() - myPos.x(); + luPixel dy = point.y() - myPos.y(); + if (dy < symbol->getY()) { + if (hasUpper() && (dx > upper->getX())) { + upper->moveLeft(cursor, this); + handled = true; + return upper; + } + } + else if (dy > symbol->getY()+symbol->getHeight()) { + if (hasLower() && (dx > lower->getX())) { + lower->moveLeft(cursor, this); + handled = true; + return lower; + } + } + + // Have the cursor jump behind the integral. + if ( ( dx < symbol->getX()+symbol->getWidth() ) && + ( dx > symbol->getX()+symbol->getWidth()/2 ) ) { + content->moveRight( cursor, this ); + handled = true; + return content; + } + + return this; + } + return 0; +} + + +/** + * Calculates our width and height and + * our children's parentPosition. + */ +void SymbolElement::calcSizes( const ContextStyle& context, + ContextStyle::TextStyle tstyle, + ContextStyle::IndexStyle istyle, + StyleAttributes& style ) +{ + double factor = style.sizeFactor(); + luPt mySize = context.getAdjustedSize( tstyle, factor ); + luPixel distX = context.ptToPixelX( context.getThinSpace( tstyle, factor ) ); + luPixel distY = context.ptToPixelY( context.getThinSpace( tstyle, factor ) ); + + //if ( symbol == 0 ) { + delete symbol; + symbol = context.fontStyle().createArtwork( symbolType ); + //} + + symbol->calcSizes(context, tstyle, factor, mySize); + content->calcSizes( context, tstyle, istyle, style ); + + //symbol->scale(((double)parentSize)/symbol->getHeight()*2); + + luPixel upperWidth = 0; + luPixel upperHeight = 0; + if (hasUpper()) { + upper->calcSizes( context, context.convertTextStyleIndex( tstyle ), + context.convertIndexStyleUpper( istyle ), style ); + upperWidth = upper->getWidth(); + upperHeight = upper->getHeight() + distY; + } + + luPixel lowerWidth = 0; + luPixel lowerHeight = 0; + if (hasLower()) { + lower->calcSizes( context, context.convertTextStyleIndex( tstyle ), + context.convertIndexStyleLower( istyle ), style ); + lowerWidth = lower->getWidth(); + lowerHeight = lower->getHeight() + distY; + } + + // widths + luPixel xOffset = TQMAX(symbol->getWidth(), TQMAX(upperWidth, lowerWidth)); + if (context.getCenterSymbol()) { + symbol->setX((xOffset - symbol->getWidth()) / 2); + } + else { + symbol->setX(xOffset - symbol->getWidth()); + } + // ??? + content->setX(xOffset + + static_cast( symbol->slant()*symbol->getHeight()/2 ) + + distX/2); + + setWidth(TQMAX(content->getX() + content->getWidth(), + TQMAX(upperWidth, lowerWidth))); + + // heights + //int toMidline = TQMAX(content->getHeight() / 2, + luPixel toMidline = TQMAX(content->axis( context, tstyle, factor ), + upperHeight + symbol->getHeight()/2); + //int fromMidline = TQMAX(content->getHeight() / 2, + luPixel fromMidline = TQMAX(content->getHeight() - content->axis( context, tstyle, factor ), + lowerHeight + symbol->getHeight()/2); + setHeight(toMidline + fromMidline); + //setMidline(toMidline); + + symbol->setY(toMidline - symbol->getHeight()/2); + //content->setY(toMidline - content->getHeight()/2); + content->setY(toMidline - content->axis( context, tstyle, factor )); + + if (hasUpper()) { + luPixel slant = + static_cast( symbol->slant()*( symbol->getHeight()+distY ) ); + if (context.getCenterSymbol()) { + upper->setX((xOffset - upperWidth) / 2 + slant ); + } + else { + if (upperWidth < symbol->getWidth()) { + upper->setX(symbol->getX() + + (symbol->getWidth() - upperWidth) / 2 + slant ); + } + else { + upper->setX(xOffset - upperWidth); + } + } + upper->setY(toMidline - upperHeight - symbol->getHeight()/2); + } + if (hasLower()) { + luPixel slant = static_cast( -symbol->slant()*distY ); + if (context.getCenterSymbol()) { + lower->setX((xOffset - lowerWidth) / 2 + slant); + } + else { + if (lowerWidth < symbol->getWidth()) { + lower->setX(symbol->getX() + + (symbol->getWidth() - lowerWidth) / 2 + slant ); + } + else { + lower->setX(xOffset - lowerWidth); + } + } + lower->setY(toMidline + symbol->getHeight()/2 + distY); + } + setBaseline(content->getBaseline() + content->getY()); +} + +/** + * Draws the whole element including its children. + * The `parentOrigin' is the point this element's parent starts. + * We can use our parentPosition to get our own origin then. + */ +void SymbolElement::draw( TQPainter& painter, const LuPixelRect& r, + const ContextStyle& context, + ContextStyle::TextStyle tstyle, + ContextStyle::IndexStyle istyle, + StyleAttributes& style, + const LuPixelPoint& parentOrigin ) +{ + LuPixelPoint myPos( parentOrigin.x()+getX(), parentOrigin.y()+getY() ); + //if ( !LuPixelRect( myPos.x(), myPos.y(), getWidth(), getHeight() ).intersects( r ) ) + // return; + + luPt mySize = context.getAdjustedSize( tstyle, style.sizeFactor() ); + symbol->draw( painter, r, context, tstyle, style, mySize, myPos ); + content->draw( painter, r, context, tstyle, istyle, style, myPos ); + if ( hasUpper() ) { + upper->draw( painter, r, context, context.convertTextStyleIndex( tstyle ), + context.convertIndexStyleUpper( istyle ), style, myPos ); + } + if ( hasLower() ) { + lower->draw( painter, r, context, context.convertTextStyleIndex( tstyle ), + context.convertIndexStyleLower( istyle ), style, myPos ); + } + + // Debug +#if 0 + painter.setBrush(TQt::NoBrush); + painter.setPen(TQt::red); +// painter.drawRect( context.layoutUnitToPixelX( myPos.x() ), +// context.layoutUnitToPixelY( myPos.y() ), +// context.layoutUnitToPixelX( getWidth() ), +// context.layoutUnitToPixelY( getHeight() ) ); + painter.drawRect( context.layoutUnitToPixelX( myPos.x()+symbol->getX() ), + context.layoutUnitToPixelY( myPos.y()+symbol->getY() ), + context.layoutUnitToPixelX( symbol->getWidth() ), + context.layoutUnitToPixelY( symbol->getHeight() ) ); + painter.setPen(TQt::green); + painter.drawLine( context.layoutUnitToPixelX( myPos.x() ), + context.layoutUnitToPixelY( myPos.y()+axis(context, tstyle) ), + context.layoutUnitToPixelX( myPos.x()+getWidth() ), + context.layoutUnitToPixelY( myPos.y()+axis(context, tstyle) ) ); +#endif +} + + +void SymbolElement::dispatchFontCommand( FontCommand* cmd ) +{ + content->dispatchFontCommand( cmd ); + if ( hasUpper() ) { + upper->dispatchFontCommand( cmd ); + } + if ( hasLower() ) { + lower->dispatchFontCommand( cmd ); + } +} + +// navigation +// +// The elements are responsible to handle cursor movement themselves. +// To do this they need to know the direction the cursor moves and +// the element it comes from. +// +// The cursor might be in normal or in selection mode. + +/** + * Enters this element while moving to the left starting inside + * the element `from'. Searches for a cursor position inside + * this element or to the left of it. + */ +void SymbolElement::moveLeft(FormulaCursor* cursor, BasicElement* from) +{ + if (cursor->isSelectionMode()) { + getParent()->moveLeft(cursor, this); + } + else { + bool linear = cursor->getLinearMovement(); + if (from == getParent()) { + content->moveLeft(cursor, this); + } + else if (from == content) { + if (linear && hasLower()) { + lower->moveLeft(cursor, this); + } + else if (linear && hasUpper()) { + upper->moveLeft(cursor, this); + } + else { + getParent()->moveLeft(cursor, this); + } + } + else if (from == lower) { + if (linear && hasUpper()) { + upper->moveLeft(cursor, this); + } + else { + getParent()->moveLeft(cursor, this); + } + } + else if (from == upper) { + getParent()->moveLeft(cursor, this); + } + } +} + +/** + * Enters this element while moving to the right starting inside + * the element `from'. Searches for a cursor position inside + * this element or to the right of it. + */ +void SymbolElement::moveRight(FormulaCursor* cursor, BasicElement* from) +{ + if (cursor->isSelectionMode()) { + getParent()->moveRight(cursor, this); + } + else { + bool linear = cursor->getLinearMovement(); + if (from == getParent()) { + if (linear && hasUpper()) { + upper->moveRight(cursor, this); + } + else if (linear && hasLower()) { + lower->moveRight(cursor, this); + } + else { + content->moveRight(cursor, this); + } + } + else if (from == upper) { + if (linear && hasLower()) { + lower->moveRight(cursor, this); + } + else { + content->moveRight(cursor, this); + } + } + else if (from == lower) { + content->moveRight(cursor, this); + } + else if (from == content) { + getParent()->moveRight(cursor, this); + } + } +} + +/** + * Enters this element while moving up starting inside + * the element `from'. Searches for a cursor position inside + * this element or above it. + */ +void SymbolElement::moveUp(FormulaCursor* cursor, BasicElement* from) +{ + if (cursor->isSelectionMode()) { + getParent()->moveUp(cursor, this); + } + else { + if (from == content) { + if (hasUpper()) { + upper->moveLeft(cursor, this); + } + else { + getParent()->moveUp(cursor, this); + } + } + else if (from == upper) { + getParent()->moveUp(cursor, this); + } + else if ((from == getParent()) || (from == lower)) { + content->moveRight(cursor, this); + } + } +} + +/** + * Enters this element while moving down starting inside + * the element `from'. Searches for a cursor position inside + * this element or below it. + */ +void SymbolElement::moveDown(FormulaCursor* cursor, BasicElement* from) +{ + if (cursor->isSelectionMode()) { + getParent()->moveDown(cursor, this); + } + else { + if (from == content) { + if (hasLower()) { + lower->moveLeft(cursor, this); + } + else { + getParent()->moveDown(cursor, this); + } + } + else if (from == lower) { + getParent()->moveDown(cursor, this); + } + else if ((from == getParent()) || (from == upper)) { + content->moveRight(cursor, this); + } + } +} + +// children + +// main child +// +// If an element has children one has to become the main one. + +// void SymbolElement::setMainChild(SequenceElement* child) +// { +// formula()->elementRemoval(content); +// content = child; +// content->setParent(this); +// formula()->changed(); +// } + + +/** + * Inserts all new children at the cursor position. Places the + * cursor according to the direction. + * + * You only can insert one index at a time. So the list must contain + * exactly on SequenceElement. And the index you want to insert + * must not exist already. + * + * The list will be emptied but stays the property of the caller. + */ +void SymbolElement::insert(FormulaCursor* cursor, + TQPtrList& newChildren, + Direction direction) +{ + SequenceElement* index = static_cast(newChildren.take(0)); + index->setParent(this); + + switch (cursor->getPos()) { + case upperMiddlePos: + upper = index; + break; + case lowerMiddlePos: + lower = index; + break; + default: + // this is an error! + return; + } + + if (direction == beforeCursor) { + index->moveLeft(cursor, this); + } + else { + index->moveRight(cursor, this); + } + cursor->setSelection(false); + formula()->changed(); +} + +/** + * Removes all selected children and returns them. Places the + * cursor to where the children have been. + * + * The cursor has to be inside one of our indexes which is supposed + * to be empty. The index will be removed and the cursor will + * be placed to the removed index so it can be inserted again. + * This methode is called by SequenceElement::remove only. + * + * The ownership of the list is passed to the caller. + */ +void SymbolElement::remove(FormulaCursor* cursor, + TQPtrList& removedChildren, + Direction direction) +{ + int pos = cursor->getPos(); + switch (pos) { + case upperMiddlePos: + removedChildren.append(upper); + formula()->elementRemoval(upper); + upper = 0; + setToUpper(cursor); + break; + case lowerMiddlePos: + removedChildren.append(lower); + formula()->elementRemoval(lower); + lower = 0; + setToLower(cursor); + break; + case contentPos: { + BasicElement* parent = getParent(); + parent->selectChild(cursor, this); + parent->remove(cursor, removedChildren, direction); + break; + } + } + formula()->changed(); +} + +/** + * Moves the cursor to a normal place where new elements + * might be inserted. + */ +void SymbolElement::normalize(FormulaCursor* cursor, Direction direction) +{ + if (direction == beforeCursor) { + content->moveLeft(cursor, this); + } + else { + content->moveRight(cursor, this); + } +} + +/** + * Returns the child at the cursor. + */ +BasicElement* SymbolElement::getChild(FormulaCursor* cursor, Direction) +{ + int pos = cursor->getPos(); + switch (pos) { + case contentPos: + return content; + case upperMiddlePos: + return upper; + case lowerMiddlePos: + return lower; + } + return 0; +} + +/** + * Sets the cursor to select the child. The mark is placed before, + * the position behind it. + */ +void SymbolElement::selectChild(FormulaCursor* cursor, BasicElement* child) +{ + if (child == content) { + setToContent(cursor); + } + else if (child == upper) { + setToUpper(cursor); + } + else if (child == lower) { + setToLower(cursor); + } +} + +void SymbolElement::setToUpper(FormulaCursor* cursor) +{ + cursor->setTo(this, upperMiddlePos); +} + +void SymbolElement::setToLower(FormulaCursor* cursor) +{ + cursor->setTo(this, lowerMiddlePos); +} + +/** + * Sets the cursor to point to the place where the content is. + * There always is a content so this is not a useful place. + * No insertion or removal will succeed as long as the cursor is + * there. + */ +void SymbolElement::setToContent(FormulaCursor* cursor) +{ + cursor->setTo(this, contentPos); +} + + +void SymbolElement::moveToUpper(FormulaCursor* cursor, Direction direction) +{ + if (hasUpper()) { + if (direction == beforeCursor) { + upper->moveLeft(cursor, this); + } + else { + upper->moveRight(cursor, this); + } + } +} + +void SymbolElement::moveToLower(FormulaCursor* cursor, Direction direction) +{ + if (hasLower()) { + if (direction == beforeCursor) { + lower->moveLeft(cursor, this); + } + else { + lower->moveRight(cursor, this); + } + } +} + + +ElementIndexPtr SymbolElement::getIndex( int position ) +{ + switch ( position ) { + case lowerMiddlePos: + return getLowerIndex(); + case upperMiddlePos: + return getUpperIndex(); + } + return getUpperIndex(); +} + + +/** + * Appends our attributes to the dom element. + */ +void SymbolElement::writeDom(TQDomElement element) +{ + BasicElement::writeDom(element); + + element.setAttribute("TYPE", symbolType); + + TQDomDocument doc = element.ownerDocument(); + + TQDomElement con = doc.createElement("CONTENT"); + con.appendChild(content->getElementDom(doc)); + element.appendChild(con); + + if(hasLower()) { + TQDomElement ind = doc.createElement("LOWER"); + ind.appendChild(lower->getElementDom(doc)); + element.appendChild(ind); + } + if(hasUpper()) { + TQDomElement ind = doc.createElement("UPPER"); + ind.appendChild(upper->getElementDom(doc)); + element.appendChild(ind); + } +} + +/** + * Reads our attributes from the element. + * Returns false if it failed. + */ +bool SymbolElement::readAttributesFromDom(TQDomElement element) +{ + if (!BasicElement::readAttributesFromDom(element)) { + return false; + } + + TQString typeStr = element.attribute("TYPE"); + if(!typeStr.isNull()) { + symbolType = static_cast(typeStr.toInt()); + } + + return true; +} + +/** + * Reads our content from the node. Sets the node to the next node + * that needs to be read. + * Returns false if it failed. + */ +bool SymbolElement::readContentFromDom(TQDomNode& node) +{ + if (!BasicElement::readContentFromDom(node)) { + return false; + } + + if ( !buildChild( content, node, "CONTENT" ) ) { + kdWarning( DEBUGID ) << "Empty content in SymbolElement." << endl; + return false; + } + node = node.nextSibling(); + + bool lowerRead = false; + bool upperRead = false; + + while (!node.isNull() && !(upperRead && lowerRead)) { + + if (!lowerRead && (node.nodeName().upper() == "LOWER")) { + lowerRead = buildChild( lower=new SequenceElement( this ), node, "LOWER" ); + if ( !lowerRead ) return false; + } + + if (!upperRead && (node.nodeName().upper() == "UPPER")) { + upperRead = buildChild( upper=new SequenceElement( this ), node, "UPPER" ); + if ( !upperRead ) return false; + } + + node = node.nextSibling(); + } + return true; +} + +TQString SymbolElement::toLatex() +{ + TQString sym; + + switch(symbolType) { + + case 1001: + sym="\\int"; + break; + case 1002: + sym="\\sum"; + break; + case 1003: + sym="\\prod"; + break; + + default: + sym=" "; + + } + + + if(hasLower()) { + sym+="_{"; + sym+=lower->toLatex(); + sym+="}"; + } + + if(hasUpper()) { + sym+="^{"; + sym+=upper->toLatex(); + sym+="} "; + } + + sym += " "; + + sym+=content->toLatex(); + + + return sym; +} + +TQString SymbolElement::formulaString() +{ + TQString sym; + switch ( symbolType ) { + case 1001: + sym="int("; + break; + case 1002: + sym="sum("; + break; + case 1003: + sym="prod("; + break; + default: + sym="("; + } + sym += content->formulaString(); + if ( hasLower() ) { + sym += ", " + lower->formulaString(); + } + if ( hasUpper() ) { + sym += ", " + upper->formulaString(); + } + return sym + ")"; +} + +void SymbolElement::writeMathML( TQDomDocument& doc, TQDomNode& parent, bool oasisFormat ) const +{ + TQDomElement de = doc.createElement( oasisFormat ? "math:mrow" : "mrow" ); + TQDomElement mo = doc.createElement( oasisFormat ? "math:mo" : "mo" ); + + TQString value; + + switch( symbolType ) + { + case EmptyBracket: break; + case LeftLineBracket: case RightLineBracket: + mo.appendChild( doc.createTextNode( "|" ) ); break; + case Integral: + mo.appendChild( doc.createEntityReference( "int" ) ); break; + case Sum: + mo.appendChild( doc.createEntityReference( "sum" ) ); break; + case Product: + mo.appendChild( doc.createEntityReference( "prod" ) ); break; + default: + mo.appendChild( doc.createTextNode( TQChar( symbolType ) ) ); + } + + TQDomElement between; + if ( hasUpper() && hasLower() ) + { + between = doc.createElement( oasisFormat ? "math:msubsup" : "msubsup" ); + between.appendChild( mo ); + lower->writeMathML( doc, between, oasisFormat ); + upper->writeMathML( doc, between, oasisFormat ); + } + else if ( hasUpper() ) + { + between = doc.createElement( oasisFormat ? "math:msup" : "msup" ); + between.appendChild( mo ); + upper->writeMathML( doc, between, oasisFormat ); + } + else if ( hasLower() ) + { + between = doc.createElement( oasisFormat ? "math:msub" : "msub" ); + between.appendChild( mo ); + lower->writeMathML( doc, between, oasisFormat ); + } + else + between = mo; + + de.appendChild( between ); + content->writeMathML( doc, de, oasisFormat ); + + parent.appendChild( de ); +} + +KFORMULA_NAMESPACE_END diff --git a/lib/kformula/symbolfontmapping.cc b/lib/kformula/symbolfontmapping.cc deleted file mode 100644 index 71fbfcb0..00000000 --- a/lib/kformula/symbolfontmapping.cc +++ /dev/null @@ -1,171 +0,0 @@ -// -// Created: Thu May 29 14:40:54 2003 -// by: gensymbolfontmap.py -// from: symbol.xml -// -// WARNING! All changes made in this file will be lost! - - - -static InternFontTable symbolMap[] = { - { 0x2208, 0xce, RELATION, normalChar }, - { 0x2209, 0xcf, RELATION, normalChar }, - { 0x2202, 0xb6, ORDINARY, normalChar }, - { 0x2203, 0x24, ORDINARY, normalChar }, - { 0x2200, 0x22, ORDINARY, normalChar }, - { 0x2207, 0xd1, ORDINARY, normalChar }, - { 0x2205, 0xc6, BINOP, normalChar }, - { 0x220D, 0x27, RELATION, normalChar }, - { 0x007C, 0x7c, ORDINARY, normalChar }, - { 0x007B, 0x7b, ORDINARY, normalChar }, - { 0x007D, 0x7d, ORDINARY, normalChar }, - { 0x00B0, 0xb0, ORDINARY, normalChar }, - { 0x00B1, 0xb1, BINOP, normalChar }, - { 0x2033, 0xb2, ORDINARY, normalChar }, - { 0x2032, 0xa2, ORDINARY, normalChar }, - { 0x03BE, 0x78, ORDINARY, normalChar }, - { 0x03BD, 0x6e, ORDINARY, normalChar }, - { 0x03BC, 0x6d, ORDINARY, normalChar }, - { 0x03BB, 0x6c, ORDINARY, normalChar }, - { 0x03BA, 0x6b, ORDINARY, normalChar }, - { 0x2329, 0xe1, ORDINARY, normalChar }, - { 0x2321, 0xf5, ORDINARY, normalChar }, - { 0x2320, 0xf3, ORDINARY, normalChar }, - { 0x232A, 0xf1, ORDINARY, normalChar }, - { 0x03B9, 0x69, ORDINARY, normalChar }, - { 0x03B8, 0x71, ORDINARY, normalChar }, - { 0x03B7, 0x68, ORDINARY, normalChar }, - { 0x03B6, 0x7a, ORDINARY, normalChar }, - { 0x03B5, 0x65, ORDINARY, normalChar }, - { 0x03B4, 0x64, ORDINARY, normalChar }, - { 0x03B3, 0x67, ORDINARY, normalChar }, - { 0x03B2, 0x62, ORDINARY, normalChar }, - { 0x03B1, 0x61, ORDINARY, normalChar }, - { 0x00F7, 0xb8, BINOP, normalChar }, - { 0x039F, 0x4f, ORDINARY, normalChar }, - { 0x039D, 0x4e, ORDINARY, normalChar }, - { 0x039E, 0x58, ORDINARY, normalChar }, - { 0x039B, 0x4c, ORDINARY, normalChar }, - { 0x039C, 0x4d, ORDINARY, normalChar }, - { 0x039A, 0x4b, ORDINARY, normalChar }, - { 0x0192, 0xa6, ORDINARY, normalChar }, - { 0x0398, 0x51, ORDINARY, normalChar }, - { 0x0399, 0x49, ORDINARY, normalChar }, - { 0x0396, 0x5a, ORDINARY, normalChar }, - { 0x0397, 0x48, ORDINARY, normalChar }, - { 0x0394, 0x44, ORDINARY, normalChar }, - { 0x0395, 0x45, ORDINARY, normalChar }, - { 0x0392, 0x42, ORDINARY, normalChar }, - { 0x0393, 0x47, ORDINARY, normalChar }, - { 0x0391, 0x41, ORDINARY, normalChar }, - { 0x2283, 0xc9, RELATION, normalChar }, - { 0x2287, 0xca, RELATION, normalChar }, - { 0x2284, 0xcb, RELATION, normalChar }, - { 0x221A, 0xd6, ORDINARY, normalChar }, - { 0x221E, 0xa5, ORDINARY, normalChar }, - { 0x221D, 0xb5, RELATION, normalChar }, - { 0x220F, 0xd5, ORDINARY, normalChar }, - { 0x2211, 0xe5, ORDINARY, normalChar }, - { 0x21D1, 0xdd, RELATION, normalChar }, - { 0x21D0, 0xdc, RELATION, normalChar }, - { 0x21D3, 0xdf, RELATION, normalChar }, - { 0x03A6, 0x46, ORDINARY, normalChar }, - { 0x03A7, 0x43, ORDINARY, normalChar }, - { 0x03A4, 0x54, ORDINARY, normalChar }, - { 0x03A5, 0x55, ORDINARY, normalChar }, - { 0x03A3, 0x53, ORDINARY, normalChar }, - { 0x03A0, 0x50, ORDINARY, normalChar }, - { 0x03A1, 0x52, ORDINARY, normalChar }, - { 0x03A8, 0x59, ORDINARY, normalChar }, - { 0x03A9, 0x57, ORDINARY, normalChar }, - { 0x2135, 0xc0, ORDINARY, normalChar }, - { 0x22C5, 0xd7, BINOP, normalChar }, - { 0x03C3, 0x73, ORDINARY, normalChar }, - { 0x26C4, 0xe0, ORDINARY, normalChar }, - { 0xF8EF, 0xea, ORDINARY, normalChar }, - { 0xF8EE, 0xe9, ORDINARY, normalChar }, - { 0xF8ED, 0xe8, ORDINARY, normalChar }, - { 0xF8EC, 0xe7, ORDINARY, normalChar }, - { 0xF8EB, 0xe6, ORDINARY, normalChar }, - { 0xF8EA, 0xe4, ORDINARY, normalChar }, - { 0x2260, 0xb9, RELATION, normalChar }, - { 0x2261, 0xba, RELATION, normalChar }, - { 0x2264, 0xa3, RELATION, normalChar }, - { 0x2265, 0xb3, RELATION, normalChar }, - { 0x005B, 0x5b, ORDINARY, normalChar }, - { 0x005D, 0x5d, ORDINARY, normalChar }, - { 0xF8E9, 0xe3, ORDINARY, normalChar }, - { 0xF8E8, 0xe2, ORDINARY, normalChar }, - { 0xF8E7, 0xbe, ORDINARY, normalChar }, - { 0xF8E6, 0xbd, RELATION, normalChar }, - { 0xF8E5, 0x60, ORDINARY, normalChar }, - { 0x2282, 0xcc, RELATION, normalChar }, - { 0x2286, 0xcd, RELATION, normalChar }, - { 0x2295, 0xc5, BINOP, normalChar }, - { 0x2297, 0xc4, BINOP, normalChar }, - { 0x2192, 0xae, RELATION, normalChar }, - { 0x2193, 0xaf, RELATION, normalChar }, - { 0x2190, 0xac, RELATION, normalChar }, - { 0x2191, 0xad, RELATION, normalChar }, - { 0x2194, 0xab, RELATION, normalChar }, - { 0x2227, 0xd9, BINOP, normalChar }, - { 0x2220, 0xd0, ORDINARY, normalChar }, - { 0x2228, 0xda, BINOP, normalChar }, - { 0x2229, 0xc7, ORDINARY, normalChar }, - { 0x0028, 0x28, ORDINARY, normalChar }, - { 0x0029, 0x29, ORDINARY, normalChar }, - { 0x222A, 0xc8, ORDINARY, normalChar }, - { 0x222B, 0xf2, ORDINARY, normalChar }, - { 0x00AE, 0xd2, ORDINARY, normalChar }, - { 0x00D7, 0xb4, BINOP, normalChar }, - { 0x2122, 0xd4, ORDINARY, normalChar }, - { 0xF8F6, 0xf6, ORDINARY, normalChar }, - { 0xF8F7, 0xf7, ORDINARY, normalChar }, - { 0xF8F4, 0xef, ORDINARY, normalChar }, - { 0xF8F2, 0xed, ORDINARY, normalChar }, - { 0xF8F3, 0xee, ORDINARY, normalChar }, - { 0xF8F0, 0xeb, ORDINARY, normalChar }, - { 0xF8F1, 0xec, ORDINARY, normalChar }, - { 0xF8F8, 0xf8, ORDINARY, normalChar }, - { 0xF8F9, 0xf9, ORDINARY, normalChar }, - { 0xF8FD, 0xfd, ORDINARY, normalChar }, - { 0xF8FE, 0xfe, ORDINARY, normalChar }, - { 0xF8FB, 0xfb, ORDINARY, normalChar }, - { 0xF8FC, 0xfc, ORDINARY, normalChar }, - { 0xF8FA, 0xfa, ORDINARY, normalChar }, - { 0x03D1, 0x4a, ORDINARY, normalChar }, - { 0x03D2, 0xa1, ORDINARY, normalChar }, - { 0x03D5, 0x6a, ORDINARY, normalChar }, - { 0x03D6, 0x76, ORDINARY, normalChar }, - { 0x2666, 0xa8, ORDINARY, normalChar }, - { 0x00AC, 0xd8, ORDINARY, normalChar }, - { 0x211C, 0xc2, ORDINARY, normalChar }, - { 0x2111, 0xc1, ORDINARY, normalChar }, - { 0x2118, 0xc3, ORDINARY, normalChar }, - { 0x00A9, 0xd3, ORDINARY, normalChar }, - { 0x2665, 0xa9, ORDINARY, normalChar }, - { 0x2660, 0xaa, ORDINARY, normalChar }, - { 0x2663, 0xa7, ORDINARY, normalChar }, - { 0x21D4, 0xdb, RELATION, normalChar }, - { 0x2026, 0xbc, ORDINARY, normalChar }, - { 0x21D2, 0xde, RELATION, normalChar }, - { 0x2022, 0xb7, BINOP, normalChar }, - { 0x223C, 0x7e, RELATION, normalChar }, - { 0x22A5, 0x5e, ORDINARY, normalChar }, - { 0x2234, 0x5c, BINOP, normalChar }, - { 0x2244, 0xa4, ORDINARY, normalChar }, - { 0x2245, 0x40, RELATION, normalChar }, - { 0x2248, 0xbb, RELATION, normalChar }, - { 0x03C0, 0x70, ORDINARY, normalChar }, - { 0x03C1, 0x72, ORDINARY, normalChar }, - { 0x03C2, 0x56, ORDINARY, normalChar }, - { 0xF8F5, 0xf4, ORDINARY, normalChar }, - { 0x03C4, 0x74, ORDINARY, normalChar }, - { 0x03C5, 0x75, ORDINARY, normalChar }, - { 0x03C6, 0x66, ORDINARY, normalChar }, - { 0x03C7, 0x63, ORDINARY, normalChar }, - { 0x03C8, 0x79, ORDINARY, normalChar }, - { 0x03C9, 0x77, ORDINARY, normalChar }, - { 0x21B5, 0xbf, ORDINARY, normalChar }, - { 0, 0, ORDINARY, normalChar } -}; diff --git a/lib/kformula/symbolfontmapping.cpp b/lib/kformula/symbolfontmapping.cpp new file mode 100644 index 00000000..71fbfcb0 --- /dev/null +++ b/lib/kformula/symbolfontmapping.cpp @@ -0,0 +1,171 @@ +// +// Created: Thu May 29 14:40:54 2003 +// by: gensymbolfontmap.py +// from: symbol.xml +// +// WARNING! All changes made in this file will be lost! + + + +static InternFontTable symbolMap[] = { + { 0x2208, 0xce, RELATION, normalChar }, + { 0x2209, 0xcf, RELATION, normalChar }, + { 0x2202, 0xb6, ORDINARY, normalChar }, + { 0x2203, 0x24, ORDINARY, normalChar }, + { 0x2200, 0x22, ORDINARY, normalChar }, + { 0x2207, 0xd1, ORDINARY, normalChar }, + { 0x2205, 0xc6, BINOP, normalChar }, + { 0x220D, 0x27, RELATION, normalChar }, + { 0x007C, 0x7c, ORDINARY, normalChar }, + { 0x007B, 0x7b, ORDINARY, normalChar }, + { 0x007D, 0x7d, ORDINARY, normalChar }, + { 0x00B0, 0xb0, ORDINARY, normalChar }, + { 0x00B1, 0xb1, BINOP, normalChar }, + { 0x2033, 0xb2, ORDINARY, normalChar }, + { 0x2032, 0xa2, ORDINARY, normalChar }, + { 0x03BE, 0x78, ORDINARY, normalChar }, + { 0x03BD, 0x6e, ORDINARY, normalChar }, + { 0x03BC, 0x6d, ORDINARY, normalChar }, + { 0x03BB, 0x6c, ORDINARY, normalChar }, + { 0x03BA, 0x6b, ORDINARY, normalChar }, + { 0x2329, 0xe1, ORDINARY, normalChar }, + { 0x2321, 0xf5, ORDINARY, normalChar }, + { 0x2320, 0xf3, ORDINARY, normalChar }, + { 0x232A, 0xf1, ORDINARY, normalChar }, + { 0x03B9, 0x69, ORDINARY, normalChar }, + { 0x03B8, 0x71, ORDINARY, normalChar }, + { 0x03B7, 0x68, ORDINARY, normalChar }, + { 0x03B6, 0x7a, ORDINARY, normalChar }, + { 0x03B5, 0x65, ORDINARY, normalChar }, + { 0x03B4, 0x64, ORDINARY, normalChar }, + { 0x03B3, 0x67, ORDINARY, normalChar }, + { 0x03B2, 0x62, ORDINARY, normalChar }, + { 0x03B1, 0x61, ORDINARY, normalChar }, + { 0x00F7, 0xb8, BINOP, normalChar }, + { 0x039F, 0x4f, ORDINARY, normalChar }, + { 0x039D, 0x4e, ORDINARY, normalChar }, + { 0x039E, 0x58, ORDINARY, normalChar }, + { 0x039B, 0x4c, ORDINARY, normalChar }, + { 0x039C, 0x4d, ORDINARY, normalChar }, + { 0x039A, 0x4b, ORDINARY, normalChar }, + { 0x0192, 0xa6, ORDINARY, normalChar }, + { 0x0398, 0x51, ORDINARY, normalChar }, + { 0x0399, 0x49, ORDINARY, normalChar }, + { 0x0396, 0x5a, ORDINARY, normalChar }, + { 0x0397, 0x48, ORDINARY, normalChar }, + { 0x0394, 0x44, ORDINARY, normalChar }, + { 0x0395, 0x45, ORDINARY, normalChar }, + { 0x0392, 0x42, ORDINARY, normalChar }, + { 0x0393, 0x47, ORDINARY, normalChar }, + { 0x0391, 0x41, ORDINARY, normalChar }, + { 0x2283, 0xc9, RELATION, normalChar }, + { 0x2287, 0xca, RELATION, normalChar }, + { 0x2284, 0xcb, RELATION, normalChar }, + { 0x221A, 0xd6, ORDINARY, normalChar }, + { 0x221E, 0xa5, ORDINARY, normalChar }, + { 0x221D, 0xb5, RELATION, normalChar }, + { 0x220F, 0xd5, ORDINARY, normalChar }, + { 0x2211, 0xe5, ORDINARY, normalChar }, + { 0x21D1, 0xdd, RELATION, normalChar }, + { 0x21D0, 0xdc, RELATION, normalChar }, + { 0x21D3, 0xdf, RELATION, normalChar }, + { 0x03A6, 0x46, ORDINARY, normalChar }, + { 0x03A7, 0x43, ORDINARY, normalChar }, + { 0x03A4, 0x54, ORDINARY, normalChar }, + { 0x03A5, 0x55, ORDINARY, normalChar }, + { 0x03A3, 0x53, ORDINARY, normalChar }, + { 0x03A0, 0x50, ORDINARY, normalChar }, + { 0x03A1, 0x52, ORDINARY, normalChar }, + { 0x03A8, 0x59, ORDINARY, normalChar }, + { 0x03A9, 0x57, ORDINARY, normalChar }, + { 0x2135, 0xc0, ORDINARY, normalChar }, + { 0x22C5, 0xd7, BINOP, normalChar }, + { 0x03C3, 0x73, ORDINARY, normalChar }, + { 0x26C4, 0xe0, ORDINARY, normalChar }, + { 0xF8EF, 0xea, ORDINARY, normalChar }, + { 0xF8EE, 0xe9, ORDINARY, normalChar }, + { 0xF8ED, 0xe8, ORDINARY, normalChar }, + { 0xF8EC, 0xe7, ORDINARY, normalChar }, + { 0xF8EB, 0xe6, ORDINARY, normalChar }, + { 0xF8EA, 0xe4, ORDINARY, normalChar }, + { 0x2260, 0xb9, RELATION, normalChar }, + { 0x2261, 0xba, RELATION, normalChar }, + { 0x2264, 0xa3, RELATION, normalChar }, + { 0x2265, 0xb3, RELATION, normalChar }, + { 0x005B, 0x5b, ORDINARY, normalChar }, + { 0x005D, 0x5d, ORDINARY, normalChar }, + { 0xF8E9, 0xe3, ORDINARY, normalChar }, + { 0xF8E8, 0xe2, ORDINARY, normalChar }, + { 0xF8E7, 0xbe, ORDINARY, normalChar }, + { 0xF8E6, 0xbd, RELATION, normalChar }, + { 0xF8E5, 0x60, ORDINARY, normalChar }, + { 0x2282, 0xcc, RELATION, normalChar }, + { 0x2286, 0xcd, RELATION, normalChar }, + { 0x2295, 0xc5, BINOP, normalChar }, + { 0x2297, 0xc4, BINOP, normalChar }, + { 0x2192, 0xae, RELATION, normalChar }, + { 0x2193, 0xaf, RELATION, normalChar }, + { 0x2190, 0xac, RELATION, normalChar }, + { 0x2191, 0xad, RELATION, normalChar }, + { 0x2194, 0xab, RELATION, normalChar }, + { 0x2227, 0xd9, BINOP, normalChar }, + { 0x2220, 0xd0, ORDINARY, normalChar }, + { 0x2228, 0xda, BINOP, normalChar }, + { 0x2229, 0xc7, ORDINARY, normalChar }, + { 0x0028, 0x28, ORDINARY, normalChar }, + { 0x0029, 0x29, ORDINARY, normalChar }, + { 0x222A, 0xc8, ORDINARY, normalChar }, + { 0x222B, 0xf2, ORDINARY, normalChar }, + { 0x00AE, 0xd2, ORDINARY, normalChar }, + { 0x00D7, 0xb4, BINOP, normalChar }, + { 0x2122, 0xd4, ORDINARY, normalChar }, + { 0xF8F6, 0xf6, ORDINARY, normalChar }, + { 0xF8F7, 0xf7, ORDINARY, normalChar }, + { 0xF8F4, 0xef, ORDINARY, normalChar }, + { 0xF8F2, 0xed, ORDINARY, normalChar }, + { 0xF8F3, 0xee, ORDINARY, normalChar }, + { 0xF8F0, 0xeb, ORDINARY, normalChar }, + { 0xF8F1, 0xec, ORDINARY, normalChar }, + { 0xF8F8, 0xf8, ORDINARY, normalChar }, + { 0xF8F9, 0xf9, ORDINARY, normalChar }, + { 0xF8FD, 0xfd, ORDINARY, normalChar }, + { 0xF8FE, 0xfe, ORDINARY, normalChar }, + { 0xF8FB, 0xfb, ORDINARY, normalChar }, + { 0xF8FC, 0xfc, ORDINARY, normalChar }, + { 0xF8FA, 0xfa, ORDINARY, normalChar }, + { 0x03D1, 0x4a, ORDINARY, normalChar }, + { 0x03D2, 0xa1, ORDINARY, normalChar }, + { 0x03D5, 0x6a, ORDINARY, normalChar }, + { 0x03D6, 0x76, ORDINARY, normalChar }, + { 0x2666, 0xa8, ORDINARY, normalChar }, + { 0x00AC, 0xd8, ORDINARY, normalChar }, + { 0x211C, 0xc2, ORDINARY, normalChar }, + { 0x2111, 0xc1, ORDINARY, normalChar }, + { 0x2118, 0xc3, ORDINARY, normalChar }, + { 0x00A9, 0xd3, ORDINARY, normalChar }, + { 0x2665, 0xa9, ORDINARY, normalChar }, + { 0x2660, 0xaa, ORDINARY, normalChar }, + { 0x2663, 0xa7, ORDINARY, normalChar }, + { 0x21D4, 0xdb, RELATION, normalChar }, + { 0x2026, 0xbc, ORDINARY, normalChar }, + { 0x21D2, 0xde, RELATION, normalChar }, + { 0x2022, 0xb7, BINOP, normalChar }, + { 0x223C, 0x7e, RELATION, normalChar }, + { 0x22A5, 0x5e, ORDINARY, normalChar }, + { 0x2234, 0x5c, BINOP, normalChar }, + { 0x2244, 0xa4, ORDINARY, normalChar }, + { 0x2245, 0x40, RELATION, normalChar }, + { 0x2248, 0xbb, RELATION, normalChar }, + { 0x03C0, 0x70, ORDINARY, normalChar }, + { 0x03C1, 0x72, ORDINARY, normalChar }, + { 0x03C2, 0x56, ORDINARY, normalChar }, + { 0xF8F5, 0xf4, ORDINARY, normalChar }, + { 0x03C4, 0x74, ORDINARY, normalChar }, + { 0x03C5, 0x75, ORDINARY, normalChar }, + { 0x03C6, 0x66, ORDINARY, normalChar }, + { 0x03C7, 0x63, ORDINARY, normalChar }, + { 0x03C8, 0x79, ORDINARY, normalChar }, + { 0x03C9, 0x77, ORDINARY, normalChar }, + { 0x21B5, 0xbf, ORDINARY, normalChar }, + { 0, 0, ORDINARY, normalChar } +}; diff --git a/lib/kformula/symboltable.cc b/lib/kformula/symboltable.cc deleted file mode 100644 index aca50b3a..00000000 --- a/lib/kformula/symboltable.cc +++ /dev/null @@ -1,152 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2001 Andrea Rizzi - Ulrich Kuettler - Copyright (C) 2006 Alfredo Beaumont Sainz - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "symboltable.h" -#include "contextstyle.h" -#include "unicodetable.cc" - - -KFORMULA_NAMESPACE_BEGIN - -#include "symbolfontmapping.cc" - -SymbolFontHelper::SymbolFontHelper() - : greek("abgdezhqiklmnxpvrstufjcywGDTQLXPSUFYVW") -{ - for ( uint i = 0; symbolMap[ i ].unicode != 0; i++ ) { - compatibility[ symbolMap[ i ].pos ] = symbolMap[ i ].unicode; - } -} - -TQChar SymbolFontHelper::unicodeFromSymbolFont( TQChar pos ) const -{ - if ( compatibility.contains( pos ) ) { - return compatibility[ pos.latin1() ]; - } - return TQChar::null; -} - - -SymbolTable::SymbolTable() -{ -} - - -void SymbolTable::init( const TQFont& font ) -{ - backupFont = font; - for ( int i=0; operatorTable[i].unicode != 0; ++i ) { - names[TQChar( operatorTable[i].unicode )] = get_name( operatorTable[i] ); - entries[get_name( operatorTable[i] )] = TQChar( operatorTable[i].unicode ); - } - for ( int i=0; arrowTable[i].unicode != 0; ++i ) { - names[TQChar( arrowTable[i].unicode )] = get_name( arrowTable[i] ); - entries[get_name( arrowTable[i] )] = TQChar( arrowTable[i].unicode ); - } - for ( int i=0; greekTable[i].unicode != 0; ++i ) { - names[TQChar( greekTable[i].unicode )] = get_name( greekTable[i] ); - entries[get_name( greekTable[i] )] = TQChar( greekTable[i].unicode ); - } -} - -bool SymbolTable::contains(TQString name) const -{ - return entries.find( name ) != entries.end(); -} - -TQChar SymbolTable::unicode(TQString name) const -{ - return entries[ name ]; -} - - -TQString SymbolTable::name( TQChar symbol ) const -{ - return names[symbol]; -} - -TQFont SymbolTable::font( TQChar symbol, const TQFont& f ) const { - TQFontMetrics fm( f ); - if ( fm.inFont( symbol ) ) { - return f; - } - return TQFont("Arev Sans"); -} - -CharClass SymbolTable::charClass( TQChar symbol ) const -{ - return ORDINARY; - // FIXME -// return entry( symbol, style ).charClass(); -} - - -TQChar SymbolTable::unicodeFromSymbolFont( TQChar pos ) const -{ - return symbolFontHelper.unicodeFromSymbolFont( pos ); -} - - -TQString SymbolTable::greekLetters() const -{ - return symbolFontHelper.greekLetters(); -} - - -TQStringList SymbolTable::allNames() const -{ - TQStringList list; - - for ( int i=0; operatorTable[i].unicode != 0; ++i ) { - list.append( get_name( operatorTable[i] )); - } - for ( int i=0; arrowTable[i].unicode != 0; ++i ) { - list.append( get_name( arrowTable[i] )); - } - for ( int i=0; greekTable[i].unicode != 0; ++i ) { - list.append( get_name( greekTable[i] ) ); - } - return list; -} - - -TQString SymbolTable::get_name( struct UnicodeNameTable entry ) const -{ - if ( !*entry.name ) { - return "U" + TQString( "%1" ).arg( entry.unicode, 4, 16 ).upper(); - } - return entry.name; -} - -KFORMULA_NAMESPACE_END diff --git a/lib/kformula/symboltable.cpp b/lib/kformula/symboltable.cpp new file mode 100644 index 00000000..a25e1b15 --- /dev/null +++ b/lib/kformula/symboltable.cpp @@ -0,0 +1,152 @@ +/* This file is part of the KDE project + Copyright (C) 2001 Andrea Rizzi + Ulrich Kuettler + Copyright (C) 2006 Alfredo Beaumont Sainz + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "symboltable.h" +#include "contextstyle.h" +#include "unicodetable.cpp" + + +KFORMULA_NAMESPACE_BEGIN + +#include "symbolfontmapping.cpp" + +SymbolFontHelper::SymbolFontHelper() + : greek("abgdezhqiklmnxpvrstufjcywGDTQLXPSUFYVW") +{ + for ( uint i = 0; symbolMap[ i ].unicode != 0; i++ ) { + compatibility[ symbolMap[ i ].pos ] = symbolMap[ i ].unicode; + } +} + +TQChar SymbolFontHelper::unicodeFromSymbolFont( TQChar pos ) const +{ + if ( compatibility.contains( pos ) ) { + return compatibility[ pos.latin1() ]; + } + return TQChar::null; +} + + +SymbolTable::SymbolTable() +{ +} + + +void SymbolTable::init( const TQFont& font ) +{ + backupFont = font; + for ( int i=0; operatorTable[i].unicode != 0; ++i ) { + names[TQChar( operatorTable[i].unicode )] = get_name( operatorTable[i] ); + entries[get_name( operatorTable[i] )] = TQChar( operatorTable[i].unicode ); + } + for ( int i=0; arrowTable[i].unicode != 0; ++i ) { + names[TQChar( arrowTable[i].unicode )] = get_name( arrowTable[i] ); + entries[get_name( arrowTable[i] )] = TQChar( arrowTable[i].unicode ); + } + for ( int i=0; greekTable[i].unicode != 0; ++i ) { + names[TQChar( greekTable[i].unicode )] = get_name( greekTable[i] ); + entries[get_name( greekTable[i] )] = TQChar( greekTable[i].unicode ); + } +} + +bool SymbolTable::contains(TQString name) const +{ + return entries.find( name ) != entries.end(); +} + +TQChar SymbolTable::unicode(TQString name) const +{ + return entries[ name ]; +} + + +TQString SymbolTable::name( TQChar symbol ) const +{ + return names[symbol]; +} + +TQFont SymbolTable::font( TQChar symbol, const TQFont& f ) const { + TQFontMetrics fm( f ); + if ( fm.inFont( symbol ) ) { + return f; + } + return TQFont("Arev Sans"); +} + +CharClass SymbolTable::charClass( TQChar symbol ) const +{ + return ORDINARY; + // FIXME +// return entry( symbol, style ).charClass(); +} + + +TQChar SymbolTable::unicodeFromSymbolFont( TQChar pos ) const +{ + return symbolFontHelper.unicodeFromSymbolFont( pos ); +} + + +TQString SymbolTable::greekLetters() const +{ + return symbolFontHelper.greekLetters(); +} + + +TQStringList SymbolTable::allNames() const +{ + TQStringList list; + + for ( int i=0; operatorTable[i].unicode != 0; ++i ) { + list.append( get_name( operatorTable[i] )); + } + for ( int i=0; arrowTable[i].unicode != 0; ++i ) { + list.append( get_name( arrowTable[i] )); + } + for ( int i=0; greekTable[i].unicode != 0; ++i ) { + list.append( get_name( greekTable[i] ) ); + } + return list; +} + + +TQString SymbolTable::get_name( struct UnicodeNameTable entry ) const +{ + if ( !*entry.name ) { + return "U" + TQString( "%1" ).arg( entry.unicode, 4, 16 ).upper(); + } + return entry.name; +} + +KFORMULA_NAMESPACE_END diff --git a/lib/kformula/textelement.cc b/lib/kformula/textelement.cc deleted file mode 100644 index 7f146b49..00000000 --- a/lib/kformula/textelement.cc +++ /dev/null @@ -1,567 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2001 Andrea Rizzi - Ulrich Kuettler - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - -#include -#include - -#include - -#include "basicelement.h" -#include "contextstyle.h" -#include "elementtype.h" -#include "elementvisitor.h" -#include "fontstyle.h" -#include "formulaelement.h" -#include "kformulacommand.h" -#include "sequenceelement.h" -#include "symboltable.h" -#include "textelement.h" - - -KFORMULA_NAMESPACE_BEGIN - -TextElement::TextElement(TQChar ch, bool beSymbol, BasicElement* parent) - : BasicElement(parent), character(ch), symbol(beSymbol) -{ - charStyle( anyChar ); - charFamily( anyFamily ); -} - - -TextElement::TextElement( const TextElement& other ) - : BasicElement( other ), - character( other.character ), - symbol( other.symbol ), - m_format( other.m_format ) -{ -} - - -bool TextElement::accept( ElementVisitor* visitor ) -{ - return visitor->visit( this ); -} - - -TokenType TextElement::getTokenType() const -{ - if ( isSymbol() ) { - return getSymbolTable().charClass( character ); - } - - switch ( character.unicode() ) { - case '+': - case '-': - case '*': - //case '/': because it counts as text -- no extra spaces - return BINOP; - case '=': - case '<': - case '>': - return RELATION; - case ',': - case ';': - case ':': - return PUNCTUATION; - case '\\': - return SEPARATOR; - case '\0': - return ELEMENT; - default: - if ( character.isNumber() ) { - return NUMBER; - } - else { - return ORDINARY; - } - } -} - - -bool TextElement::isInvisible() const -{ - if (getElementType() != 0) { - return getElementType()->isInvisible(*this); - } - return false; -} - - -/** - * Calculates our width and height and - * our children's parentPosition. - */ -void TextElement::calcSizes( const ContextStyle& context, - ContextStyle::TextStyle tstyle, - ContextStyle::IndexStyle /*istyle*/, - StyleAttributes& style ) -{ - double factor = style.sizeFactor(); - luPt mySize = context.getAdjustedSize( tstyle, factor ); - - setCharStyle( style.charStyle() ); - setCharFamily( style.charFamily() ); - - TQFont font = getFont( context, style ); - double fontsize = context.layoutUnitPtToPt( mySize ); - double scriptsize = pow( style.scriptSizeMultiplier(), style.scriptLevel() ); - double size = fontsize * scriptsize; - font.setPointSizeFloat( size < style.scriptMinSize() ? style.scriptMinSize() : size ); - - TQFontMetrics fm( font ); - if ( character == applyFunctionChar || character == invisibleTimes || character == invisibleComma ) { - setWidth( 0 ); - setHeight( 0 ); - setBaseline( getHeight() ); - } - else { - TQChar ch = getRealCharacter(context); - if ( ch == TQChar::null ) { - setWidth( tqRound( context.getEmptyRectWidth( factor ) * 2./3. ) ); - setHeight( tqRound( context.getEmptyRectHeight( factor ) * 2./3. ) ); - setBaseline( getHeight() ); - } - else { - TQRect bound = fm.boundingRect( ch ); - setWidth( context.ptToLayoutUnitPt( fm.width( ch ) ) ); - setHeight( context.ptToLayoutUnitPt( bound.height() ) ); - setBaseline( context.ptToLayoutUnitPt( -bound.top() ) ); - - // There are some glyphs in TeX that have - // baseline==0. (\int, \sum, \prod) - if ( getBaseline() == 0 ) { - //setBaseline( getHeight()/2 + context.axisHeight( tstyle ) ); - setBaseline( -1 ); - } - } - } -} - -/** - * Draws the whole element including its children. - * The `parentOrigin' is the point this element's parent starts. - * We can use our parentPosition to get our own origin then. - */ -void TextElement::draw( TQPainter& painter, const LuPixelRect& /*r*/, - const ContextStyle& context, - ContextStyle::TextStyle tstyle, - ContextStyle::IndexStyle /*istyle*/, - StyleAttributes& style, - const LuPixelPoint& parentOrigin ) -{ - if ( character == applyFunctionChar || character == invisibleTimes || character == invisibleComma ) { - return; - } - - LuPixelPoint myPos( parentOrigin.x()+getX(), parentOrigin.y()+getY() ); - //if ( !LuPixelRect( myPos.x(), myPos.y(), getWidth(), getHeight() ).intersects( r ) ) - // return; - - // Let container set the color, instead of elementType - //setUpPainter( context, painter ); - painter.setPen( style.color() ); - - setCharStyle( style.charStyle() ); - setCharFamily( style.charFamily() ); - - double factor = style.sizeFactor(); - luPt mySize = context.getAdjustedSize( tstyle, factor ); - TQFont font = getFont( context, style ); - double fontsize = context.layoutUnitPtToPt( mySize ); - double scriptsize = pow( style.scriptSizeMultiplier(), style.scriptLevel() ); - double size = fontsize * scriptsize; - font.setPointSizeFloat( size < style.scriptMinSize() ? style.scriptMinSize() : size ); - painter.setFont( font ); - - //kdDebug( DEBUGID ) << "TextElement::draw font=" << font.rawName() << endl; - //kdDebug( DEBUGID ) << "TextElement::draw size=" << mySize << endl; - //kdDebug( DEBUGID ) << "TextElement::draw size=" << context.layoutUnitToFontSize( mySize, false ) << endl; - //kdDebug( DEBUGID ) << "TextElement::draw height: " << getHeight() << endl; - //kdDebug( DEBUGID ) << "TextElement::draw width: " << getWidth() << endl; - //kdDebug( DEBUGID ) << endl; - - // Each starting element draws the whole token - /* - ElementType* token = getElementType(); - if ( ( token != 0 ) && !symbol ) { - TQString text = token->text( static_cast( getParent() ) ); -// kdDebug() << "draw text: " << text[0].unicode() -// << " " << painter.font().family().latin1() -// << endl; - painter.fillRect( context.layoutUnitToPixelX( parentOrigin.x() ), - context.layoutUnitToPixelY( parentOrigin.y() ), - context.layoutUnitToPixelX( getParent()->getWidth() ), - context.layoutUnitToPixelY( getParent()->getHeight() ), - style.background() ); - painter.drawText( context.layoutUnitToPixelX( myPos.x() ), - context.layoutUnitToPixelY( myPos.y()+getBaseline() ), - text ); - } - else { - */ - TQChar ch = getRealCharacter(context); - if ( ch != TQChar::null ) { - luPixel bl = getBaseline(); - if ( bl == -1 ) { - // That's quite hacky and actually not the way it's - // meant to be. You shouldn't calculate a lot in - // draw. But I don't see how else to deal with - // baseline==0 glyphs without yet another flag. - bl = -( getHeight()/2 + context.axisHeight( tstyle, factor ) ); - } - painter.drawText( context.layoutUnitToPixelX( myPos.x() ), - context.layoutUnitToPixelY( myPos.y()+bl ), - TQString(ch) ); - } - else { - painter.setPen( TQPen( context.getErrorColor(), - context.layoutUnitToPixelX( context.getLineWidth( factor ) ) ) ); - painter.drawRect( context.layoutUnitToPixelX( myPos.x() ), - context.layoutUnitToPixelY( myPos.y() ), - context.layoutUnitToPixelX( getWidth() ), - context.layoutUnitToPixelY( getHeight() ) ); - } -// } - - // Debug - //painter.setBrush(TQt::NoBrush); -// if ( isSymbol() ) { -// painter.setPen( TQt::red ); -// painter.drawRect( context.layoutUnitToPixelX( myPos.x() ), -// context.layoutUnitToPixelX( myPos.y() ), -// context.layoutUnitToPixelX( getWidth() ), -// context.layoutUnitToPixelX( getHeight() ) ); -// painter.setPen(TQt::green); -// painter.drawLine(myPos.x(), myPos.y()+axis( context, tstyle ), -// myPos.x()+getWidth(), myPos.y()+axis( context, tstyle )); -// } -} - - -void TextElement::dispatchFontCommand( FontCommand* cmd ) -{ - cmd->addTextElement( this ); -} - -void TextElement::setCharStyle( CharStyle cs ) -{ - charStyle( cs ); - formula()->changed(); -} - -void TextElement::setCharFamily( CharFamily cf ) -{ - charFamily( cf ); - formula()->changed(); -} - -TQChar TextElement::getRealCharacter(const ContextStyle& context) -{ - return character; -/* - if ( !isSymbol() ) { - const FontStyle& fontStyle = context.fontStyle(); - const AlphaTable* alphaTable = fontStyle.alphaTable(); - if ( alphaTable != 0 ) { - AlphaTableEntry ate = alphaTable->entry( character, - charFamily(), - charStyle() ); - if ( ate.valid() ) { - return ate.pos; - } - } - return character; - } - else { - return getSymbolTable().character(character, charStyle()); - } -*/ -} - - -TQFont TextElement::getFont(const ContextStyle& context, const StyleAttributes& style) -{ - const FontStyle& fontStyle = context.fontStyle(); - TQFont font; - if ( style.customFont() ) { - font = style.font(); - } - else if (getElementType() != 0) { - font = getElementType()->getFont(context); - } - else { - font = context.getDefaultFont(); - } - switch ( charStyle() ) { - case anyChar: - font.setItalic( false ); - font.setBold( false ); - break; - case normalChar: - font.setItalic( false ); - font.setBold( false ); - break; - case boldChar: - font.setItalic( false ); - font.setBold( true ); - break; - case italicChar: - font.setItalic( true ); - font.setBold( false ); - break; - case boldItalicChar: - font.setItalic( true ); - font.setBold( true ); - break; - } - return fontStyle.symbolTable()->font( character, font ); -} - - -void TextElement::setUpPainter(const ContextStyle& context, TQPainter& painter) -{ - if (getElementType() != 0) { - getElementType()->setUpPainter(context, painter); - } - else { - painter.setPen(TQt::red); - } -} - -const SymbolTable& TextElement::getSymbolTable() const -{ - return formula()->getSymbolTable(); -} - - -void TextElement::writeMathML( TQDomDocument& doc, TQDomNode& parent, bool ) const -{ - parent.appendChild( doc.createTextNode( getCharacter() ) ); -} - -/** - * Appends our attributes to the dom element. - */ -void TextElement::writeDom(TQDomElement element) -{ - BasicElement::writeDom(element); - element.setAttribute("CHAR", TQString(character)); - //TQString s; - //element.setAttribute("CHAR", s.sprintf( "#x%05X", character ) ); - if (symbol) element.setAttribute("SYMBOL", "3"); - - switch ( charStyle() ) { - case anyChar: break; - case normalChar: element.setAttribute("STYLE", "normal"); break; - case boldChar: element.setAttribute("STYLE", "bold"); break; - case italicChar: element.setAttribute("STYLE", "italic"); break; - case boldItalicChar: element.setAttribute("STYLE", "bolditalic"); break; - } - - switch ( charFamily() ) { - case normalFamily: element.setAttribute("FAMILY", "normal"); break; - case scriptFamily: element.setAttribute("FAMILY", "script"); break; - case frakturFamily: element.setAttribute("FAMILY", "fraktur"); break; - case doubleStruckFamily: element.setAttribute("FAMILY", "doublestruck"); break; - case anyFamily: break; - } -} - -/** - * Reads our attributes from the element. - * Returns false if it failed. - */ -bool TextElement::readAttributesFromDom(TQDomElement element) -{ - if (!BasicElement::readAttributesFromDom(element)) { - return false; - } - TQString charStr = element.attribute("CHAR"); - if(!charStr.isNull()) { - character = charStr.at(0); - } - TQString symbolStr = element.attribute("SYMBOL"); - if(!symbolStr.isNull()) { - int symbolInt = symbolStr.toInt(); - if ( symbolInt == 1 ) { - character = getSymbolTable().unicodeFromSymbolFont(character); - } - if ( symbolInt == 2 ) { - switch ( character.unicode() ) { - case 0x03D5: character = 0x03C6; break; - case 0x03C6: character = 0x03D5; break; - case 0x03Ba: character = 0x03BA; break; - case 0x00B4: character = 0x2032; break; - case 0x2215: character = 0x2244; break; - case 0x00B7: character = 0x2022; break; - case 0x1D574: character = 0x2111; break; - case 0x1D579: character = 0x211C; break; - case 0x2219: character = 0x22C5; break; - case 0x2662: character = 0x26C4; break; - case 0x220B: character = 0x220D; break; - case 0x224C: character = 0x2245; break; - case 0x03DB: character = 0x03C2; break; - } - } - symbol = symbolInt != 0; - } - - TQString styleStr = element.attribute("STYLE"); - if ( styleStr == "normal" ) { - charStyle( normalChar ); - } - else if ( styleStr == "bold" ) { - charStyle( boldChar ); - } - else if ( styleStr == "italic" ) { - charStyle( italicChar ); - } - else if ( styleStr == "bolditalic" ) { - charStyle( boldItalicChar ); - } - else { - charStyle( anyChar ); - } - - TQString familyStr = element.attribute( "FAMILY" ); - if ( familyStr == "normal" ) { - charFamily( normalFamily ); - } - else if ( familyStr == "script" ) { - charFamily( scriptFamily ); - } - else if ( familyStr == "fraktur" ) { - charFamily( frakturFamily ); - } - else if ( familyStr == "doublestruck" ) { - charFamily( doubleStruckFamily ); - } - else { - charFamily( anyFamily ); - } - -// kdDebug() << "charStyle=" << charStyle() -// << " charFamily=" << charFamily() -// << " format=" << int( format() ) << endl; - - return true; -} - -/** - * Reads our content from the node. Sets the node to the next node - * that needs to be read. - * Returns false if it failed. - */ -bool TextElement::readContentFromDom(TQDomNode& node) -{ - return BasicElement::readContentFromDom(node); -} - -TQString TextElement::toLatex() -{ - if ( isSymbol() ) { - TQString texName = getSymbolTable().name( character ); - if ( !texName.isNull() ) - return " \\" + texName + " "; - return " ? "; - } - else { - return TQString(character); - } -} - -TQString TextElement::formulaString() -{ - if ( isSymbol() ) { - TQString texName = getSymbolTable().name( character ); - if ( !texName.isNull() ) - return " " + texName + " "; - return " ? "; - } - else { - return character; - } -} - - -EmptyElement::EmptyElement( BasicElement* parent ) - : BasicElement( parent ) -{ -} - -EmptyElement::EmptyElement( const EmptyElement& other ) - : BasicElement( other ) -{ -} - - -bool EmptyElement::accept( ElementVisitor* visitor ) -{ - return visitor->visit( this ); -} - - -void EmptyElement::calcSizes( const ContextStyle& context, - ContextStyle::TextStyle tstyle, - ContextStyle::IndexStyle /*istyle*/, - StyleAttributes& style ) -{ - luPt mySize = context.getAdjustedSize( tstyle, style.sizeFactor() ); - //kdDebug( DEBUGID ) << "TextElement::calcSizes size=" << mySize << endl; - - TQFont font = context.getDefaultFont(); - font.setPointSizeFloat( context.layoutUnitPtToPt( mySize ) ); - - TQFontMetrics fm( font ); - TQChar ch = 'A'; - TQRect bound = fm.boundingRect( ch ); - setWidth( 0 ); - setHeight( context.ptToLayoutUnitPt( bound.height() ) ); - setBaseline( context.ptToLayoutUnitPt( -bound.top() ) ); -} - -void EmptyElement::draw( TQPainter& painter, const LuPixelRect& /*r*/, - const ContextStyle& context, - ContextStyle::TextStyle /*tstyle*/, - ContextStyle::IndexStyle /*istyle*/, - StyleAttributes& /*style*/ , - const LuPixelPoint& parentOrigin ) -{ - LuPixelPoint myPos( parentOrigin.x()+getX(), parentOrigin.y()+getY() ); - /* - if ( !LuPixelRect( myPos.x(), myPos.y(), getWidth(), getHeight() ).intersects( r ) ) - return; - */ - - if ( context.edit() ) { - painter.setPen( context.getHelpColor() ); - painter.drawLine( context.layoutUnitToPixelX( myPos.x() ), - context.layoutUnitToPixelY( myPos.y() ), - context.layoutUnitToPixelX( myPos.x() ), - context.layoutUnitToPixelY( myPos.y()+getHeight() ) ); - } -} - -TQString EmptyElement::toLatex() -{ - return "{}"; -} - -KFORMULA_NAMESPACE_END diff --git a/lib/kformula/textelement.cpp b/lib/kformula/textelement.cpp new file mode 100644 index 00000000..7f146b49 --- /dev/null +++ b/lib/kformula/textelement.cpp @@ -0,0 +1,567 @@ +/* This file is part of the KDE project + Copyright (C) 2001 Andrea Rizzi + Ulrich Kuettler + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include + +#include + +#include "basicelement.h" +#include "contextstyle.h" +#include "elementtype.h" +#include "elementvisitor.h" +#include "fontstyle.h" +#include "formulaelement.h" +#include "kformulacommand.h" +#include "sequenceelement.h" +#include "symboltable.h" +#include "textelement.h" + + +KFORMULA_NAMESPACE_BEGIN + +TextElement::TextElement(TQChar ch, bool beSymbol, BasicElement* parent) + : BasicElement(parent), character(ch), symbol(beSymbol) +{ + charStyle( anyChar ); + charFamily( anyFamily ); +} + + +TextElement::TextElement( const TextElement& other ) + : BasicElement( other ), + character( other.character ), + symbol( other.symbol ), + m_format( other.m_format ) +{ +} + + +bool TextElement::accept( ElementVisitor* visitor ) +{ + return visitor->visit( this ); +} + + +TokenType TextElement::getTokenType() const +{ + if ( isSymbol() ) { + return getSymbolTable().charClass( character ); + } + + switch ( character.unicode() ) { + case '+': + case '-': + case '*': + //case '/': because it counts as text -- no extra spaces + return BINOP; + case '=': + case '<': + case '>': + return RELATION; + case ',': + case ';': + case ':': + return PUNCTUATION; + case '\\': + return SEPARATOR; + case '\0': + return ELEMENT; + default: + if ( character.isNumber() ) { + return NUMBER; + } + else { + return ORDINARY; + } + } +} + + +bool TextElement::isInvisible() const +{ + if (getElementType() != 0) { + return getElementType()->isInvisible(*this); + } + return false; +} + + +/** + * Calculates our width and height and + * our children's parentPosition. + */ +void TextElement::calcSizes( const ContextStyle& context, + ContextStyle::TextStyle tstyle, + ContextStyle::IndexStyle /*istyle*/, + StyleAttributes& style ) +{ + double factor = style.sizeFactor(); + luPt mySize = context.getAdjustedSize( tstyle, factor ); + + setCharStyle( style.charStyle() ); + setCharFamily( style.charFamily() ); + + TQFont font = getFont( context, style ); + double fontsize = context.layoutUnitPtToPt( mySize ); + double scriptsize = pow( style.scriptSizeMultiplier(), style.scriptLevel() ); + double size = fontsize * scriptsize; + font.setPointSizeFloat( size < style.scriptMinSize() ? style.scriptMinSize() : size ); + + TQFontMetrics fm( font ); + if ( character == applyFunctionChar || character == invisibleTimes || character == invisibleComma ) { + setWidth( 0 ); + setHeight( 0 ); + setBaseline( getHeight() ); + } + else { + TQChar ch = getRealCharacter(context); + if ( ch == TQChar::null ) { + setWidth( tqRound( context.getEmptyRectWidth( factor ) * 2./3. ) ); + setHeight( tqRound( context.getEmptyRectHeight( factor ) * 2./3. ) ); + setBaseline( getHeight() ); + } + else { + TQRect bound = fm.boundingRect( ch ); + setWidth( context.ptToLayoutUnitPt( fm.width( ch ) ) ); + setHeight( context.ptToLayoutUnitPt( bound.height() ) ); + setBaseline( context.ptToLayoutUnitPt( -bound.top() ) ); + + // There are some glyphs in TeX that have + // baseline==0. (\int, \sum, \prod) + if ( getBaseline() == 0 ) { + //setBaseline( getHeight()/2 + context.axisHeight( tstyle ) ); + setBaseline( -1 ); + } + } + } +} + +/** + * Draws the whole element including its children. + * The `parentOrigin' is the point this element's parent starts. + * We can use our parentPosition to get our own origin then. + */ +void TextElement::draw( TQPainter& painter, const LuPixelRect& /*r*/, + const ContextStyle& context, + ContextStyle::TextStyle tstyle, + ContextStyle::IndexStyle /*istyle*/, + StyleAttributes& style, + const LuPixelPoint& parentOrigin ) +{ + if ( character == applyFunctionChar || character == invisibleTimes || character == invisibleComma ) { + return; + } + + LuPixelPoint myPos( parentOrigin.x()+getX(), parentOrigin.y()+getY() ); + //if ( !LuPixelRect( myPos.x(), myPos.y(), getWidth(), getHeight() ).intersects( r ) ) + // return; + + // Let container set the color, instead of elementType + //setUpPainter( context, painter ); + painter.setPen( style.color() ); + + setCharStyle( style.charStyle() ); + setCharFamily( style.charFamily() ); + + double factor = style.sizeFactor(); + luPt mySize = context.getAdjustedSize( tstyle, factor ); + TQFont font = getFont( context, style ); + double fontsize = context.layoutUnitPtToPt( mySize ); + double scriptsize = pow( style.scriptSizeMultiplier(), style.scriptLevel() ); + double size = fontsize * scriptsize; + font.setPointSizeFloat( size < style.scriptMinSize() ? style.scriptMinSize() : size ); + painter.setFont( font ); + + //kdDebug( DEBUGID ) << "TextElement::draw font=" << font.rawName() << endl; + //kdDebug( DEBUGID ) << "TextElement::draw size=" << mySize << endl; + //kdDebug( DEBUGID ) << "TextElement::draw size=" << context.layoutUnitToFontSize( mySize, false ) << endl; + //kdDebug( DEBUGID ) << "TextElement::draw height: " << getHeight() << endl; + //kdDebug( DEBUGID ) << "TextElement::draw width: " << getWidth() << endl; + //kdDebug( DEBUGID ) << endl; + + // Each starting element draws the whole token + /* + ElementType* token = getElementType(); + if ( ( token != 0 ) && !symbol ) { + TQString text = token->text( static_cast( getParent() ) ); +// kdDebug() << "draw text: " << text[0].unicode() +// << " " << painter.font().family().latin1() +// << endl; + painter.fillRect( context.layoutUnitToPixelX( parentOrigin.x() ), + context.layoutUnitToPixelY( parentOrigin.y() ), + context.layoutUnitToPixelX( getParent()->getWidth() ), + context.layoutUnitToPixelY( getParent()->getHeight() ), + style.background() ); + painter.drawText( context.layoutUnitToPixelX( myPos.x() ), + context.layoutUnitToPixelY( myPos.y()+getBaseline() ), + text ); + } + else { + */ + TQChar ch = getRealCharacter(context); + if ( ch != TQChar::null ) { + luPixel bl = getBaseline(); + if ( bl == -1 ) { + // That's quite hacky and actually not the way it's + // meant to be. You shouldn't calculate a lot in + // draw. But I don't see how else to deal with + // baseline==0 glyphs without yet another flag. + bl = -( getHeight()/2 + context.axisHeight( tstyle, factor ) ); + } + painter.drawText( context.layoutUnitToPixelX( myPos.x() ), + context.layoutUnitToPixelY( myPos.y()+bl ), + TQString(ch) ); + } + else { + painter.setPen( TQPen( context.getErrorColor(), + context.layoutUnitToPixelX( context.getLineWidth( factor ) ) ) ); + painter.drawRect( context.layoutUnitToPixelX( myPos.x() ), + context.layoutUnitToPixelY( myPos.y() ), + context.layoutUnitToPixelX( getWidth() ), + context.layoutUnitToPixelY( getHeight() ) ); + } +// } + + // Debug + //painter.setBrush(TQt::NoBrush); +// if ( isSymbol() ) { +// painter.setPen( TQt::red ); +// painter.drawRect( context.layoutUnitToPixelX( myPos.x() ), +// context.layoutUnitToPixelX( myPos.y() ), +// context.layoutUnitToPixelX( getWidth() ), +// context.layoutUnitToPixelX( getHeight() ) ); +// painter.setPen(TQt::green); +// painter.drawLine(myPos.x(), myPos.y()+axis( context, tstyle ), +// myPos.x()+getWidth(), myPos.y()+axis( context, tstyle )); +// } +} + + +void TextElement::dispatchFontCommand( FontCommand* cmd ) +{ + cmd->addTextElement( this ); +} + +void TextElement::setCharStyle( CharStyle cs ) +{ + charStyle( cs ); + formula()->changed(); +} + +void TextElement::setCharFamily( CharFamily cf ) +{ + charFamily( cf ); + formula()->changed(); +} + +TQChar TextElement::getRealCharacter(const ContextStyle& context) +{ + return character; +/* + if ( !isSymbol() ) { + const FontStyle& fontStyle = context.fontStyle(); + const AlphaTable* alphaTable = fontStyle.alphaTable(); + if ( alphaTable != 0 ) { + AlphaTableEntry ate = alphaTable->entry( character, + charFamily(), + charStyle() ); + if ( ate.valid() ) { + return ate.pos; + } + } + return character; + } + else { + return getSymbolTable().character(character, charStyle()); + } +*/ +} + + +TQFont TextElement::getFont(const ContextStyle& context, const StyleAttributes& style) +{ + const FontStyle& fontStyle = context.fontStyle(); + TQFont font; + if ( style.customFont() ) { + font = style.font(); + } + else if (getElementType() != 0) { + font = getElementType()->getFont(context); + } + else { + font = context.getDefaultFont(); + } + switch ( charStyle() ) { + case anyChar: + font.setItalic( false ); + font.setBold( false ); + break; + case normalChar: + font.setItalic( false ); + font.setBold( false ); + break; + case boldChar: + font.setItalic( false ); + font.setBold( true ); + break; + case italicChar: + font.setItalic( true ); + font.setBold( false ); + break; + case boldItalicChar: + font.setItalic( true ); + font.setBold( true ); + break; + } + return fontStyle.symbolTable()->font( character, font ); +} + + +void TextElement::setUpPainter(const ContextStyle& context, TQPainter& painter) +{ + if (getElementType() != 0) { + getElementType()->setUpPainter(context, painter); + } + else { + painter.setPen(TQt::red); + } +} + +const SymbolTable& TextElement::getSymbolTable() const +{ + return formula()->getSymbolTable(); +} + + +void TextElement::writeMathML( TQDomDocument& doc, TQDomNode& parent, bool ) const +{ + parent.appendChild( doc.createTextNode( getCharacter() ) ); +} + +/** + * Appends our attributes to the dom element. + */ +void TextElement::writeDom(TQDomElement element) +{ + BasicElement::writeDom(element); + element.setAttribute("CHAR", TQString(character)); + //TQString s; + //element.setAttribute("CHAR", s.sprintf( "#x%05X", character ) ); + if (symbol) element.setAttribute("SYMBOL", "3"); + + switch ( charStyle() ) { + case anyChar: break; + case normalChar: element.setAttribute("STYLE", "normal"); break; + case boldChar: element.setAttribute("STYLE", "bold"); break; + case italicChar: element.setAttribute("STYLE", "italic"); break; + case boldItalicChar: element.setAttribute("STYLE", "bolditalic"); break; + } + + switch ( charFamily() ) { + case normalFamily: element.setAttribute("FAMILY", "normal"); break; + case scriptFamily: element.setAttribute("FAMILY", "script"); break; + case frakturFamily: element.setAttribute("FAMILY", "fraktur"); break; + case doubleStruckFamily: element.setAttribute("FAMILY", "doublestruck"); break; + case anyFamily: break; + } +} + +/** + * Reads our attributes from the element. + * Returns false if it failed. + */ +bool TextElement::readAttributesFromDom(TQDomElement element) +{ + if (!BasicElement::readAttributesFromDom(element)) { + return false; + } + TQString charStr = element.attribute("CHAR"); + if(!charStr.isNull()) { + character = charStr.at(0); + } + TQString symbolStr = element.attribute("SYMBOL"); + if(!symbolStr.isNull()) { + int symbolInt = symbolStr.toInt(); + if ( symbolInt == 1 ) { + character = getSymbolTable().unicodeFromSymbolFont(character); + } + if ( symbolInt == 2 ) { + switch ( character.unicode() ) { + case 0x03D5: character = 0x03C6; break; + case 0x03C6: character = 0x03D5; break; + case 0x03Ba: character = 0x03BA; break; + case 0x00B4: character = 0x2032; break; + case 0x2215: character = 0x2244; break; + case 0x00B7: character = 0x2022; break; + case 0x1D574: character = 0x2111; break; + case 0x1D579: character = 0x211C; break; + case 0x2219: character = 0x22C5; break; + case 0x2662: character = 0x26C4; break; + case 0x220B: character = 0x220D; break; + case 0x224C: character = 0x2245; break; + case 0x03DB: character = 0x03C2; break; + } + } + symbol = symbolInt != 0; + } + + TQString styleStr = element.attribute("STYLE"); + if ( styleStr == "normal" ) { + charStyle( normalChar ); + } + else if ( styleStr == "bold" ) { + charStyle( boldChar ); + } + else if ( styleStr == "italic" ) { + charStyle( italicChar ); + } + else if ( styleStr == "bolditalic" ) { + charStyle( boldItalicChar ); + } + else { + charStyle( anyChar ); + } + + TQString familyStr = element.attribute( "FAMILY" ); + if ( familyStr == "normal" ) { + charFamily( normalFamily ); + } + else if ( familyStr == "script" ) { + charFamily( scriptFamily ); + } + else if ( familyStr == "fraktur" ) { + charFamily( frakturFamily ); + } + else if ( familyStr == "doublestruck" ) { + charFamily( doubleStruckFamily ); + } + else { + charFamily( anyFamily ); + } + +// kdDebug() << "charStyle=" << charStyle() +// << " charFamily=" << charFamily() +// << " format=" << int( format() ) << endl; + + return true; +} + +/** + * Reads our content from the node. Sets the node to the next node + * that needs to be read. + * Returns false if it failed. + */ +bool TextElement::readContentFromDom(TQDomNode& node) +{ + return BasicElement::readContentFromDom(node); +} + +TQString TextElement::toLatex() +{ + if ( isSymbol() ) { + TQString texName = getSymbolTable().name( character ); + if ( !texName.isNull() ) + return " \\" + texName + " "; + return " ? "; + } + else { + return TQString(character); + } +} + +TQString TextElement::formulaString() +{ + if ( isSymbol() ) { + TQString texName = getSymbolTable().name( character ); + if ( !texName.isNull() ) + return " " + texName + " "; + return " ? "; + } + else { + return character; + } +} + + +EmptyElement::EmptyElement( BasicElement* parent ) + : BasicElement( parent ) +{ +} + +EmptyElement::EmptyElement( const EmptyElement& other ) + : BasicElement( other ) +{ +} + + +bool EmptyElement::accept( ElementVisitor* visitor ) +{ + return visitor->visit( this ); +} + + +void EmptyElement::calcSizes( const ContextStyle& context, + ContextStyle::TextStyle tstyle, + ContextStyle::IndexStyle /*istyle*/, + StyleAttributes& style ) +{ + luPt mySize = context.getAdjustedSize( tstyle, style.sizeFactor() ); + //kdDebug( DEBUGID ) << "TextElement::calcSizes size=" << mySize << endl; + + TQFont font = context.getDefaultFont(); + font.setPointSizeFloat( context.layoutUnitPtToPt( mySize ) ); + + TQFontMetrics fm( font ); + TQChar ch = 'A'; + TQRect bound = fm.boundingRect( ch ); + setWidth( 0 ); + setHeight( context.ptToLayoutUnitPt( bound.height() ) ); + setBaseline( context.ptToLayoutUnitPt( -bound.top() ) ); +} + +void EmptyElement::draw( TQPainter& painter, const LuPixelRect& /*r*/, + const ContextStyle& context, + ContextStyle::TextStyle /*tstyle*/, + ContextStyle::IndexStyle /*istyle*/, + StyleAttributes& /*style*/ , + const LuPixelPoint& parentOrigin ) +{ + LuPixelPoint myPos( parentOrigin.x()+getX(), parentOrigin.y()+getY() ); + /* + if ( !LuPixelRect( myPos.x(), myPos.y(), getWidth(), getHeight() ).intersects( r ) ) + return; + */ + + if ( context.edit() ) { + painter.setPen( context.getHelpColor() ); + painter.drawLine( context.layoutUnitToPixelX( myPos.x() ), + context.layoutUnitToPixelY( myPos.y() ), + context.layoutUnitToPixelX( myPos.x() ), + context.layoutUnitToPixelY( myPos.y()+getHeight() ) ); + } +} + +TQString EmptyElement::toLatex() +{ + return "{}"; +} + +KFORMULA_NAMESPACE_END diff --git a/lib/kformula/tokenelement.cc b/lib/kformula/tokenelement.cc deleted file mode 100644 index 9970ac45..00000000 --- a/lib/kformula/tokenelement.cc +++ /dev/null @@ -1,124 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2006 Alfredo Beaumont Sainz - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - -#include - -#include - -#include - -#include "entities.h" -#include "elementtype.h" -#include "sequenceelement.h" -#include "textelement.h" -#include "glyphelement.h" -#include "tokenelement.h" -#include "identifierelement.h" -#include "kformulacommand.h" -#include "kformulacontainer.h" -#include "kformuladocument.h" -#include "formulaelement.h" -#include "creationstrategy.h" - -KFORMULA_NAMESPACE_BEGIN - -TokenElement::TokenElement( BasicElement* parent ) : TokenStyleElement( parent ), - m_textOnly( true ) -{ -} - -int TokenElement::buildChildrenFromMathMLDom(TQPtrList& list, TQDomNode n) -{ - while ( ! n.isNull() ) { - if ( n.isText() ) { - TQString textelements = n.toText().data(); - textelements = textelements.stripWhiteSpace(); - - for (uint i = 0; i < textelements.length(); i++) { - TextElement* child = new TextElement(textelements[i]); - child->setParent(this); - child->setCharFamily( charFamily() ); - child->setCharStyle( charStyle() ); - list.append(child); - } - } - else if ( n.isEntityReference() ) { - TQString entity = n.toEntityReference().nodeName(); - const entityMap* begin = entities; - const entityMap* end = entities + entityMap::size(); - const entityMap* pos = std::lower_bound( begin, end, entity.ascii() ); - if ( pos == end || TQString( pos->name ) != entity ) { - kdWarning() << "Invalid entity refererence: " << entity << endl; - } - else { - TextElement* child = new TextElement( TQChar( pos->unicode ) ); - child->setParent(this); - child->setCharFamily( charFamily() ); - child->setCharStyle( charStyle() ); - list.append(child); - } - } - else if ( n.isElement() ) { - m_textOnly = false; - // Only mglyph element is allowed - TQDomElement e = n.toElement(); - if ( e.tagName().lower() != "mglyph" ) { - kdWarning( DEBUGID ) << "Invalid element inside Token Element\n"; - return -1; - } - GlyphElement* child = new GlyphElement(); - child->setParent(this); - child->setCharFamily( charFamily() ); - child->setCharStyle( charStyle() ); - if ( child->buildFromMathMLDom( e ) == -1 ) { - return -1; - } - list.append( child ); - } - else { - kdWarning() << "Invalid content in TokenElement\n"; - } - n = n.nextSibling(); - } -// parse(); - kdWarning() << "Num of children " << list.count() << endl; - return 1; -} - -luPt TokenElement::getSpaceBefore( const ContextStyle& context, - ContextStyle::TextStyle tstyle, - double factor ) -{ - if ( !context.isScript( tstyle ) ) { - return context.getMediumSpace( tstyle, factor ); - } - return 0; -} - -luPt TokenElement::getSpaceAfter( const ContextStyle& context, - ContextStyle::TextStyle tstyle, - double factor ) -{ - if ( !context.isScript( tstyle ) ) { - return context.getThinSpace( tstyle, factor ); - } - return 0; -} - -KFORMULA_NAMESPACE_END diff --git a/lib/kformula/tokenelement.cpp b/lib/kformula/tokenelement.cpp new file mode 100644 index 00000000..9970ac45 --- /dev/null +++ b/lib/kformula/tokenelement.cpp @@ -0,0 +1,124 @@ +/* This file is part of the KDE project + Copyright (C) 2006 Alfredo Beaumont Sainz + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include + +#include + +#include + +#include "entities.h" +#include "elementtype.h" +#include "sequenceelement.h" +#include "textelement.h" +#include "glyphelement.h" +#include "tokenelement.h" +#include "identifierelement.h" +#include "kformulacommand.h" +#include "kformulacontainer.h" +#include "kformuladocument.h" +#include "formulaelement.h" +#include "creationstrategy.h" + +KFORMULA_NAMESPACE_BEGIN + +TokenElement::TokenElement( BasicElement* parent ) : TokenStyleElement( parent ), + m_textOnly( true ) +{ +} + +int TokenElement::buildChildrenFromMathMLDom(TQPtrList& list, TQDomNode n) +{ + while ( ! n.isNull() ) { + if ( n.isText() ) { + TQString textelements = n.toText().data(); + textelements = textelements.stripWhiteSpace(); + + for (uint i = 0; i < textelements.length(); i++) { + TextElement* child = new TextElement(textelements[i]); + child->setParent(this); + child->setCharFamily( charFamily() ); + child->setCharStyle( charStyle() ); + list.append(child); + } + } + else if ( n.isEntityReference() ) { + TQString entity = n.toEntityReference().nodeName(); + const entityMap* begin = entities; + const entityMap* end = entities + entityMap::size(); + const entityMap* pos = std::lower_bound( begin, end, entity.ascii() ); + if ( pos == end || TQString( pos->name ) != entity ) { + kdWarning() << "Invalid entity refererence: " << entity << endl; + } + else { + TextElement* child = new TextElement( TQChar( pos->unicode ) ); + child->setParent(this); + child->setCharFamily( charFamily() ); + child->setCharStyle( charStyle() ); + list.append(child); + } + } + else if ( n.isElement() ) { + m_textOnly = false; + // Only mglyph element is allowed + TQDomElement e = n.toElement(); + if ( e.tagName().lower() != "mglyph" ) { + kdWarning( DEBUGID ) << "Invalid element inside Token Element\n"; + return -1; + } + GlyphElement* child = new GlyphElement(); + child->setParent(this); + child->setCharFamily( charFamily() ); + child->setCharStyle( charStyle() ); + if ( child->buildFromMathMLDom( e ) == -1 ) { + return -1; + } + list.append( child ); + } + else { + kdWarning() << "Invalid content in TokenElement\n"; + } + n = n.nextSibling(); + } +// parse(); + kdWarning() << "Num of children " << list.count() << endl; + return 1; +} + +luPt TokenElement::getSpaceBefore( const ContextStyle& context, + ContextStyle::TextStyle tstyle, + double factor ) +{ + if ( !context.isScript( tstyle ) ) { + return context.getMediumSpace( tstyle, factor ); + } + return 0; +} + +luPt TokenElement::getSpaceAfter( const ContextStyle& context, + ContextStyle::TextStyle tstyle, + double factor ) +{ + if ( !context.isScript( tstyle ) ) { + return context.getThinSpace( tstyle, factor ); + } + return 0; +} + +KFORMULA_NAMESPACE_END diff --git a/lib/kformula/tokenstyleelement.cc b/lib/kformula/tokenstyleelement.cc deleted file mode 100644 index fcce16e7..00000000 --- a/lib/kformula/tokenstyleelement.cc +++ /dev/null @@ -1,624 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2006 Alfredo Beaumont Sainz - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - -#include - -#include "basicelement.h" -#include "tokenstyleelement.h" - -KFORMULA_NAMESPACE_BEGIN - -TokenStyleElement::TokenStyleElement( BasicElement* parent ) : SequenceElement( parent ), - m_mathSizeType ( NoSize ), - m_charStyle( anyChar ), - m_charFamily( anyFamily ), - m_mathColor( "#000000" ), - m_mathBackground( "#FFFFFF" ), - m_fontSizeType( NoSize ), - m_customMathVariant( false ), - m_customMathColor( false ), - m_customMathBackground( false ), - m_customFontWeight( false ), - m_customFontStyle( false ), - m_customFontFamily( false ), - m_customColor( false ) -{ -} - -void TokenStyleElement::calcSizes( const ContextStyle& context, - ContextStyle::TextStyle tstyle, - ContextStyle::IndexStyle istyle, - StyleAttributes& style ) -{ - setStyleSize( context, style ); - setStyleVariant( style ); - setStyleColor( style ); - setStyleBackground( style ); - inherited::calcSizes( context, tstyle, istyle, style ); - resetStyle( style ); -} - -void TokenStyleElement::draw( TQPainter& painter, const LuPixelRect& r, - const ContextStyle& context, - ContextStyle::TextStyle tstyle, - ContextStyle::IndexStyle istyle, - StyleAttributes& style, - const LuPixelPoint& parentOrigin ) -{ - setStyleSize( context, style ); - setStyleVariant( style ); - setStyleColor( style ); - setStyleBackground( style ); - if ( style.background() != TQt::color0 ) { - painter.fillRect( context.layoutUnitToPixelX( parentOrigin.x() + getX() ), - context.layoutUnitToPixelY( parentOrigin.y() + getY() ), - context.layoutUnitToPixelX( getWidth() ), - context.layoutUnitToPixelY( getHeight() ), - style.background() ); - } - inherited::draw( painter, r, context, tstyle, istyle, style, parentOrigin ); - resetStyle( style ); -} - -bool TokenStyleElement::readAttributesFromMathMLDom( const TQDomElement& element ) -{ - if ( !BasicElement::readAttributesFromMathMLDom( element ) ) { - return false; - } - - // MathML Section 3.2.2 - TQString variantStr = element.attribute( "mathvariant" ); - if ( !variantStr.isNull() ) { - if ( variantStr == "normal" ) { - setCharStyle( normalChar ); - setCharFamily( normalFamily ); - } - else if ( variantStr == "bold" ) { - setCharStyle( boldChar ); - setCharFamily( normalFamily ); - } - else if ( variantStr == "italic" ) { - setCharStyle( italicChar ); - setCharFamily( normalFamily ); - } - else if ( variantStr == "bold-italic" ) { - setCharStyle( boldItalicChar ); - setCharFamily( normalFamily ); - } - else if ( variantStr == "double-struck" ) { - setCharStyle( normalChar ); - setCharFamily( doubleStruckFamily ); - } - else if ( variantStr == "bold-fraktur" ) { - setCharStyle( boldChar ); - setCharFamily( frakturFamily ); - } - else if ( variantStr == "script" ) { - setCharStyle( normalChar ); - setCharFamily( scriptFamily ); - } - else if ( variantStr == "bold-script" ) { - setCharStyle( boldChar ); - setCharFamily( scriptFamily ); - } - else if ( variantStr == "fraktur" ) { - setCharStyle( boldChar ); - setCharFamily( frakturFamily ); - } - else if ( variantStr == "sans-serif" ) { - setCharStyle( normalChar ); - setCharFamily( sansSerifFamily ); - } - else if ( variantStr == "bold-sans-serif" ) { - setCharStyle( boldChar ); - setCharFamily( sansSerifFamily ); - } - else if ( variantStr == "sans-serif-italic" ) { - setCharStyle( italicChar ); - setCharFamily( sansSerifFamily ); - } - else if ( variantStr == "sans-serif-bold-italic" ) { - setCharStyle( boldItalicChar ); - setCharFamily( sansSerifFamily ); - } - else if ( variantStr == "monospace" ) { - setCharStyle( normalChar ); - setCharFamily( monospaceFamily ); - } - } - - TQString sizeStr = element.attribute( "mathsize" ); - if ( !sizeStr.isNull() ) { - if ( sizeStr == "small" ) { - setRelativeSize( 0.8 ); // ### Arbitrary size - } - else if ( sizeStr == "normal" ) { - setRelativeSize( 1.0 ); - } - else if ( sizeStr == "big" ) { - setRelativeSize( 1.2 ); // ### Arbitrary size - } - else { - double s = getSize( sizeStr, &m_mathSizeType ); - switch ( m_mathSizeType ) { - case AbsoluteSize: - setAbsoluteSize( s ); - break; - case RelativeSize: - setRelativeSize( s ); - break; - case PixelSize: - setPixelSize( s ); - break; - default: - break; - } - } - } - - TQString colorStr = element.attribute( "mathcolor" ); - if ( !colorStr.isNull() ) { - if ( colorStr[0] != '#' ) { - setMathColor( TQColor( getHtmlColor( colorStr ) ) ); - } - else { - setMathColor( TQColor( colorStr ) ); - } - } - TQString backgroundStr = element.attribute( "mathbackground" ); - if ( !backgroundStr.isNull() ) { - if ( backgroundStr[0] != '#' ) { - setMathBackground( TQColor( getHtmlColor( backgroundStr ) ) ); - } - else { - setMathBackground( TQColor( backgroundStr ) ); - } - } - - // Deprecated attributes. See Section 3.2.2.1 - - sizeStr = element.attribute( "fontsize" ); - if ( ! sizeStr.isNull() ) { - if ( sizeStr == "small" ) { - setRelativeSize( 0.8, true ); // ### Arbitrary size - } - else if ( sizeStr == "normal" ) { - setRelativeSize( 1.0, true ); - } - else if ( sizeStr == "big" ) { - setRelativeSize( 1.2, true ); // ### Arbitrary size - } - else { - double s = getSize( sizeStr, &m_fontSizeType ); - switch ( m_fontSizeType ) { - case AbsoluteSize: - setAbsoluteSize( s, true ); - break; - case RelativeSize: - setRelativeSize( s, true ); - break; - case PixelSize: - setPixelSize( s, true ); - break; - default: - break; - } - } - } - - TQString styleStr = element.attribute( "fontstyle" ); - if ( ! styleStr.isNull() ) { - if ( styleStr.lower() == "italic" ) { - setFontStyle( true ); - } - else { - setFontStyle( false ); - } - } - - TQString weightStr = element.attribute( "fontweight" ); - if ( ! weightStr.isNull() ) { - if ( weightStr.lower() == "bold" ) { - setFontWeight( true ); - } - else { - setFontWeight( false ); - } - } - - TQString familyStr = element.attribute( "fontfamily" ); - if ( ! familyStr.isNull() ) { - setFontFamily( familyStr ); - } - - colorStr = element.attribute( "color" ); - if ( ! colorStr.isNull() ) { - if ( colorStr[0] != '#' ) { - setColor( TQColor( getHtmlColor( colorStr ) ) ); - } - else { - setColor( TQColor( colorStr ) ); - } - } - - return true; -} - -void TokenStyleElement::writeMathMLAttributes( TQDomElement& element ) const -{ - // mathvariant attribute - if ( customMathVariant() ) { - if ( charFamily() == normalFamily ) { - if ( charStyle() == normalChar ) { - element.setAttribute( "mathvariant", "normal" ); - } - else if ( charStyle() == boldChar ) { - element.setAttribute( "mathvariant", "bold" ); - } - else if ( charStyle() == italicChar ) { - element.setAttribute( "mathvariant", "italic" ); - } - else if ( charStyle() == boldItalicChar ) { - element.setAttribute( "mathvariant", "bold-italic" ); - } - else { // anyChar or unknown, it's always an error - kdWarning( DEBUGID ) << "Mathvariant: unknown style for normal family\n"; - } - } - else if ( charFamily() == doubleStruckFamily ) { - if ( charStyle() == normalChar ) { - element.setAttribute( "mathvariant", "double-struck" ); - } - else { // Shouldn't happen, it's a bug - kdWarning( DEBUGID ) << "Mathvariant: unknown style for double-struck family\n"; - } - } - else if ( charFamily() == frakturFamily ) { - if ( charStyle() == normalChar ) { - element.setAttribute( "mathvariant", "fraktur" ); - } - else if ( charStyle() == boldChar ) { - element.setAttribute( "mathvariant", "bold-fraktur" ); - } - else { - kdWarning( DEBUGID ) << "Mathvariant: unknown style for fraktur family\n"; - } - } - else if ( charFamily() == scriptFamily ) { - if ( charStyle() == normalChar ) { - element.setAttribute( "mathvariant", "script" ); - } - else if ( charStyle() == boldChar ) { - element.setAttribute( "mathvariant", "bold-script" ); - } - else { // Shouldn't happen, it's a bug - kdWarning( DEBUGID ) << "Mathvariant: unknown style for script family\n"; - } - } - else if ( charFamily() == sansSerifFamily ) { - if ( charStyle() == normalChar ) { - element.setAttribute( "mathvariant", "sans-serif" ); - } - else if ( charStyle() == boldChar ) { - element.setAttribute( "mathvariant", "bold-sans-serif" ); - } - else if ( charStyle() == italicChar ) { - element.setAttribute( "mathvariant", "sans-serif-italic" ); - } - else if ( charStyle() == boldItalicChar ) { - element.setAttribute( "mathvariant", "sans-serif-bold-italic" ); - } - else { - kdWarning( DEBUGID ) << "Mathvariant: unknown style for sans serif family\n"; - } - } - else if ( charFamily() == monospaceFamily ) { - if ( charStyle() == normalChar ) { - element.setAttribute( "mathvariant", "monospace" ); - } - else { - kdWarning( DEBUGID ) << "Mathvariant: unknown style for monospace family\n"; - } - } - else { - kdWarning( DEBUGID ) << "Mathvariant: unknown family\n"; - } - } - - // mathsize attribute - switch ( m_mathSizeType ) { - case AbsoluteSize: - element.setAttribute( "mathsize", TQString( "%1pt" ).arg( m_mathSize ) ); - break; - case RelativeSize: - element.setAttribute( "mathsize", TQString( "%1%" ).arg( m_mathSize * 100.0 ) ); - break; - case PixelSize: - element.setAttribute( "mathsize", TQString( "%1px" ).arg( m_mathSize ) ); - break; - default: - break; - } - - // mathcolor attribute - if ( customMathColor() ) { - element.setAttribute( "mathcolor", mathColor().name() ); - } - - // mathbackground attribute - if ( customMathBackground() ) { - element.setAttribute( "mathbackground", mathBackground().name() ); - } - - // Deprecated MathML 1.01 Attributes - // fontsize attribute - switch ( m_fontSizeType ) { - case AbsoluteSize: - element.setAttribute( "fontsize", TQString( "%1pt" ).arg( m_fontSize ) ); - break; - case RelativeSize: - element.setAttribute( "fontsize", TQString( "%1%" ).arg( m_fontSize * 100.0 ) ); - break; - case PixelSize: - element.setAttribute( "fontsize", TQString( "%3px" ).arg( m_fontSize ) ); - break; - default: - break; - } - - // fontweight attribute - if ( customFontWeight() ) { - element.setAttribute( "fontweight", fontWeight() ? "bold" : "normal" ); - } - - // fontstyle attribute - if ( customFontStyle() ) { - element.setAttribute( "fontstyle", fontStyle() ? "italic" : "normal" ); - } - - // fontfamily attribute - if ( customFontFamily() ) { - element.setAttribute( "fontfamily", fontFamily() ); - } - - // color attribute - if ( customColor() ) { - element.setAttribute( "color", color().name() ); - } -} - -void TokenStyleElement::setAbsoluteSize( double s, bool fontsize ) -{ - kdDebug( DEBUGID) << "Setting absolute size: " << s << endl; - if ( fontsize ) { - m_fontSizeType = AbsoluteSize; - m_fontSize = s; - } - else { - m_mathSizeType = AbsoluteSize; - m_mathSize = s; - } -} - -void TokenStyleElement::setRelativeSize( double f, bool fontsize ) -{ - kdDebug( DEBUGID) << "Setting relative size: " << f << endl; - if ( fontsize ) { - m_fontSizeType = RelativeSize; - m_fontSize = f; - } - else { - m_mathSizeType = RelativeSize; - m_mathSize = f; - } -} - -void TokenStyleElement::setPixelSize( double px, bool fontsize ) -{ - kdDebug( DEBUGID) << "Setting pixel size: " << px << endl; - if ( fontsize ) { - m_fontSizeType = PixelSize; - m_fontSize = px; - } - else { - m_mathSizeType = PixelSize; - m_mathSize = px; - } -} - -void TokenStyleElement::setStyleSize( const ContextStyle& context, StyleAttributes& style ) -{ - style.setSizeFactor( sizeFactor( context, style.sizeFactor() ) ); -} - -void TokenStyleElement::setStyleVariant( StyleAttributes& style ) -{ - if ( customMathVariant() || style.customMathVariant() ) { - style.setCustomMathVariant ( true ); - style.setCustomFontWeight( false ); - style.setCustomFontStyle( false ); - style.setCustomFont( false ); - if ( customMathVariant() ) { - style.setCharFamily ( charFamily() ); - style.setCharStyle( charStyle() ); - } - else { - style.setCharFamily( style.charFamily() ); - style.setCharStyle( style.charStyle() ); - } - } - else { - style.setCustomMathVariant( false ); - if ( customFontFamily() ) { - style.setCustomFont( true ); - style.setFont( TQFont(fontFamily()) ); - } - - bool fontweight = false; - if ( customFontWeight() || style.customFontWeight() ) { - style.setCustomFontWeight( true ); - if ( customFontWeight() ) { - fontweight = fontWeight(); - } - else { - fontweight = style.fontWeight(); - } - style.setFontWeight( fontweight ); - } - else { - style.setCustomFontWeight( false ); - } - - bool fontstyle = false; - if ( style.customFontStyle() ) { - style.setCustomFontStyle( true ); - fontstyle = style.fontStyle(); - style.setFontStyle( fontstyle ); - } - else { - style.setCustomFontStyle( false ); - } - if ( customFontStyle() ) { - fontstyle = fontStyle(); - } - - if ( fontweight && fontstyle ) { - style.setCharStyle( boldItalicChar ); - } - else if ( fontweight && ! fontstyle ) { - style.setCharStyle( boldChar ); - } - else if ( ! fontweight && fontstyle ) { - style.setCharStyle( italicChar ); - } - else { - style.setCharStyle( normalChar ); - } - } -} - -void TokenStyleElement::setStyleColor( StyleAttributes& style ) -{ - if ( customMathColor() ) { - style.setColor( mathColor() ); - } - else if ( customColor() ) { - style.setColor( color() ); - } - else { - style.setColor( style.color() ); - } -} - -void TokenStyleElement::setStyleBackground( StyleAttributes& style ) -{ - if ( customMathBackground() ) { - style.setBackground( mathBackground() ); - } - else { - style.setBackground( style.background() ); - } -} - -void TokenStyleElement::resetStyle( StyleAttributes& style ) -{ - style.resetSize(); - style.resetCharStyle(); - style.resetCharFamily(); - style.resetColor(); - style.resetBackground(); - style.resetFontFamily(); - style.resetFontWeight(); - style.resetFontStyle(); -} - -double TokenStyleElement::sizeFactor( const ContextStyle& context, double factor ) -{ - double basesize = context.layoutUnitPtToPt( context.getBaseSize() ); - switch ( m_mathSizeType ) { - case AbsoluteSize: - return m_mathSize / basesize; - case RelativeSize: - return m_mathSize; - case PixelSize: - // 3.2.2 says v-unit instead of h-unit, that's why we use Y and not X - return context.pixelYToPt( m_mathSize ) / basesize; - case NoSize: - switch ( m_fontSizeType ) { - case AbsoluteSize: - return m_fontSize / basesize; - case RelativeSize: - return m_fontSize; - case PixelSize: - return context.pixelYToPt( m_fontSize ) / basesize; - default: - return factor; - } - default: - break; - } - kdWarning( DEBUGID ) << k_funcinfo << " Unknown SizeType\n"; - return factor; -} - -/** - * Return RGB string from HTML Colors. See HTML Spec, section 6.5 - */ -TQString TokenStyleElement::getHtmlColor( const TQString& colorStr ){ - - TQString colorname = colorStr.lower(); - - if ( colorname == "black" ) - return "#000000"; - if ( colorname == "silver" ) - return "#C0C0C0"; - if ( colorname == "gray" ) - return "#808080"; - if ( colorname == "white" ) - return "#FFFFFF"; - if ( colorname == "maroon" ) - return "#800000"; - if ( colorname == "red" ) - return "#FF0000"; - if ( colorname == "purple" ) - return "#800080"; - if ( colorname == "fuchsia" ) - return "#FF00FF"; - if ( colorname == "green" ) - return "#008000"; - if ( colorname == "lime" ) - return "#00FF00"; - if ( colorname == "olive" ) - return "#808000"; - if ( colorname == "yellow" ) - return "#FFFF00"; - if ( colorname == "navy" ) - return "#000080"; - if ( colorname == "blue") - return "#0000FF"; - if ( colorname == "teal" ) - return "#008080"; - if ( colorname == "aqua" ) - return "#00FFFF"; - kdWarning( DEBUGID ) << "Invalid HTML color: " << colorname << endl; - return "#FFFFFF"; // ### Arbitrary selection of default color -} - - -KFORMULA_NAMESPACE_END diff --git a/lib/kformula/tokenstyleelement.cpp b/lib/kformula/tokenstyleelement.cpp new file mode 100644 index 00000000..fcce16e7 --- /dev/null +++ b/lib/kformula/tokenstyleelement.cpp @@ -0,0 +1,624 @@ +/* This file is part of the KDE project + Copyright (C) 2006 Alfredo Beaumont Sainz + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include + +#include "basicelement.h" +#include "tokenstyleelement.h" + +KFORMULA_NAMESPACE_BEGIN + +TokenStyleElement::TokenStyleElement( BasicElement* parent ) : SequenceElement( parent ), + m_mathSizeType ( NoSize ), + m_charStyle( anyChar ), + m_charFamily( anyFamily ), + m_mathColor( "#000000" ), + m_mathBackground( "#FFFFFF" ), + m_fontSizeType( NoSize ), + m_customMathVariant( false ), + m_customMathColor( false ), + m_customMathBackground( false ), + m_customFontWeight( false ), + m_customFontStyle( false ), + m_customFontFamily( false ), + m_customColor( false ) +{ +} + +void TokenStyleElement::calcSizes( const ContextStyle& context, + ContextStyle::TextStyle tstyle, + ContextStyle::IndexStyle istyle, + StyleAttributes& style ) +{ + setStyleSize( context, style ); + setStyleVariant( style ); + setStyleColor( style ); + setStyleBackground( style ); + inherited::calcSizes( context, tstyle, istyle, style ); + resetStyle( style ); +} + +void TokenStyleElement::draw( TQPainter& painter, const LuPixelRect& r, + const ContextStyle& context, + ContextStyle::TextStyle tstyle, + ContextStyle::IndexStyle istyle, + StyleAttributes& style, + const LuPixelPoint& parentOrigin ) +{ + setStyleSize( context, style ); + setStyleVariant( style ); + setStyleColor( style ); + setStyleBackground( style ); + if ( style.background() != TQt::color0 ) { + painter.fillRect( context.layoutUnitToPixelX( parentOrigin.x() + getX() ), + context.layoutUnitToPixelY( parentOrigin.y() + getY() ), + context.layoutUnitToPixelX( getWidth() ), + context.layoutUnitToPixelY( getHeight() ), + style.background() ); + } + inherited::draw( painter, r, context, tstyle, istyle, style, parentOrigin ); + resetStyle( style ); +} + +bool TokenStyleElement::readAttributesFromMathMLDom( const TQDomElement& element ) +{ + if ( !BasicElement::readAttributesFromMathMLDom( element ) ) { + return false; + } + + // MathML Section 3.2.2 + TQString variantStr = element.attribute( "mathvariant" ); + if ( !variantStr.isNull() ) { + if ( variantStr == "normal" ) { + setCharStyle( normalChar ); + setCharFamily( normalFamily ); + } + else if ( variantStr == "bold" ) { + setCharStyle( boldChar ); + setCharFamily( normalFamily ); + } + else if ( variantStr == "italic" ) { + setCharStyle( italicChar ); + setCharFamily( normalFamily ); + } + else if ( variantStr == "bold-italic" ) { + setCharStyle( boldItalicChar ); + setCharFamily( normalFamily ); + } + else if ( variantStr == "double-struck" ) { + setCharStyle( normalChar ); + setCharFamily( doubleStruckFamily ); + } + else if ( variantStr == "bold-fraktur" ) { + setCharStyle( boldChar ); + setCharFamily( frakturFamily ); + } + else if ( variantStr == "script" ) { + setCharStyle( normalChar ); + setCharFamily( scriptFamily ); + } + else if ( variantStr == "bold-script" ) { + setCharStyle( boldChar ); + setCharFamily( scriptFamily ); + } + else if ( variantStr == "fraktur" ) { + setCharStyle( boldChar ); + setCharFamily( frakturFamily ); + } + else if ( variantStr == "sans-serif" ) { + setCharStyle( normalChar ); + setCharFamily( sansSerifFamily ); + } + else if ( variantStr == "bold-sans-serif" ) { + setCharStyle( boldChar ); + setCharFamily( sansSerifFamily ); + } + else if ( variantStr == "sans-serif-italic" ) { + setCharStyle( italicChar ); + setCharFamily( sansSerifFamily ); + } + else if ( variantStr == "sans-serif-bold-italic" ) { + setCharStyle( boldItalicChar ); + setCharFamily( sansSerifFamily ); + } + else if ( variantStr == "monospace" ) { + setCharStyle( normalChar ); + setCharFamily( monospaceFamily ); + } + } + + TQString sizeStr = element.attribute( "mathsize" ); + if ( !sizeStr.isNull() ) { + if ( sizeStr == "small" ) { + setRelativeSize( 0.8 ); // ### Arbitrary size + } + else if ( sizeStr == "normal" ) { + setRelativeSize( 1.0 ); + } + else if ( sizeStr == "big" ) { + setRelativeSize( 1.2 ); // ### Arbitrary size + } + else { + double s = getSize( sizeStr, &m_mathSizeType ); + switch ( m_mathSizeType ) { + case AbsoluteSize: + setAbsoluteSize( s ); + break; + case RelativeSize: + setRelativeSize( s ); + break; + case PixelSize: + setPixelSize( s ); + break; + default: + break; + } + } + } + + TQString colorStr = element.attribute( "mathcolor" ); + if ( !colorStr.isNull() ) { + if ( colorStr[0] != '#' ) { + setMathColor( TQColor( getHtmlColor( colorStr ) ) ); + } + else { + setMathColor( TQColor( colorStr ) ); + } + } + TQString backgroundStr = element.attribute( "mathbackground" ); + if ( !backgroundStr.isNull() ) { + if ( backgroundStr[0] != '#' ) { + setMathBackground( TQColor( getHtmlColor( backgroundStr ) ) ); + } + else { + setMathBackground( TQColor( backgroundStr ) ); + } + } + + // Deprecated attributes. See Section 3.2.2.1 + + sizeStr = element.attribute( "fontsize" ); + if ( ! sizeStr.isNull() ) { + if ( sizeStr == "small" ) { + setRelativeSize( 0.8, true ); // ### Arbitrary size + } + else if ( sizeStr == "normal" ) { + setRelativeSize( 1.0, true ); + } + else if ( sizeStr == "big" ) { + setRelativeSize( 1.2, true ); // ### Arbitrary size + } + else { + double s = getSize( sizeStr, &m_fontSizeType ); + switch ( m_fontSizeType ) { + case AbsoluteSize: + setAbsoluteSize( s, true ); + break; + case RelativeSize: + setRelativeSize( s, true ); + break; + case PixelSize: + setPixelSize( s, true ); + break; + default: + break; + } + } + } + + TQString styleStr = element.attribute( "fontstyle" ); + if ( ! styleStr.isNull() ) { + if ( styleStr.lower() == "italic" ) { + setFontStyle( true ); + } + else { + setFontStyle( false ); + } + } + + TQString weightStr = element.attribute( "fontweight" ); + if ( ! weightStr.isNull() ) { + if ( weightStr.lower() == "bold" ) { + setFontWeight( true ); + } + else { + setFontWeight( false ); + } + } + + TQString familyStr = element.attribute( "fontfamily" ); + if ( ! familyStr.isNull() ) { + setFontFamily( familyStr ); + } + + colorStr = element.attribute( "color" ); + if ( ! colorStr.isNull() ) { + if ( colorStr[0] != '#' ) { + setColor( TQColor( getHtmlColor( colorStr ) ) ); + } + else { + setColor( TQColor( colorStr ) ); + } + } + + return true; +} + +void TokenStyleElement::writeMathMLAttributes( TQDomElement& element ) const +{ + // mathvariant attribute + if ( customMathVariant() ) { + if ( charFamily() == normalFamily ) { + if ( charStyle() == normalChar ) { + element.setAttribute( "mathvariant", "normal" ); + } + else if ( charStyle() == boldChar ) { + element.setAttribute( "mathvariant", "bold" ); + } + else if ( charStyle() == italicChar ) { + element.setAttribute( "mathvariant", "italic" ); + } + else if ( charStyle() == boldItalicChar ) { + element.setAttribute( "mathvariant", "bold-italic" ); + } + else { // anyChar or unknown, it's always an error + kdWarning( DEBUGID ) << "Mathvariant: unknown style for normal family\n"; + } + } + else if ( charFamily() == doubleStruckFamily ) { + if ( charStyle() == normalChar ) { + element.setAttribute( "mathvariant", "double-struck" ); + } + else { // Shouldn't happen, it's a bug + kdWarning( DEBUGID ) << "Mathvariant: unknown style for double-struck family\n"; + } + } + else if ( charFamily() == frakturFamily ) { + if ( charStyle() == normalChar ) { + element.setAttribute( "mathvariant", "fraktur" ); + } + else if ( charStyle() == boldChar ) { + element.setAttribute( "mathvariant", "bold-fraktur" ); + } + else { + kdWarning( DEBUGID ) << "Mathvariant: unknown style for fraktur family\n"; + } + } + else if ( charFamily() == scriptFamily ) { + if ( charStyle() == normalChar ) { + element.setAttribute( "mathvariant", "script" ); + } + else if ( charStyle() == boldChar ) { + element.setAttribute( "mathvariant", "bold-script" ); + } + else { // Shouldn't happen, it's a bug + kdWarning( DEBUGID ) << "Mathvariant: unknown style for script family\n"; + } + } + else if ( charFamily() == sansSerifFamily ) { + if ( charStyle() == normalChar ) { + element.setAttribute( "mathvariant", "sans-serif" ); + } + else if ( charStyle() == boldChar ) { + element.setAttribute( "mathvariant", "bold-sans-serif" ); + } + else if ( charStyle() == italicChar ) { + element.setAttribute( "mathvariant", "sans-serif-italic" ); + } + else if ( charStyle() == boldItalicChar ) { + element.setAttribute( "mathvariant", "sans-serif-bold-italic" ); + } + else { + kdWarning( DEBUGID ) << "Mathvariant: unknown style for sans serif family\n"; + } + } + else if ( charFamily() == monospaceFamily ) { + if ( charStyle() == normalChar ) { + element.setAttribute( "mathvariant", "monospace" ); + } + else { + kdWarning( DEBUGID ) << "Mathvariant: unknown style for monospace family\n"; + } + } + else { + kdWarning( DEBUGID ) << "Mathvariant: unknown family\n"; + } + } + + // mathsize attribute + switch ( m_mathSizeType ) { + case AbsoluteSize: + element.setAttribute( "mathsize", TQString( "%1pt" ).arg( m_mathSize ) ); + break; + case RelativeSize: + element.setAttribute( "mathsize", TQString( "%1%" ).arg( m_mathSize * 100.0 ) ); + break; + case PixelSize: + element.setAttribute( "mathsize", TQString( "%1px" ).arg( m_mathSize ) ); + break; + default: + break; + } + + // mathcolor attribute + if ( customMathColor() ) { + element.setAttribute( "mathcolor", mathColor().name() ); + } + + // mathbackground attribute + if ( customMathBackground() ) { + element.setAttribute( "mathbackground", mathBackground().name() ); + } + + // Deprecated MathML 1.01 Attributes + // fontsize attribute + switch ( m_fontSizeType ) { + case AbsoluteSize: + element.setAttribute( "fontsize", TQString( "%1pt" ).arg( m_fontSize ) ); + break; + case RelativeSize: + element.setAttribute( "fontsize", TQString( "%1%" ).arg( m_fontSize * 100.0 ) ); + break; + case PixelSize: + element.setAttribute( "fontsize", TQString( "%3px" ).arg( m_fontSize ) ); + break; + default: + break; + } + + // fontweight attribute + if ( customFontWeight() ) { + element.setAttribute( "fontweight", fontWeight() ? "bold" : "normal" ); + } + + // fontstyle attribute + if ( customFontStyle() ) { + element.setAttribute( "fontstyle", fontStyle() ? "italic" : "normal" ); + } + + // fontfamily attribute + if ( customFontFamily() ) { + element.setAttribute( "fontfamily", fontFamily() ); + } + + // color attribute + if ( customColor() ) { + element.setAttribute( "color", color().name() ); + } +} + +void TokenStyleElement::setAbsoluteSize( double s, bool fontsize ) +{ + kdDebug( DEBUGID) << "Setting absolute size: " << s << endl; + if ( fontsize ) { + m_fontSizeType = AbsoluteSize; + m_fontSize = s; + } + else { + m_mathSizeType = AbsoluteSize; + m_mathSize = s; + } +} + +void TokenStyleElement::setRelativeSize( double f, bool fontsize ) +{ + kdDebug( DEBUGID) << "Setting relative size: " << f << endl; + if ( fontsize ) { + m_fontSizeType = RelativeSize; + m_fontSize = f; + } + else { + m_mathSizeType = RelativeSize; + m_mathSize = f; + } +} + +void TokenStyleElement::setPixelSize( double px, bool fontsize ) +{ + kdDebug( DEBUGID) << "Setting pixel size: " << px << endl; + if ( fontsize ) { + m_fontSizeType = PixelSize; + m_fontSize = px; + } + else { + m_mathSizeType = PixelSize; + m_mathSize = px; + } +} + +void TokenStyleElement::setStyleSize( const ContextStyle& context, StyleAttributes& style ) +{ + style.setSizeFactor( sizeFactor( context, style.sizeFactor() ) ); +} + +void TokenStyleElement::setStyleVariant( StyleAttributes& style ) +{ + if ( customMathVariant() || style.customMathVariant() ) { + style.setCustomMathVariant ( true ); + style.setCustomFontWeight( false ); + style.setCustomFontStyle( false ); + style.setCustomFont( false ); + if ( customMathVariant() ) { + style.setCharFamily ( charFamily() ); + style.setCharStyle( charStyle() ); + } + else { + style.setCharFamily( style.charFamily() ); + style.setCharStyle( style.charStyle() ); + } + } + else { + style.setCustomMathVariant( false ); + if ( customFontFamily() ) { + style.setCustomFont( true ); + style.setFont( TQFont(fontFamily()) ); + } + + bool fontweight = false; + if ( customFontWeight() || style.customFontWeight() ) { + style.setCustomFontWeight( true ); + if ( customFontWeight() ) { + fontweight = fontWeight(); + } + else { + fontweight = style.fontWeight(); + } + style.setFontWeight( fontweight ); + } + else { + style.setCustomFontWeight( false ); + } + + bool fontstyle = false; + if ( style.customFontStyle() ) { + style.setCustomFontStyle( true ); + fontstyle = style.fontStyle(); + style.setFontStyle( fontstyle ); + } + else { + style.setCustomFontStyle( false ); + } + if ( customFontStyle() ) { + fontstyle = fontStyle(); + } + + if ( fontweight && fontstyle ) { + style.setCharStyle( boldItalicChar ); + } + else if ( fontweight && ! fontstyle ) { + style.setCharStyle( boldChar ); + } + else if ( ! fontweight && fontstyle ) { + style.setCharStyle( italicChar ); + } + else { + style.setCharStyle( normalChar ); + } + } +} + +void TokenStyleElement::setStyleColor( StyleAttributes& style ) +{ + if ( customMathColor() ) { + style.setColor( mathColor() ); + } + else if ( customColor() ) { + style.setColor( color() ); + } + else { + style.setColor( style.color() ); + } +} + +void TokenStyleElement::setStyleBackground( StyleAttributes& style ) +{ + if ( customMathBackground() ) { + style.setBackground( mathBackground() ); + } + else { + style.setBackground( style.background() ); + } +} + +void TokenStyleElement::resetStyle( StyleAttributes& style ) +{ + style.resetSize(); + style.resetCharStyle(); + style.resetCharFamily(); + style.resetColor(); + style.resetBackground(); + style.resetFontFamily(); + style.resetFontWeight(); + style.resetFontStyle(); +} + +double TokenStyleElement::sizeFactor( const ContextStyle& context, double factor ) +{ + double basesize = context.layoutUnitPtToPt( context.getBaseSize() ); + switch ( m_mathSizeType ) { + case AbsoluteSize: + return m_mathSize / basesize; + case RelativeSize: + return m_mathSize; + case PixelSize: + // 3.2.2 says v-unit instead of h-unit, that's why we use Y and not X + return context.pixelYToPt( m_mathSize ) / basesize; + case NoSize: + switch ( m_fontSizeType ) { + case AbsoluteSize: + return m_fontSize / basesize; + case RelativeSize: + return m_fontSize; + case PixelSize: + return context.pixelYToPt( m_fontSize ) / basesize; + default: + return factor; + } + default: + break; + } + kdWarning( DEBUGID ) << k_funcinfo << " Unknown SizeType\n"; + return factor; +} + +/** + * Return RGB string from HTML Colors. See HTML Spec, section 6.5 + */ +TQString TokenStyleElement::getHtmlColor( const TQString& colorStr ){ + + TQString colorname = colorStr.lower(); + + if ( colorname == "black" ) + return "#000000"; + if ( colorname == "silver" ) + return "#C0C0C0"; + if ( colorname == "gray" ) + return "#808080"; + if ( colorname == "white" ) + return "#FFFFFF"; + if ( colorname == "maroon" ) + return "#800000"; + if ( colorname == "red" ) + return "#FF0000"; + if ( colorname == "purple" ) + return "#800080"; + if ( colorname == "fuchsia" ) + return "#FF00FF"; + if ( colorname == "green" ) + return "#008000"; + if ( colorname == "lime" ) + return "#00FF00"; + if ( colorname == "olive" ) + return "#808000"; + if ( colorname == "yellow" ) + return "#FFFF00"; + if ( colorname == "navy" ) + return "#000080"; + if ( colorname == "blue") + return "#0000FF"; + if ( colorname == "teal" ) + return "#008080"; + if ( colorname == "aqua" ) + return "#00FFFF"; + kdWarning( DEBUGID ) << "Invalid HTML color: " << colorname << endl; + return "#FFFFFF"; // ### Arbitrary selection of default color +} + + +KFORMULA_NAMESPACE_END diff --git a/lib/kformula/unicodetable.cc b/lib/kformula/unicodetable.cc deleted file mode 100644 index 23dc8636..00000000 --- a/lib/kformula/unicodetable.cc +++ /dev/null @@ -1,546 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2006 Alfredo Beaumont Sainz - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - -KFORMULA_NAMESPACE_BEGIN - -struct UnicodeNameTable { short unicode; const char* name; }; - -static UnicodeNameTable greekTable[] = { - { 0x03B1, "alpha" }, - { 0x03B2, "beta" }, - { 0x03B3, "gamma" }, - { 0x03B4, "delta" }, - { 0x03B5, "epsilon" }, - { 0x03F5, "varepsilon" }, - { 0x03B6, "zeta" }, - { 0x03B7, "eta" }, - { 0x03B8, "theta" }, - { 0x03D1, "vartheta" }, - { 0x03B9, "iota" }, - { 0x03BA, "kappa" }, - { 0x03F0, "varkappa" }, - { 0x03BB, "lambda" }, - { 0x03BC, "mu" }, - { 0x03BD, "nu" }, - { 0x03BE, "xi" }, - { 0x03C0, "pi" }, - { 0x03D6, "varpi" }, - { 0x03C1, "rho" }, - { 0x03F1, "varrho" }, - { 0x03C3, "sigma" }, - { 0x03C2, "varsigma" }, - { 0x03C4, "tau" }, - { 0x03C5, "upsilon" }, - { 0x03D5, "phi" }, - { 0x03C6, "varphi" }, - { 0x03C7, "chi" }, - { 0x03C8, "psi" }, - { 0x03C9, "omega" }, - { 0x0393, "Gamma" }, - { 0x0394, "Delta" }, - { 0x0398, "Theta" }, - { 0x039B, "Lambda" }, - { 0x039E, "Xi" }, - { 0x03A0, "Pi" }, - { 0x03A3, "Sigma" }, - { 0x03D2, "Upsilon" }, - { 0x03A6, "Phi" }, - { 0x03A8, "Psi" }, - { 0x03A9, "Omega" }, - { 0, 0 } -}; - -static UnicodeNameTable arrowTable[] = { - { 0x2190, "leftarrow" }, - { 0x2191, "uparrow" }, - { 0x2192, "rightarrow" }, - { 0x2193, "downarrow" }, - { 0x2194, "leftrightarrow" }, - { 0x2195, "updownarrow" }, - { 0x2196, "nwarrow" }, - { 0x2197, "nearrow" }, - { 0x2198, "searrow" }, - { 0x2199, "swarrow" }, - { 0x219A, "nleftarrow" }, - { 0x219B, "nrightarrow" }, - { 0x219C, "" }, - { 0x219D, "rightsquigarrow" }, - { 0x219E, "twoheadleftarrow" }, - { 0x219F, "" }, - { 0x21A0, "twoheadrightarrow" }, - { 0x21A1, "" }, - { 0x21A2, "leftarrowtail" }, - { 0x21A3, "rightarrowtail" }, - { 0x21A4, "" }, - { 0x21A5, "" }, - { 0x21A6, "mapsto" }, - { 0x21A7, "" }, - { 0x21A8, "" }, - { 0x21A9, "hookleftarrow" }, - { 0x21AA, "hookrightarrow" }, - { 0x21AB, "looparrowleft" }, - { 0x21AC, "looparrowright" }, - { 0x21AD, "leftrightsquigarrow" }, - { 0x21AE, "nleftrightarrow" }, - { 0x21AF, "" }, - { 0x21B0, "Lsh" }, - { 0x21B1, "Rsh" }, - { 0x21B2, "" }, - { 0x21B3, "" }, - { 0x21B4, "" }, - { 0x21B5, "carriagereturn" }, - { 0x21B6, "curvearrowleft" }, - { 0x21B7, "curvearrowright" }, - { 0x21B8, "" }, - { 0x21B9, "" }, - { 0x21BA, "acwopencirclearrow" }, - { 0x21BB, "cwopencirclearrow" }, - { 0x21BC, "leftharpoonup" }, - { 0x21BD, "leftharpoondown" }, - { 0x21BE, "upharpoonright" }, - { 0x21BF, "upharpoonleft" }, - { 0x21C0, "rightharpoonup" }, - { 0x21C1, "rightharpoondown" }, - { 0x21C2, "downharpoonright" }, - { 0x21C3, "downharpoonleft" }, - { 0x21C4, "rightleftarrows" }, - { 0x21C5, "" }, - { 0x21C6, "leftrightarrows" }, - { 0x21C7, "leftleftarrows" }, - { 0x21C8, "upuparrows" }, - { 0x21C9, "rightrightarrows" }, - { 0x21CA, "downdownarrows" }, - { 0x21CB, "leftrightharpoons" }, - { 0x21CC, "rightleftharpoons" }, - { 0x21CD, "nLeftarrow" }, - { 0x21CE, "nLeftrightarrow" }, - { 0x21CF, "nRightarrow" }, - { 0x21D0, "Leftarrow" }, - { 0x21D1, "Uparrow" }, - { 0x21D2, "Rightarrow" }, - { 0x21D3, "Downarrow" }, - { 0x21D4, "Leftrightarrow" }, - { 0x21D5, "Updownarrow" }, - { 0x21D6, "" }, - { 0x21D7, "" }, - { 0x21D8, "" }, - { 0x21D9, "" }, - { 0x21DA, "Lleftarrow" }, - { 0x21DB, "Rrightarrow" }, - { 0x21DC, "" }, - { 0x21DD, "rightzigzagarrow" }, - { 0x21DE, "" }, - { 0x21DF, "" }, - { 0x21E0, "" }, - { 0x21E1, "" }, - { 0x21E2, "" }, - { 0x21E3, "" }, - { 0x21E4, "" }, - { 0x21E5, "" }, - { 0x21E6, "" }, - { 0x21E7, "" }, - { 0x21E8, "" }, - { 0x21E9, "" }, - { 0x21EA, "" }, - { 0x21EB, "" }, - { 0x21EC, "" }, - { 0x21ED, "" }, - { 0x21EE, "" }, - { 0x21EF, "" }, - { 0x21F0, "" }, - { 0x21F1, "" }, - { 0x21F2, "" }, - { 0x21F3, "" }, - { 0x21F4, "" }, - { 0x21F5, "" }, - { 0x21F6, "" }, - { 0x21F7, "" }, - { 0x21F8, "" }, - { 0x21F9, "" }, - { 0x21FA, "" }, - { 0x21FB, "" }, - { 0x21FC, "" }, - { 0x21FD, "" }, - { 0x21FE, "" }, - { 0x21FF, "" }, - { 0, 0 } -}; - -/* - { 0x003A, "colon" }, - { 0x003A, "colon" }, - { 0x003C, "less" }, - { 0x003C, "less" }, - { 0x003E, "greater" }, - { 0x003E, "greater" }, - { 0x005C, "backslash" }, - { 0x005E, "textasciicircum" }, - { 0x007B, "lbrace" }, - { 0x007C, "vert" }, - { 0x007D, "rbrace" }, - { 0x007E, "textasciitilde" }, - { 0x00A1, "textexclamdown" }, - { 0x00A7, "S" }, - { 0x00AC, "neg" }, - { 0x00B0, "degree" }, - { 0x00B1, "pm" }, - { 0x00B6, "P" }, - { 0x00BF, "textquestiondown" }, - { 0x00D7, "times" }, - { 0x00D8, "O" }, - { 0x00F7, "div" }, - { 0x00F8, "o" }, - { 0x019B, "lambdabar" }, - { 0x0300, "grave" }, - { 0x0301, "acute" }, - { 0x0302, "hat" }, - { 0x0304, "bar" }, - { 0x030A, "ocirc" }, - { 0x0338, "not" }, - { 0x2013, "endash" }, - { 0x2014, "emdash" }, - { 0x2022, "bullet" }, - { 0x2026, "ldots" }, - { 0x2032, "prime" }, - { 0x2035, "backprime" }, - { 0x20D0, "leftharpoonaccent" }, - { 0x20D1, "rightharpoonaccent" }, - { 0x20D6, "overleftarrow" }, - { 0x20D7, "vec" }, - { 0x20E1, "overleftrightarrow" }, - { 0x2111, "Im" }, - { 0x2118, "wp" }, - { 0x211C, "Re" }, - { 0x2127, "mho" }, - { 0x2309, "rceil" }, - { 0x2329, "langle" }, - { 0x232A, "rangle" }, - { 0x24C8, "circledS" }, - { 0x25B3, "bigtriangleup" }, - { 0x25B4, "blacktriangle" }, - { 0x25B5, "vartriangle" }, - { 0x25B6, "blacktriangleright" }, - { 0x25BD, "bigtriangledown" }, - { 0x25BE, "blacktriangledown" }, - { 0x25C0, "blacktriangleleft" }, - { 0x25CB, "bigcirc" }, - { 0x2605, "bigstar" }, - { 0x2660, "spadesuit" }, - { 0x2661, "heartsuit" }, - { 0x2662, "diamondsuit" }, - { 0x2663, "clubsuit" }, - { 0x2666, "diamondsuit" }, - { 0x266D, "flat" }, - { 0x266E, "natural" }, - { 0x266F, "sharp" }, - { 0x2713, "checkmark" }, - { 0x2720, "maltese" }, - { 0xE201, "longleftarrow" }, - { 0xE205, "longrightarrow" }, - { 0xE29F, "gnapprox" }, - { 0xE2A0, "gneq" }, - { 0xE2A3, "lneq" }, - { 0xE2A6, "ngeqslant" }, - { 0xE2A7, "nleqslant" }, - { 0xE2A8, "nleqq" }, - { 0xE2B0, "nsupseteqq" }, - { 0xE2B2, "precnapprox" }, - { 0xE2B4, "succnapprox" }, - { 0xE2B6, "subsetneqq" }, - { 0xE2B7, "supsetneqq" }, - { 0xE2B8, "varsubsetneqq" }, - { 0xE2B9, "varsubsetneq" }, - { 0xE2BA, "varsupsetneq" }, - { 0xE2BB, "varsupsetneqq" }, - { 0xE2F4, "gtrapprox" }, - { 0xE2F5, "gtreqqless" }, - { 0xE2F6, "geqslant" }, - { 0xE2F8, "lessapprox" }, - { 0xE2F9, "lesseqqgtr" }, - { 0xE2FA, "leqslant" }, - { 0xE2FD, "precapprox" }, - { 0xE2FE, "preceq" }, - { 0xE2FF, "succapprox" }, - { 0xE300, "succeq" }, - { 0xE304, "subseteqq" }, - { 0xE305, "supseteqq" }, - { 0xE5CF, "eqslantless" }, - { 0xE5DC, "npreceq" }, - { 0xE5F1, "nsucceq" }, - { 0xE663, "Upsilon" }, -*/ - -static UnicodeNameTable operatorTable[] = { - { 0x2200, "forall" }, - { 0x2201, "complement" }, - { 0x2202, "partial" }, - { 0x2203, "exists" }, - { 0x2204, "nexists" }, - { 0x2205, "oslash" }, - { 0x2206, "triangle" }, - { 0x2207, "nabla" }, - { 0x2208, "in" }, - { 0x2209, "notin" }, - { 0x220A, "in" }, - { 0x220B, "ni" }, - { 0x220C, "" }, - { 0x220D, "ni" }, - { 0x220E, "blacksquare" }, - { 0x220F, "prod" }, - { 0x2210, "coprod" }, - { 0x2211, "sum" }, - { 0x2212, "minus" }, - { 0x2213, "mp" }, - { 0x2214, "dotplus" }, - { 0x2215, "slash" }, - { 0x2216, "setminus" }, - { 0x2217, "ast" }, - { 0x2218, "circ" }, - { 0x2219, "bullet" }, - { 0x221A, "surd" }, - { 0x221B, "" }, - { 0x221C, "" }, - { 0x221D, "propto" }, - { 0x221E, "infty" }, - { 0x221F, "" }, - { 0x2220, "angle" }, - { 0x2221, "measuredangle" }, - { 0x2222, "" }, - { 0x2223, "mid" }, - { 0x2224, "nmid" }, - { 0x2225, "parallel" }, - { 0x2226, "nparallel" }, - { 0x2227, "wedge" }, - { 0x2228, "vee" }, - { 0x2229, "cap" }, - { 0x222A, "cup" }, - { 0x222B, "int" }, - { 0x222C, "" }, - { 0x222D, "" }, - { 0x222E, "oint" }, - { 0x222F, "" }, - { 0x2230, "" }, - { 0x2231, "" }, - { 0x2232, "" }, - { 0x2233, "" }, - { 0x2234, "therefore" }, - { 0x2235, "because" }, - { 0x2236, "" }, - { 0x2237, "" }, - { 0x2238, "" }, - { 0x2239, "" }, - { 0x223A, "" }, - { 0x223B, "" }, - { 0x223C, "sim" }, - { 0x223D, "backsim" }, - { 0x223E, "" }, - { 0x223F, "" }, - { 0x2240, "wr" }, - { 0x2241, "" }, - { 0x2242, "eqsim" }, - { 0x2243, "simeq" }, - { 0x2244, "nsime" }, - { 0x2245, "cong" }, - { 0x2246, "" }, - { 0x2247, "ncong" }, - { 0x2248, "approx" }, - { 0x2249, "" }, - { 0x224A, "approxeq" }, - { 0x224B, "" }, - { 0x224C, "" }, - { 0x224D, "asymp" }, - { 0x224E, "Bumpeq" }, - { 0x224F, "bumpeq" }, - { 0x2250, "doteq" }, - { 0x2251, "Doteq" }, - { 0x2252, "fallingdotseq" }, - { 0x2253, "risingdotseq" }, - { 0x2254, "" }, - { 0x2255, "" }, - { 0x2256, "eqcirc" }, - { 0x2257, "circeq" }, - { 0x2258, "" }, - { 0x2259, "wedgeq" }, - { 0x225A, "" }, - { 0x225B, "" }, - { 0x225C, "triangleq" }, - { 0x225D, "" }, - { 0x225E, "" }, - { 0x225F, "" }, - { 0x2260, "neq" }, - { 0x2261, "equiv" }, - { 0x2262, "" }, - { 0x2263, "" }, - { 0x2264, "leq" }, - { 0x2265, "geq" }, - { 0x2266, "leqq" }, - { 0x2267, "geqq" }, - { 0x2268, "" }, - { 0x2269, "" }, - { 0x226A, "ll" }, - { 0x226B, "gg" }, - { 0x226C, "between" }, - { 0x226D, "" }, - { 0x226E, "nless" }, - { 0x226F, "ngtr" }, - { 0x2270, "nleq" }, - { 0x2271, "ngeq" }, - { 0x2272, "lesssim" }, - { 0x2273, "gtrsim" }, - { 0x2274, "" }, - { 0x2275, "" }, - { 0x2276, "lessgtr" }, - { 0x2277, "gtrless" }, - { 0x2278, "" }, - { 0x2279, "" }, - { 0x227A, "prec" }, - { 0x227B, "succ" }, - { 0x227C, "preccurlyeq" }, - { 0x227D, "succcurlyeq" }, - { 0x227E, "precsim" }, - { 0x227F, "succsim" }, - { 0x2280, "nprec" }, - { 0x2281, "nsucc" }, - { 0x2282, "subset" }, - { 0x2283, "supset" }, - { 0x2284, "nsubset" }, - { 0x2286, "subseteq" }, - { 0x2287, "supseteq" }, - { 0x2288, "nsubseteq" }, - { 0x2289, "nsupseteq" }, - { 0x228A, "subsetneq" }, - { 0x228B, "supsetneq" }, - { 0x228C, "" }, - { 0x228D, "" }, - { 0x228E, "uplus" }, - { 0x228F, "sqsubset" }, - { 0x2290, "sqsupset" }, - { 0x2291, "sqsubseteq" }, - { 0x2292, "sqsupseteq" }, - { 0x2293, "sqcap" }, - { 0x2294, "sqcup" }, - { 0x2295, "oplus" }, - { 0x2296, "ominus" }, - { 0x2297, "otimes" }, - { 0x2298, "oslash" }, - { 0x2299, "odot" }, - { 0x229A, "circledcirc" }, - { 0x229B, "circledast" }, - { 0x229C, "" }, - { 0x229D, "circleddash" }, - { 0x229E, "boxplus" }, - { 0x229F, "boxminus" }, - { 0x22A0, "boxtimes" }, - { 0x22A1, "boxdot" }, - { 0x22A2, "" }, - { 0x22A3, "dashv" }, - { 0x22A4, "top" }, - { 0x22A5, "" }, - { 0x22A6, "" }, - { 0x22A7, "" }, - { 0x22A8, "vDash" }, - { 0x22A9, "Vdash" }, - { 0x22AA, "Vvdash" }, - { 0x22AB, "" }, - { 0x22AC, "nvdash" }, - { 0x22AD, "nvDash" }, - { 0x22AE, "nVdash" }, - { 0x22AF, "nVDash" }, - { 0x22B1, "" }, - { 0x22B2, "vartriangleleft" }, - { 0x22B3, "vartriangleright" }, - { 0x22B4, "trianglelefteq" }, - { 0x22B5, "trianglerighteq" }, - { 0x22B6, "" }, - { 0x22B7, "" }, - { 0x22B8, "multimap" }, - { 0x22B9, "" }, - { 0x22BA, "intercal" }, - { 0x22BB, "veebar" }, - { 0x22BC, "barwedge" }, - { 0x22BD, "" }, - { 0x22BE, "" }, - { 0x22BF, "" }, - { 0x22C1, "" }, - { 0x22C2, "" }, - { 0x22C3, "" }, - { 0x22C4, "diamond" }, - { 0x22C5, "cdot" }, - { 0x22C6, "star" }, - { 0x22C7, "divideontimes" }, - { 0x22C8, "" }, - { 0x22C9, "ltimes" }, - { 0x22CA, "rtimes" }, - { 0x22CB, "leftthreetimes" }, - { 0x22CC, "rightthreetimes" }, - { 0x22CD, "backsimeq" }, - { 0x22CE, "curlyvee" }, - { 0x22CF, "curlywedge" }, - { 0x22D0, "Subset" }, - { 0x22D1, "Supset" }, - { 0x22D2, "Cap" }, - { 0x22D3, "Cup" }, - { 0x22D4, "pitchfork" }, - { 0x22D5, "" }, - { 0x22D6, "lessdot" }, - { 0x22D7, "gtrdot" }, - { 0x22D8, "lll" }, - { 0x22D9, "ggg" }, - { 0x22DA, "lesseqgtr" }, - { 0x22DB, "gtreqless" }, - { 0x22DC, "eqless" }, - { 0x22DD, "eqgtr" }, - { 0x22DE, "curlyeqprec" }, - { 0x22DF, "curlyeqsucc" }, - { 0x22E0, "" }, - { 0x22E1, "" }, - { 0x22E2, "" }, - { 0x22E3, "" }, - { 0x22E4, "" }, - { 0x22E5, "" }, - { 0x22E6, "lnsim" }, - { 0x22E7, "gnsim" }, - { 0x22E8, "precnsim" }, - { 0x22E9, "succnsim" }, - { 0x22EA, "ntriangleleft" }, - { 0x22EB, "ntriangleright" }, - { 0x22EC, "ntrianglelefteq" }, - { 0x22ED, "ntrianglerighteq" }, - { 0x22EE, "vdots" }, - { 0x22EF, "cdots" }, - { 0x22F0, "adots" }, - { 0x22F1, "ddots" }, - { 0x22F2, "" }, - { 0x22F3, "" }, - { 0x22F4, "" }, - { 0x22F5, "" }, - { 0x22F6, "" }, - { 0x22F7, "" }, - { 0x22F8, "" }, - { 0x22F9, "" }, - { 0x22FA, "" }, - { 0x22FB, "" }, - { 0x22FC, "" }, - { 0x22FD, "" }, - { 0x22FE, "" }, - { 0x22FF, "" }, - { 0, 0 } -}; - -KFORMULA_NAMESPACE_END diff --git a/lib/kformula/unicodetable.cpp b/lib/kformula/unicodetable.cpp new file mode 100644 index 00000000..23dc8636 --- /dev/null +++ b/lib/kformula/unicodetable.cpp @@ -0,0 +1,546 @@ +/* This file is part of the KDE project + Copyright (C) 2006 Alfredo Beaumont Sainz + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +KFORMULA_NAMESPACE_BEGIN + +struct UnicodeNameTable { short unicode; const char* name; }; + +static UnicodeNameTable greekTable[] = { + { 0x03B1, "alpha" }, + { 0x03B2, "beta" }, + { 0x03B3, "gamma" }, + { 0x03B4, "delta" }, + { 0x03B5, "epsilon" }, + { 0x03F5, "varepsilon" }, + { 0x03B6, "zeta" }, + { 0x03B7, "eta" }, + { 0x03B8, "theta" }, + { 0x03D1, "vartheta" }, + { 0x03B9, "iota" }, + { 0x03BA, "kappa" }, + { 0x03F0, "varkappa" }, + { 0x03BB, "lambda" }, + { 0x03BC, "mu" }, + { 0x03BD, "nu" }, + { 0x03BE, "xi" }, + { 0x03C0, "pi" }, + { 0x03D6, "varpi" }, + { 0x03C1, "rho" }, + { 0x03F1, "varrho" }, + { 0x03C3, "sigma" }, + { 0x03C2, "varsigma" }, + { 0x03C4, "tau" }, + { 0x03C5, "upsilon" }, + { 0x03D5, "phi" }, + { 0x03C6, "varphi" }, + { 0x03C7, "chi" }, + { 0x03C8, "psi" }, + { 0x03C9, "omega" }, + { 0x0393, "Gamma" }, + { 0x0394, "Delta" }, + { 0x0398, "Theta" }, + { 0x039B, "Lambda" }, + { 0x039E, "Xi" }, + { 0x03A0, "Pi" }, + { 0x03A3, "Sigma" }, + { 0x03D2, "Upsilon" }, + { 0x03A6, "Phi" }, + { 0x03A8, "Psi" }, + { 0x03A9, "Omega" }, + { 0, 0 } +}; + +static UnicodeNameTable arrowTable[] = { + { 0x2190, "leftarrow" }, + { 0x2191, "uparrow" }, + { 0x2192, "rightarrow" }, + { 0x2193, "downarrow" }, + { 0x2194, "leftrightarrow" }, + { 0x2195, "updownarrow" }, + { 0x2196, "nwarrow" }, + { 0x2197, "nearrow" }, + { 0x2198, "searrow" }, + { 0x2199, "swarrow" }, + { 0x219A, "nleftarrow" }, + { 0x219B, "nrightarrow" }, + { 0x219C, "" }, + { 0x219D, "rightsquigarrow" }, + { 0x219E, "twoheadleftarrow" }, + { 0x219F, "" }, + { 0x21A0, "twoheadrightarrow" }, + { 0x21A1, "" }, + { 0x21A2, "leftarrowtail" }, + { 0x21A3, "rightarrowtail" }, + { 0x21A4, "" }, + { 0x21A5, "" }, + { 0x21A6, "mapsto" }, + { 0x21A7, "" }, + { 0x21A8, "" }, + { 0x21A9, "hookleftarrow" }, + { 0x21AA, "hookrightarrow" }, + { 0x21AB, "looparrowleft" }, + { 0x21AC, "looparrowright" }, + { 0x21AD, "leftrightsquigarrow" }, + { 0x21AE, "nleftrightarrow" }, + { 0x21AF, "" }, + { 0x21B0, "Lsh" }, + { 0x21B1, "Rsh" }, + { 0x21B2, "" }, + { 0x21B3, "" }, + { 0x21B4, "" }, + { 0x21B5, "carriagereturn" }, + { 0x21B6, "curvearrowleft" }, + { 0x21B7, "curvearrowright" }, + { 0x21B8, "" }, + { 0x21B9, "" }, + { 0x21BA, "acwopencirclearrow" }, + { 0x21BB, "cwopencirclearrow" }, + { 0x21BC, "leftharpoonup" }, + { 0x21BD, "leftharpoondown" }, + { 0x21BE, "upharpoonright" }, + { 0x21BF, "upharpoonleft" }, + { 0x21C0, "rightharpoonup" }, + { 0x21C1, "rightharpoondown" }, + { 0x21C2, "downharpoonright" }, + { 0x21C3, "downharpoonleft" }, + { 0x21C4, "rightleftarrows" }, + { 0x21C5, "" }, + { 0x21C6, "leftrightarrows" }, + { 0x21C7, "leftleftarrows" }, + { 0x21C8, "upuparrows" }, + { 0x21C9, "rightrightarrows" }, + { 0x21CA, "downdownarrows" }, + { 0x21CB, "leftrightharpoons" }, + { 0x21CC, "rightleftharpoons" }, + { 0x21CD, "nLeftarrow" }, + { 0x21CE, "nLeftrightarrow" }, + { 0x21CF, "nRightarrow" }, + { 0x21D0, "Leftarrow" }, + { 0x21D1, "Uparrow" }, + { 0x21D2, "Rightarrow" }, + { 0x21D3, "Downarrow" }, + { 0x21D4, "Leftrightarrow" }, + { 0x21D5, "Updownarrow" }, + { 0x21D6, "" }, + { 0x21D7, "" }, + { 0x21D8, "" }, + { 0x21D9, "" }, + { 0x21DA, "Lleftarrow" }, + { 0x21DB, "Rrightarrow" }, + { 0x21DC, "" }, + { 0x21DD, "rightzigzagarrow" }, + { 0x21DE, "" }, + { 0x21DF, "" }, + { 0x21E0, "" }, + { 0x21E1, "" }, + { 0x21E2, "" }, + { 0x21E3, "" }, + { 0x21E4, "" }, + { 0x21E5, "" }, + { 0x21E6, "" }, + { 0x21E7, "" }, + { 0x21E8, "" }, + { 0x21E9, "" }, + { 0x21EA, "" }, + { 0x21EB, "" }, + { 0x21EC, "" }, + { 0x21ED, "" }, + { 0x21EE, "" }, + { 0x21EF, "" }, + { 0x21F0, "" }, + { 0x21F1, "" }, + { 0x21F2, "" }, + { 0x21F3, "" }, + { 0x21F4, "" }, + { 0x21F5, "" }, + { 0x21F6, "" }, + { 0x21F7, "" }, + { 0x21F8, "" }, + { 0x21F9, "" }, + { 0x21FA, "" }, + { 0x21FB, "" }, + { 0x21FC, "" }, + { 0x21FD, "" }, + { 0x21FE, "" }, + { 0x21FF, "" }, + { 0, 0 } +}; + +/* + { 0x003A, "colon" }, + { 0x003A, "colon" }, + { 0x003C, "less" }, + { 0x003C, "less" }, + { 0x003E, "greater" }, + { 0x003E, "greater" }, + { 0x005C, "backslash" }, + { 0x005E, "textasciicircum" }, + { 0x007B, "lbrace" }, + { 0x007C, "vert" }, + { 0x007D, "rbrace" }, + { 0x007E, "textasciitilde" }, + { 0x00A1, "textexclamdown" }, + { 0x00A7, "S" }, + { 0x00AC, "neg" }, + { 0x00B0, "degree" }, + { 0x00B1, "pm" }, + { 0x00B6, "P" }, + { 0x00BF, "textquestiondown" }, + { 0x00D7, "times" }, + { 0x00D8, "O" }, + { 0x00F7, "div" }, + { 0x00F8, "o" }, + { 0x019B, "lambdabar" }, + { 0x0300, "grave" }, + { 0x0301, "acute" }, + { 0x0302, "hat" }, + { 0x0304, "bar" }, + { 0x030A, "ocirc" }, + { 0x0338, "not" }, + { 0x2013, "endash" }, + { 0x2014, "emdash" }, + { 0x2022, "bullet" }, + { 0x2026, "ldots" }, + { 0x2032, "prime" }, + { 0x2035, "backprime" }, + { 0x20D0, "leftharpoonaccent" }, + { 0x20D1, "rightharpoonaccent" }, + { 0x20D6, "overleftarrow" }, + { 0x20D7, "vec" }, + { 0x20E1, "overleftrightarrow" }, + { 0x2111, "Im" }, + { 0x2118, "wp" }, + { 0x211C, "Re" }, + { 0x2127, "mho" }, + { 0x2309, "rceil" }, + { 0x2329, "langle" }, + { 0x232A, "rangle" }, + { 0x24C8, "circledS" }, + { 0x25B3, "bigtriangleup" }, + { 0x25B4, "blacktriangle" }, + { 0x25B5, "vartriangle" }, + { 0x25B6, "blacktriangleright" }, + { 0x25BD, "bigtriangledown" }, + { 0x25BE, "blacktriangledown" }, + { 0x25C0, "blacktriangleleft" }, + { 0x25CB, "bigcirc" }, + { 0x2605, "bigstar" }, + { 0x2660, "spadesuit" }, + { 0x2661, "heartsuit" }, + { 0x2662, "diamondsuit" }, + { 0x2663, "clubsuit" }, + { 0x2666, "diamondsuit" }, + { 0x266D, "flat" }, + { 0x266E, "natural" }, + { 0x266F, "sharp" }, + { 0x2713, "checkmark" }, + { 0x2720, "maltese" }, + { 0xE201, "longleftarrow" }, + { 0xE205, "longrightarrow" }, + { 0xE29F, "gnapprox" }, + { 0xE2A0, "gneq" }, + { 0xE2A3, "lneq" }, + { 0xE2A6, "ngeqslant" }, + { 0xE2A7, "nleqslant" }, + { 0xE2A8, "nleqq" }, + { 0xE2B0, "nsupseteqq" }, + { 0xE2B2, "precnapprox" }, + { 0xE2B4, "succnapprox" }, + { 0xE2B6, "subsetneqq" }, + { 0xE2B7, "supsetneqq" }, + { 0xE2B8, "varsubsetneqq" }, + { 0xE2B9, "varsubsetneq" }, + { 0xE2BA, "varsupsetneq" }, + { 0xE2BB, "varsupsetneqq" }, + { 0xE2F4, "gtrapprox" }, + { 0xE2F5, "gtreqqless" }, + { 0xE2F6, "geqslant" }, + { 0xE2F8, "lessapprox" }, + { 0xE2F9, "lesseqqgtr" }, + { 0xE2FA, "leqslant" }, + { 0xE2FD, "precapprox" }, + { 0xE2FE, "preceq" }, + { 0xE2FF, "succapprox" }, + { 0xE300, "succeq" }, + { 0xE304, "subseteqq" }, + { 0xE305, "supseteqq" }, + { 0xE5CF, "eqslantless" }, + { 0xE5DC, "npreceq" }, + { 0xE5F1, "nsucceq" }, + { 0xE663, "Upsilon" }, +*/ + +static UnicodeNameTable operatorTable[] = { + { 0x2200, "forall" }, + { 0x2201, "complement" }, + { 0x2202, "partial" }, + { 0x2203, "exists" }, + { 0x2204, "nexists" }, + { 0x2205, "oslash" }, + { 0x2206, "triangle" }, + { 0x2207, "nabla" }, + { 0x2208, "in" }, + { 0x2209, "notin" }, + { 0x220A, "in" }, + { 0x220B, "ni" }, + { 0x220C, "" }, + { 0x220D, "ni" }, + { 0x220E, "blacksquare" }, + { 0x220F, "prod" }, + { 0x2210, "coprod" }, + { 0x2211, "sum" }, + { 0x2212, "minus" }, + { 0x2213, "mp" }, + { 0x2214, "dotplus" }, + { 0x2215, "slash" }, + { 0x2216, "setminus" }, + { 0x2217, "ast" }, + { 0x2218, "circ" }, + { 0x2219, "bullet" }, + { 0x221A, "surd" }, + { 0x221B, "" }, + { 0x221C, "" }, + { 0x221D, "propto" }, + { 0x221E, "infty" }, + { 0x221F, "" }, + { 0x2220, "angle" }, + { 0x2221, "measuredangle" }, + { 0x2222, "" }, + { 0x2223, "mid" }, + { 0x2224, "nmid" }, + { 0x2225, "parallel" }, + { 0x2226, "nparallel" }, + { 0x2227, "wedge" }, + { 0x2228, "vee" }, + { 0x2229, "cap" }, + { 0x222A, "cup" }, + { 0x222B, "int" }, + { 0x222C, "" }, + { 0x222D, "" }, + { 0x222E, "oint" }, + { 0x222F, "" }, + { 0x2230, "" }, + { 0x2231, "" }, + { 0x2232, "" }, + { 0x2233, "" }, + { 0x2234, "therefore" }, + { 0x2235, "because" }, + { 0x2236, "" }, + { 0x2237, "" }, + { 0x2238, "" }, + { 0x2239, "" }, + { 0x223A, "" }, + { 0x223B, "" }, + { 0x223C, "sim" }, + { 0x223D, "backsim" }, + { 0x223E, "" }, + { 0x223F, "" }, + { 0x2240, "wr" }, + { 0x2241, "" }, + { 0x2242, "eqsim" }, + { 0x2243, "simeq" }, + { 0x2244, "nsime" }, + { 0x2245, "cong" }, + { 0x2246, "" }, + { 0x2247, "ncong" }, + { 0x2248, "approx" }, + { 0x2249, "" }, + { 0x224A, "approxeq" }, + { 0x224B, "" }, + { 0x224C, "" }, + { 0x224D, "asymp" }, + { 0x224E, "Bumpeq" }, + { 0x224F, "bumpeq" }, + { 0x2250, "doteq" }, + { 0x2251, "Doteq" }, + { 0x2252, "fallingdotseq" }, + { 0x2253, "risingdotseq" }, + { 0x2254, "" }, + { 0x2255, "" }, + { 0x2256, "eqcirc" }, + { 0x2257, "circeq" }, + { 0x2258, "" }, + { 0x2259, "wedgeq" }, + { 0x225A, "" }, + { 0x225B, "" }, + { 0x225C, "triangleq" }, + { 0x225D, "" }, + { 0x225E, "" }, + { 0x225F, "" }, + { 0x2260, "neq" }, + { 0x2261, "equiv" }, + { 0x2262, "" }, + { 0x2263, "" }, + { 0x2264, "leq" }, + { 0x2265, "geq" }, + { 0x2266, "leqq" }, + { 0x2267, "geqq" }, + { 0x2268, "" }, + { 0x2269, "" }, + { 0x226A, "ll" }, + { 0x226B, "gg" }, + { 0x226C, "between" }, + { 0x226D, "" }, + { 0x226E, "nless" }, + { 0x226F, "ngtr" }, + { 0x2270, "nleq" }, + { 0x2271, "ngeq" }, + { 0x2272, "lesssim" }, + { 0x2273, "gtrsim" }, + { 0x2274, "" }, + { 0x2275, "" }, + { 0x2276, "lessgtr" }, + { 0x2277, "gtrless" }, + { 0x2278, "" }, + { 0x2279, "" }, + { 0x227A, "prec" }, + { 0x227B, "succ" }, + { 0x227C, "preccurlyeq" }, + { 0x227D, "succcurlyeq" }, + { 0x227E, "precsim" }, + { 0x227F, "succsim" }, + { 0x2280, "nprec" }, + { 0x2281, "nsucc" }, + { 0x2282, "subset" }, + { 0x2283, "supset" }, + { 0x2284, "nsubset" }, + { 0x2286, "subseteq" }, + { 0x2287, "supseteq" }, + { 0x2288, "nsubseteq" }, + { 0x2289, "nsupseteq" }, + { 0x228A, "subsetneq" }, + { 0x228B, "supsetneq" }, + { 0x228C, "" }, + { 0x228D, "" }, + { 0x228E, "uplus" }, + { 0x228F, "sqsubset" }, + { 0x2290, "sqsupset" }, + { 0x2291, "sqsubseteq" }, + { 0x2292, "sqsupseteq" }, + { 0x2293, "sqcap" }, + { 0x2294, "sqcup" }, + { 0x2295, "oplus" }, + { 0x2296, "ominus" }, + { 0x2297, "otimes" }, + { 0x2298, "oslash" }, + { 0x2299, "odot" }, + { 0x229A, "circledcirc" }, + { 0x229B, "circledast" }, + { 0x229C, "" }, + { 0x229D, "circleddash" }, + { 0x229E, "boxplus" }, + { 0x229F, "boxminus" }, + { 0x22A0, "boxtimes" }, + { 0x22A1, "boxdot" }, + { 0x22A2, "" }, + { 0x22A3, "dashv" }, + { 0x22A4, "top" }, + { 0x22A5, "" }, + { 0x22A6, "" }, + { 0x22A7, "" }, + { 0x22A8, "vDash" }, + { 0x22A9, "Vdash" }, + { 0x22AA, "Vvdash" }, + { 0x22AB, "" }, + { 0x22AC, "nvdash" }, + { 0x22AD, "nvDash" }, + { 0x22AE, "nVdash" }, + { 0x22AF, "nVDash" }, + { 0x22B1, "" }, + { 0x22B2, "vartriangleleft" }, + { 0x22B3, "vartriangleright" }, + { 0x22B4, "trianglelefteq" }, + { 0x22B5, "trianglerighteq" }, + { 0x22B6, "" }, + { 0x22B7, "" }, + { 0x22B8, "multimap" }, + { 0x22B9, "" }, + { 0x22BA, "intercal" }, + { 0x22BB, "veebar" }, + { 0x22BC, "barwedge" }, + { 0x22BD, "" }, + { 0x22BE, "" }, + { 0x22BF, "" }, + { 0x22C1, "" }, + { 0x22C2, "" }, + { 0x22C3, "" }, + { 0x22C4, "diamond" }, + { 0x22C5, "cdot" }, + { 0x22C6, "star" }, + { 0x22C7, "divideontimes" }, + { 0x22C8, "" }, + { 0x22C9, "ltimes" }, + { 0x22CA, "rtimes" }, + { 0x22CB, "leftthreetimes" }, + { 0x22CC, "rightthreetimes" }, + { 0x22CD, "backsimeq" }, + { 0x22CE, "curlyvee" }, + { 0x22CF, "curlywedge" }, + { 0x22D0, "Subset" }, + { 0x22D1, "Supset" }, + { 0x22D2, "Cap" }, + { 0x22D3, "Cup" }, + { 0x22D4, "pitchfork" }, + { 0x22D5, "" }, + { 0x22D6, "lessdot" }, + { 0x22D7, "gtrdot" }, + { 0x22D8, "lll" }, + { 0x22D9, "ggg" }, + { 0x22DA, "lesseqgtr" }, + { 0x22DB, "gtreqless" }, + { 0x22DC, "eqless" }, + { 0x22DD, "eqgtr" }, + { 0x22DE, "curlyeqprec" }, + { 0x22DF, "curlyeqsucc" }, + { 0x22E0, "" }, + { 0x22E1, "" }, + { 0x22E2, "" }, + { 0x22E3, "" }, + { 0x22E4, "" }, + { 0x22E5, "" }, + { 0x22E6, "lnsim" }, + { 0x22E7, "gnsim" }, + { 0x22E8, "precnsim" }, + { 0x22E9, "succnsim" }, + { 0x22EA, "ntriangleleft" }, + { 0x22EB, "ntriangleright" }, + { 0x22EC, "ntrianglelefteq" }, + { 0x22ED, "ntrianglerighteq" }, + { 0x22EE, "vdots" }, + { 0x22EF, "cdots" }, + { 0x22F0, "adots" }, + { 0x22F1, "ddots" }, + { 0x22F2, "" }, + { 0x22F3, "" }, + { 0x22F4, "" }, + { 0x22F5, "" }, + { 0x22F6, "" }, + { 0x22F7, "" }, + { 0x22F8, "" }, + { 0x22F9, "" }, + { 0x22FA, "" }, + { 0x22FB, "" }, + { 0x22FC, "" }, + { 0x22FD, "" }, + { 0x22FE, "" }, + { 0x22FF, "" }, + { 0, 0 } +}; + +KFORMULA_NAMESPACE_END -- cgit v1.2.1