Index: trunk/koffice/lib/kformula2/operatorelement.cc =================================================================== --- trunk/koffice/lib/kformula2/operatorelement.cc (revision 83429) +++ trunk/koffice/lib/kformula2/operatorelement.cc (revision 83430) @@ -1,55 +1,62 @@ /* This file is part of the KDE project Copyright (C) 2001 Andrea Rizzi Ulrich Kuettler This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include "operatorelement.h" OperatorElement::OperatorElement(QChar ch) : TextElement(ch) { } /** * Calculates our width and height and * our children's parentPosition. */ void OperatorElement::calcSizes(ContextStyle& context, int parentSize) { TextElement::calcSizes(context, parentSize); QFontMetrics fm(context.getDefaultFont()); spaceWidth = fm.width(' '); setWidth(getWidth()+spaceWidth); } /** * Draws the whole element including its children. * The `parentOrigin' is the point this element's parent starts. * We can use our parentPosition to get our own origin then. */ void OperatorElement::draw(QPainter& painter, ContextStyle& context, int parentSize, const QPoint& parentOrigin) { TextElement::draw(painter, context, parentSize, QPoint(parentOrigin.x()+spaceWidth/2, parentOrigin.y())); } +QDomElement OperatorElement::getElementDom(QDomDocument *doc) +{ +return TextElement::getElementDom(doc); +} + + + Index: trunk/koffice/lib/kformula2/operatorelement.h =================================================================== --- trunk/koffice/lib/kformula2/operatorelement.h (revision 83429) +++ trunk/koffice/lib/kformula2/operatorelement.h (revision 83430) @@ -1,56 +1,60 @@ /* This file is part of the KDE project Copyright (C) 2001 Andrea Rizzi Ulrich Kuettler This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __OPERATORELEMENT_H #define __OPERATORELEMENT_H #include "textelement.h" /** * An textelement that has spaces before and after the char. */ class OperatorElement : public TextElement { public: OperatorElement(QChar ch); /** * Calculates our width and height and * our children's parentPosition. */ virtual void calcSizes(ContextStyle& context, int parentSize); /** * Draws the whole element including its children. * The `parentOrigin' is the point this element's parent starts. * We can use our parentPosition to get our own origin then. */ virtual void draw(QPainter& painter, ContextStyle& context, int parentSize, const QPoint& parentOrigin); + virtual QDomElement getElementDom(QDomDocument *doc); + + + private: /** * The width that is added to the TextElement's width. */ int spaceWidth; }; #endif // __OPERATORELEMENT_H Index: trunk/koffice/lib/kformula2/symbolelement.cc =================================================================== --- trunk/koffice/lib/kformula2/symbolelement.cc (revision 83429) +++ trunk/koffice/lib/kformula2/symbolelement.cc (revision 83430) @@ -1,460 +1,488 @@ /* This file is part of the KDE project Copyright (C) 2001 Andrea Rizzi Ulrich Kuettler This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2. 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include "formulacursor.h" #include "formulaelement.h" #include "sequenceelement.h" #include "symbolelement.h" SymbolElement::SymbolElement(Artwork::SymbolType type, BasicElement* parent) : ComplexElement(parent), symbol(type) { content = new SequenceElement(this); upper = new SequenceElement(this); lower = new SequenceElement(this); } SymbolElement::~SymbolElement() { delete lower; delete upper; delete content; } /** * Calculates our width and height and * our children's parentPosition. */ void SymbolElement::calcSizes(ContextStyle& style, int parentSize) { int mySize = parentSize + getRelativeSize(); symbol.calcSizes(style, mySize); content->calcSizes(style, mySize); symbol.scale(((double)parentSize)/symbol.getHeight()*2); int upperWidth = 0; int upperHeight = 0; if (hasUpper()) { upper->calcSizes(style, mySize); upperWidth = upper->getWidth(); upperHeight = upper->getHeight(); } int lowerWidth = 0; int lowerHeight = 0; if (hasLower()) { lower->calcSizes(style, mySize); lowerWidth = lower->getWidth(); lowerHeight = lower->getHeight(); } // widths int xOffset = QMAX(symbol.getWidth(), QMAX(upperWidth, lowerWidth)); symbol.setX(xOffset - symbol.getWidth()); content->setX(xOffset); setWidth(QMAX(content->getX() + content->getWidth(), QMAX(upperWidth, lowerWidth))); // heights int toMidline = QMAX(content->getMidline(), upperHeight + symbol.getHeight()/2); int fromMidline = QMAX(content->getHeight() - content->getMidline(), lowerHeight + symbol.getHeight()/2); setHeight(toMidline + fromMidline); setMidline(toMidline); symbol.setY(toMidline - symbol.getHeight()/2); content->setY(toMidline - content->getMidline()); if (hasUpper()) { if (upperWidth < symbol.getWidth()) { upper->setX(symbol.getX() + (symbol.getWidth() - upperWidth) / 2); } else { upper->setX(xOffset - upperWidth); } upper->setY(toMidline - upperHeight - symbol.getHeight()/2); } if (hasLower()) { if (lowerWidth < symbol.getWidth()) { lower->setX(symbol.getX() + (symbol.getWidth() - lowerWidth) / 2); } else { lower->setX(xOffset - lowerWidth); } lower->setY(toMidline + symbol.getHeight()/2); } } /** * Draws the whole element including its children. * The `parentOrigin' is the point this element's parent starts. * We can use our parentPosition to get our own origin then. */ void SymbolElement::draw(QPainter& painter, ContextStyle& style, int parentSize, const QPoint& parentOrigin) { QPoint myPos(parentOrigin.x()+getX(), parentOrigin.y()+getY()); int mySize = parentSize + getRelativeSize(); symbol.draw(painter, style, mySize, myPos); content->draw(painter, style, mySize, myPos); if (hasUpper()) { upper->draw(painter, style, mySize, myPos); } if (hasLower()) { lower->draw(painter, style, mySize, myPos); } } // navigation // // The elements are responsible to handle cursor movement themselves. // To do this they need to know the direction the cursor moves and // the element it comes from. // // The cursor might be in normal or in selection mode. /** * Enters this element while moving to the left starting inside * the element `from'. Searches for a cursor position inside * this element or to the left of it. */ void SymbolElement::moveLeft(FormulaCursor* cursor, BasicElement* from) { if (cursor->isSelectionMode()) { getParent()->moveLeft(cursor, this); } else { if (from == getParent()) { content->moveLeft(cursor, this); } else if (from == content) { if (hasLower()) { lower->moveLeft(cursor, this); } else if (hasUpper()) { upper->moveLeft(cursor, this); } else { getParent()->moveLeft(cursor, this); } } else if (from == lower) { if (hasUpper()) { upper->moveLeft(cursor, this); } else { getParent()->moveLeft(cursor, this); } } else if (from == upper) { getParent()->moveLeft(cursor, this); } } } /** * Enters this element while moving to the right starting inside * the element `from'. Searches for a cursor position inside * this element or to the right of it. */ void SymbolElement::moveRight(FormulaCursor* cursor, BasicElement* from) { if (cursor->isSelectionMode()) { getParent()->moveRight(cursor, this); } else { if (from == getParent()) { if (hasUpper()) { upper->moveRight(cursor, this); } else if (hasLower()) { lower->moveRight(cursor, this); } else { content->moveRight(cursor, this); } } else if (from == upper) { if (hasLower()) { lower->moveRight(cursor, this); } else { content->moveRight(cursor, this); } } else if (from == lower) { content->moveRight(cursor, this); } else if (from == content) { getParent()->moveRight(cursor, this); } } } /** * Enters this element while moving up starting inside * the element `from'. Searches for a cursor position inside * this element or above it. */ void SymbolElement::moveUp(FormulaCursor* cursor, BasicElement* from) { if (cursor->isSelectionMode()) { getParent()->moveUp(cursor, this); } else { if (from == content) { if (hasUpper()) { upper->moveLeft(cursor, this); } else { getParent()->moveUp(cursor, this); } } else if (from == upper) { getParent()->moveUp(cursor, this); } else if ((from == getParent()) || (from == lower)) { content->moveRight(cursor, this); } } } /** * Enters this element while moving down starting inside * the element `from'. Searches for a cursor position inside * this element or below it. */ void SymbolElement::moveDown(FormulaCursor* cursor, BasicElement* from) { if (cursor->isSelectionMode()) { getParent()->moveDown(cursor, this); } else { if (from == content) { if (hasLower()) { lower->moveLeft(cursor, this); } else { getParent()->moveDown(cursor, this); } } else if (from == lower) { getParent()->moveDown(cursor, this); } else if ((from == getParent()) || (from == upper)) { content->moveRight(cursor, this); } } } // children // main child // // If an element has children one has to become the main one. void SymbolElement::setMainChild(SequenceElement* child) { formula()->elementRemoval(content); content = child; content->setParent(this); formula()->changed(); } /** * Inserts all new children at the cursor position. Places the * cursor according to the direction. * * You only can insert one index at a time. So the list must contain * exactly on SequenceElement. And the index you want to insert * must not exist already. * * The list will be emptied but stays the property of the caller. */ void SymbolElement::insert(FormulaCursor* cursor, QList& newChildren, Direction direction) { SequenceElement* index = static_cast(newChildren.take(0)); index->setParent(this); switch (cursor->getPos()) { case upperPos: upper = index; break; case lowerPos: lower = index; break; default: // this is an error! return; } if (direction == beforeCursor) { index->moveLeft(cursor, this); } else { index->moveRight(cursor, this); } cursor->setSelection(false); formula()->changed(); } /** * Removes all selected children and returns them. Places the * cursor to where the children have been. * * The cursor has to be inside one of our indexes which is supposed * to be empty. The index will be removed and the cursor will * be placed to the removed index so it can be inserted again. * This methode is called by SequenceElement::remove only. * * The ownership of the list is passed to the caller. */ void SymbolElement::remove(FormulaCursor* cursor, QList& removedChildren, Direction direction) { int pos = cursor->getPos(); switch (pos) { case upperPos: removedChildren.append(upper); formula()->elementRemoval(upper); upper = 0; setToUpper(cursor); break; case lowerPos: removedChildren.append(lower); formula()->elementRemoval(lower); lower = 0; setToLower(cursor); break; case contentPos: { BasicElement* parent = getParent(); parent->selectChild(cursor, this); parent->remove(cursor, removedChildren, direction); break; } } formula()->changed(); } /** * Moves the cursor to a normal place where new elements * might be inserted. */ void SymbolElement::normalize(FormulaCursor* cursor, Direction direction) { if (direction == BasicElement::beforeCursor) { content->moveLeft(cursor, this); } else { content->moveRight(cursor, this); } } /** * Returns the child at the cursor. */ BasicElement* SymbolElement::getChild(FormulaCursor* cursor, Direction) { int pos = cursor->getPos(); switch (pos) { case contentPos: return content; case upperPos: return upper; case lowerPos: return lower; } return 0; } /** * Sets the cursor to select the child. The mark is placed before, * the position behind it. */ void SymbolElement::selectChild(FormulaCursor* cursor, BasicElement* child) { if (child == content) { setToContent(cursor); } else if (child == upper) { setToUpper(cursor); } else if (child == lower) { setToLower(cursor); } } void SymbolElement::setToUpper(FormulaCursor* cursor) { cursor->setTo(this, upperPos); } void SymbolElement::setToLower(FormulaCursor* cursor) { cursor->setTo(this, lowerPos); } /** * Sets the cursor to point to the place where the content is. * There always is a content so this is not a useful place. * No insertion or removal will succeed as long as the cursor is * there. */ void SymbolElement::setToContent(FormulaCursor* cursor) { cursor->setTo(this, contentPos); } void SymbolElement::moveToUpperIndex(FormulaCursor* cursor, Direction direction) { if (hasUpper()) { if (direction == beforeCursor) { upper->moveLeft(cursor, this); } else { upper->moveRight(cursor, this); } } } void SymbolElement::moveToLowerIndex(FormulaCursor* cursor, Direction direction) { if (hasLower()) { if (direction == beforeCursor) { lower->moveLeft(cursor, this); } else { lower->moveRight(cursor, this); } } } + +QDomElement SymbolElement::getElementDom(QDomDocument *doc) +{ + QDomElement de=doc->createElement("SYMBOL"); + int sz=getRelativeSize(); + if(sz!=0) { + de.setAttribute("SIZE",sz); + } + QDomElement con=doc->createElement("CONTENT"); + con.appendChild(content->getElementDom(doc)); + de.appendChild(con); + + de.setAttribute("TYPE","not yet implemented"); + + if(hasLower()) { + QDomElement ind=doc->createElement("LOWER"); + ind.appendChild(lower->getElementDom(doc)); + de.appendChild(ind); + } + if(hasUpper()) { + QDomElement ind=doc->createElement("UPPER"); + ind.appendChild(upper->getElementDom(doc)); + de.appendChild(ind); + } + return de; +} + + Index: trunk/koffice/lib/kformula2/matrixelement.h =================================================================== --- trunk/koffice/lib/kformula2/matrixelement.h (revision 83429) +++ trunk/koffice/lib/kformula2/matrixelement.h (revision 83430) @@ -1,124 +1,128 @@ /* This file is part of the KDE project Copyright (C) 2001 Andrea Rizzi Ulrich Kuettler This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2. 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __MATRIXELEMENT_H #define __MATRIXELEMENT_H #include #include "basicelement.h" /** * A matrix. */ class MatrixElement : public BasicElement { public: MatrixElement(int rows, int columns, BasicElement* parent = 0); ~MatrixElement(); // drawing // // Drawing depends on a context which knows the required properties like // fonts, spaces and such. // It is essential to calculate elements size with the same context // before you draw. /** * Calculates our width and height and * our children's parentPosition. */ virtual void calcSizes(ContextStyle& context, int parentSize); /** * Draws the whole element including its children. * The `parentOrigin' is the point this element's parent starts. * We can use our parentPosition to get our own origin then. */ virtual void draw(QPainter& painter, ContextStyle& context, int parentSize, const QPoint& parentOrigin); // navigation // // The elements are responsible to handle cursor movement themselves. // To do this they need to know the direction the cursor moves and // the element it comes from. // // The cursor might be in normal or in selection mode. /** * Enters this element while moving to the left starting inside * the element `from'. Searches for a cursor position inside * this element or to the left of it. */ virtual void moveLeft(FormulaCursor* cursor, BasicElement* from); /** * Enters this element while moving to the right starting inside * the element `from'. Searches for a cursor position inside * this element or to the right of it. */ virtual void moveRight(FormulaCursor* cursor, BasicElement* from); /** * Enters this element while moving up starting inside * the element `from'. Searches for a cursor position inside * this element or above it. */ virtual void moveUp(FormulaCursor*, BasicElement*); /** * Enters this element while moving down starting inside * the element `from'. Searches for a cursor position inside * this element or below it. */ virtual void moveDown(FormulaCursor*, BasicElement*); /** * Sets the cursor inside this element to its start position. * For most elements that is the main child. */ virtual void goInside(FormulaCursor* cursor); + + + virtual QDomElement getElementDom(QDomDocument *doc); + private: uint getRows() { return content.count(); } uint getColumns() { return content.at(0)->count(); } SequenceElement* getElement(uint row, uint column) { return content.at(row)->at(column); } /** * Searches throught the matrix for the element. Sets the * row and column if found. * Returns true if the element was found. false otherwise. */ bool searchElement(BasicElement* element, int& row, int& column); /** * The elements we contain. */ QList > content; }; #endif // __MATRIXELEMENT_H Index: trunk/koffice/lib/kformula2/symbolelement.h =================================================================== --- trunk/koffice/lib/kformula2/symbolelement.h (revision 83429) +++ trunk/koffice/lib/kformula2/symbolelement.h (revision 83430) @@ -1,199 +1,202 @@ /* This file is part of the KDE project Copyright (C) 2001 Andrea Rizzi Ulrich Kuettler This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2. 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __SYMBOLELEMENT_H #define __SYMBOLELEMENT_H #include "artwork.h" #include "complexelement.h" /** * A symbol is simply a piece of art. */ class SymbolElement : public ComplexElement { public: enum { contentPos, upperPos, lowerPos }; SymbolElement(Artwork::SymbolType type, BasicElement* parent = 0); ~SymbolElement(); // drawing // // Drawing depends on a context which knows the required properties like // fonts, spaces and such. // It is essential to calculate elements size with the same context // before you draw. /** * Calculates our width and height and * our children's parentPosition. */ virtual void calcSizes(ContextStyle& context, int parentSize); /** * Draws the whole element including its children. * The `parentOrigin' is the point this element's parent starts. * We can use our parentPosition to get our own origin then. */ virtual void draw(QPainter& painter, ContextStyle& context, int parentSize, const QPoint& parentOrigin); // navigation // // The elements are responsible to handle cursor movement themselves. // To do this they need to know the direction the cursor moves and // the element it comes from. // // The cursor might be in normal or in selection mode. /** * Enters this element while moving to the left starting inside * the element `from'. Searches for a cursor position inside * this element or to the left of it. */ virtual void moveLeft(FormulaCursor* cursor, BasicElement* from); /** * Enters this element while moving to the right starting inside * the element `from'. Searches for a cursor position inside * this element or to the right of it. */ virtual void moveRight(FormulaCursor* cursor, BasicElement* from); /** * Enters this element while moving up starting inside * the element `from'. Searches for a cursor position inside * this element or above it. */ virtual void moveUp(FormulaCursor* cursor, BasicElement* from); /** * Enters this element while moving down starting inside * the element `from'. Searches for a cursor position inside * this element or below it. */ virtual void moveDown(FormulaCursor* cursor, BasicElement* from); // children /** * Removes the child. If this was the main child this element might * request its own removal. * The cursor is the one that caused the removal. It has to be moved * to the place any user expects the cursor after that particular * element has been removed. */ //virtual void removeChild(FormulaCursor* cursor, BasicElement* child); // main child // // If an element has children one has to become the main one. virtual SequenceElement* getMainChild() { return content; } virtual void setMainChild(SequenceElement*); /** * Inserts all new children at the cursor position. Places the * cursor according to the direction. * * You only can insert one index at a time. So the list must contain * exactly on SequenceElement. And the index you want to insert * must not exist already. * * The list will be emptied but stays the property of the caller. */ virtual void insert(FormulaCursor*, QList&, Direction); /** * Removes all selected children and returns them. Places the * cursor to where the children have been. * * The cursor has to be inside one of our indexes which is supposed * to be empty. The index will be removed and the cursor will * be placed to the removed index so it can be inserted again. * This methode is called by SequenceElement::remove only. * * The ownership of the list is passed to the caller. */ virtual void remove(FormulaCursor*, QList&, Direction); /** * Moves the cursor to a normal place where new elements * might be inserted. */ virtual void normalize(FormulaCursor*, Direction); /** * Returns the child at the cursor. */ virtual BasicElement* getChild(FormulaCursor*, Direction = beforeCursor); /** * Sets the cursor to select the child. The mark is placed before, * the position behind it. */ virtual void selectChild(FormulaCursor* cursor, BasicElement* child); bool hasUpper() const { return upper != 0; } bool hasLower() const { return lower != 0; } // If we want to create an index we need a cursor that points there. void setToUpper(FormulaCursor* cursor); void setToLower(FormulaCursor* cursor); // ComplexElement // Moves the cursor inside the index. The index has to exist. virtual void moveToUpperIndex(FormulaCursor*, Direction); virtual void moveToLowerIndex(FormulaCursor*, Direction); // Sets the cursor to point to the place where the index normaly // is. These functions are only used if there is no such index and // we want to insert them. virtual void setToUpperIndex(FormulaCursor* cursor) { setToUpper(cursor); } virtual void setToLowerIndex(FormulaCursor* cursor) { setToLower(cursor); } // Tells whether we own those indexes virtual bool hasUpperIndex() const { return hasUpper(); } virtual bool hasLowerIndex() const { return hasLower(); } + virtual QDomElement getElementDom(QDomDocument *doc); + + private: void setToContent(FormulaCursor* cursor); SequenceElement* content; SequenceElement* upper; SequenceElement* lower; /** * Our symbol. */ Artwork symbol; }; #endif // __SYMBOLELEMENT_H Index: trunk/koffice/lib/kformula2/textelement.cc =================================================================== --- trunk/koffice/lib/kformula2/textelement.cc (revision 83429) +++ trunk/koffice/lib/kformula2/textelement.cc (revision 83430) @@ -1,126 +1,124 @@ /* This file is part of the KDE project Copyright (C) 2001 Andrea Rizzi Ulrich Kuettler This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // Debug #include #include #include #include "basicelement.h" #include "textelement.h" #include "contextstyle.h" TextElement::TextElement(QChar ch, BasicElement* parent) : BasicElement(parent), character(ch) { } ostream& TextElement::output(ostream& stream) { stream << "TextElement: " << character << ", "; BasicElement::output(stream); return stream; } /** * Calculates our width and height and * our children's parentPosition. */ void TextElement::calcSizes(ContextStyle& context, int parentSize) { int mySize = parentSize + getRelativeSize(); //QFontMetrics fm = context.fontMetrics(); QFont font = context.getDefaultFont(); font.setPointSize(mySize); QFontMetrics fm(font); setWidth(fm.width(character)); setHeight(fm.height()); setMidline(getHeight() / 2); baseline = fm.ascent(); } /** * Draws the whole element including its children. * The `parentOrigin' is the point this element's parent starts. * We can use our parentPosition to get our own origin then. */ void TextElement::draw(QPainter& painter, ContextStyle& context, int parentSize, const QPoint& parentOrigin) { int mySize = parentSize + getRelativeSize(); //context.setupPainter(painter); //cerr << "TextElement::draw: " << parentOrigin.x()+getX() << " " << parentOrigin.y()+getY()+baseline << " " << character << "\n"; QFont font = context.getDefaultFont(); font.setPointSize(mySize); painter.setFont(font); painter.setPen(context.getDefaultColor()); painter.drawText(parentOrigin.x()+getX(), parentOrigin.y()+getY()+baseline, character); } // navigation // // The elements are responsible to handle cursor movement themselves. // To do this they need to know the direction the cursor moves and // the element it comes from. // // The cursor might be in normal or in selection mode. /** * Enters this element while moving to the left starting inside * the element `from'. Searches for a cursor position inside * this element or to the left of it. */ void TextElement::moveLeft(FormulaCursor* cursor, BasicElement*) { getParent()->moveLeft(cursor, this); } /** * Enters this element while moving to the right starting inside * the element `from'. Searches for a cursor position inside * this element or to the right of it. */ void TextElement::moveRight(FormulaCursor* cursor, BasicElement*) { getParent()->moveRight(cursor, this); } QDomElement TextElement::getElementDom(QDomDocument *doc) { QDomElement de=doc->createElement("TEXT"); int sz=getRelativeSize(); if(sz!=0) { de.setAttribute("SIZE",sz); } //May be this is wrong de.setAttribute("CHAR",QString(character)); - cerr << "TAG: " << (const char *)de.tagName().latin1() << endl; - cerr << "end of text" << endl; return de; } Index: trunk/koffice/lib/kformula2/matrixelement.cc =================================================================== --- trunk/koffice/lib/kformula2/matrixelement.cc (revision 83429) +++ trunk/koffice/lib/kformula2/matrixelement.cc (revision 83430) @@ -1,315 +1,342 @@ /* This file is part of the KDE project Copyright (C) 2001 Andrea Rizzi Ulrich Kuettler This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2. 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include "formulacursor.h" #include "matrixelement.h" #include "sequenceelement.h" MatrixElement::MatrixElement(int rows, int columns, BasicElement* parent) : BasicElement(parent) { for (uint r = 0; r < rows; r++) { QList* list = new QList; list->setAutoDelete(true); for (uint c = 0; c < columns; c++) { list->append(new SequenceElement(this)); } content.append(list); } content.setAutoDelete(true); } MatrixElement::~MatrixElement() { } // drawing // // Drawing depends on a context which knows the required properties like // fonts, spaces and such. // It is essential to calculate elements size with the same context // before you draw. /** * Calculates our width and height and * our children's parentPosition. */ void MatrixElement::calcSizes(ContextStyle& style, int parentSize) { int mySize = parentSize + getRelativeSize(); QArray toMidlines(getRows()); QArray fromMidlines(getRows()); QArray widths(getColumns()); toMidlines.fill(0); fromMidlines.fill(0); widths.fill(0); uint rows = getRows(); uint columns = getColumns(); for (uint r = 0; r < rows; r++) { QList* list = content.at(r); for (uint c = 0; c < columns; c++) { SequenceElement* element = list->at(c); element->calcSizes(style, mySize); toMidlines[r] = QMAX(toMidlines[r], element->getMidline()); fromMidlines[r] = QMAX(fromMidlines[r], element->getHeight()-element->getMidline()); widths[c] = QMAX(widths[c], element->getWidth()); } } int dist = style.getDistance(); int yPos = 0; for (uint r = 0; r < rows; r++) { QList* list = content.at(r); int xPos = 0; yPos += toMidlines[r]; for (uint c = 0; c < columns; c++) { SequenceElement* element = list->at(c); switch (style.getMatrixAlignment()) { case ContextStyle::left: element->setX(xPos); break; case ContextStyle::center: element->setX(xPos + (widths[c] - element->getWidth())/2); break; case ContextStyle::right: element->setX(xPos + widths[c] - element->getWidth()); break; } element->setY(yPos - element->getMidline()); xPos += widths[c] + dist; } yPos += fromMidlines[r] + dist; } int width = dist * (columns - 1); int height = dist * (rows - 1); for (uint r = 0; r < rows; r++) height += toMidlines[r] + fromMidlines[r]; for (uint c = 0; c < columns; c++) width += widths[c]; setWidth(width); setHeight(height); setMidline(height/2); } /** * Draws the whole element including its children. * The `parentOrigin' is the point this element's parent starts. * We can use our parentPosition to get our own origin then. */ void MatrixElement::draw(QPainter& painter, ContextStyle& style, int parentSize, const QPoint& parentOrigin) { QPoint myPos(parentOrigin.x()+getX(), parentOrigin.y()+getY()); int mySize = parentSize + getRelativeSize(); uint rows = getRows(); uint columns = getColumns(); for (uint r = 0; r < rows; r++) { for (uint c = 0; c < columns; c++) { getElement(r, c)->draw(painter, style, mySize, myPos); } } // Debug //painter.setPen(Qt::red); //painter.drawRect(myPos.x(), myPos.y(), getWidth(), getHeight()); } // navigation // // The elements are responsible to handle cursor movement themselves. // To do this they need to know the direction the cursor moves and // the element it comes from. // // The cursor might be in normal or in selection mode. /** * Enters this element while moving to the left starting inside * the element `from'. Searches for a cursor position inside * this element or to the left of it. */ void MatrixElement::moveLeft(FormulaCursor* cursor, BasicElement* from) { if (cursor->isSelectionMode()) { getParent()->moveLeft(cursor, this); } else { if (from == getParent()) { getElement(getRows()-1, getColumns()-1)->moveLeft(cursor, this); } else { int row = 0; int column = 0; if (searchElement(from, row, column)) { if (column > 0) { getElement(row, column-1)->moveLeft(cursor, this); } else if (row > 0) { getElement(row-1, getColumns()-1)->moveLeft(cursor, this); } else { getParent()->moveLeft(cursor, this); } } else { getParent()->moveLeft(cursor, this); } } } } /** * Enters this element while moving to the right starting inside * the element `from'. Searches for a cursor position inside * this element or to the right of it. */ void MatrixElement::moveRight(FormulaCursor* cursor, BasicElement* from) { if (cursor->isSelectionMode()) { getParent()->moveRight(cursor, this); } else { if (from == getParent()) { getElement(0, 0)->moveRight(cursor, this); } else { int row = 0; int column = 0; if (searchElement(from, row, column)) { if (column < getColumns()-1) { getElement(row, column+1)->moveRight(cursor, this); } else if (row < getRows()-1) { getElement(row+1, 0)->moveRight(cursor, this); } else { getParent()->moveRight(cursor, this); } } else { getParent()->moveRight(cursor, this); } } } } /** * Enters this element while moving up starting inside * the element `from'. Searches for a cursor position inside * this element or above it. */ void MatrixElement::moveUp(FormulaCursor* cursor, BasicElement* from) { if (cursor->isSelectionMode()) { getParent()->moveUp(cursor, this); } else { if (from == getParent()) { getElement(0, 0)->moveRight(cursor, this); } else { int row = 0; int column = 0; if (searchElement(from, row, column)) { if (row > 0) { getElement(row-1, column)->moveRight(cursor, this); } else { getParent()->moveUp(cursor, this); } } else { getParent()->moveUp(cursor, this); } } } } /** * Enters this element while moving down starting inside * the element `from'. Searches for a cursor position inside * this element or below it. */ void MatrixElement::moveDown(FormulaCursor* cursor, BasicElement* from) { if (cursor->isSelectionMode()) { getParent()->moveDown(cursor, this); } else { if (from == getParent()) { getElement(0, 0)->moveRight(cursor, this); } else { int row = 0; int column = 0; if (searchElement(from, row, column)) { if (row < getRows()-1) { getElement(row+1, column)->moveRight(cursor, this); } else { getParent()->moveDown(cursor, this); } } else { getParent()->moveDown(cursor, this); } } } } /** * Sets the cursor inside this element to its start position. * For most elements that is the main child. */ void MatrixElement::goInside(FormulaCursor* cursor) { getElement(0, 0)->moveRight(cursor, this); } bool MatrixElement::searchElement(BasicElement* element, int& row, int& column) { uint rows = getRows(); uint columns = getColumns(); for (uint r = 0; r < rows; r++) { for (uint c = 0; c < columns; c++) { if (element == getElement(r, c)) { row = r; column = c; return true; } } } return false; } + +QDomElement MatrixElement::getElementDom(QDomDocument *doc) +{ + QDomElement de=doc->createElement("MATRIX"); + int sz=getRelativeSize(); + if(sz!=0) { + de.setAttribute("SIZE",sz); + } + uint rows = getRows(); + uint cols = getColumns(); + + de.setAttribute("ROWS",rows); + de.setAttribute("COULMNS",cols); + + for (uint i = 0; i < rows; i++) { + for (uint j = 0; j < cols; j++) { + QDomElement tmpEleDom=getElement(i,j)->getElementDom(doc); + de.appendChild(tmpEleDom); + + } + de.appendChild(doc->createComment("end of row")); + } + + return de; +} + +