diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-01-20 01:29:50 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-01-20 01:29:50 +0000 |
commit | 8362bf63dea22bbf6736609b0f49c152f975eb63 (patch) | |
tree | 0eea3928e39e50fae91d4e68b21b1e6cbae25604 /kformula | |
download | koffice-8362bf63dea22bbf6736609b0f49c152f975eb63.tar.gz koffice-8362bf63dea22bbf6736609b0f49c152f975eb63.zip |
Added old abandoned KDE3 version of koffice
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/koffice@1077364 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kformula')
34 files changed, 3716 insertions, 0 deletions
diff --git a/kformula/AUTHORS b/kformula/AUTHORS new file mode 100644 index 00000000..6d05ad35 --- /dev/null +++ b/kformula/AUTHORS @@ -0,0 +1 @@ +Andrea Rizzi <rizzi@kde.org> diff --git a/kformula/DESIGN b/kformula/DESIGN new file mode 100644 index 00000000..eec70869 --- /dev/null +++ b/kformula/DESIGN @@ -0,0 +1,297 @@ + + The design of kformula + (as we imagine it) + +The core of kformula is a tree of element objects that make up the +formula which is beeing edited. + +The element tree itself +####################### + +BasicElement +------------ + +All element classes are derived from this one. +So it provides the interface that is common to all elements. +BasicElement itself is an abstract class. You never want to create +objects from it. + +Responsebilities +(This goes for every derived element and therefore for each one.) + +- knows its children. Actually BasicElement doesn't have any. But it + already defines that children must be known by their parent. +- knows its bounding rectangle (its size.) The children are included + in this rect. (Only width and height are needed. Positions are + handled by the parent) +//- knows its middle line. (for alignment) +- knows it's zero point for midline (vertical alignment) and + keep open the possibility of negative positions (out of bounding rect) +- draws itself (given a painter); children are drawn, too +- knows all positions where the cursor is allowed to be. (see below) +- knows its parent; The topmost element has no parent; there is a + implicit garantie that the topmost element is always a + SequenceElement. +- can save and load itself. different formates. (see below) +- all children must be a SequenceElement. Except for SequenceElement's + children that might be of any type. +- might have its own color. +- might have its own font size (see below). + + +SequenceElement from BasicElement +--------------- + +Manages a list of children. The children are aligned horizontally at +one middle line. No gaps, no overlaps. + +Has no own look. It just draws all its children and is done. Except if +its empty. It looks like an empty space then (i.e. a little square) + +Has n+1 valid cursor positions where n is the number of +children. These are before, between and after the children. + +May contain any (type of) element as child + +except SequenceElements if they contains a SequenceElement they merge +it in the list + +They can handle splitting of the sequence to allow "select an put selected item +between parenthesis" i.e. as content child of a delimiterelement) + + +FormulaElement from SequenceElement +-------------- + +The only element those parent is null. The root of the element object +tree. + +This is the element that is created by the KFormulaDoc and that knows +about it. As every other element knows its parent and therefore the +FormulaElement we get a chance to pass messages to the outside world. + + +RootElement from BasicElement +----------- + +contains two children. content and index. index is optional. + + +IndexElement from BasicElement +------------ + +contains five children. content and four indexes. all indexes are +optional. If there is no index the element might be replaced by its content. + + +TextElement from BasicElement +----------- + +contains one char and no children at all. + + +Might have its own font and size. But preferes to use a reasonalbe +font and size that are calculated from its parents font and a given +scheme (see below). + + +DelimiterElement from BasicElement +---------------- + +contains one child and draws delimiters around it. You are free to +choose with. + + +FractionElement from BasicElement +--------------- + +2 children: numerator, denominator + + +DecorationElement from BasicElement +----------------- + +A piece of art. It has one child and decorates it above (or below or +both) with some nice decor. Some decor might be required to be as +width as the content. There is a way to guarantee this. + +We could even add yet another child that can optionally be shown at +the other side of the decoration. + + +SumIntegralElement from BasicElement //PrefixedElement +------------------ + +draws all sorts of mathematical symbols with three children. Above, +below (or whereever the indices and limits go)and to the right. + + +GeometryElement from BasicElement +--------------- + +One child. +Draw it at a fixed position relative to parent or absolute. +This is to do dirty things. + +This element must not be used, kformula will provide you everything +without the use of this kind of element, any way for strange reasons +you want to do things that are not usually allowed and that are not +typical of a math formula. +[We will decide if implement this element or not] + + +MatrixElement from BasicElement +------------- + +A matrix of children. +With all align stuff, internal borders etc, matrix dots handling (i.e. +those dots or lines that complete the matrix, not well handled in TeX), +etc.. + +SpaceElement from BasicElement +------------ + +No children at all. Provides the facility to insert horizontal spaces +in the formula. (therefore it is similar to TextElement.) + + +OperatorElement from TextElement +--------------- + +The element to be used for all kinds of operators. It needed because +operators require some space before and after and are therefore no +simple text. + +They can you pixamps inestead of fonts, the use of pixmaps is needed only +to give the user the possibilty of introduce its strange operator that we +do not provide as a font. There problems with the scalability but we will +include as fonts (or vectorial images) in kformula all TeX operators so we +hope there is no need to use pixamps for a standard use of KFormula + +Navigation +########## + +There is a class Cursor that implements a pointer to a valid cursor +position inside the formula structure. Each kformula view needs to +have its own object of this class. + +The Cursor class uses the elements facility to travel throught the +structure. (It gives the key to the current element and asks for the +new position.) + +If the cursor points into an element this element is said to own the +cursor. There are a few rules that describe how new cursor positions +are calculated given the current key: + +- An elements cursor positions are its children. The element might not +own the cursor except when it is owned by one of its children. The +only exception is SequenceElement which has valid cursor positions +before, between and after its children, too. + +(Therefore the cursor is always owned by a SequenceElement.) + +- Each element's children are ordered. If the cursor leaves one child +the next child it. The direction depends on the key that moved the +cursor. If there is child left the cursor is passed to the parent. + +- If the cursor comes from our parent the first or the last child gets +it. Depending on the direction in which the cursor moved. + +Please note that because each element knows its own cursor positions +and how to behave, it is possible for each combination of elements to +work together correctly. + + + +Save and Load (Import/Export) +############################# + +there are quite a few formats we want to read and write: + +Built in: +- native koffice xml + +Import/Export filters +- MathML +- C like math strings +- LaTeX + + + +Element templates +################# + +example: you can create a template to write limits: +it is a "lim ( )" string over 2 empty elements with an arrows that separe +them + + + +"Look" templates +################ + +There need to be templates that tell which font to use, how the sizes +differ among different elements and what spaces are to be +included. (And much more.) + +Your only need to choose one of them to get a reasonable good look. + + + +Interface templates +################### + +Decide what KAction have to be toolbars, +what element templates must be loaded, what toolbar display.... +There will be predefined (sorry for the spelling error) templates for +-General... +-Physics (Vectors , integral, partial derivative etc are preferred..) +-Analysis (Integral and diff equation stuff) +-Geometry (Tensor product etc) +-Chemistry (Arrows, Periodic table external toolbar) +-Computer science (...) +-???? + + + +Context sensibility +################### + +We want a formula to look different according to its +surroundings. (Most obviosly according to the available height and/or width.) + +It would be great to get something like automatic operator +alignment. So if you type some formulas each on its own line the +assigment operators should be automatically in a column. (If the user +turns this on.) + + + +Fonts and font size (2 ideas) +################### + +1) +Each element know its font family (also if it is not a text element) so that it +can give this font to its children. + +The font size is calculated starting from a global scale factor and appling to it +a local size modifier (like HTML -2, -1,+3,etc..), this also calculate the +QPen width for vector drawn stuff (like root symbol etc) and it gives a scale +factor for pixmap. + +2) +When it comes to drawing we pass a StyleContext to the +FormulaElement. The StyleContext contains the font family to use, the +normal font size, the spaces to include between certain elements and +all sorts of context information that is needed to draw the +formula. As it is passed down the tree it also counts the current level +so it can tell each element the font size it is supposed to use. + +The elements use this information to calculate their sizes and to draw +themselves. Each element is allowed to choose different settings for +whatever reason. But if the formula looks ugly then its the elements +blame. + + +Andrea Rizzi <rizzi@kde.org> +Ulrich Kuettler <ulrich.kuettler@mailbox.tu-dresden.de> diff --git a/kformula/Makefile.am b/kformula/Makefile.am new file mode 100644 index 00000000..e291a340 --- /dev/null +++ b/kformula/Makefile.am @@ -0,0 +1,41 @@ +INCLUDES = $(KOFFICE_INCLUDES) $(KFORMULA_INCLUDES) $(KOTEXT_INCLUDES) -I$(interfacedir) $(all_includes) +KDE_CXXFLAGS = $(USE_RTTI) + +## The part +kde_module_LTLIBRARIES = libkformulapart.la +libkformulapart_la_SOURCES = kformula_doc.cc \ + kformula_view.cc kformula_factory.cc kformulawidget.cc kfconfig.cc \ + kformula_view_iface.skel kformula_view_iface.cc formulastring.cc fsparser.cc +libkformulapart_la_LDFLAGS = $(KDE_PLUGIN) +libkformulapart_la_LIBADD = $(LIB_KOFFICEUI) $(LIB_KFORMULA) $(LIB_KOTEXT) +libkformulapart_la_METASOURCES = AUTO + +## The kdeinit loadable module +kdeinit_LTLIBRARIES = kformula.la +kformula_la_SOURCES = main.cc +kformula_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +kformula_la_LIBADD = $(LIB_KOFFICECORE) + +bin_PROGRAMS = +lib_LTLIBRARIES = + +noinst_HEADERS = kformula_doc.h \ + kformula_view.h kformula_factory.h \ + kformula_aboutdata.h kformula_view_iface.h formulastring.h fsparser.h + +xdg_apps_DATA = kformula.desktop + +rc_DATA = kformula.rc kformula_readonly.rc +rcdir = $(kde_datadir)/kformula + +SUBDIRS = pics + +tipdir = $(kde_datadir)/kformula +tip_DATA = tips + +messages: rc.cpp + $(PREPARETIPS) >> rc.cpp + $(XGETTEXT) rc.cpp *.cc kformula_aboutdata.h -o $(podir)/kformula.pot +kde_services_DATA = kformulapart.desktop + +include $(top_srcdir)/admin/Doxyfile.am diff --git a/kformula/TODO b/kformula/TODO new file mode 100644 index 00000000..fd957f95 --- /dev/null +++ b/kformula/TODO @@ -0,0 +1,17 @@ +2004-08-30 + +Oasis format: +------------- +todo: +----- +-> Load oasis format + +Done: +----- +-> Save oasis format + +In progress: +------------ +I don't know if libkformula implement 100% MathML format + +Laurent Montel <montel@kde.org> diff --git a/kformula/formulastring.cc b/kformula/formulastring.cc new file mode 100644 index 00000000..b73603db --- /dev/null +++ b/kformula/formulastring.cc @@ -0,0 +1,118 @@ +/* This file is part of the KDE project + Copyright (C) 2002 Ulrich Kuettler <ulrich.kuettler@mailbox.tu-dresden.de> + + 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 <qlabel.h> +#include <qlayout.h> +#include <qstringlist.h> +#include <qtextedit.h> +#include <qtooltip.h> +#include <qvariant.h> +#include <qwhatsthis.h> + +#include <kapplication.h> +#include <kmessagebox.h> +#include <klocale.h> +#include <kstdguiitem.h> +#include <kpushbutton.h> + +#include "formulastring.h" +#include "kformula_view.h" + + +FormulaString::FormulaString( KFormulaPartView* parent, const char* name, bool modal, WFlags fl ) + : QDialog( parent, name, modal, fl ), view( parent ) +{ + if ( !name ) + setName( "FormulaString" ); + resize( 511, 282 ); + setCaption( i18n( "Formula String" ) ); + setSizeGripEnabled( TRUE ); + QVBoxLayout* FormulaStringLayout = new QVBoxLayout( this, 11, 6, "FormulaStringLayout"); + + textWidget = new QTextEdit( this, "textWidget" ); + FormulaStringLayout->addWidget( textWidget ); + + QHBoxLayout* Layout2 = new QHBoxLayout( 0, 0, 6, "Layout2"); + QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum ); + Layout2->addItem( spacer ); + + position = new QLabel( this, "position" ); + position->setText( trUtf8( "1:1" ) ); + Layout2->addWidget( position ); + FormulaStringLayout->addLayout( Layout2 ); + + QHBoxLayout* Layout1 = new QHBoxLayout( 0, 0, 6, "Layout1"); + + buttonHelp = new KPushButton( KStdGuiItem::help(), this, "buttonHelp" ); + buttonHelp->setAccel( 4144 ); + buttonHelp->setAutoDefault( TRUE ); + Layout1->addWidget( buttonHelp ); + spacer = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum ); + Layout1->addItem( spacer ); + + buttonOk = new KPushButton( KStdGuiItem::ok(), this, "buttonOk" ); + buttonOk->setAccel( 0 ); + buttonOk->setAutoDefault( TRUE ); + buttonOk->setDefault( TRUE ); + Layout1->addWidget( buttonOk ); + + buttonCancel = new KPushButton( KStdGuiItem::cancel(), this, "buttonCancel" ); + buttonCancel->setAccel( 0 ); + buttonCancel->setAutoDefault( TRUE ); + Layout1->addWidget( buttonCancel ); + FormulaStringLayout->addLayout( Layout1 ); + + // signals and slots connections + connect( buttonOk, SIGNAL( clicked() ), this, SLOT( accept() ) ); + connect( buttonCancel, SIGNAL( clicked() ), this, SLOT( reject() ) ); + connect( buttonHelp, SIGNAL(clicked() ), this, SLOT( helpButtonClicked() ) ); + connect( textWidget, SIGNAL( cursorPositionChanged( int, int ) ), + this, SLOT( cursorPositionChanged( int, int ) ) ); +} + +/* + * Destroys the object and frees any allocated resources + */ +FormulaString::~FormulaString() +{ + // no need to delete child widgets, Qt does it all for us +} + +void FormulaString::accept() +{ + QStringList errorList = view->readFormulaString( textWidget->text() ); + if ( errorList.count() == 0 ) { + QDialog::accept(); + } + else { + KMessageBox::sorry( this, errorList.join( "\n" ), i18n( "Parser Error" ) ); + } +} + +void FormulaString::helpButtonClicked() +{ + kapp->invokeHelp( "formula-strings", "kformula" ); +} + +void FormulaString::cursorPositionChanged( int para, int pos ) +{ + position->setText( QString( "%1:%2" ).arg( para+1 ).arg( pos+1 ) ); +} + +#include "formulastring.moc" diff --git a/kformula/formulastring.h b/kformula/formulastring.h new file mode 100644 index 00000000..3cfdbf9d --- /dev/null +++ b/kformula/formulastring.h @@ -0,0 +1,60 @@ +/* This file is part of the KDE project + Copyright (C) 2002 Ulrich Kuettler <ulrich.kuettler@mailbox.tu-dresden.de> + + 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. +*/ + +#ifndef FORMULASTRING_H +#define FORMULASTRING_H + +#include <qvariant.h> +#include <qdialog.h> + +class QGridLayout; +class QHBoxLayout; +class QLabel; +class QPushButton; +class QTextEdit; +class QVBoxLayout; + +class KFormulaPartView; + +class FormulaString : public QDialog +{ + Q_OBJECT + +public: + FormulaString( KFormulaPartView* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~FormulaString(); + + QTextEdit* textWidget; + QPushButton* buttonHelp; + QPushButton* buttonOk; + QPushButton* buttonCancel; + QLabel* position; + +protected slots: + + virtual void accept (); + void helpButtonClicked(); + + void cursorPositionChanged ( int para, int pos ); + +private: + KFormulaPartView* view; +}; + +#endif // FORMULASTRING_H diff --git a/kformula/fsparser.cc b/kformula/fsparser.cc new file mode 100644 index 00000000..4b7f1c88 --- /dev/null +++ b/kformula/fsparser.cc @@ -0,0 +1,829 @@ +/* This file is part of the KDE project + Copyright (C) 2002 Ulrich Kuettler <ulrich.kuettler@mailbox.tu-dresden.de> + + 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 <qptrlist.h> + +#include <kdebug.h> +#include <klocale.h> + +#include <kformuladefs.h> +#include <kformuladocument.h> +#include <symboltable.h> + +#include "fsparser.h" + + +using namespace std; + +class ParserNode { +public: + ParserNode() { debugCount++; } + virtual ~ParserNode() { debugCount--; } + //virtual void output( ostream& ) = 0; + virtual void buildXML( QDomDocument& doc, QDomElement element ) = 0; + virtual bool isSimple() { return false; } + + static int debugCount; +}; + +int ParserNode::debugCount = 0; + +class PrimaryNode : public ParserNode { +public: + PrimaryNode( QString primary ) : m_primary( primary ), m_functionName( false ) {} + //virtual void output( ostream& stream ) { stream << "PrimaryNode {" << m_primary << "}" << endl; } + virtual void buildXML( QDomDocument& doc, QDomElement element ); + virtual bool isSimple() { return true; } + void setUnicode( QChar unicode ) { m_unicode = unicode; } + void setFunctionName( bool functionName ) { m_functionName = functionName; } + QString primary() const { return m_primary; } +private: + QString m_primary; + QChar m_unicode; + bool m_functionName; +}; + +void PrimaryNode::buildXML( QDomDocument& doc, QDomElement element ) +{ + if ( m_unicode != QChar::null ) { + QDomElement de = doc.createElement( "TEXT" ); + de.setAttribute( "CHAR", QString( m_unicode ) ); + de.setAttribute( "SYMBOL", "3" ); + element.appendChild( de ); + } + else { + if ( m_functionName ) { + QDomElement namesequence = doc.createElement( "NAMESEQUENCE" ); + element.appendChild( namesequence ); + element = namesequence; + } + for ( uint i = 0; i < m_primary.length(); i++ ) { + QDomElement de = doc.createElement( "TEXT" ); + de.setAttribute( "CHAR", QString( m_primary[i] ) ); + element.appendChild( de ); + } + } +} + +class UnaryMinus : public ParserNode { +public: + UnaryMinus( ParserNode* primary ) : m_primary( primary ) {} + ~UnaryMinus() { delete m_primary; } + virtual void buildXML( QDomDocument& doc, QDomElement element ); +private: + ParserNode* m_primary; +}; + +void UnaryMinus::buildXML( QDomDocument& doc, QDomElement element ) +{ + QDomElement de = doc.createElement( "TEXT" ); + de.setAttribute( "CHAR", "-" ); + element.appendChild( de ); + m_primary->buildXML( doc, element ); +} + +class OperatorNode : public ParserNode { +public: + OperatorNode( QString type, ParserNode* lhs, ParserNode* rhs ) + : m_type( type ), m_lhs( lhs ), m_rhs( rhs ) {} + ~OperatorNode() { delete m_rhs; delete m_lhs; } +// virtual void output( ostream& stream ) { +// stream << "OperatorNode {"; +// m_lhs->output( stream ); stream << m_type; m_rhs->output( stream ); +// stream << "}" << endl; } +protected: + QString m_type; + ParserNode* m_lhs; + ParserNode* m_rhs; +}; + +class AssignNode : public OperatorNode { +public: + AssignNode( QString type, ParserNode* lhs, ParserNode* rhs ) : OperatorNode( type, lhs, rhs ) {} + virtual void buildXML( QDomDocument& doc, QDomElement element ); +}; + +void AssignNode::buildXML( QDomDocument& doc, QDomElement element ) +{ + m_lhs->buildXML( doc, element ); + QDomElement de = doc.createElement( "TEXT" ); + de.setAttribute( "CHAR", QString( m_type ) ); + element.appendChild( de ); + m_rhs->buildXML( doc, element ); +} + +class ExprNode : public OperatorNode { +public: + ExprNode( QString type, ParserNode* lhs, ParserNode* rhs ) : OperatorNode( type, lhs, rhs ) {} + virtual void buildXML( QDomDocument& doc, QDomElement element ); +}; + +void ExprNode::buildXML( QDomDocument& doc, QDomElement element ) +{ + m_lhs->buildXML( doc, element ); + QDomElement de = doc.createElement( "TEXT" ); + de.setAttribute( "CHAR", QString( m_type ) ); + element.appendChild( de ); + m_rhs->buildXML( doc, element ); +} + +class TermNode : public OperatorNode { +public: + TermNode( QString type, ParserNode* lhs, ParserNode* rhs ) : OperatorNode( type, lhs, rhs ) {} + virtual void buildXML( QDomDocument& doc, QDomElement element ); +}; + +void TermNode::buildXML( QDomDocument& doc, QDomElement element ) +{ + if ( m_type == "*" ) { + m_lhs->buildXML( doc, element ); + QDomElement de = doc.createElement( "TEXT" ); + de.setAttribute( "CHAR", QString( m_type ) ); + element.appendChild( de ); + m_rhs->buildXML( doc, element ); + } + else { + QDomElement fraction = doc.createElement( "FRACTION" ); + QDomElement numerator = doc.createElement( "NUMERATOR" ); + QDomElement sequence = doc.createElement( "SEQUENCE" ); + m_lhs->buildXML( doc, sequence ); + numerator.appendChild( sequence ); + fraction.appendChild( numerator ); + QDomElement denominator = doc.createElement( "DENOMINATOR" ); + sequence = doc.createElement( "SEQUENCE" ); + m_rhs->buildXML( doc, sequence ); + denominator.appendChild( sequence ); + fraction.appendChild( denominator ); + element.appendChild( fraction ); + } +} + + +class PowerNode : public OperatorNode { +public: + PowerNode( QString type, ParserNode* lhs, ParserNode* rhs ) : OperatorNode( type, lhs, rhs ) {} + virtual void buildXML( QDomDocument& doc, QDomElement element ); +}; + +void PowerNode::buildXML( QDomDocument& doc, QDomElement element ) +{ + QDomElement index = doc.createElement( "INDEX" ); + QDomElement content = doc.createElement( "CONTENT" ); + QDomElement sequence = doc.createElement( "SEQUENCE" ); + content.appendChild( sequence ); + index.appendChild( content ); + + if ( !m_lhs->isSimple() ) { + QDomElement bracket = doc.createElement( "BRACKET" ); + bracket.setAttribute( "LEFT", '(' ); + bracket.setAttribute( "RIGHT", ')' ); + sequence.appendChild( bracket ); + + content = doc.createElement( "CONTENT" ); + bracket.appendChild( content ); + + sequence = doc.createElement( "SEQUENCE" ); + content.appendChild( sequence ); + } + m_lhs->buildXML( doc, sequence ); + if ( m_type == "_" ) { + QDomElement lowerRight = doc.createElement( "LOWERRIGHT" ); + sequence = doc.createElement( "SEQUENCE" ); + m_rhs->buildXML( doc, sequence ); + lowerRight.appendChild( sequence ); + index.appendChild( lowerRight ); + } + else { + QDomElement upperRight = doc.createElement( "UPPERRIGHT" ); + sequence = doc.createElement( "SEQUENCE" ); + m_rhs->buildXML( doc, sequence ); + upperRight.appendChild( sequence ); + index.appendChild( upperRight ); + } + element.appendChild( index ); +} + + +class FunctionNode : public ParserNode { +public: + FunctionNode( PrimaryNode* name, QPtrList<ParserNode>& args ) : m_name( name ), m_args( args ) { + m_args.setAutoDelete( true ); + } + ~FunctionNode() { delete m_name; } + //virtual void output( ostream& stream ); + virtual void buildXML( QDomDocument& doc, QDomElement element ); +private: + void buildSymbolXML( QDomDocument& doc, QDomElement element, KFormula::SymbolType type ); + PrimaryNode* m_name; + QPtrList<ParserNode> m_args; +}; + +void FunctionNode::buildSymbolXML( QDomDocument& doc, QDomElement element, KFormula::SymbolType type ) +{ + QDomElement symbol = doc.createElement( "SYMBOL" ); + symbol.setAttribute( "TYPE", type ); + QDomElement content = doc.createElement( "CONTENT" ); + QDomElement sequence = doc.createElement( "SEQUENCE" ); + m_args.at( 0 )->buildXML( doc, sequence ); + content.appendChild( sequence ); + symbol.appendChild( content ); + if ( m_args.count() > 2 ) { + ParserNode* lowerLimit = m_args.at( m_args.count()-2 ); + ParserNode* upperLimit = m_args.at( m_args.count()-1 ); + + QDomElement lower = doc.createElement( "LOWER" ); + sequence = doc.createElement( "SEQUENCE" ); + lowerLimit->buildXML( doc, sequence ); + lower.appendChild( sequence ); + symbol.appendChild( lower ); + + QDomElement upper = doc.createElement( "UPPER" ); + sequence = doc.createElement( "SEQUENCE" ); + upperLimit->buildXML( doc, sequence ); + upper.appendChild( sequence ); + symbol.appendChild( upper ); + } + element.appendChild( symbol ); +} + +void FunctionNode::buildXML( QDomDocument& doc, QDomElement element ) +{ + if ( ( m_name->primary() == "sqrt" ) && ( m_args.count() == 1 ) ) { + QDomElement root = doc.createElement( "ROOT" ); + QDomElement content = doc.createElement( "CONTENT" ); + QDomElement sequence = doc.createElement( "SEQUENCE" ); + m_args.at( 0 )->buildXML( doc, sequence ); + content.appendChild( sequence ); + root.appendChild( content ); + element.appendChild( root ); + } + else if ( ( m_name->primary() == "pow" ) && ( m_args.count() == 2 ) ) { + QDomElement index = doc.createElement( "INDEX" ); + QDomElement content = doc.createElement( "CONTENT" ); + QDomElement sequence = doc.createElement( "SEQUENCE" ); + m_args.at( 0 )->buildXML( doc, sequence ); + content.appendChild( sequence ); + index.appendChild( content ); + QDomElement upperRight = doc.createElement( "UPPERRIGHT" ); + sequence = doc.createElement( "SEQUENCE" ); + m_args.at( 1 )->buildXML( doc, sequence ); + upperRight.appendChild( sequence ); + index.appendChild( upperRight ); + element.appendChild( index ); + } + else if ( ( m_name->primary() == "sum" ) && ( m_args.count() > 0 ) ) { + buildSymbolXML( doc, element, KFormula::Sum ); + } + else if ( ( m_name->primary() == "prod" ) && ( m_args.count() > 0 ) ) { + buildSymbolXML( doc, element, KFormula::Product ); + } + else if ( ( ( m_name->primary() == "int" ) || + ( m_name->primary() == "integrate" ) || + ( m_name->primary() == "quad" ) ) + && ( m_args.count() > 0 ) ) { + buildSymbolXML( doc, element, KFormula::Integral ); + } + else { + m_name->buildXML( doc, element ); + QDomElement bracket = doc.createElement( "BRACKET" ); + bracket.setAttribute( "LEFT", '(' ); + bracket.setAttribute( "RIGHT", ')' ); + QDomElement content = doc.createElement( "CONTENT" ); + QDomElement sequence = doc.createElement( "SEQUENCE" ); + + for ( uint i = 0; i < m_args.count(); i++ ) { + m_args.at( i )->buildXML( doc, sequence ); + if ( i < m_args.count()-1 ) { + QDomElement de = doc.createElement( "TEXT" ); + de.setAttribute( "CHAR", "," ); + sequence.appendChild( de ); + } + } + + content.appendChild( sequence ); + bracket.appendChild( content ); + element.appendChild( bracket ); + } +} + +// void FunctionNode::output( ostream& stream ) +// { +// m_name->output( stream ); +// for ( uint i = 0; i < m_args.count(); i++ ) { +// m_args.at( i )->output( stream ); +// } +// } + +class RowNode : public ParserNode { +public: + RowNode( QPtrList<ParserNode> row ) : m_row( row ) { m_row.setAutoDelete( true ); } + //virtual void output( ostream& stream ); + virtual void buildXML( QDomDocument& doc, QDomElement element ); + uint columns() const { return m_row.count(); } + void setRequiredColumns( uint requiredColumns ) { m_requiredColumns = requiredColumns; } +private: + QPtrList<ParserNode> m_row; + uint m_requiredColumns; +}; + +void RowNode::buildXML( QDomDocument& doc, QDomElement element ) +{ + for ( uint i = 0; i < m_requiredColumns; i++ ) { + QDomElement sequence = doc.createElement( "SEQUENCE" ); + if ( i < m_row.count() ) { + m_row.at( i )->buildXML( doc, sequence ); + } + else { + QDomElement de = doc.createElement( "TEXT" ); + de.setAttribute( "CHAR", "0" ); + sequence.appendChild( de ); + } + element.appendChild( sequence ); + } +} + +// void RowNode::output( ostream& stream ) +// { +// stream << "["; +// for ( uint i = 0; i < m_row.count(); i++ ) { +// m_row.at( i )->output( stream ); +// if ( i < m_row.count()-1 ) { +// stream << ", "; +// } +// } +// stream << "]"; +// } + +class MatrixNode : public ParserNode { +public: + MatrixNode( QPtrList<RowNode> rows ) : m_rows( rows ) { m_rows.setAutoDelete( true ); } + //virtual void output( ostream& stream ); + virtual void buildXML( QDomDocument& doc, QDomElement element ); + virtual bool isSimple() { return true; } + uint columns(); + uint rows() { return m_rows.count(); } +private: + QPtrList<RowNode> m_rows; +}; + +uint MatrixNode::columns() +{ + uint columns = 0; + for ( uint i = 0; i < m_rows.count(); i++ ) { + columns = QMAX( columns, m_rows.at( i )->columns() ); + } + return columns; +} + +void MatrixNode::buildXML( QDomDocument& doc, QDomElement element ) +{ + QDomElement bracket = doc.createElement( "BRACKET" ); + bracket.setAttribute( "LEFT", '(' ); + bracket.setAttribute( "RIGHT", ')' ); + QDomElement content = doc.createElement( "CONTENT" ); + QDomElement sequence = doc.createElement( "SEQUENCE" ); + + uint cols = columns(); + QDomElement matrix = doc.createElement( "MATRIX" ); + matrix.setAttribute( "ROWS", m_rows.count() ); + matrix.setAttribute( "COLUMNS", cols ); + for ( uint i = 0; i < m_rows.count(); i++ ) { + m_rows.at( i )->setRequiredColumns( cols ); + m_rows.at( i )->buildXML( doc, matrix ); + matrix.appendChild( doc.createComment( "end of row" ) ); + } + sequence.appendChild( matrix ); + content.appendChild( sequence ); + bracket.appendChild( content ); + element.appendChild( bracket ); +} + +// void MatrixNode::output( ostream& stream ) +// { +// stream << "["; +// for ( uint i = 0; i < m_rows.count(); i++ ) { +// m_rows.at( i )->output( stream ); +// if ( i < m_rows.count()-1 ) { +// stream << ", "; +// } +// } +// stream << "]"; +// } + + +FormulaStringParser::FormulaStringParser( const KFormula::SymbolTable& symbolTable, QString formula ) + : m_symbolTable( symbolTable ), m_formula( formula ), + pos( 0 ), line( 1 ), column( 1 ), m_newlineIsSpace( true ) +{ +} + +FormulaStringParser::~FormulaStringParser() +{ + delete head; + if ( ParserNode::debugCount != 0 ) { + kdDebug( KFormula::DEBUGID ) << "ParserNode::debugCount = " << ParserNode::debugCount << endl; + } +} + +QDomDocument FormulaStringParser::parse() +{ + nextToken(); + head = parseAssign(); + //head->output( cout ); + if ( !eol() ) { + error( QString( i18n( "Aborted parsing at %1:%2" ) ).arg( line ).arg( column ) ); + } + + QDomDocument doc = KFormula::Document::createDomDocument(); + QDomElement root = doc.documentElement(); + QDomElement de = doc.createElement( "FORMULA" ); + // here comes the current version of FormulaElement + //de.setAttribute( "VERSION", "4" ); + head->buildXML( doc, de ); + root.appendChild(de); + + kdDebug( 39001 ) << doc.toString() << endl; + return doc; +} + +ParserNode* FormulaStringParser::parseAssign() +{ + ParserNode* lhs = parseExpr(); + for ( ;; ) { + switch ( currentType ) { + case ASSIGN: { + QString c = current; + nextToken(); + lhs = new AssignNode( c, lhs, parseExpr() ); + break; + } + default: + return lhs; + } + } +} + +ParserNode* FormulaStringParser::parseExpr() +{ + ParserNode* lhs = parseTerm(); + for ( ;; ) { + switch ( currentType ) { + case PLUS: + case SUB: { + QString c = current; + nextToken(); + lhs = new ExprNode( c, lhs, parseTerm() ); + break; + } + default: + return lhs; + } + } +} + +ParserNode* FormulaStringParser::parseTerm() +{ + ParserNode* lhs = parsePower(); + for ( ;; ) { + switch ( currentType ) { + case MUL: + case DIV: { + QString c = current; + nextToken(); + lhs = new TermNode( c, lhs, parsePower() ); + break; + } + default: + return lhs; + } + } +} + +ParserNode* FormulaStringParser::parsePower() +{ + ParserNode* lhs = parsePrimary(); + for ( ;; ) { + switch ( currentType ) { + case INDEX: + case POW: { + QString c = current; + nextToken(); + lhs = new PowerNode( c, lhs, parsePrimary() ); + break; + } + default: + return lhs; + } + } +} + +ParserNode* FormulaStringParser::parsePrimary() +{ + switch ( currentType ) { + case NUMBER: { + PrimaryNode* node = new PrimaryNode( current ); + nextToken(); + return node; + } + case NAME: { + PrimaryNode* node = new PrimaryNode( current ); + node->setUnicode( m_symbolTable.unicode( current ) ); + nextToken(); + if ( currentType == LP ) { + nextToken(); + QPtrList<ParserNode> args; + args.setAutoDelete( false ); + while ( ( currentType != EOL ) && ( currentType != RP ) ) { + ParserNode* node = parseExpr(); + args.append( node ); + if ( currentType == COMMA ) { + nextToken(); + } + } + expect( RP, QString( i18n( "'%3' expected at %1:%2" ) ).arg( line ).arg( column ).arg( ")" ) ); + node->setFunctionName( true ); + return new FunctionNode( node, args ); + } + return node; + } + case SUB: { + nextToken(); + //ParserNode* node = new UnaryMinus( parsePrimary() ); + ParserNode* node = new UnaryMinus( parseTerm() ); + return node; + } + case LP: { + nextToken(); + ParserNode* node = parseExpr(); + expect( RP, QString( i18n( "'%3' expected at %1:%2" ) ).arg( line ).arg( column ).arg( ")" ) ); + return node; + } + case LB: { + nextToken(); + QPtrList<RowNode> rows; + rows.setAutoDelete( false ); + bool innerBrackets = currentType == LB; + m_newlineIsSpace = innerBrackets; + while ( ( currentType != EOL ) && ( currentType != RB ) ) { + if ( innerBrackets ) { + expect( LB, QString( i18n( "'%3' expected at %1:%2" ) ).arg( line ).arg( column ).arg( "[" ) ); + } + QPtrList<ParserNode> row; + row.setAutoDelete( false ); + while ( ( currentType != EOL ) && ( currentType != RB ) && + ( innerBrackets || ( currentType != SEMIC && currentType != NEWLINE ) ) ) { + row.append( parseExpr() ); + if ( currentType == COMMA ) { + nextToken(); + } + } + if ( innerBrackets ) { + expect( RB, QString( i18n( "'%3' expected at %1:%2" ) ).arg( line ).arg( column ).arg( "]" ) ); + if ( currentType == COMMA ) { + nextToken(); + } + } + else { + if ( currentType != RB ) { + if ( currentType == NEWLINE ) { + nextToken(); + } + else { + expect( SEMIC, QString( i18n( "'%3' expected at %1:%2" ) ).arg( line ).arg( column ).arg( ";" ) ); + } + } + } + rows.append( new RowNode( row ) ); + } + m_newlineIsSpace = true; + expect( RB, QString( i18n( "'%3' expected at %1:%2" ) ).arg( line ).arg( column ).arg( "]" ) ); + MatrixNode* node = new MatrixNode( rows ); + if ( node->columns() == 0 ) { + error( QString( i18n( "Null columns in Matrix at %1:%2" ) ).arg( line ).arg( column ) ); + } + if ( node->rows() == 0 ) { + error( QString( i18n( "Null rows in Matrix at %1:%2" ) ).arg( line ).arg( column ) ); + } + return node; + } + case OTHER: { + ParserNode* node = new PrimaryNode( current ); + nextToken(); + return node; + } + default: + error( QString( i18n( "Unexpected token at %1:%2" ) ).arg( line ).arg( column ) ); + return new PrimaryNode( "?" ); + } +} + +void FormulaStringParser::expect( TokenType type, QString msg ) +{ + if ( currentType == type ) { + nextToken(); + } + else { + error( msg ); + } +} + +QString FormulaStringParser::nextToken() +{ + // We skip any ' or " so that we can parse string literals. + while ( !eol() && ( m_formula[pos].isSpace() || + ( m_formula[pos] == '"' ) || + ( m_formula[pos] == '\'' ) ) ) { + if ( m_formula[pos] == '\n' ) { + line++; + if ( m_newlineIsSpace ) { + column = 0; + } + else { + pos++; + column = 1; + currentType = NEWLINE; + return current = "\n"; + } + } + pos++; column++; + } + if ( eol() ) { + currentType = EOL; + return QString::null; + } + if ( m_formula[pos].isDigit() || m_formula[pos] == '.' ) { + uint begin = pos; + readNumber(); + currentType = NUMBER; + current = m_formula.mid( begin, pos-begin ); + if ( current[0] == '.' ) { + current = "0" + current; + } + if ( current[current.length()-1] == '.' ) { + current = current + "0"; + } + return current; + } + else if ( m_formula[pos].isLetter() ) { + uint begin = pos; + pos++; column++; + while ( !eol() && m_formula[pos].isLetter() ) { + pos++; column++; + } + currentType = NAME; + return current = m_formula.mid( begin, pos-begin ); + } + else { + switch ( m_formula[pos].latin1() ) { + case '+': + pos++; column++; + currentType = PLUS; + return current = "+"; + case '-': + pos++; column++; + currentType = SUB; + return current = "-"; + case '*': + pos++; column++; + if ( !eol() && m_formula[pos] == '*' ) { + pos++; column++; + currentType = POW; + return current = "**"; + } + currentType = MUL; + return current = "*"; + case '/': + pos++; column++; + currentType = DIV; + return current = "/"; + case '^': + pos++; column++; + currentType = POW; + return current = "**"; + case '_': + pos++; column++; + currentType = INDEX; + return current = "_"; + case '(': + pos++; column++; + currentType = LP; + return current = "("; + case ')': + pos++; column++; + currentType = RP; + return current = ")"; + case '[': + pos++; column++; + currentType = LB; + return current = "["; + case ']': + pos++; column++; + currentType = RB; + return current = "]"; + case ',': + pos++; column++; + currentType = COMMA; + return current = ","; + case ';': + pos++; column++; + currentType = SEMIC; + return current = ";"; + case '=': + pos++; column++; + currentType = ASSIGN; + return current = "="; + default: + pos++; column++; + currentType = OTHER; + return current = m_formula.mid( pos-1, 1 ); + } + } +} + +void FormulaStringParser::readNumber() +{ + bool digitsBeforeDot = m_formula[pos] != '.'; + + readDigits(); + if ( pos < m_formula.length()-1 ) { + QChar ch = m_formula[pos]; + + // Look for a dot. + if ( ch == '.' ) { + pos++; + column++; + ch = m_formula[pos]; + if ( ch.isDigit() ) { + readDigits(); + } + else if ( !digitsBeforeDot ) { + error( QString( i18n( "A single '.' is not a number at %1:%2" ) ).arg( line ).arg( column ) ); + return; + } + } + + // there might as well be an exponent + if ( pos < m_formula.length()-1 ) { + ch = m_formula[pos]; + if ( ( ch == 'E' ) || ( ch == 'e' ) ) { + pos++; + column++; + ch = m_formula[pos]; + + // signs are allowed after the exponent + if ( ( ( ch == '+' ) || ( ch == '-' ) ) && + ( pos < m_formula.length()-1 ) ) { + pos++; + column++; + ch = m_formula[pos]; + if ( ch.isDigit() ) { + readDigits(); + } + else { + pos -= 2; + column -= 2; + return; + } + } + else if ( ch.isDigit() ) { + readDigits(); + } + else { + pos--; + column--; + } + } + } + } +} + + +void FormulaStringParser::readDigits() +{ + while ( !eol() && m_formula[pos].isDigit() ) { + pos++; + column++; + } +} + +void FormulaStringParser::error( QString err ) +{ + kdDebug( KFormula::DEBUGID ) << err << " (" << currentType << "; " << current << ")" << endl; + m_errorList.push_back( err ); +} diff --git a/kformula/fsparser.h b/kformula/fsparser.h new file mode 100644 index 00000000..ab594a4d --- /dev/null +++ b/kformula/fsparser.h @@ -0,0 +1,76 @@ +/* This file is part of the KDE project + Copyright (C) 2002 Ulrich Kuettler <ulrich.kuettler@mailbox.tu-dresden.de> + + 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. +*/ + +#ifndef FSPARSER_H +#define FSPARSER_H + +#include <qstring.h> +#include <qstringlist.h> +#include <qdom.h> + +namespace KFormula { class SymbolTable; } +class ParserNode; + +/** + * The parser for simple (C style) formula strings. + */ +class FormulaStringParser { +public: + FormulaStringParser( const KFormula::SymbolTable& symbolTable, QString formula ); + ~FormulaStringParser(); + + QDomDocument parse(); + + QStringList errorList() const { return m_errorList; } + +private: + + enum TokenType { NUMBER, NAME, PLUS, SUB, MUL, DIV, POW, INDEX, LP, RP, LB, RB, + ASSIGN, COMMA, SEMIC, NEWLINE, OTHER, EOL }; + + ParserNode* parseAssign(); + ParserNode* parseExpr(); + ParserNode* parseTerm(); + ParserNode* parsePower(); + ParserNode* parsePrimary(); + void expect( TokenType type, QString msg ); + + QString nextToken(); + bool eol() { return m_formula.length() == pos; } + + void readNumber(); + void readDigits(); + + void error( QString err ); + QStringList m_errorList; + + const KFormula::SymbolTable& m_symbolTable; + QString m_formula; + uint pos; + uint line; + uint column; + bool m_newlineIsSpace; + + TokenType currentType; + QString current; + + ParserNode* head; +}; + +#endif diff --git a/kformula/kfconfig.cc b/kformula/kfconfig.cc new file mode 100644 index 00000000..0a24dc8f --- /dev/null +++ b/kformula/kfconfig.cc @@ -0,0 +1,76 @@ +/* This file is part of the KDE project + Copyright (C) 2001 Andrea Rizzi <rizzi@kde.org> + Ulrich Kuettler <ulrich.kuettler@mailbox.tu-dresden.de> + + 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 <kdebug.h> +#include <kiconloader.h> +#include <kinstance.h> +#include <klocale.h> + +#include "kfconfig.h" +#include "kformula_factory.h" +#include "kformula_doc.h" +#include "kformula_view.h" + + +KFConfig::KFConfig( KFormulaPartView* parent ) + : KDialogBase( KDialogBase::IconList, i18n( "Configure KFormula" ), + KDialogBase::Ok | KDialogBase::Apply | KDialogBase::Cancel | KDialogBase::Default, + KDialogBase::Ok, parent ) +{ + //kdDebug( 40000 ) << "KFConfig::KFConfig" << endl; + QVBox* page1 = addVBoxPage( i18n( "Formula" ), i18n( "Formula Settings" ), + BarIcon( "kformula", KIcon::SizeMedium ) ); + _page = new KFormula::ConfigurePage( parent->document()->getDocument(), this, + KFormulaFactory::global()->config(), + page1 ); +// QVBox* page2 = addVBoxPage( i18n( "Math Fonts" ), i18n( "Math Fonts Settings" ), +// BarIcon( "kformula", KIcon::SizeMedium ) ); +// _mathFontPage = new KFormula::MathFontsConfigurePage( parent->document()->getDocument(), this, +// KFormulaFactory::global()->config(), +// page2 ); + + connect( this, SIGNAL( okClicked() ), this, SLOT( slotApply() ) ); +} + +void KFConfig::slotApply() +{ +// _mathFontPage->apply(); + + // The "normal" page triggers the recalc and must be called last + // for this reason. + _page->apply(); +} + +void KFConfig::slotDefault() +{ + switch(activePageIndex()) + { + case 0: + _page->slotDefault(); + break; +// case 1: +// _mathFontPage->slotDefault(); +// break; + default: + break; + } +} + +#include "kfconfig.moc" diff --git a/kformula/kfconfig.h b/kformula/kfconfig.h new file mode 100644 index 00000000..9231ff1c --- /dev/null +++ b/kformula/kfconfig.h @@ -0,0 +1,49 @@ +/* This file is part of the KDE project + Copyright (C) 2001 Andrea Rizzi <rizzi@kde.org> + Ulrich Kuettler <ulrich.kuettler@mailbox.tu-dresden.de> + + 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. +*/ + +#ifndef kfconfig_h +#define kfconfig_h + +#include <kdialogbase.h> + +#include <kformulaconfigpage.h> + +class KFormulaPartView; + + +/** + * The big config dialog. + */ +class KFConfig : public KDialogBase +{ + Q_OBJECT +public: + KFConfig( KFormulaPartView* parent ); + +public slots: + void slotApply(); + void slotDefault(); + +private: + KFormula::ConfigurePage* _page; +// KFormula::MathFontsConfigurePage* _mathFontPage; +}; + +#endif diff --git a/kformula/kformula.desktop b/kformula/kformula.desktop new file mode 100644 index 00000000..20e5a5d1 --- /dev/null +++ b/kformula/kformula.desktop @@ -0,0 +1,82 @@ +[Desktop Entry] +Name=KFormula +Name[af]=Kformula +Name[cy]=KFformiwla +Name[fo]=KFormul +Name[hi]=के-फ़ॉर्मूला +Name[lo]=ສູດຄະນິດສາດ K +Name[mk]=К-формула +Name[ne]=केडीई सूत्र +Name[sv]=Kformula +Name[th]=สูตรคณิตศาสตร์ K +Name[ven]=Fomula ya K +Exec=kformula %u +GenericName=Formula Editor +GenericName[af]=Formule Redigeerder +GenericName[ar]=مُحَرِّر المعادَلات +GenericName[az]=Formul Editoru +GenericName[bg]=Формули +GenericName[br]=Un aozer formulennoù +GenericName[bs]=Editor matematičkih jednačina +GenericName[ca]=Editor de fórmules +GenericName[cs]=Editor vzorců +GenericName[cy]=Golygydd Fformiwla +GenericName[da]=Formeleditor +GenericName[de]=Formel-Editor +GenericName[el]=Επεξεργαστής μαθηματικών τύπων +GenericName[eo]=Redaktilo por matematikaj formuloj +GenericName[es]=Editor de fórmulas +GenericName[et]=Valemiredaktor +GenericName[eu]=Formulen editorea +GenericName[fa]=ویرایشگر فرمول +GenericName[fi]=Kaavamuokkain +GenericName[fo]=Formulritil +GenericName[fr]=Éditeur de formules +GenericName[fy]=Formulebewurker +GenericName[gl]=Editor de Fórmulas +GenericName[he]=עורך נוסחאות +GenericName[hr]=Uređivač formula +GenericName[hu]=Képletszerkesztő +GenericName[is]=Formúlu ritill +GenericName[it]=Editor di formule +GenericName[ja]=数式エディタ +GenericName[km]=កម្មវិធីនិពន្ធរូបមន្ត +GenericName[lo]=ເຄື່ອງມືແກ້ໄຂສູດຄະນິດສາດ +GenericName[lt]=Formulės redaktorius +GenericName[lv]=Formulu redaktors +GenericName[ms]=Editor Formula +GenericName[mt]=Editur tal-Formuli +GenericName[nb]=Formelredigering +GenericName[nds]=Tabelleneditor +GenericName[ne]=सूत्र सम्पादक +GenericName[nl]=Formulebewerker +GenericName[nn]=Formelredigering +GenericName[pl]=Edytor wyrażeń matematycznych +GenericName[pt]=Editor de Fórmulas +GenericName[pt_BR]=Fórmula +GenericName[ro]=Un editor de formule +GenericName[ru]=Формулы +GenericName[se]=Hápmodoaimmaheaddji +GenericName[sk]=Editor rovníc +GenericName[sl]=Urejevalnik formul +GenericName[sr]=Уређивач формула +GenericName[sr@Latn]=Uređivač formula +GenericName[sv]=Formeleditor +GenericName[ta]=சூத்திரத் தொகுப்பாளர் +GenericName[tg]=Муҳаррири Формула +GenericName[th]=เครื่องมือแก้ไขสูตรคณิตศาสตร์ +GenericName[tr]=Formül Düzenleyici +GenericName[uk]=Редактор формул +GenericName[uz]=Formula tahrirchi +GenericName[uz@cyrillic]=Формула таҳрирчи +GenericName[wa]=Aspougneu d' formules +GenericName[xh]=Umhleli wendlela yokubala +GenericName[zh_CN]=公式编辑器 +GenericName[zh_TW]=方程式編輯器 +MimeType=application/vnd.oasis.opendocument.formula;application/x-kformula +Type=Application +Icon=kformula +X-KDE-NativeMimeType=application/vnd.oasis.opendocument.formula +X-DCOP-ServiceType=Multi +DocPath=kformula/index.html +Categories=Qt;KDE;Office;X-KDE-More; diff --git a/kformula/kformula.rc b/kformula/kformula.rc new file mode 100644 index 00000000..f79716b3 --- /dev/null +++ b/kformula/kformula.rc @@ -0,0 +1,161 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd" ><kpartgui name="KFormula" version="3"> +<MenuBar> + <Menu name="Edit"><text>&Edit</text> + <Action name="koffice_undo"/> + <Action name="koffice_redo"/> + <Separator/> + <Action name="edit_cut"/> + <Action name="edit_copy"/> + <Action name="edit_paste"/> + <Separator/> + <Action name="edit_select_all"/> + <Action name="formula_removeenclosing"/> + <Action name="formula_makegreek"/> + <Action name="formula_formulastring"/> + </Menu> + <Menu name="Element"><text>E&lement</text> + <Menu name="Add"><text>Add</text> + <Action name="formula_addtext"/> + <Action name="formula_addroot"/> + <Action name="formula_addfrac"/> + <Action name="formula_addbra"/> + <Action name="formula_addintegral"/> + <Action name="formula_addsum"/> + <Action name="formula_addproduct"/> + <Action name="formula_addmatrix"/> + <Action name="formula_add_one_by_two_matrix"/> + <Action name="formula_addoverline"/> + <Action name="formula_addunderline"/> + <Action name="formula_addmultiline"/> + <Separator/> + <Action name="formula_addupperindex"/> + <Action name="formula_addlowerindex"/> + <Separator/> + <Action name="formula_addnegthinspace"/> + <Action name="formula_addthinspace"/> + <Action name="formula_addmediumspace"/> + <Action name="formula_addthickspace"/> + <Action name="formula_addquadspace"/> + </Menu> + <Menu name="matrix"><text>Matrix</text> + <Action name="formula_insertcolumn"/> + <Action name="formula_appendcolumn"/> + <Action name="formula_removecolumn"/> + <Action name="formula_insertrow"/> + <Action name="formula_appendrow"/> + <Action name="formula_removerow"/> + </Menu> + <Action name="formula_textsize"/> + + <Action name="formula_typeleft"/> + <Action name="formula_typeright"/> + <Action name="formula_insertsymbol"/> + </Menu> +<!-- + <Menu name="Font"><text>Font</text> + <Action name="textfont"/> + <Action name="textsize"/> + <Action name="textbold"/> + <Action name="textitalic"/> + <Action name="textunder"/> + <Menu name="scale"><text>Increase/Decrease Options..</text> + <Action name="fontelement"/> + <Action name="fontindex"/> + <Action name="fontchild"/> + <Action name="fontnext"/> + + </Menu> + </Menu> +--> + <Menu name="settings"><text>&Settings</text> + <Separator group="settings_show"/> + <Action name="formula_syntaxhighlighting" group="settings_show"/> + <Separator group="settings_show"/> + <Action name="configure" group="settings_configure"/> + </Menu> + + <Menu name="help"> + <Action name="help_show_tip"/> + </Menu> +</MenuBar> + + <ToolBar fullWidth="false" name="edit_toolbar" position="top"><Text>Edit</Text> + <Action name="koffice_undo"/> + <Action name="koffice_redo"/> + <Separator/> + <Action name="edit_cut"/> + <Action name="edit_copy"/> + <Action name="edit_paste"/> + </ToolBar> + <ToolBar name="Add"><Text>Add</Text> + <Action name="formula_addtext"/> + <Action name="formula_addroot"/> + <Action name="formula_addfrac"/> + <Action name="formula_addbra"/> + <Action name="formula_addsqrbra"/> + <Action name="formula_addcurbra"/> + <Action name="formula_addabsbra"/> + <Action name="formula_addoverline"/> + <Action name="formula_addunderline"/> + <Action name="formula_addintegral"/> + <Action name="formula_addsum"/> + <Action name="formula_addproduct"/> + <Action name="formula_addmatrix"/> + <Action name="formula_add_one_by_two_matrix"/> + <Action name="formula_addupperleft"/> + <Action name="formula_addlowerleft"/> + <Action name="formula_addupperindex"/> + <Action name="formula_addlowerindex"/> + <Action name="formula_addupperright"/> + <Action name="formula_addlowerright"/> + <Action name="formula_addmultiline"/> + <Separator/> + <Action name="formula_typeleft"/> + <Action name="formula_typeright"/> + </ToolBar> + <ToolBar name="Font"><Text>Font</Text> + <Action name="formula_textsize"/> + <Separator/> + <Action name="formula_format_bold"/> + <Action name="formula_format_italic"/> + <Separator/> + <Action name="formula_fontfamily"/> + </ToolBar> +<!-- + <ToolBar name="Element"><Text>Element</Text> + <Action name="textsplit"/> + <Action name="rootindex"/> + <Action name="typeleft"/> + <Action name="typeright"/> + <Action name="fracup"/> + <Action name="fracmiddle"/> + <Action name="fracdown"/> + <Action name="fracleft"/> + <Action name="fraccenter"/> + <Action name="fracright"/> + <Action name="fracmidline"/> + <Action name="fracnear"/> + <Action name="fracfar"/> + <Action name="ihigher"/> + <Action name="ilower"/> + <Action name="matrixset"/> + <Action name="matrixinsrow"/> + <Action name="matrixinscol"/> + <Action name="matrixremrow"/> + <Action name="matrixremcol"/> + </ToolBar> +--> + <ToolBar name="Symbol"><Text>Symbol</Text> + <Action name="formula_tokenelement"/> + <Action name="formula_symbolnames"/> + <Action name="formula_insertsymbol"/> + </ToolBar> + <ToolBar name="Matrix"><Text>Matrix</Text> + <Action name="formula_insertcolumn"/> + <Action name="formula_appendcolumn"/> + <Action name="formula_removecolumn"/> + <Action name="formula_insertrow"/> + <Action name="formula_appendrow"/> + <Action name="formula_removerow"/> + </ToolBar> +</kpartgui> diff --git a/kformula/kformula.xpm b/kformula/kformula.xpm new file mode 100644 index 00000000..93921d36 --- /dev/null +++ b/kformula/kformula.xpm @@ -0,0 +1,44 @@ +/* XPM */ +static char*kformula[]={ +"32 32 9 1", +"g c #008000", +"b c #000080", +"f c #000000", +"d c #ffc0ff", +"a c #0000ff", +". c None", +"# c #c00000", +"c c #c000c0", +"e c #ff0000", +"................................", +"................................", +".#####.#######..................", +".#####.######...................", +".#####.#####....................", +".#####.#####....................", +".#####.##aaaaaaaaaaaaaaaaaaaa...", +".#####.##abbbbbbbbbbbbbbbbbbb...", +".#####.##ab......c..............", +".#####.##ab......cd.............", +".#####.##ab......cd.............", +".#####.#.ab...ccccccc...........", +".#####...ab....ddcdddd..ee......", +".#####...ab......cd....e..e.....", +".#####.##ab......cd....e..e.....", +".###fa.##ab.......d......e......", +".###ba.##ab.............e.......", +".###ba.##ab#...........ee.......", +".####ba##ab#..ff......feeee..g..", +".####ba##ab#...ff....ff.....ggg.", +".####ba##ab##...ff..ff.......g..", +".#####ba#ab##....ffff...........", +".#####ba#ab###....ff............", +".#####ba#ab####..ffff........g..", +".......baab.....ff..ff......ggg.", +".......baab....ff....ff......g..", +".......baab...ff......ff........", +"........bab.....................", +".........bb.....................", +"................................", +"................................", +"................................"}; diff --git a/kformula/kformula_aboutdata.h b/kformula/kformula_aboutdata.h new file mode 100644 index 00000000..5cddaa11 --- /dev/null +++ b/kformula/kformula_aboutdata.h @@ -0,0 +1,50 @@ +/* This file is part of the KDE project + Copyright (C) 2001 Andrea Rizzi <rizzi@kde.org> + Ulrich Kuettler <ulrich.kuettler@mailbox.tu-dresden.de> + Copyright (C) 2006 Alfredo Beaumont Sainz <alfredo.beaumont@gmail.com> + + 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. + + 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. +*/ + +#ifndef KFORMULA_ABOUTDATA +#define KFORMULA_ABOUTDATA + +#include <kaboutdata.h> +#include <klocale.h> +#include <config.h> + +static const char* description=I18N_NOOP("KOffice Formula Editor"); +static const char* version=VERSION; + +KAboutData * newKFormulaAboutData() +{ + KAboutData * aboutData = new KAboutData( "kformula", I18N_NOOP( "KFormula" ), + version, description, KAboutData::License_GPL, + "(c) 1998-2006, The KFormula Team", 0, + "http://www.koffice.org/kformula/" ); + aboutData->addAuthor( "Alfredo Beaumont", + I18N_NOOP( "current maintainer" ), + "alfredo.beaumont@gmail.com", + "http://www.alfredobeaumont.org" ); + aboutData->addAuthor( "Andrea Rizzi", I18N_NOOP( "original author" ), "rizzi@kde.org" ); + aboutData->addAuthor( "Ulrich Kuettler", I18N_NOOP( "core developer" ), "ulrich.kuettler@gmx.de" ); + aboutData->addAuthor( "Heinrich Kuettler", I18N_NOOP( "core developer" ), "heinrich.kuettler@gmx.de" ); + aboutData->addCredit( "Claus O. Wilke", I18N_NOOP( "for your advice to look at TeX first" ) ); + //aboutData->addCredit( "Tom Deblauwe", I18N_NOOP( "for the sweet icons" ) ); + return aboutData; +} + +#endif diff --git a/kformula/kformula_doc.cc b/kformula/kformula_doc.cc new file mode 100644 index 00000000..4e83baf8 --- /dev/null +++ b/kformula/kformula_doc.cc @@ -0,0 +1,247 @@ +/* This file is part of the KDE project + Copyright (C) 2001 Andrea Rizzi <rizzi@kde.org> + Ulrich Kuettler <ulrich.kuettler@mailbox.tu-dresden.de> + + 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. + + 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 "kformula_doc.h" +#include "kformula_view.h" +#include "kformula_factory.h" + +#include <qbitmap.h> +#include <qcolor.h> +#include <qdom.h> +#include <qpainter.h> +#include <qpopupmenu.h> +#include <qprinter.h> +#include <qstring.h> +#include <qwmatrix.h> +#include <qfile.h> + +#include <config.h> +#include <unistd.h> + +#include <kaboutdialog.h> +#include <kaction.h> +#include <kapplication.h> +#include <kdebug.h> +#include <KoGlobal.h> +#include <kiconloader.h> +#include <klocale.h> +#include <kstdaction.h> +#include <kstandarddirs.h> +#include <kurl.h> +#include <KoXmlWriter.h> +#include <KoStoreDevice.h> +#include <ktempfile.h> +#include <KoMainWindow.h> + +#include <kformulacontainer.h> +#include <kformuladocument.h> + + +KFormulaDoc::KFormulaDoc(QWidget *parentWidget, const char *widgetName, QObject* parent, const char* name, bool singleViewMode) + : KoDocument(parentWidget, widgetName, parent, name, singleViewMode) +{ + setInstance(KFormulaFactory::global(), false); + //kdDebug(39001) << "General Settings" << endl; + + history = new KoCommandHistory( actionCollection() ); + wrapper = new KFormula::DocumentWrapper( kapp->config(), + actionCollection(), + history ); + document = new KFormula::Document; + wrapper->document( document ); + formula = document->createFormula(); + + document->setEnabled( true ); + + // the modify flag + connect(history, SIGNAL(commandExecuted()), this, SLOT(commandExecuted())); + connect(history, SIGNAL(documentRestored()), this, SLOT(documentRestored())); + dcopObject(); +} + + +KFormulaDoc::~KFormulaDoc() +{ + delete history; + delete wrapper; +} + + +bool KFormulaDoc::saveOasis( KoStore* store, KoXmlWriter* manifestWriter ) +{ + if ( !store->open( "content.xml" ) ) + return false; + + KoStoreDevice dev( store ); + KoXmlWriter* contentWriter = createOasisXmlWriter( &dev, "math:math" ); + + + KTempFile contentTmpFile; + contentTmpFile.setAutoDelete( true ); + QFile* tmpFile = contentTmpFile.file(); + + //todo save content + QTextStream stream(tmpFile); + stream.setEncoding( QTextStream::UnicodeUTF8 ); + formula->saveMathML( stream, true ); + + tmpFile->close(); + contentWriter->addCompleteElement( tmpFile ); + contentTmpFile.close(); + + + + contentWriter->endElement(); + delete contentWriter; + + if(!store->close()) + return false; + + manifestWriter->addManifestEntry("content.xml", "text/xml"); + + setModified( false ); + + return true; +} + + +QDomDocument KFormulaDoc::saveXML() +{ + QDomDocument doc = document->saveXML(); + history->documentSaved(); + return doc; +} + +bool KFormulaDoc::loadOasis( const QDomDocument& doc, KoOasisStyles&, const QDomDocument&, KoStore* ) +{ + // we don't have style into this format + // we don't have settings into kformula (for the moment) + // necessary to adapt kformula code to load MathML format with Oasis Extension. + + if ( document->loadOasis( doc ) ) { + history->clear(); + history->documentSaved(); + return true; + } + return false; +} + +bool KFormulaDoc::loadXML(QIODevice *, const QDomDocument& doc) +{ + if ( doc.doctype().name().lower() == "math" + || doc.documentElement().tagName().lower() == "math" ) + if ( document->loadOasis( doc ) ) { + history->clear(); + history->documentSaved(); + return true; + } + if ( document->loadXML( doc ) ) { + history->clear(); + history->documentSaved(); + return true; + } + return false; +} + +/** + * Saves the document in native format, to a given file. + * It is reimplemented to handle the special case of MathML, since it is + * a native format but not compressed. + */ +bool KFormulaDoc::saveNativeFormat( const QString & file ) +{ + QCString mimeType = outputMimeType(); + bool mathml = !mimeType.isEmpty() && mimeType.contains( "mathml", false ); + if ( mathml ) { + QFile f( file ); + if ( f.open( IO_WriteOnly | IO_Translate ) ) + { + QTextStream stream( &f ); + stream.setEncoding( QTextStream::UnicodeUTF8 ); + formula->saveMathML( stream, false ); + f.close(); + return true; + } + else + return false; + } + // If it's not MathML, let the parent handle it + return KoDocument::saveNativeFormat( file ); +} + +KoView* KFormulaDoc::createViewInstance(QWidget* _parent, const char *name) +{ + return new KFormulaPartView(this, _parent, name); +} + +void KFormulaDoc::commandExecuted() +{ + if (formula->isEmpty()) { + setEmpty(); + } + setModified(true); +} + +void KFormulaDoc::documentRestored() +{ + setModified(false); +} + + +bool KFormulaDoc::initDoc(InitDocFlags /*flags*/, QWidget* /*parentWidget*/) +{ + // If nothing is loaded, do initialize here + return TRUE; +} + +void KFormulaDoc::showStartUpWidget(KoMainWindow* parent, bool /*alwaysShow*/) +{ + parent->setRootDocument( this ); +} + +bool KFormulaDoc::showEmbedInitDialog(QWidget* /*parent*/) +{ + return true; +} + +void KFormulaDoc::paintContent(QPainter& painter, const QRect& rect, bool transparent, double zoomX, double zoomY) +{ + // ####### handle transparency and zoom + // Need to draw only the document rectangle described in the parameter rect. + + bool forPrint = painter.device() && painter.device()->devType() == QInternal::Printer; + document->setZoomAndResolution( 100, zoomX, zoomY, true, forPrint ); + if ( !transparent ) { + painter.fillRect( rect, Qt::white ); + } + formula->draw( painter, rect ); +} + +QString KFormulaDoc::configFile() const +{ +// return readConfigFile( locate( "data", "kformula/kformula.rc", +// KFormulaFactory::global() ) ); + +// return readConfigFile( "kformula.rc" ); + return QString::null; +} + +#include "kformula_doc.moc" diff --git a/kformula/kformula_doc.h b/kformula/kformula_doc.h new file mode 100644 index 00000000..b139f922 --- /dev/null +++ b/kformula/kformula_doc.h @@ -0,0 +1,113 @@ +/* This file is part of the KDE project + Copyright (C) 2001 Andrea Rizzi <rizzi@kde.org> + Ulrich Kuettler <ulrich.kuettler@mailbox.tu-dresden.de> + + 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. + + 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. +*/ + +#ifndef KFORMULA_DOC_H +#define KFORMULA_DOC_H + +#include <qptrlist.h> +#include <qpainter.h> + +#include <kcommand.h> +#include <KoDocument.h> +#include <KoCommandHistory.h> +#include <kformuladefs.h> + +#include "kformula_view.h" + +class KoXmlWriter; + +KFORMULA_NAMESPACE_BEGIN + +class FormulaCursor; +class Container; +class Document; +class DocumentWrapper; + +KFORMULA_NAMESPACE_END + + +/** + * The part's document. Forwards most of the requests. + */ +class KFormulaDoc : public KoDocument +{ + Q_OBJECT + +public: + + KFormulaDoc(QWidget *parentWidget = 0, + const char *widgetName = 0, + QObject* parent = 0, + const char* name = 0, + bool singleViewMode = false); + ~KFormulaDoc(); + + virtual void paintContent( QPainter &painter, const QRect &rect, bool transparent = false, double zoomX = 1.0, double zoomY = 1.0 ); + + virtual bool initDoc(InitDocFlags flags, QWidget* parentWidget=0); + virtual void showStartUpWidget(KoMainWindow* parent, bool alwaysShow = false); + virtual bool showEmbedInitDialog(QWidget* parent); + virtual bool loadOasis( const QDomDocument& doc, KoOasisStyles& oasisStyles, const QDomDocument& settings, KoStore* ); + virtual bool loadXML(QIODevice *, const QDomDocument& doc); + virtual QDomDocument saveXML(); + virtual bool saveOasis( KoStore* store, KoXmlWriter* manifestWriter ); + + /** + * Saves the document in native format, to a given file. + * It is reimplemented to handle the special case of MathML, since it is + * a native format but not compressed. + */ + virtual bool saveNativeFormat( const QString & file ); + + KFormula::Container* getFormula() const { return formula; } + KFormula::Document* getDocument() const { return document; } + +protected slots: + + void commandExecuted(); + void documentRestored(); + +protected: + + virtual QString configFile() const; + virtual KoView* createViewInstance(QWidget* parent, const char* name); + +private: + + /** + * Our undo stack. + */ + KoCommandHistory* history; + + /** + * The place where all formula related work is done. + */ + KFormula::Container* formula; + + /** + * The document that contains all the formulas. + * Right now we only have one, but this might change. + */ + KFormula::Document* document; + + KFormula::DocumentWrapper* wrapper; +}; + +#endif diff --git a/kformula/kformula_factory.cc b/kformula/kformula_factory.cc new file mode 100644 index 00000000..021f10de --- /dev/null +++ b/kformula/kformula_factory.cc @@ -0,0 +1,70 @@ +#include "kformula_factory.h" +#include "kformula_doc.h" +#include "kformula_aboutdata.h" + +#include <kinstance.h> +#include <kiconloader.h> + +#include <kfiledialog.h> +#include <kglobal.h> +#include <kstandarddirs.h> +#include <klocale.h> + +#include <qstringlist.h> + +K_EXPORT_COMPONENT_FACTORY( libkformulapart, KFormulaFactory ) + +KInstance* KFormulaFactory::s_global = 0; +KAboutData* KFormulaFactory::s_aboutData = 0; + +KAboutData* KFormulaFactory::aboutData() +{ + if( !s_aboutData ) + s_aboutData=newKFormulaAboutData(); + return s_aboutData; +} + + +KFormulaFactory::KFormulaFactory( QObject* parent, const char* name ) + : KoFactory( parent, name ) +{ + // Create our instance, so that it becomes KGlobal::instance if the + // main app is KFormula. + (void)global(); +} + +KFormulaFactory::~KFormulaFactory() +{ + delete s_aboutData; + s_aboutData=0; + delete s_global; + s_global = 0L; +} + +KParts::Part* KFormulaFactory::createPartObject( QWidget *parentWidget, const char *widgetName, QObject* parent, const char* name, const char* classname, const QStringList & ) +{ + bool bWantKoDocument = ( strcmp( classname, "KoDocument" ) == 0 ); + + KFormulaDoc *doc = new KFormulaDoc( parentWidget, widgetName, parent, name, !bWantKoDocument ); + + if ( !bWantKoDocument ) + doc->setReadWrite( false ); + + return doc; +} + +KInstance* KFormulaFactory::global() +{ + if ( !s_global ) + { + s_global = new KInstance(aboutData()); + s_global->dirs()->addResourceType( "toolbar", + KStandardDirs::kde_default("data") + "koffice/toolbar/"); + // Tell the iconloader about share/apps/koffice/icons*/ + s_global->iconLoader()->addAppDir("koffice"); + } + + return s_global; +} + +#include "kformula_factory.moc" diff --git a/kformula/kformula_factory.h b/kformula/kformula_factory.h new file mode 100644 index 00000000..dc9fe2f1 --- /dev/null +++ b/kformula/kformula_factory.h @@ -0,0 +1,29 @@ +#ifndef KFORMULA_FACTORY_H +#define KFORMULA_FACTORY_H + +#include <KoFactory.h> +//#include <kaboutdata.h> + +class KInstance; +class KInstance; +class KAboutData; + +class KFormulaFactory : public KoFactory +{ + Q_OBJECT +public: + KFormulaFactory( QObject* parent = 0, const char* name = 0 ); + ~KFormulaFactory(); + + virtual KParts::Part *createPartObject( QWidget *parentWidget = 0, const char *widgetName = 0, QObject *parent = 0, const char *name = 0, const char *classname = "KoDocument", const QStringList &args = QStringList() ); + + static KInstance* global(); + + static KAboutData* aboutData(); + +private: + static KInstance* s_global; + static KAboutData* s_aboutData; +}; + +#endif diff --git a/kformula/kformula_readonly.rc b/kformula/kformula_readonly.rc new file mode 100644 index 00000000..70885a2d --- /dev/null +++ b/kformula/kformula_readonly.rc @@ -0,0 +1,13 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd" ><kpartgui name="KFormula" version="1"> +<MenuBar> + <Menu name="edit"><text>&Edit</text> + <Action name="edit_copy"/> + <Separator/> + <Action name="edit_select_all"/> + </Menu> +</MenuBar> + +<ToolBar fullWidth="false" name="edit_toolbar" position="top"><Text>Edit</Text> + <Action name="edit_copy"/> +</ToolBar> +</kpartgui> diff --git a/kformula/kformula_view.cc b/kformula/kformula_view.cc new file mode 100644 index 00000000..f109de69 --- /dev/null +++ b/kformula/kformula_view.cc @@ -0,0 +1,284 @@ +/* This file is part of the KDE project + Copyright (C) 2001 Andrea Rizzi <rizzi@kde.org> + Ulrich Kuettler <ulrich.kuettler@mailbox.tu-dresden.de> + + 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. + + 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. +*/ + +class KPrinter; + +#include <qpainter.h> +#include <qpopupmenu.h> +#include <qtextedit.h> +#include <qtimer.h> + +#include <kaction.h> +#include <kdebug.h> +#include <kiconloader.h> +#include <klocale.h> +#include <kstdaction.h> +#include <ktip.h> +//#include <kglobal.h> + +#include <kformulacontainer.h> +#include <kformuladocument.h> + +#include "formulastring.h" +#include "fsparser.h" +#include "kfconfig.h" +#include "kformula_doc.h" +#include "kformula_factory.h" +#include "kformula_view.h" +#include "kformula_view_iface.h" +#include "kformulawidget.h" + + +bool KFormulaPartView::first_window = true; + +KFormulaPartView::KFormulaPartView(KFormulaDoc* _doc, QWidget* _parent, const char* _name) + : KoView( _doc, _parent, _name ), m_pDoc(_doc) +{ + setInstance(KFormulaFactory::global()); + if ( !_doc->isReadWrite() ) + setXMLFile("kformula_readonly.rc"); + else + setXMLFile("kformula.rc"); + + m_dcop = 0; + dcopObject(); // build it + + scrollview = new QScrollView(this, "scrollview"); + formulaWidget = new KFormulaWidget(_doc->getFormula(), scrollview->viewport(), "formulaWidget"); + scrollview->addChild(formulaWidget); + + scrollview->viewport()->setFocusProxy( scrollview ); + scrollview->viewport()->setFocusPolicy( WheelFocus ); + scrollview->setFocusPolicy( NoFocus ); + formulaWidget->setFocus(); + + // Nice parts start in read only mode. + formulaWidget->setReadOnly(true); + + KFormula::Container* formula = m_pDoc->getFormula(); + KFormula::Document* document = m_pDoc->getDocument(); + + // copy&paste + cutAction = KStdAction::cut(document->wrapper(), SLOT(cut()), actionCollection()); + copyAction = KStdAction::copy(document->wrapper(), SLOT(copy()), actionCollection()); + pasteAction = KStdAction::paste(document->wrapper(), SLOT(paste()), actionCollection()); + cutAction->setEnabled(false); + copyAction->setEnabled(false); + + // tip of the day + KStdAction::tipOfDay( this, SLOT( slotShowTip() ), actionCollection() ); + + // elements + addBracketAction = document->wrapper()->getAddBracketAction(); + addFractionAction = document->wrapper()->getAddFractionAction(); + addRootAction = document->wrapper()->getAddRootAction(); + addSumAction = document->wrapper()->getAddSumAction(); + addProductAction = document->wrapper()->getAddProductAction(); + addIntegralAction = document->wrapper()->getAddIntegralAction(); + addMatrixAction = document->wrapper()->getAddMatrixAction(); + addUpperLeftAction = document->wrapper()->getAddUpperLeftAction(); + addLowerLeftAction = document->wrapper()->getAddLowerLeftAction(); + addUpperRightAction = document->wrapper()->getAddUpperRightAction(); + addLowerRightAction = document->wrapper()->getAddLowerRightAction(); + addGenericUpperAction = document->wrapper()->getAddGenericUpperAction(); + addGenericLowerAction = document->wrapper()->getAddGenericLowerAction(); + removeEnclosingAction = document->wrapper()->getRemoveEnclosingAction(); + + (void) KStdAction::selectAll(formulaWidget, SLOT(slotSelectAll()), actionCollection()); + + //------------------------ Settings menu + KStdAction::preferences( this, SLOT(configure()), actionCollection(), "configure" ); + + // font stuff +// KFontAction* actionElement_Text_Font = new KFontAction(i18n( "Font Family" ),0, +// actionCollection(),"textfont"); +// connect( actionElement_Text_Font, SIGNAL( activated( const QString& ) ), this, SLOT( fontSelected( const QString& ) ) ); + + KFontSizeAction* actionTextSize = new KFontSizeAction(i18n( "Size" ),0, + actionCollection(),"formula_textsize"); + actionTextSize->setFontSize( m_pDoc->getFormula()->fontSize() ); + + connect( actionTextSize, SIGNAL( fontSizeChanged( int ) ), this, SLOT( sizeSelected( int ) ) ); + connect( formula, SIGNAL( baseSizeChanged( int ) ), actionTextSize, SLOT( setFontSize( int ) ) ); + +// KToggleAction* actionElement_Text_Bold = new KToggleAction(i18n( "Bold" ), +// "bold", +// 0, +// actionCollection(),"textbold"); +// connect( actionElement_Text_Bold, SIGNAL( toggled( bool ) ), this, SLOT( bold( bool ) ) ); + +// KToggleAction* actionElement_Text_Italic = new KToggleAction(i18n( "Italic" ), +// "italic", +// 0, +// actionCollection(),"textitalic"); +// connect( actionElement_Text_Italic, SIGNAL( toggled( bool ) ), this, SLOT( italic( bool ) ) ); + +// KToggleAction* actionElement_Text_Under = new KToggleAction(i18n( "Underlined" ), +// "underl", +// 0, +// actionCollection(),"textunder"); +// connect(actionElement_Text_Under, SIGNAL( toggled( bool ) ), this, SLOT( underline( bool ) ) ); + + + formulaStringAction = new KAction( i18n( "Edit Formula String..." ), + 0, + this, SLOT( formulaString() ), + actionCollection(), "formula_formulastring" ); + // notify on cursor change + connect(formulaWidget, SIGNAL(cursorChanged(bool, bool)), + this, SLOT(cursorChanged(bool, bool))); + + connect( formula, SIGNAL( statusMsg( const QString& ) ), + this, SLOT( slotActionStatusText( const QString& ) ) ); + + if ( !_doc->isEmbedded() && first_window ) { + QTimer::singleShot( 200, this, SLOT(slotShowTipOnStart()) ); + first_window = false; + } +} + + +KFormulaPartView::~KFormulaPartView() +{ + delete m_dcop; +} + +DCOPObject* KFormulaPartView::dcopObject() +{ + if ( !m_dcop ) + m_dcop = new KformulaViewIface( this ); + + return m_dcop; +} + + +void KFormulaPartView::focusInEvent(QFocusEvent*) +{ + formulaWidget->setFocus(); +} + +void KFormulaPartView::updateReadWrite(bool readwrite) +{ + formulaWidget->setReadOnly(!readwrite); + setEnabled(readwrite); +} + +void KFormulaPartView::slotShowTipOnStart() { + KTipDialog::showTip( this ); +} + +void KFormulaPartView::slotShowTip() { + KTipDialog::showTip( this, QString::null, true ); +} + + +void KFormulaPartView::setEnabled(bool enabled) +{ + addBracketAction->setEnabled(enabled); + addFractionAction->setEnabled(enabled); + addRootAction->setEnabled(enabled); + addSumAction->setEnabled(enabled); + addIntegralAction->setEnabled(enabled); + addMatrixAction->setEnabled(enabled); + addUpperLeftAction->setEnabled(enabled); + addLowerLeftAction->setEnabled(enabled); + addUpperRightAction->setEnabled(enabled); + addLowerRightAction->setEnabled(enabled); + addGenericUpperAction->setEnabled(enabled); + addGenericLowerAction->setEnabled(enabled); + removeEnclosingAction->setEnabled(enabled); +} + +void KFormulaPartView::resizeEvent( QResizeEvent * ) +{ + scrollview->setGeometry(0, 0, width(), height()); +} + + +void KFormulaPartView::setupPrinter(KPrinter&) +{ +} + +void KFormulaPartView::print(KPrinter& printer) +{ + m_pDoc->getFormula()->print(printer); +} + +const KFormula::View* KFormulaPartView::formulaView() const { return formulaWidget->view(); } +KFormula::View* KFormulaPartView::formulaView() { return formulaWidget->view(); } + +void KFormulaPartView::cursorChanged(bool visible, bool selecting) +{ + cutAction->setEnabled(visible && selecting); + copyAction->setEnabled(visible && selecting); + + removeEnclosingAction->setEnabled(!selecting); + + if (visible) { + int x = formulaWidget->getCursorPoint().x(); + int y = formulaWidget->getCursorPoint().y(); + scrollview->ensureVisible(x, y); + } + + KFormula::Document* doc = document()->getDocument(); + doc->wrapper()->getFormatBoldAction()->setEnabled( selecting ); + doc->wrapper()->getFormatItalicAction()->setEnabled( selecting ); + doc->wrapper()->getFontFamilyAction()->setEnabled( selecting ); + if ( !selecting ) { + doc->wrapper()->getFormatBoldAction()->setChecked( false ); + doc->wrapper()->getFormatItalicAction()->setChecked( false ); + doc->wrapper()->getFontFamilyAction()->setCurrentItem( 0 ); + } +} + +void KFormulaPartView::formulaString() +{ + FormulaString dia( this ); + dia.textWidget->setText( document()->getFormula()->formulaString() ); + if ( dia.exec() ) { + // How lovely. + } +} + +void KFormulaPartView::sizeSelected( int size ) +{ + document()->getFormula()->setFontSize( size ); + formulaWidget->setFocus(); +} + +QStringList KFormulaPartView::readFormulaString( QString text ) +{ + FormulaStringParser parser( document()->getDocument()->getSymbolTable(), text ); + QDomDocument formula = parser.parse(); + QStringList errorList = parser.errorList(); + //if ( errorList.count() == 0 ) { + formulaView()->slotSelectAll(); + document()->getFormula()->paste( formula, i18n( "Read Formula String" ) ); + //} + return errorList; +} + +void KFormulaPartView::configure() +{ + KFConfig configDia( this ); + configDia.exec(); +} + +#include "kformula_view.moc" diff --git a/kformula/kformula_view.h b/kformula/kformula_view.h new file mode 100644 index 00000000..4bb70bf3 --- /dev/null +++ b/kformula/kformula_view.h @@ -0,0 +1,119 @@ +/* This file is part of the KDE project + Copyright (C) 2001 Andrea Rizzi <rizzi@kde.org> + Ulrich Kuettler <ulrich.kuettler@mailbox.tu-dresden.de> + + 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. + + 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. +*/ + +#ifndef __kformula_view_h__ +#define __kformula_view_h__ + +class KAction; +class KFormulaDoc; +class KFormulaPartView; +class KFormulaWidget; +class KSelectAction; +class QPaintEvent; +class QScrollView; +class DCOPObject; + +namespace KFormula { + class View; +} + +#include <KoView.h> +#include <qptrlist.h> +#include <qstringlist.h> + +/** + * The parts view. + */ +class KFormulaPartView : public KoView +{ + Q_OBJECT + +public: + KFormulaPartView(KFormulaDoc* _doc, QWidget* _parent=0, const char* _name=0); + virtual ~KFormulaPartView(); + virtual DCOPObject* dcopObject(); + + virtual void setupPrinter( KPrinter &printer ); + virtual void print( KPrinter &printer ); + + KFormulaDoc* document() const { return m_pDoc; } + + const KFormula::View* formulaView() const; + KFormula::View* formulaView(); + + QStringList readFormulaString( QString text ); + +protected: + + virtual void resizeEvent(QResizeEvent* _ev); + virtual void focusInEvent(QFocusEvent*); + + virtual void updateReadWrite(bool); + +protected slots: + + void configure(); + void cursorChanged(bool visible, bool selecting); + + void formulaString(); + + void sizeSelected( int ); + + void slotShowTipOnStart(); + void slotShowTip(); + +private: + + /** + * Enables the actions that modify the formula. + */ + void setEnabled(bool enabled); + + KFormulaDoc *m_pDoc; + KFormulaWidget* formulaWidget; + QScrollView* scrollview; + + KAction* cutAction; + KAction* copyAction; + KAction* pasteAction; + + KAction* addBracketAction; + KAction* addFractionAction; + KAction* addRootAction; + KAction* addSumAction; + KAction* addProductAction; + KAction* addIntegralAction; + KAction* addMatrixAction; + KAction* addUpperLeftAction; + KAction* addLowerLeftAction; + KAction* addUpperRightAction; + KAction* addLowerRightAction; + KAction* addGenericUpperAction; + KAction* addGenericLowerAction; + KAction* removeEnclosingAction; + + KAction* formulaStringAction; + + static bool first_window; + + DCOPObject *m_dcop; +}; + +#endif diff --git a/kformula/kformula_view_iface.cc b/kformula/kformula_view_iface.cc new file mode 100644 index 00000000..4ad217f6 --- /dev/null +++ b/kformula/kformula_view_iface.cc @@ -0,0 +1,254 @@ +/* This file is part of the KDE project + Copyright (C) 2002 Laurent Montel <lmontel@mandrakesoft.com> + + 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 "kformula_view_iface.h" +#include <kformuladocument.h> +#include <kformulaview.h> + +#include "kformula_view.h" +#include "kformula_doc.h" +#include <dcopclient.h> + +KformulaViewIface::KformulaViewIface( KFormulaPartView *view_ ) + : KoViewIface( view_ ) +{ + m_view = view_; +} + +void KformulaViewIface::addThinSpace() +{ + m_view->document()->getDocument()->wrapper()->addThinSpace(); +} + +void KformulaViewIface::addMediumSpace() +{ + m_view->document()->getDocument()->wrapper()->addMediumSpace(); +} + +void KformulaViewIface::addThickSpace() +{ + m_view->document()->getDocument()->wrapper()->addThickSpace(); +} + +void KformulaViewIface::addQuadSpace() +{ + m_view->document()->getDocument()->wrapper()->addQuadSpace(); +} + +void KformulaViewIface::addBracket( int left, int right ) +{ + m_view->document()->getDocument()-> + wrapper()->addBracket( static_cast<KFormula::SymbolType>( left ), + static_cast<KFormula::SymbolType>( right ) ); +} + +void KformulaViewIface::addParenthesis() +{ + m_view->document()->getDocument()->wrapper()->addParenthesis(); +} + +void KformulaViewIface::addSquareBracket() +{ + m_view->document()->getDocument()->wrapper()->addSquareBracket(); +} + +void KformulaViewIface::addCurlyBracket() +{ + m_view->document()->getDocument()->wrapper()->addCurlyBracket(); +} + +void KformulaViewIface::addLineBracket() +{ + m_view->document()->getDocument()->wrapper()->addLineBracket(); +} + +void KformulaViewIface::addFraction() +{ + m_view->document()->getDocument()->wrapper()->addFraction(); +} + +void KformulaViewIface::addRoot() +{ + m_view->document()->getDocument()->wrapper()->addRoot(); +} + +void KformulaViewIface::addIntegral() +{ + m_view->document()->getDocument()->wrapper()->addIntegral(); +} + +void KformulaViewIface::addProduct() +{ + m_view->document()->getDocument()->wrapper()->addProduct(); +} + +void KformulaViewIface::addSum() +{ + m_view->document()->getDocument()->wrapper()->addSum(); +} + +void KformulaViewIface::addMatrix() +{ + m_view->document()->getDocument()->wrapper()->addMatrix(); +} + +void KformulaViewIface::addMatrix( uint rows, uint columns ) +{ + m_view->document()->getDocument()->wrapper()->addMatrix( rows, columns ); +} + +void KformulaViewIface::addOneByTwoMatrix() +{ + m_view->document()->getDocument()->wrapper()->addOneByTwoMatrix(); +} + +void KformulaViewIface::addNameSequence() +{ + m_view->document()->getDocument()->wrapper()->addNameSequence(); +} + +void KformulaViewIface::addLowerLeftIndex() +{ + m_view->document()->getDocument()->wrapper()->addLowerLeftIndex(); +} + +void KformulaViewIface::addUpperLeftIndex() +{ + m_view->document()->getDocument()->wrapper()->addUpperLeftIndex(); +} + +void KformulaViewIface::addLowerRightIndex() +{ + m_view->document()->getDocument()->wrapper()->addLowerRightIndex(); +} + +void KformulaViewIface::addUpperRightIndex() +{ + m_view->document()->getDocument()->wrapper()->addUpperRightIndex(); +} + +void KformulaViewIface::addGenericLowerIndex() +{ + m_view->document()->getDocument()->wrapper()->addGenericLowerIndex(); +} + +void KformulaViewIface::addGenericUpperIndex() +{ + m_view->document()->getDocument()->wrapper()->addGenericUpperIndex(); +} + +void KformulaViewIface::removeEnclosing() +{ + m_view->document()->getDocument()->wrapper()->removeEnclosing(); +} + +void KformulaViewIface::makeGreek() +{ + m_view->document()->getDocument()->wrapper()->makeGreek(); +} + +void KformulaViewIface::insertSymbol( QString name ) +{ + m_view->document()->getDocument()->wrapper()->insertSymbol( name ); +} + +void KformulaViewIface::appendColumn() +{ + m_view->document()->getDocument()->wrapper()->appendColumn(); +} + +void KformulaViewIface::insertColumn() +{ + m_view->document()->getDocument()->wrapper()->insertColumn(); +} + +void KformulaViewIface::removeColumn() +{ + m_view->document()->getDocument()->wrapper()->removeColumn(); +} + +void KformulaViewIface::appendRow() +{ + m_view->document()->getDocument()->wrapper()->appendRow(); +} + +void KformulaViewIface::insertRow() +{ + m_view->document()->getDocument()->wrapper()->insertRow(); +} + +void KformulaViewIface::removeRow() +{ + m_view->document()->getDocument()->wrapper()->removeRow(); +} + +void KformulaViewIface::moveRight( int flag ) +{ + m_view->formulaView()->moveRight( flag ); +} + +void KformulaViewIface::moveUp( int flag ) +{ + m_view->formulaView()->moveUp( flag ); +} + +void KformulaViewIface::moveDown( int flag ) +{ + m_view->formulaView()->moveDown( flag ); +} + +void KformulaViewIface::moveLeft( int flag ) +{ + m_view->formulaView()->moveLeft( flag ); +} + +void KformulaViewIface::moveHome( int flag ) +{ + m_view->formulaView()->moveHome( flag ); +} + +void KformulaViewIface::moveEnd( int flag ) +{ + m_view->formulaView()->moveEnd( flag ); +} + +bool KformulaViewIface::isHome() const +{ + return m_view->formulaView()->isHome(); +} + +bool KformulaViewIface::isEnd() const +{ + return m_view->formulaView()->isEnd(); +} + +void KformulaViewIface::eraseSelection( int direction ) +{ + m_view->formulaView()->eraseSelection( static_cast<KFormula::Direction>( direction ) ); +} + +void KformulaViewIface::addText( QString str ) +{ + m_view->formulaView()->addText( str ); +} + +QStringList KformulaViewIface::readFormulaString( QString text ) +{ + return m_view->readFormulaString( text ); +} diff --git a/kformula/kformula_view_iface.h b/kformula/kformula_view_iface.h new file mode 100644 index 00000000..04f50af4 --- /dev/null +++ b/kformula/kformula_view_iface.h @@ -0,0 +1,95 @@ +/* This file is part of the KDE project + Copyright (C) 2002 Laurent Montel <lmontel@mandrakesoft.com> + + 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. +*/ + +#ifndef KFORMULA_VIEW_IFACE_H +#define KFORMULA_VIEW_IFACE_H + +#include <KoViewIface.h> + +#include <qstring.h> +#include <qstringlist.h> + +class KFormulaPartView; + +class KformulaViewIface : public KoViewIface +{ + K_DCOP +public: + KformulaViewIface( KFormulaPartView *view_ ); +k_dcop: + void addThinSpace(); + void addMediumSpace(); + void addThickSpace(); + void addQuadSpace(); + void addBracket( int left, int right ); + void addParenthesis(); + void addSquareBracket(); + void addCurlyBracket(); + void addLineBracket(); + void addFraction(); + void addRoot(); + void addIntegral(); + void addProduct(); + void addSum(); + void addMatrix(); + void addMatrix( uint rows, uint columns ); + void addOneByTwoMatrix(); + void addNameSequence(); + + void addLowerLeftIndex(); + void addUpperLeftIndex(); + void addLowerRightIndex(); + void addUpperRightIndex(); + void addGenericLowerIndex(); + void addGenericUpperIndex(); + void removeEnclosing(); + void makeGreek(); + void insertSymbol( QString name ); + + void appendColumn(); + void insertColumn(); + void removeColumn(); + void appendRow(); + void insertRow(); + void removeRow(); + + void moveLeft( int flag ); + void moveRight( int flag ); + void moveUp( int flag ); + void moveDown( int flag ); + + void moveHome( int flag ); + void moveEnd( int flag ); + + /** @returns whether the cursor is at the first position. */ + bool isHome() const; + + /** @returns whether the cursor is at the last position. */ + bool isEnd() const; + + void eraseSelection( int direction ); + void addText( QString str ); + + QStringList readFormulaString( QString text ); + +private: + KFormulaPartView *m_view; +}; + +#endif diff --git a/kformula/kformulapart.desktop b/kformula/kformulapart.desktop new file mode 100644 index 00000000..86303e75 --- /dev/null +++ b/kformula/kformulapart.desktop @@ -0,0 +1,119 @@ +[Desktop Entry] +Name=KOffice Formula Component +Name[bg]=Компонент за формули в KOffice +Name[ca]=Component de fórmules de KOffice +Name[cy]=Cydran Fformiwla KOffice +Name[da]=KOffice formelkomponent +Name[de]=KOffice-Komponente für Formeln +Name[el]=Συστατικό μαθηματικών τύπων του KOffice +Name[eo]=KOffice formulkomponanto +Name[es]=Componente de fórmula de KOffice +Name[et]=KOffice'i valemikomponent +Name[eu]=KOffice-en formulen osagaia +Name[fa]=مؤلفۀ فرمول KOffice +Name[fi]=KOfficen kaavakomponentti +Name[fr]=Composant formules de KOffice +Name[fy]=KOffice Formula-komponint +Name[gl]=Componente de Fórmulas de KOffice +Name[he]=רכיב נוסחאות KOffice +Name[hr]=KOffice komponenta formula +Name[hu]=KOffice képletszerkesztő komponens +Name[is]=KOffice formúlu eining +Name[it]=Componente per formule di KOffice +Name[ja]=KOffice 数式コンポーネント +Name[km]=សមាសភាគរូបមន្តKOffice +Name[lv]=KOffice formulu komponente +Name[ms]=Komponen Formula KOffice +Name[nb]=Formelkomponent for KOffice +Name[nds]=Formelkomponent för KOffice +Name[ne]=केडीई कार्यालय सूत्र अवयव +Name[nl]=KOffice Formula-component +Name[nn]=Formelkomponent for KOffice +Name[pl]=Komponent wyrażeń matematycznych dla KOffice +Name[pt]=Componente de Fórmulas do KOffice +Name[pt_BR]=Componente de Fórmulas do KOffice +Name[ru]=Компонент формул KOffice +Name[se]=KOffice hápmokomponeanta +Name[sk]=Modul rovníc pre Koffice +Name[sl]=Komponenta za enačbe za KOffice +Name[sr]=KOffice-ова компонента за формуле +Name[sr@Latn]=KOffice-ova komponenta za formule +Name[sv]=Koffice-formelkomponent +Name[tg]=Формулаи компоненти KOffice +Name[tr]=KOffice Formül Bileşeni +Name[uk]=Компонент формул KOffice +Name[uz]=KOffice formula komponenti +Name[uz@cyrillic]=KOffice формула компоненти +Name[wa]=Componint formule matematike di KOffice +Name[zh_CN]=KOffice 公式组件 +Name[zh_TW]=KOffice Formula 元件 +X-KDE-Library=libkformulapart +MimeType=application/vnd.oasis.opendocument.formula;application/vnd.oasis.opendocument.formula-template;application/x-kformula;application/mathml+xml +Type=Service +ServiceTypes=KOfficePart,KParts/ReadOnlyPart,KParts/ReadWritePart +X-KDE-NativeMimeType=application/vnd.oasis.opendocument.formula +X-KDE-NativeOasisMimeType=application/vnd.oasis.opendocument.formula +X-KDE-ExtraNativeMimeTypes=application/x-kformula,application/vnd.oasis.opendocument.formula-template,application/mathml+xml +GenericName=Formula Editor +GenericName[af]=Formule Redigeerder +GenericName[ar]=مُحَرِّر المعادَلات +GenericName[az]=Formul Editoru +GenericName[bg]=Формули +GenericName[br]=Un aozer formulennoù +GenericName[bs]=Editor matematičkih jednačina +GenericName[ca]=Editor de fórmules +GenericName[cs]=Editor vzorců +GenericName[cy]=Golygydd Fformiwla +GenericName[da]=Formeleditor +GenericName[de]=Formel-Editor +GenericName[el]=Επεξεργαστής μαθηματικών τύπων +GenericName[eo]=Redaktilo por matematikaj formuloj +GenericName[es]=Editor de fórmulas +GenericName[et]=Valemiredaktor +GenericName[eu]=Formulen editorea +GenericName[fa]=ویرایشگر فرمول +GenericName[fi]=Kaavamuokkain +GenericName[fo]=Formulritil +GenericName[fr]=Éditeur de formules +GenericName[fy]=Formulebewurker +GenericName[gl]=Editor de Fórmulas +GenericName[he]=עורך נוסחאות +GenericName[hr]=Uređivač formula +GenericName[hu]=Képletszerkesztő +GenericName[is]=Formúlu ritill +GenericName[it]=Editor di formule +GenericName[ja]=数式エディタ +GenericName[km]=កម្មវិធីនិពន្ធរូបមន្ត +GenericName[lo]=ເຄື່ອງມືແກ້ໄຂສູດຄະນິດສາດ +GenericName[lt]=Formulės redaktorius +GenericName[lv]=Formulu redaktors +GenericName[ms]=Editor Formula +GenericName[mt]=Editur tal-Formuli +GenericName[nb]=Formelredigering +GenericName[nds]=Tabelleneditor +GenericName[ne]=सूत्र सम्पादक +GenericName[nl]=Formulebewerker +GenericName[nn]=Formelredigering +GenericName[pl]=Edytor wyrażeń matematycznych +GenericName[pt]=Editor de Fórmulas +GenericName[pt_BR]=Fórmula +GenericName[ro]=Un editor de formule +GenericName[ru]=Формулы +GenericName[se]=Hápmodoaimmaheaddji +GenericName[sk]=Editor rovníc +GenericName[sl]=Urejevalnik formul +GenericName[sr]=Уређивач формула +GenericName[sr@Latn]=Uređivač formula +GenericName[sv]=Formeleditor +GenericName[ta]=சூத்திரத் தொகுப்பாளர் +GenericName[tg]=Муҳаррири Формула +GenericName[th]=เครื่องมือแก้ไขสูตรคณิตศาสตร์ +GenericName[tr]=Formül Düzenleyici +GenericName[uk]=Редактор формул +GenericName[uz]=Formula tahrirchi +GenericName[uz@cyrillic]=Формула таҳрирчи +GenericName[wa]=Aspougneu d' formules +GenericName[xh]=Umhleli wendlela yokubala +GenericName[zh_CN]=公式编辑器 +GenericName[zh_TW]=方程式編輯器 +Icon=kformula diff --git a/kformula/kformulawidget.cc b/kformula/kformulawidget.cc new file mode 100644 index 00000000..862814e0 --- /dev/null +++ b/kformula/kformulawidget.cc @@ -0,0 +1,157 @@ +/* This file is part of the KDE project + Copyright (C) 2001 Andrea Rizzi <rizzi@kde.org> + Ulrich Kuettler <ulrich.kuettler@mailbox.tu-dresden.de> + + 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 <iostream> + +#include <qpainter.h> + +#include <kapplication.h> +#include <kdebug.h> + +#include <basicelement.h> +#include <formulacursor.h> +#include <formulaelement.h> +#include <kformulacontainer.h> +#include <kformuladocument.h> +#include "kformulawidget.h" + + +KFormulaWidget::KFormulaWidget(KFormula::Container* doc, + QWidget* parent, const char* name, WFlags f) + : QWidget(parent, name, f | WRepaintNoErase | WResizeNoErase), + formulaView(doc) +{ + connect(doc, SIGNAL(formulaChanged(int, int)), + this, SLOT(slotFormulaChanged(int, int))); + connect(&formulaView, SIGNAL(cursorChanged(bool, bool)), + this, SLOT(slotCursorChanged(bool, bool))); + + setFocusPolicy(QWidget::StrongFocus); + setBackgroundMode(NoBackground/*QWidget::PaletteBase*/); + + QRect rect = doc->boundingRect(); + slotFormulaChanged(rect.width(), rect.height()); +} + +KFormulaWidget::~KFormulaWidget() +{ +} + + +QPoint KFormulaWidget::getCursorPoint() const +{ + return formulaView.getCursorPoint(); +} + +void KFormulaWidget::setReadOnly(bool ro) +{ + formulaView.setReadOnly(ro); +} + + +void KFormulaWidget::paintEvent(QPaintEvent* event) +{ + // Always repaint the buffer. This is not so much more work + // than it seems to be as each cursor movement requires a repaint. + QPainter p( &buffer ); + //p.translate( -fr.x(), -fr.y() ); + formulaView.draw( p, event->rect(), colorGroup() ); + + QPainter 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(QKeyEvent* event) +{ + formulaView.keyPressEvent(event); +} + + +void KFormulaWidget::focusInEvent(QFocusEvent* event) +{ + formulaView.focusInEvent(event); +} + +void KFormulaWidget::focusOutEvent(QFocusEvent* event) +{ + formulaView.focusOutEvent(event); +} + +void KFormulaWidget::mousePressEvent(QMouseEvent* event) +{ + formulaView.mousePressEvent(event); +} + +void KFormulaWidget::mouseReleaseEvent(QMouseEvent* event) +{ + formulaView.mouseReleaseEvent(event); +} + +void KFormulaWidget::mouseDoubleClickEvent(QMouseEvent* event) +{ + formulaView.mouseDoubleClickEvent(event); +} + +void KFormulaWidget::mouseMoveEvent(QMouseEvent* event) +{ + formulaView.mouseMoveEvent(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); + update(); + //kdDebug( 40000 ) << "KFormulaWidget::slotFormulaChanged" << endl; +} + +/** + * The document we show. + */ +KFormula::Container* KFormulaWidget::getDocument() +{ + return formulaView.getDocument(); +} + +/** + * Our cursor. + */ +KFormula::FormulaCursor* KFormulaWidget::getCursor() +{ + return formulaView.getCursor(); +} + + +void KFormulaWidget::slotSelectAll() +{ + formulaView.slotSelectAll(); +} + +void KFormulaWidget::slotCursorChanged(bool visible, bool selecting) +{ + emit cursorChanged(visible, selecting); + update(); +} + +#include "kformulawidget.moc" diff --git a/kformula/kformulawidget.h b/kformula/kformulawidget.h new file mode 100644 index 00000000..c266de4d --- /dev/null +++ b/kformula/kformulawidget.h @@ -0,0 +1,117 @@ +/* This file is part of the KDE project + Copyright (C) 2001 Andrea Rizzi <rizzi@kde.org> + Ulrich Kuettler <ulrich.kuettler@mailbox.tu-dresden.de> + + 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. +*/ + +#ifndef KFORMULAWIDGET_H +#define KFORMULAWIDGET_H + +#include <qdom.h> +#include <qpixmap.h> +#include <qpoint.h> +#include <qwidget.h> + +#include <kformuladefs.h> +#include <kformulaview.h> + +KFORMULA_NAMESPACE_BEGIN + +class FormulaCursor; +class Container; + +KFORMULA_NAMESPACE_END + + +/** + * The view. A widget that shows the formula. There are methods + * to move the cursor around. To edit the formula use the document. + */ +class KFormulaWidget : public QWidget { + Q_OBJECT + +public: + KFormulaWidget(KFormula::Container*, QWidget* parent=0, const char* name=0, WFlags f=0); + ~KFormulaWidget(); + + + /** + * @returns the point inside the formula widget where the cursor is. + */ + QPoint getCursorPoint() const; + + /** + * Puts the widget in read only mode. + */ + void setReadOnly(bool ro); + + const KFormula::View* view() const { return &formulaView; } + KFormula::View* view() { return &formulaView; } + +public slots: + + void slotSelectAll(); + +signals: + + /** + * Is emitted every time the cursor might have changed. + */ + void cursorChanged(bool visible, bool selecting); + +protected slots: + + /** + * The formula has changed and needs to be redrawn. + */ + void slotFormulaChanged(int width, int height); + + void slotCursorChanged(bool visible, bool selecting); + +protected: + + virtual void mousePressEvent(QMouseEvent* event); + virtual void mouseReleaseEvent(QMouseEvent* event); + virtual void mouseDoubleClickEvent(QMouseEvent* event); + virtual void mouseMoveEvent(QMouseEvent* event); + + virtual void paintEvent(QPaintEvent* event); + virtual void keyPressEvent(QKeyEvent* event); + virtual void focusInEvent(QFocusEvent* event); + virtual void focusOutEvent(QFocusEvent* event); + + /** + * The document we show. + */ + KFormula::Container* getDocument(); + + /** + * Our cursor. + */ + KFormula::FormulaCursor* getCursor(); + +private: + + /** + * This widget is a wrapper around the actual view. + */ + KFormula::View formulaView; + + QPixmap buffer; +}; + +#endif // KFORMULAWIDGET_H diff --git a/kformula/main.cc b/kformula/main.cc new file mode 100644 index 00000000..825e5f0b --- /dev/null +++ b/kformula/main.cc @@ -0,0 +1,44 @@ + +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Reginald Stadlbauer <reggie@kde.org> + + 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 <KoApplication.h> +#include <kcmdlineargs.h> +#include <klocale.h> +#include <dcopclient.h> + +#include "kformula_aboutdata.h" + +static const KCmdLineOptions options[]= +{ + {"+[file]", I18N_NOOP("File to open"),0}, + KCmdLineLastOption +}; + +extern "C" KFORMULA_EXPORT int kdemain( int argc, char **argv ) +{ + KCmdLineArgs::init( argc, argv, newKFormulaAboutData() ); + KCmdLineArgs::addCmdLineOptions( options ); + + KoApplication app; + + if (!app.start()) + return 1; + return app.exec(); +} diff --git a/kformula/pics/Makefile.am b/kformula/pics/Makefile.am new file mode 100644 index 00000000..974a63b8 --- /dev/null +++ b/kformula/pics/Makefile.am @@ -0,0 +1 @@ +KDE_ICON = kformula diff --git a/kformula/pics/hi16-app-kformula.png b/kformula/pics/hi16-app-kformula.png Binary files differnew file mode 100644 index 00000000..f256ff41 --- /dev/null +++ b/kformula/pics/hi16-app-kformula.png diff --git a/kformula/pics/hi22-app-kformula.png b/kformula/pics/hi22-app-kformula.png Binary files differnew file mode 100644 index 00000000..f6a7c007 --- /dev/null +++ b/kformula/pics/hi22-app-kformula.png diff --git a/kformula/pics/hi32-app-kformula.png b/kformula/pics/hi32-app-kformula.png Binary files differnew file mode 100644 index 00000000..610fe2ff --- /dev/null +++ b/kformula/pics/hi32-app-kformula.png diff --git a/kformula/pics/hi48-app-kformula.png b/kformula/pics/hi48-app-kformula.png Binary files differnew file mode 100644 index 00000000..cbdf184a --- /dev/null +++ b/kformula/pics/hi48-app-kformula.png diff --git a/kformula/tests/oasis-kformula.sh b/kformula/tests/oasis-kformula.sh new file mode 100755 index 00000000..6954148a --- /dev/null +++ b/kformula/tests/oasis-kformula.sh @@ -0,0 +1,87 @@ +#!/bin/bash + +# This script helps finding out problems in the OASIS loading/saving code, +# by converting .kfo -> .odf -> .kfo and comparing the initial and final .kwd files. +# We use the kfo format as a "dump" of the KFormula data, to check if everything is correct +# in memory, but the point is of course to ensure that the .odt has all the information. + +# To use this script, you need to pass the full path to an existing kwd file as argument. +# Don't use a relative path, dcopstart won't handle it +input="$1" + +# Set this to 1 in order to validate the saved oasis document using oasislint +checkoasis="1" + +appname=kformula +oldextension=kfo +oasisextension=odf +oasismimetype=application/vnd.oasis.opendocument.formula + +test -f "$input" || { echo "No such file $input"; exit 1; } + +# Load old native file +appid=`dcopstart $appname $input` +test -n "$appid" || { echo "Error starting $appname!"; exit 1; } +while `dcop $appid Document-0 isLoading` == "true"; do + sleep 1; +done + +# Save again (in case of changes in syntax etc.) +origfile=$PWD/oasisregtest-initial.$oldextension +dcop $appid Document-0 saveAs $origfile || exit 1 +test -f $origfile || exit 1 + +# Save to OASIS +tmpoasisfile=$PWD/oasisregtest.$oasisextension +dcop $appid Document-0 setOutputMimeType $oasismimetype || exit 1 +dcop $appid Document-0 saveAs $tmpoasisfile || exit 1 +test -f $tmpoasisfile || exit 1 + +dcopquit $appid + +# Load resulting OASIS file, convert to old native format +tmpnativefile=$PWD/oasisregtest-final.$oldextension +appid=`dcopstart $appname $tmpoasisfile` +while `dcop $appid Document-0 isLoading` == "true"; do + sleep 1; +done +dcop $appid Document-0 setOutputMimeType "application/x-$appname" || exit 1 +dcop $appid Document-0 saveAs $tmpnativefile || exit 1 +test -f $tmpnativefile || exit 1 + +# Unpack everything +rm -rf oasisregtest-orig +mkdir oasisregtest-orig +rm -rf oasisregtest-final +mkdir oasisregtest-final +rm -rf oasisregtest-oasis +mkdir oasisregtest-oasis +cd oasisregtest-orig || exit 1 +unzip $origfile || exit 1 +cd .. +cd oasisregtest-final || exit 1 +unzip $tmpnativefile || exit 1 +cd .. +# Validate OASIS format +cd oasisregtest-oasis || exit 1 +unzip $tmpoasisfile || exit 1 +if test "$checkoasis" = "1"; then + if type -p oasislint >/dev/null 2>&1; then + for f in content.xml styles.xml meta.xml settings.xml; do + echo "Checking $f..." ; oasislint $f + done + fi + if type -p oasislint-strict >/dev/null 2>&1; then + for f in content.xml styles.xml meta.xml settings.xml; do + echo "Checking $f strict..." && oasislint-strict $f + done + fi +fi +cd .. + +# Compare initial and final "native format" files +diff -urp oasisregtest-orig oasisregtest-final 2>&1 | tee oasisdiff | less + +echo "See oasisregtest-oasis for the OASIS xml files." +echo "For a better diffing mechanism, launch xemacs and paste into a terminal:" +echo "gnudoit '(ediff-files \"$PWD/oasisregtest-orig/maindoc.xml\" \"$PWD/oasisregtest-final/maindoc.xml\")'" diff --git a/kformula/tips b/kformula/tips new file mode 100644 index 00000000..c387a8f3 --- /dev/null +++ b/kformula/tips @@ -0,0 +1,66 @@ +<tip category="KFormula|Keyboard"> +<html> +<p>...that you can use Ctrl-U/Ctrl-L to create an index above or below +the currently selected elements?</p> +</html> +</tip> + +<tip category="KFormula|Filters"> +<html> +<p>...that you can import and export <em>MathML</em> files?</p> +</html> +</tip> + +<tip category="KFormula|General"> +<html> +<p>...to get the most out of KFormula you need to install +the TrueType version of the famous TeX fonts. +You can find them in <a href="http://www.ctan.org">ctan</a> at +<a href="http://www.ctan.org/tex-archive/fonts/cm/ps-type1/bakoma/ttf/?action=/tex-archive/fonts/cm/ps-type1/bakoma/">/tex-archive/fonts/cm/ps-type1/bakoma/</a>. +However you don't need to install all of those. Right now the fonts +<tt>cmbx10</tt>, +<tt>cmex10</tt>, +<tt>cmmi10</tt>, +<tt>cmr10</tt>, +<tt>cmsy10</tt>, +<tt>msam10</tt> +and +<tt>msbm10</tt> +are required. +</p> +</html> +</tip> + +<tip category="KFormula|Keyboard"> +<html> +<p>...that you can use the keys <tt>^</tt> and <tt>_</tt> to create +right upper and lower indices? If you type <tt>Ctrl-^</tt> or +<tt>Ctrl-_</tt> instead, you will get a left index. +</p> +</html> +</tip> + +<tip category="KFormula|Keyboard"> +<html> +<p>...that you can insert any of the many supported symbols by typing its +name? Simply press the backslash key, type the symbol's name and press +space. +</p> +</html> +</tip> + +<tip category="KFormula|Keyboard"> +<html> +<p>...that you can insert Greek letters very easily by typing the +corresponding latin letter and pressing Ctrl-G afterwards? +</p> +</html> +</tip> + +<tip category="KFormula|Keyboard"> +<html> +<p>...that you can insert any number of lines using the <em>Multiline</em> element? +By inserting <tt>&</tt> you can align these lines. +</p> +</html> +</tip> |