summaryrefslogtreecommitdiffstats
path: root/tqtinterface/qt4/src/kernel/tqrichtext.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tqtinterface/qt4/src/kernel/tqrichtext.cpp')
-rw-r--r--tqtinterface/qt4/src/kernel/tqrichtext.cpp16625
1 files changed, 0 insertions, 16625 deletions
diff --git a/tqtinterface/qt4/src/kernel/tqrichtext.cpp b/tqtinterface/qt4/src/kernel/tqrichtext.cpp
deleted file mode 100644
index 644255b..0000000
--- a/tqtinterface/qt4/src/kernel/tqrichtext.cpp
+++ /dev/null
@@ -1,16625 +0,0 @@
-#include "tqtglobaldefines.h"
-
-#ifdef USE_QT4
-// #if 0
-
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the Qt3Support module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial Usage
-** Licensees holding valid Qt Commercial licenses may use this file in
-** accordance with the Qt Commercial License Agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Nokia.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "tqrichtext_p.h"
-
-#ifndef QT_NO_RICHTEXT
-
-#include "Qt/qbitmap.h"
-#include "Qt/qapplication.h"
-#include "tqcleanuphandler.h"
-#include "Qt/qcursor.h"
-#include "Qt/qdatastream.h"
-#include "tqdragobject.h"
-#include "Qt/qdrawutil.h"
-#include "Qt/qfile.h"
-#include "Qt/qfileinfo.h"
-#include "Qt/qfont.h"
-#include "Qt/qimage.h"
-#include "Qt/qmap.h"
-#include "Qt/qmime.h"
-#include "tqpaintdevicemetrics.h"
-#include "tqpainter.h"
-#include "tqstringlist.h"
-#include "Qt/qstyle.h"
-#include "Qt/qstyleoption.h"
-#include "tqstylesheet.h"
-#include "Qt/qtextstream.h"
-#include "private/qt4_qtextengine_p.h"
-// #include <private/qunicodetables_p.h>
-
-#include <stdlib.h>
-
-#if defined(Q_WS_X11)
-// #include "qx11info_x11.h"
-#endif
-
-QT_BEGIN_NAMESPACE
-
-static TQTextCursor* richTextExportStart = 0;
-static TQTextCursor* richTextExportEnd = 0;
-
-class TQTextFormatCollection;
-
-const int border_tolerance = 2;
-
-#ifdef Q_WS_WIN
-QT_BEGIN_INCLUDE_NAMESPACE
-#include "qt_windows.h"
-QT_END_INCLUDE_NAMESPACE
-#endif
-
-static inline bool is_printer(TQPainter *p)
-{
- if (!p || !p->device())
- return false;
- return p->device()->devType() == QInternal::Printer;
-}
-
-static inline int scale(int value, TQPainter *painter)
-{
- if (is_printer(painter)) {
- TQPaintDeviceMetrics metrics(painter->device());
-#if defined(Q_WS_X11)
- value = value * metrics.logicalDpiY() /
- QX11Info::appDpiY(painter->tqdevice()->x11Screen());
-#elif defined (Q_WS_WIN)
- HDC hdc = GetDC(0);
- int gdc = GetDeviceCaps(hdc, LOGPIXELSY);
- if (gdc)
- value = value * metrics.logicalDpiY() / gdc;
- ReleaseDC(0, hdc);
-#elif defined (Q_WS_MAC)
- value = value * metrics.logicalDpiY() / 75; // ##### FIXME
-#elif defined (Q_WS_QWS)
- value = value * metrics.logicalDpiY() / 75;
-#endif
- }
- return value;
-}
-
-
-static inline bool isBreakable(TQTextString *string, int pos)
-{
- if (string->at(pos).nobreak)
- return false;
- return (pos < string->length()-1 && string->at(pos+1).softBreak);
-}
-
-// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-void TQTextCommandHistory::addCommand(TQTextCommand *cmd)
-{
- if (current < history.count() - 1) {
- QList<TQTextCommand *> commands;
-
- for (int i = 0; i <= current; ++i)
- commands.insert(i, history.takeFirst());
-
- commands.append(cmd);
- while (!history.isEmpty())
- delete history.takeFirst();
- history = commands;
- } else {
- history.append(cmd);
- }
-
- if (history.count() > steps)
- delete history.takeFirst();
- else
- ++current;
-}
-
-TQTextCursor *TQTextCommandHistory::undo(TQTextCursor *c)
-{
- if (current > -1) {
- TQTextCursor *c2 = history.at(current)->unexecute(c);
- --current;
- return c2;
- }
- return 0;
-}
-
-TQTextCursor *TQTextCommandHistory::redo(TQTextCursor *c)
-{
- if (current > -1) {
- if (current < history.count() - 1) {
- ++current;
- return history.at(current)->execute(c);
- }
- } else {
- if (history.count() > 0) {
- ++current;
- return history.at(current)->execute(c);
- }
- }
- return 0;
-}
-
-bool TQTextCommandHistory::isUndoAvailable()
-{
- return current > -1;
-}
-
-bool TQTextCommandHistory::isRedoAvailable()
-{
- return (current > -1 && current < history.count() - 1) || (current == -1 && history.count() > 0);
-}
-
-// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-TQTextDeleteCommand::TQTextDeleteCommand(TQTextDocument *dc, int i, int idx, const QVector<TQTextStringChar> &str,
- const QByteArray& oldStyleInfo)
- : TQTextCommand(dc), id(i), index(idx), parag(0), text(str), styleInformation(oldStyleInfo)
-{
- for (int j = 0; j < (int)text.size(); ++j) {
- if (text[j].format())
- text[j].format()->addRef();
- }
-}
-
-TQTextDeleteCommand::TQTextDeleteCommand(TQTextParagraph *p, int idx, const QVector<TQTextStringChar> &str)
- : TQTextCommand(0), id(-1), index(idx), parag(p), text(str)
-{
- for (int i = 0; i < (int)text.size(); ++i) {
- if (text[i].format())
- text[i].format()->addRef();
- }
-}
-
-TQTextDeleteCommand::~TQTextDeleteCommand()
-{
- for (int i = 0; i < (int)text.size(); ++i) {
- if (text[i].format())
- text[i].format()->removeRef();
- }
- text.resize(0);
-}
-
-TQTextCursor *TQTextDeleteCommand::execute(TQTextCursor *c)
-{
- TQTextParagraph *s = doc ? doc->paragAt(id) : parag;
- if (!s) {
- qWarning("can't locate parag at %d, last parag: %d", id, doc->lastParagraph()->paragId());
- return 0;
- }
-
- cursor.setParagraph(s);
- cursor.setIndex(index);
- int len = text.size();
- if (c)
- *c = cursor;
- if (doc) {
- doc->setSelectionStart(TQTextDocument::Temp, cursor);
- for (int i = 0; i < len; ++i)
- cursor.gotoNextLetter();
- doc->setSelectionEnd(TQTextDocument::Temp, cursor);
- doc->removeSelectedText(TQTextDocument::Temp, &cursor);
- if (c)
- *c = cursor;
- } else {
- s->remove(index, len);
- }
-
- return c;
-}
-
-TQTextCursor *TQTextDeleteCommand::unexecute(TQTextCursor *c)
-{
- TQTextParagraph *s = doc ? doc->paragAt(id) : parag;
- if (!s) {
- qWarning("can't locate parag at %d, last parag: %d", id, doc->lastParagraph()->paragId());
- return 0;
- }
-
- cursor.setParagraph(s);
- cursor.setIndex(index);
- TQString str = TQTextString::toString(text);
- cursor.insert(str, true, &text);
- if (c)
- *c = cursor;
- cursor.setParagraph(s);
- cursor.setIndex(index);
-
-#ifndef QT_NO_DATASTREAM
- if (!styleInformation.isEmpty()) {
- QDataStream styleStream(&styleInformation, IO_ReadOnly);
- int num;
- styleStream >> num;
- TQTextParagraph *p = s;
- while (num-- && p) {
- p->readStyleInformation(styleStream);
- p = p->next();
- }
- }
-#endif
- s = cursor.paragraph();
- while (s) {
- s->format();
- s->setChanged(true);
- if (s == c->paragraph())
- break;
- s = s->next();
- }
-
- return &cursor;
-}
-
-TQTextFormatCommand::TQTextFormatCommand(TQTextDocument *dc, int sid, int sidx, int eid, int eidx,
- const QVector<TQTextStringChar> &old, TQTextFormat *f, int fl)
- : TQTextCommand(dc), startId(sid), startIndex(sidx), endId(eid), endIndex(eidx), format(f), oldFormats(old), flags(fl)
-{
- format = dc->formatCollection()->format(f);
- for (int j = 0; j < (int)oldFormats.size(); ++j) {
- if (oldFormats[j].format())
- oldFormats[j].format()->addRef();
- }
-}
-
-TQTextFormatCommand::~TQTextFormatCommand()
-{
- format->removeRef();
- for (int j = 0; j < (int)oldFormats.size(); ++j) {
- if (oldFormats[j].format())
- oldFormats[j].format()->removeRef();
- }
-}
-
-TQTextCursor *TQTextFormatCommand::execute(TQTextCursor *c)
-{
- TQTextParagraph *sp = doc->paragAt(startId);
- TQTextParagraph *ep = doc->paragAt(endId);
- if (!sp || !ep)
- return c;
-
- TQTextCursor start(doc);
- start.setParagraph(sp);
- start.setIndex(startIndex);
- TQTextCursor end(doc);
- end.setParagraph(ep);
- end.setIndex(endIndex);
-
- doc->setSelectionStart(TQTextDocument::Temp, start);
- doc->setSelectionEnd(TQTextDocument::Temp, end);
- doc->setFormat(TQTextDocument::Temp, format, flags);
- doc->removeSelection(TQTextDocument::Temp);
- if (endIndex == ep->length())
- end.gotoLeft();
- *c = end;
- return c;
-}
-
-TQTextCursor *TQTextFormatCommand::unexecute(TQTextCursor *c)
-{
- TQTextParagraph *sp = doc->paragAt(startId);
- TQTextParagraph *ep = doc->paragAt(endId);
- if (!sp || !ep)
- return 0;
-
- int idx = startIndex;
- int fIndex = 0;
- while ( fIndex < int(oldFormats.size()) ) {
- if (oldFormats.at(fIndex).c == TQLatin1Char('\n')) {
- if (idx > 0) {
- if (idx < sp->length() && fIndex > 0)
- sp->setFormat(idx, 1, oldFormats.at(fIndex - 1).format());
- if (sp == ep)
- break;
- sp = sp->next();
- idx = 0;
- }
- fIndex++;
- }
- if (oldFormats.at(fIndex).format())
- sp->setFormat(idx, 1, oldFormats.at(fIndex).format());
- idx++;
- fIndex++;
- if (fIndex >= (int)oldFormats.size())
- break;
- if (idx >= sp->length()) {
- if (sp == ep)
- break;
- sp = sp->next();
- idx = 0;
- }
- }
-
- TQTextCursor end(doc);
- end.setParagraph(ep);
- end.setIndex(endIndex);
- if (endIndex == ep->length())
- end.gotoLeft();
- *c = end;
- return c;
-}
-
-TQTextStyleCommand::TQTextStyleCommand(TQTextDocument *dc, int fParag, int lParag, const QByteArray& beforeChange)
- : TQTextCommand(dc), firstParag(fParag), lastParag(lParag), before(beforeChange)
-{
- after = readStyleInformation( dc, fParag, lParag);
-}
-
-
-QByteArray TQTextStyleCommand::readStyleInformation( TQTextDocument* doc, int fParag, int lParag)
-{
- QByteArray style;
-#ifndef QT_NO_DATASTREAM
- TQTextParagraph *p = doc->paragAt(fParag);
- if (!p)
- return style;
- QDataStream styleStream(&style, IO_WriteOnly);
- int num = lParag - fParag + 1;
- styleStream << num;
- while (num -- && p) {
- p->writeStyleInformation(styleStream);
- p = p->next();
- }
-#endif
- return style;
-}
-
-void TQTextStyleCommand::writeStyleInformation( TQTextDocument* doc, int fParag, const QByteArray& style)
-{
-#ifndef QT_NO_DATASTREAM
- TQTextParagraph *p = doc->paragAt(fParag);
- if (!p)
- return;
- QByteArray copy = style;
- QDataStream styleStream(&copy, IO_ReadOnly);
- int num;
- styleStream >> num;
- while (num-- && p) {
- p->readStyleInformation(styleStream);
- p = p->next();
- }
-#endif
-}
-
-TQTextCursor *TQTextStyleCommand::execute(TQTextCursor *c)
-{
- writeStyleInformation(doc, firstParag, after);
- return c;
-}
-
-TQTextCursor *TQTextStyleCommand::unexecute(TQTextCursor *c)
-{
- writeStyleInformation(doc, firstParag, before);
- return c;
-}
-
-// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-TQTextCursor::TQTextCursor(TQTextDocument *dc)
- : idx(0), tmpX(-1), ox(0), oy(0),
- valid(true)
-{
- para = dc ? dc->firstParagraph() : 0;
-}
-
-TQTextCursor::TQTextCursor(const TQTextCursor &c)
-{
- ox = c.ox;
- oy = c.oy;
- idx = c.idx;
- para = c.para;
- tmpX = c.tmpX;
- indices = c.indices;
- paras = c.paras;
- xOffsets = c.xOffsets;
- yOffsets = c.yOffsets;
- valid = c.valid;
-}
-
-TQTextCursor::~TQTextCursor()
-{
-}
-
-TQTextCursor &TQTextCursor::operator=(const TQTextCursor &c)
-{
- ox = c.ox;
- oy = c.oy;
- idx = c.idx;
- para = c.para;
- tmpX = c.tmpX;
- indices = c.indices;
- paras = c.paras;
- xOffsets = c.xOffsets;
- yOffsets = c.yOffsets;
- valid = c.valid;
-
- return *this;
-}
-
-bool TQTextCursor::operator==(const TQTextCursor &c) const
-{
- return para == c.para && idx == c.idx;
-}
-
-int TQTextCursor::totalOffsetX() const
-{
- int xoff = ox;
- for (QStack<int>::ConstIterator xit = xOffsets.begin(); xit != xOffsets.end(); ++xit)
- xoff += *xit;
- return xoff;
-}
-
-int TQTextCursor::totalOffsetY() const
-{
- int yoff = oy;
- for (QStack<int>::ConstIterator yit = yOffsets.begin(); yit != yOffsets.end(); ++yit)
- yoff += *yit;
- return yoff;
-}
-
-#ifndef QT_NO_TEXTCUSTOMITEM
-void TQTextCursor::gotoIntoNested(const QPoint &globalPos)
-{
- if (!para)
- return;
- Q_ASSERT(para->at(idx)->isCustom());
- push();
- ox = 0;
- int bl, y;
- para->lineHeightOfChar(idx, &bl, &y);
- oy = y + para->rect().y();
- ox = para->at(idx)->x;
- TQTextDocument* doc = document();
- para->at(idx)->customItem()->enterAt(this, doc, para, idx, ox, oy, globalPos-QPoint(ox,oy));
-}
-#endif
-
-void TQTextCursor::invalidateNested()
-{
- if (nestedDepth()) {
- QStack<TQTextParagraph*>::Iterator it = paras.begin();
- QStack<int>::Iterator it2 = indices.begin();
- for (; it != paras.end(); ++it, ++it2) {
- if (*it == para)
- continue;
- (*it)->invalidate(0);
-#ifndef QT_NO_TEXTCUSTOMITEM
- if ((*it)->at(*it2)->isCustom())
- (*it)->at(*it2)->customItem()->invalidate();
-#endif
- }
- }
-}
-
-void TQTextCursor::insert(const QString &str, bool checkNewLine, QVector<TQTextStringChar> *formatting)
-{
- tmpX = -1;
- bool justInsert = true;
- TQString s(str);
-#if defined(Q_WS_WIN)
- if (checkNewLine) {
- int i = 0;
- while ((i = s.indexOf(TQLatin1Char('\r'), i)) != -1)
- s.remove(i ,1);
- }
-#endif
- if (checkNewLine)
- justInsert = s.indexOf(TQLatin1Char('\n')) == -1;
- if (justInsert) { // we ignore new lines and insert all in the current para at the current index
- para->insert(idx, s.unicode(), s.length());
- if (formatting) {
- for (int i = 0; i < (int)s.length(); ++i) {
- if (formatting->at(i).format()) {
- formatting->at(i).format()->addRef();
- para->string()->setFormat(idx + i, formatting->at(i).format(), true);
- }
- }
- }
- idx += s.length();
- } else { // we split at new lines
- int start = -1;
- int end;
- int y = para->rect().y() + para->rect().height();
- int lastIndex = 0;
- do {
- end = s.indexOf(TQLatin1Char('\n'), start + 1); // find line break
- if (end == -1) // didn't find one, so end of line is end of string
- end = s.length();
- int len = (start == -1 ? end : end - start - 1);
- if (len > 0) // insert the line
- para->insert(idx, s.unicode() + start + 1, len);
- else
- para->invalidate(0);
- if (formatting) { // set formats to the chars of the line
- for (int i = 0; i < len; ++i) {
- if (formatting->at(i + lastIndex).format()) {
- formatting->at(i + lastIndex).format()->addRef();
- para->string()->setFormat(i + idx, formatting->at(i + lastIndex).format(), true);
- }
- }
- lastIndex += len;
- }
- start = end; // next start is at the end of this line
- idx += len; // increase the index of the cursor to the end of the inserted text
- if (s[end] == TQLatin1Char('\n')) { // if at the end was a line break, break the line
- splitAndInsertEmptyParagraph(false, true);
- para->setEndState(-1);
- para->prev()->format(-1, false);
- lastIndex++;
- }
-
- } while (end < (int)s.length());
-
- para->format(-1, false);
- int dy = para->rect().y() + para->rect().height() - y;
- TQTextParagraph *p = para;
- p->setParagId(p->prev() ? p->prev()->paragId() + 1 : 0);
- p = p->next();
- while (p) {
- p->setParagId(p->prev()->paragId() + 1);
- p->move(dy);
- p->invalidate(0);
- p->setEndState(-1);
- p = p->next();
- }
- }
-
- int h = para->rect().height();
- para->format(-1, true);
- if (h != para->rect().height())
- invalidateNested();
- else if (para->document() && para->document()->parent())
- para->document()->nextDoubleBuffered = true;
-
- fixCursorPosition();
-}
-
-void TQTextCursor::gotoLeft()
-{
- if (para->string()->isRightToLeft())
- gotoNextLetter();
- else
- gotoPreviousLetter();
-}
-
-void TQTextCursor::gotoPreviousLetter()
-{
- tmpX = -1;
-
- if (idx > 0) {
- idx = para->string()->previousCursorPosition(idx);
-#ifndef QT_NO_TEXTCUSTOMITEM
- const TQTextStringChar *tsc = para->at(idx);
- if (tsc && tsc->isCustom() && tsc->customItem()->isNested())
- processNesting(EnterEnd);
-#endif
- } else if (para->prev()) {
- para = para->prev();
- while (!para->isVisible() && para->prev())
- para = para->prev();
- idx = para->length() - 1;
- } else if (nestedDepth()) {
- pop();
- processNesting(Prev);
- if (idx == -1) {
- pop();
- if (idx > 0) {
- idx = para->string()->previousCursorPosition(idx);
-#ifndef QT_NO_TEXTCUSTOMITEM
- const TQTextStringChar *tsc = para->at(idx);
- if (tsc && tsc->isCustom() && tsc->customItem()->isNested())
- processNesting(EnterEnd);
-#endif
- } else if (para->prev()) {
- para = para->prev();
- idx = para->length() - 1;
- }
- }
- }
-}
-
-void TQTextCursor::push()
-{
- indices.push(idx);
- paras.push(para);
- xOffsets.push(ox);
- yOffsets.push(oy);
-}
-
-void TQTextCursor::pop()
-{
- if (indices.isEmpty())
- return;
- idx = indices.pop();
- para = paras.pop();
- ox = xOffsets.pop();
- oy = yOffsets.pop();
-}
-
-void TQTextCursor::restoreState()
-{
- while (!indices.isEmpty())
- pop();
-}
-
-bool TQTextCursor::place(const QPoint &p, TQTextParagraph *s, bool link)
-{
- QPoint pos(p);
- TQRect r;
- TQTextParagraph *str = s;
- if (pos.y() < s->rect().y()) {
- pos.setY(s->rect().y());
-#ifdef Q_WS_MAC
- pos.setX(s->rect().x());
-#endif
- }
- while (s) {
- r = s->rect();
- r.setWidth(document() ? document()->width() : QWIDGETSIZE_MAX);
- if (s->isVisible())
- str = s;
- if (pos.y() >= r.y() && pos.y() <= r.y() + r.height())
- break;
- if (!s->next()) {
-#ifdef Q_WS_MAC
- pos.setX(s->rect().x() + s->rect().width());
-#endif
- break;
- }
- s = s->next();
- }
-
- if (!s || !str)
- return false;
-
- s = str;
-
- setParagraph(s);
- int y = s->rect().y();
- int lines = s->lines();
- TQTextStringChar *chr = 0;
- int index = 0;
- int i = 0;
- int cy = 0;
- int ch = 0;
- for (; i < lines; ++i) {
- chr = s->lineStartOfLine(i, &index);
- cy = s->lineY(i);
- ch = s->lineHeight(i);
- if (!chr)
- return false;
- if (pos.y() <= y + cy + ch)
- break;
- }
- int nextLine;
- if (i < lines - 1)
- s->lineStartOfLine(i+1, &nextLine);
- else
- nextLine = s->length();
- i = index;
- int x = s->rect().x();
- if (pos.x() < x)
- pos.setX(x + 1);
- int cw;
- int curpos = s->length()-1;
- int dist = 10000000;
- bool inCustom = false;
- while (i < nextLine) {
- chr = s->at(i);
- int cpos = x + chr->x;
- cw = s->string()->width(i);
-#ifndef QT_NO_TEXTCUSTOMITEM
- if (chr->isCustom() && chr->customItem()->isNested()) {
- if (pos.x() >= cpos && pos.x() <= cpos + cw &&
- pos.y() >= y + cy && pos.y() <= y + cy + chr->height()) {
- inCustom = true;
- curpos = i;
- break;
- }
- } else
-#endif
- {
- if(chr->rightToLeft)
- cpos += cw;
- int diff = cpos - pos.x();
- bool dm = diff < 0 ? !chr->rightToLeft : chr->rightToLeft;
- if ((QABS(diff) < dist || (dist == diff && dm == true)) && para->string()->validCursorPosition(i)) {
- dist = QABS(diff);
- if (!link || pos.x() >= x + chr->x)
- curpos = i;
- }
- }
- i++;
- }
- setIndex(curpos);
-
-#ifndef QT_NO_TEXTCUSTOMITEM
- if (inCustom && para->document() && para->at(curpos)->isCustom() && para->at(curpos)->customItem()->isNested()) {
- TQTextDocument *oldDoc = para->document();
- gotoIntoNested(pos);
- if (oldDoc == para->document())
- return true;
- QPoint p(pos.x() - offsetX(), pos.y() - offsetY());
- if (!place(p, document()->firstParagraph(), link))
- pop();
- }
-#endif
- return true;
-}
-
-bool TQTextCursor::processNesting(Operation op)
-{
- if (!para->document())
- return false;
- TQTextDocument* doc = para->document();
- push();
- ox = para->at(idx)->x;
- int bl, y;
- para->lineHeightOfChar(idx, &bl, &y);
- oy = y + para->rect().y();
- bool ok = false;
-
-#ifndef QT_NO_TEXTCUSTOMITEM
- switch (op) {
- case EnterBegin:
- ok = para->at(idx)->customItem()->enter(this, doc, para, idx, ox, oy);
- break;
- case EnterEnd:
- ok = para->at(idx)->customItem()->enter(this, doc, para, idx, ox, oy, true);
- break;
- case Next:
- ok = para->at(idx)->customItem()->next(this, doc, para, idx, ox, oy);
- break;
- case Prev:
- ok = para->at(idx)->customItem()->prev(this, doc, para, idx, ox, oy);
- break;
- case Down:
- ok = para->at(idx)->customItem()->down(this, doc, para, idx, ox, oy);
- break;
- case Up:
- ok = para->at(idx)->customItem()->up(this, doc, para, idx, ox, oy);
- break;
- }
- if (!ok)
-#endif
- pop();
- return ok;
-}
-
-void TQTextCursor::gotoRight()
-{
- if (para->string()->isRightToLeft())
- gotoPreviousLetter();
- else
- gotoNextLetter();
-}
-
-void TQTextCursor::gotoNextLetter()
-{
- tmpX = -1;
-
-#ifndef QT_NO_TEXTCUSTOMITEM
- const TQTextStringChar *tsc = para->at(idx);
- if (tsc && tsc->isCustom() && tsc->customItem()->isNested()) {
- if (processNesting(EnterBegin))
- return;
- }
-#endif
-
- if (idx < para->length() - 1) {
- idx = para->string()->nextCursorPosition(idx);
- } else if (para->next()) {
- para = para->next();
- while (!para->isVisible() && para->next())
- para = para->next();
- idx = 0;
- } else if (nestedDepth()) {
- pop();
- processNesting(Next);
- if (idx == -1) {
- pop();
- if (idx < para->length() - 1) {
- idx = para->string()->nextCursorPosition(idx);
- } else if (para->next()) {
- para = para->next();
- idx = 0;
- }
- }
- }
-}
-
-void TQTextCursor::gotoUp()
-{
- int indexOfLineStart;
- int line;
- TQTextStringChar *c = para->lineStartOfChar(idx, &indexOfLineStart, &line);
- if (!c)
- return;
-
- if (tmpX < 0)
- tmpX = x();
-
- if (indexOfLineStart == 0) {
- if (!para->prev()) {
- if (!nestedDepth())
- return;
- pop();
- processNesting(Up);
- if (idx == -1) {
- pop();
- if (!para->prev())
- return;
- idx = tmpX = 0;
- } else {
- tmpX = -1;
- return;
- }
- }
- TQTextParagraph *p = para->prev();
- while (p && !p->isVisible())
- p = p->prev();
- if (p)
- para = p;
- int lastLine = para->lines() - 1;
- if (!para->lineStartOfLine(lastLine, &indexOfLineStart))
- return;
- idx = indexOfLineStart;
- while (idx < para->length()-1 && para->at(idx)->x < tmpX)
- ++idx;
- if (idx > indexOfLineStart &&
- para->at(idx)->x - tmpX > tmpX - para->at(idx-1)->x)
- --idx;
- } else {
- --line;
- int oldIndexOfLineStart = indexOfLineStart;
- if (!para->lineStartOfLine(line, &indexOfLineStart))
- return;
- idx = indexOfLineStart;
- while (idx < oldIndexOfLineStart-1 && para->at(idx)->x < tmpX)
- ++idx;
- if (idx > indexOfLineStart &&
- para->at(idx)->x - tmpX > tmpX - para->at(idx-1)->x)
- --idx;
- }
- fixCursorPosition();
-}
-
-void TQTextCursor::gotoDown()
-{
- int indexOfLineStart;
- int line;
- TQTextStringChar *c = para->lineStartOfChar(idx, &indexOfLineStart, &line);
- if (!c)
- return;
-
- if (tmpX < 0)
- tmpX = x();
-
- if (line == para->lines() - 1) {
- if (!para->next()) {
- if (!nestedDepth())
- return;
- pop();
- processNesting(Down);
- if (idx == -1) {
- pop();
- if (!para->next())
- return;
- idx = tmpX = 0;
- } else {
- tmpX = -1;
- return;
- }
- }
- TQTextParagraph *s = para->next();
- while (s && !s->isVisible())
- s = s->next();
- if (s)
- para = s;
- if (!para->lineStartOfLine(0, &indexOfLineStart))
- return;
- int end;
- if (para->lines() == 1)
- end = para->length();
- else
- para->lineStartOfLine(1, &end);
-
- idx = indexOfLineStart;
- while (idx < end-1 && para->at(idx)->x < tmpX)
- ++idx;
- if (idx > indexOfLineStart &&
- para->at(idx)->x - tmpX > tmpX - para->at(idx-1)->x)
- --idx;
- } else {
- ++line;
- int end;
- if (line == para->lines() - 1)
- end = para->length();
- else
- para->lineStartOfLine(line + 1, &end);
- if (!para->lineStartOfLine(line, &indexOfLineStart))
- return;
- idx = indexOfLineStart;
- while (idx < end-1 && para->at(idx)->x < tmpX)
- ++idx;
- if (idx > indexOfLineStart &&
- para->at(idx)->x - tmpX > tmpX - para->at(idx-1)->x)
- --idx;
- }
- fixCursorPosition();
-}
-
-void TQTextCursor::gotoLineEnd()
-{
- tmpX = -1;
- int indexOfLineStart;
- int line;
- TQTextStringChar *c = para->lineStartOfChar(idx, &indexOfLineStart, &line);
- if (!c)
- return;
-
- if (line == para->lines() - 1) {
- idx = para->length() - 1;
- } else {
- c = para->lineStartOfLine(++line, &indexOfLineStart);
- indexOfLineStart--;
- idx = indexOfLineStart;
- }
-}
-
-void TQTextCursor::gotoLineStart()
-{
- tmpX = -1;
- int indexOfLineStart;
- int line;
- TQTextStringChar *c = para->lineStartOfChar(idx, &indexOfLineStart, &line);
- if (!c)
- return;
-
- idx = indexOfLineStart;
-}
-
-void TQTextCursor::gotoHome()
-{
- if (topParagraph()->document())
- gotoPosition(topParagraph()->document()->firstParagraph());
- else
- gotoLineStart();
-}
-
-void TQTextCursor::gotoEnd()
-{
- if (topParagraph()->document() && topParagraph()->document()->lastParagraph()->isValid())
- gotoPosition(topParagraph()->document()->lastParagraph(),
- topParagraph()->document()->lastParagraph()->length() - 1);
- else
- gotoLineEnd();
-}
-
-void TQTextCursor::gotoPageUp(int visibleHeight)
-{
- int targetY = globalY() - visibleHeight;
- TQTextParagraph* old; int index;
- do {
- old = para; index = idx;
- gotoUp();
- } while ((old != para || index != idx) && globalY() > targetY);
-}
-
-void TQTextCursor::gotoPageDown(int visibleHeight)
-{
- int targetY = globalY() + visibleHeight;
- TQTextParagraph* old; int index;
- do {
- old = para; index = idx;
- gotoDown();
- } while ((old != para || index != idx) && globalY() < targetY);
-}
-
-void TQTextCursor::gotoWordRight()
-{
- if (para->string()->isRightToLeft())
- gotoPreviousWord();
- else
- gotoNextWord();
-}
-
-void TQTextCursor::gotoWordLeft()
-{
- if (para->string()->isRightToLeft())
- gotoNextWord();
- else
- gotoPreviousWord();
-}
-
-static bool is_seperator(const TQChar &c, bool onlySpace)
-{
- if (onlySpace)
- return c.isSpace();
- return c.isSpace() ||
- c == TQLatin1Char('\t') ||
- c == TQLatin1Char('.') ||
- c == TQLatin1Char(',') ||
- c == TQLatin1Char(':') ||
- c == TQLatin1Char(';') ||
- c == TQLatin1Char('-') ||
- c == TQLatin1Char('<') ||
- c == TQLatin1Char('>') ||
- c == TQLatin1Char('[') ||
- c == TQLatin1Char(']') ||
- c == TQLatin1Char('(') ||
- c == TQLatin1Char(')') ||
- c == TQLatin1Char('{') ||
- c == TQLatin1Char('}');
-}
-
-void TQTextCursor::gotoPreviousWord(bool onlySpace)
-{
- gotoPreviousLetter();
- tmpX = -1;
- TQTextString *s = para->string();
- bool allowSame = false;
- if (idx == ((int)s->length()-1))
- return;
- for (int i = idx; i >= 0; --i) {
- if (is_seperator(s->at(i).c, onlySpace)) {
- if (!allowSame)
- continue;
- idx = i + 1;
- return;
- }
- if (!allowSame && !is_seperator(s->at(i).c, onlySpace))
- allowSame = true;
- }
- idx = 0;
-}
-
-void TQTextCursor::gotoNextWord(bool onlySpace)
-{
- tmpX = -1;
- TQTextString *s = para->string();
- bool allowSame = false;
- for (int i = idx; i < (int)s->length(); ++i) {
- if (!is_seperator(s->at(i).c, onlySpace)) {
- if (!allowSame)
- continue;
- idx = i;
- return;
- }
- if (!allowSame && is_seperator(s->at(i).c, onlySpace))
- allowSame = true;
-
- }
-
- if (idx < ((int)s->length()-1)) {
- gotoLineEnd();
- } else if (para->next()) {
- TQTextParagraph *p = para->next();
- while (p && !p->isVisible())
- p = p->next();
- if (s) {
- para = p;
- idx = 0;
- }
- } else {
- gotoLineEnd();
- }
-}
-
-bool TQTextCursor::atParagStart()
-{
- return idx == 0;
-}
-
-bool TQTextCursor::atParagEnd()
-{
- return idx == para->length() - 1;
-}
-
-void TQTextCursor::splitAndInsertEmptyParagraph(bool ind, bool updateIds)
-{
- if (!para->document())
- return;
- tmpX = -1;
- TQTextFormat *f = 0;
- if (para->document()->useFormatCollection()) {
- f = para->at(idx)->format();
- if (idx == para->length() - 1 && idx > 0)
- f = para->at(idx - 1)->format();
- if (f->isMisspelled()) {
- f->removeRef();
- f = para->document()->formatCollection()->format(f->font(), f->color());
- }
- }
-
- if (atParagEnd()) {
- TQTextParagraph *n = para->next();
- TQTextParagraph *s = para->document()->createParagraph(para->document(), para, n, updateIds);
- if (f)
- s->setFormat(0, 1, f, true);
- s->copyParagData(para);
- if (ind) {
- int oi, ni;
- s->indent(&oi, &ni);
- para = s;
- idx = ni;
- } else {
- para = s;
- idx = 0;
- }
- } else if (atParagStart()) {
- TQTextParagraph *p = para->prev();
- TQTextParagraph *s = para->document()->createParagraph(para->document(), p, para, updateIds);
- if (f)
- s->setFormat(0, 1, f, true);
- s->copyParagData(para);
- if (ind) {
- s->indent();
- s->format();
- indent();
- para->format();
- }
- } else {
- TQString str = para->string()->toString().mid(idx, 0xFFFFFF);
- TQTextParagraph *n = para->next();
- TQTextParagraph *s = para->document()->createParagraph(para->document(), para, n, updateIds);
- s->copyParagData(para);
- s->remove(0, 1);
- s->append(str, true);
- for (int i = 0; i < str.length(); ++i) {
- TQTextStringChar* tsc = para->at(idx + i);
- s->setFormat(i, 1, tsc->format(), true);
-#ifndef QT_NO_TEXTCUSTOMITEM
- if (tsc->isCustom()) {
- TQTextCustomItem * item = tsc->customItem();
- s->at(i)->setCustomItem(item);
- tsc->loseCustomItem();
- }
-#endif
- if (tsc->isAnchor())
- s->at(i)->setAnchor(tsc->anchorName(),
- tsc->anchorHref());
- }
- para->truncate(idx);
- if (ind) {
- int oi, ni;
- s->indent(&oi, &ni);
- para = s;
- idx = ni;
- } else {
- para = s;
- idx = 0;
- }
- }
-
- invalidateNested();
-}
-
-bool TQTextCursor::remove()
-{
- tmpX = -1;
- if (!atParagEnd()) {
- int next = para->string()->nextCursorPosition(idx);
- para->remove(idx, next-idx);
- int h = para->rect().height();
- para->format(-1, true);
- if (h != para->rect().height())
- invalidateNested();
- else if (para->document() && para->document()->parent())
- para->document()->nextDoubleBuffered = true;
- return false;
- } else if (para->next()) {
- para->join(para->next());
- invalidateNested();
- return true;
- }
- return false;
-}
-
-/* needed to implement backspace the correct way */
-bool TQTextCursor::removePreviousChar()
-{
- tmpX = -1;
- if (!atParagStart()) {
- para->remove(idx-1, 1);
- int h = para->rect().height();
- idx--;
- // shouldn't be needed, just to make sure.
- fixCursorPosition();
- para->format(-1, true);
- if (h != para->rect().height())
- invalidateNested();
- else if (para->document() && para->document()->parent())
- para->document()->nextDoubleBuffered = true;
- return false;
- } else if (para->prev()) {
- para = para->prev();
- para->join(para->next());
- invalidateNested();
- return true;
- }
- return false;
-}
-
-void TQTextCursor::indent()
-{
- int oi = 0, ni = 0;
- para->indent(&oi, &ni);
- if (oi == ni)
- return;
-
- if (idx >= oi)
- idx += ni - oi;
- else
- idx = ni;
-}
-
-void TQTextCursor::fixCursorPosition()
-{
- // searches for the closest valid cursor position
- if (para->string()->validCursorPosition(idx))
- return;
-
- int lineIdx;
- TQTextStringChar *start = para->lineStartOfChar(idx, &lineIdx, 0);
- int x = para->string()->at(idx).x;
- int diff = QABS(start->x - x);
- int best = lineIdx;
-
- TQTextStringChar *c = start;
- ++c;
-
- TQTextStringChar *end = &para->string()->at(para->length()-1);
- while (c <= end && !c->lineStart) {
- int xp = c->x;
- if (c->rightToLeft)
- xp += para->string()->width(lineIdx + (c-start));
- int ndiff = QABS(xp - x);
- if (ndiff < diff && para->string()->validCursorPosition(lineIdx + (c-start))) {
- diff = ndiff;
- best = lineIdx + (c-start);
- }
- ++c;
- }
- idx = best;
-}
-
-
-// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-TQTextDocument::TQTextDocument(TQTextDocument *p)
- : par(p), parentPar(0)
-#ifndef QT_NO_TEXTCUSTOMITEM
- , tc(0)
-#endif
- , tArray(0), tStopWidth(0)
-{
- fCollection = par ? par->fCollection : new TQTextFormatCollection;
- init();
-}
-
-void TQTextDocument::init()
-{
- oTextValid = true;
- mightHaveCustomItems = false;
- if (par)
- par->insertChild(this);
- pProcessor = 0;
- useFC = true;
- pFormatter = 0;
- indenter = 0;
- fParag = 0;
- txtFormat = TQt::AutoText;
- preferRichText = false;
- pages = false;
- focusIndicator.parag = 0;
- minw = 0;
- wused = 0;
- minwParag = curParag = 0;
- align = TQt::AlignAuto;
- nSelections = 1;
-
- setStyleSheet(TQStyleSheet::defaultSheet());
-#ifndef QT_NO_MIME
- factory_ = TQMimeSourceFactory::defaultFactory();
-#endif
- contxt.clear();
-
- underlLinks = par ? par->underlLinks : true;
- backBrush = 0;
- buf_pixmap = 0;
- nextDoubleBuffered = false;
-
- if (par)
- withoutDoubleBuffer = par->withoutDoubleBuffer;
- else
- withoutDoubleBuffer = false;
-
- lParag = fParag = createParagraph(this, 0, 0);
-
- cx = 0;
- cy = 2;
- if (par)
- cx = cy = 0;
- cw = 600;
- vw = 0;
- flow_ = new TQTextFlow;
- flow_->setWidth(cw);
-
- leftmargin = rightmargin = 4;
- scaleFontsFactor = 1;
-
- commandHistory = new TQTextCommandHistory(100);
- tStopWidth = formatCollection()->defaultFormat()->width(TQLatin1Char('x')) * 8;
-}
-
-TQTextDocument::~TQTextDocument()
-{
- delete commandHistory;
- if (par)
- par->removeChild(this);
- clear();
- delete flow_;
- if (!par) {
- delete pFormatter;
- delete fCollection;
- }
- delete pProcessor;
- delete buf_pixmap;
- delete indenter;
- delete backBrush;
- delete [] tArray;
-}
-
-void TQTextDocument::clear(bool createEmptyParag)
-{
- while (fParag) {
- TQTextParagraph *p = fParag->next();
- delete fParag;
- fParag = p;
- }
- if (flow_)
- flow_->clear();
- fParag = lParag = 0;
- if (createEmptyParag)
- fParag = lParag = createParagraph(this);
- selections.clear();
- oText.clear();
- oTextValid = false;
-}
-
-int TQTextDocument::widthUsed() const
-{
- return wused + 2*border_tolerance;
-}
-
-int TQTextDocument::height() const
-{
- int h = 0;
- if (lParag)
- h = lParag->rect().top() + lParag->rect().height() + 1;
- int fh = flow_->boundingRect().bottom();
- return qMax(h, fh);
-}
-
-
-
-TQTextParagraph *TQTextDocument::createParagraph(TQTextDocument *dc, TQTextParagraph *pr, TQTextParagraph *nx, bool updateIds)
-{
- return new TQTextParagraph(dc, pr, nx, updateIds);
-}
-
-bool TQTextDocument::setMinimumWidth(int needed, int used, TQTextParagraph *p)
-{
- if (needed == -1) {
- minw = 0;
- wused = 0;
- p = 0;
- }
- if (p == minwParag) {
- if (minw > needed) {
- TQTextParagraph *tp = fParag;
- while (tp) {
- if (tp != p && tp->minwidth > needed) {
- needed = tp->minwidth;
- minwParag = tp;
- }
- tp = tp->n;
- }
- }
- minw = needed;
- emit minimumWidthChanged(minw);
- } else if (needed > minw) {
- minw = needed;
- minwParag = p;
- emit minimumWidthChanged(minw);
- }
- wused = qMax(wused, used);
- wused = qMax(wused, minw);
- cw = qMax(minw, cw);
- return true;
-}
-
-void TQTextDocument::setPlainText(const TQString &text)
-{
- preferRichText = false;
- clear();
- oTextValid = true;
- oText = text;
-
- int lastNl = 0;
- int nl = text.indexOf(TQLatin1Char('\n'));
- if (nl == -1) {
- lParag = createParagraph(this, lParag, 0);
- if (!fParag)
- fParag = lParag;
- TQString s = text;
- if (!s.isEmpty()) {
- if (s[(int)s.length() - 1] == TQLatin1Char('\r'))
- s.remove(s.length() - 1, 1);
- lParag->append(s);
- }
- } else {
- for (;;) {
- lParag = createParagraph(this, lParag, 0);
- if (!fParag)
- fParag = lParag;
- int l = nl - lastNl;
- if (l > 0) {
- if (text.unicode()[nl-1] == TQLatin1Char('\r'))
- l--;
- TQString cs = TQString::fromRawData(text.unicode()+lastNl, l);
- lParag->append(cs);
- }
- if (nl == (int)text.length())
- break;
- lastNl = nl + 1;
- nl = text.indexOf(TQLatin1Char('\n'), nl + 1);
- if (nl == -1)
- nl = text.length();
- }
- }
- if (!lParag)
- lParag = fParag = createParagraph(this, 0, 0);
-}
-
-struct TQTextDocumentTag {
- TQTextDocumentTag(){}
- TQTextDocumentTag(const TQString&n, const TQStyleSheetItem* s, const TQTextFormat& f)
- :name(n),style(s), format(f), alignment(TQt::AlignAuto), direction(TQChar::DirON),liststyle(TQStyleSheetItem::ListDisc) {
- wsm = TQStyleSheetItem::WhiteSpaceNormal;
- }
- TQString name;
- const TQStyleSheetItem* style;
- TQString anchorHref;
- TQStyleSheetItem::WhiteSpaceMode wsm;
- TQTextFormat format;
- signed int alignment : 16;
- signed int direction : 5;
- TQStyleSheetItem::ListStyle liststyle;
-
- TQTextDocumentTag( const TQTextDocumentTag& t) {
- name = t.name;
- style = t.style;
- anchorHref = t.anchorHref;
- wsm = t.wsm;
- format = t.format;
- alignment = t.alignment;
- direction = t.direction;
- liststyle = t.liststyle;
- }
- TQTextDocumentTag& operator=(const TQTextDocumentTag& t) {
- name = t.name;
- style = t.style;
- anchorHref = t.anchorHref;
- wsm = t.wsm;
- format = t.format;
- alignment = t.alignment;
- direction = t.direction;
- liststyle = t.liststyle;
- return *this;
- }
-
- Q_DUMMY_COMPARISON_OPERATOR(TQTextDocumentTag)
-};
-
-
-#define NEWPAR \
- do{ \
- if (!hasNewPar) { \
- if (!textEditMode && curpar && curpar->length()>1 \
- && curpar->at(curpar->length()-2)->c == TQChar::LineSeparator) \
- curpar->remove(curpar->length()-2, 1); \
- curpar = createParagraph(this, curpar, curpar->next()); \
- styles.append(vec); \
- vec = 0; \
- } \
- hasNewPar = true; \
- curpar->rtext = true; \
- curpar->align = curtag.alignment; \
- curpar->lstyle = curtag.liststyle; \
- curpar->litem = (curtag.style->displayMode() == TQStyleSheetItem::DisplayListItem); \
- curpar->str->setDirection((TQChar::Direction)curtag.direction); \
- space = true; \
- tabExpansionColumn = 0; \
- delete vec; \
- vec = new QVector<TQStyleSheetItem *>(); \
- for (QStack<TQTextDocumentTag>::Iterator it = tags.begin(); it != tags.end(); ++it) \
- vec->append(const_cast<TQStyleSheetItem *>((*it).style)); \
- vec->append(const_cast<TQStyleSheetItem *>(curtag.style)); \
- } while(false);
-
-
-void TQTextDocument::setRichText(const TQString &text, const TQString &context, const TQTextFormat *initialFormat)
-{
- preferRichText = true;
- if (!context.isEmpty())
- setContext(context);
- clear();
- fParag = lParag = createParagraph(this);
- oTextValid = true;
- oText = text;
- setRichTextInternal(text, 0, initialFormat);
- fParag->rtext = true;
-}
-
-void TQTextDocument::setRichTextInternal(const TQString &text, TQTextCursor* cursor, const TQTextFormat *initialFormat)
-{
- TQTextParagraph* curpar = lParag;
- int pos = 0;
- QStack<TQTextDocumentTag> tags;
- if (!initialFormat)
- initialFormat = formatCollection()->defaultFormat();
- TQTextDocumentTag initag(TQLatin1String(""), sheet_->item(TQLatin1String("")), *initialFormat);
- if (bodyText.isValid())
- initag.format.setColor(bodyText);
- TQTextDocumentTag curtag = initag;
- bool space = true;
- bool canMergeLi = false;
-
- bool textEditMode = false;
- int tabExpansionColumn = 0;
-
- const TQChar* doc = static_cast<const TQChar*>(text.unicode());
- int length = text.length();
- bool hasNewPar = curpar->length() <= 1;
- TQString anchorName;
-
- // style sheet handling for margin and line spacing calculation below
- TQTextParagraph* stylesPar = curpar;
- QVector<TQStyleSheetItem *>* vec = 0;
- QList< QVector<TQStyleSheetItem *> *> styles;
-
- if (cursor) {
- cursor->splitAndInsertEmptyParagraph();
- TQTextCursor tmp = *cursor;
- tmp.gotoPreviousLetter();
- stylesPar = curpar = tmp.paragraph();
- hasNewPar = true;
- textEditMode = true;
- } else {
- NEWPAR;
- }
-
- // set rtext spacing to false for the initial paragraph.
- curpar->rtext = false;
-
- TQString wellKnownTags = TQLatin1String("br hr wsp table qt body meta title");
-
- while (pos < length) {
- if (hasPrefix(doc, length, pos, TQLatin1Char('<'))){
- if (!hasPrefix(doc, length, pos+1, TQLatin1Char('/'))) {
- // open tag
- QMap<TQString, TQString> attr;
- QMap<TQString, TQString>::Iterator it, end = attr.end();
- bool emptyTag = false;
- TQString tagname = parseOpenTag(doc, length, pos, attr, emptyTag);
- if (tagname.isEmpty())
- continue; // nothing we could do with this, probably parse error
-
- const TQStyleSheetItem* nstyle = sheet_->item(tagname);
-
- if (nstyle) {
- // we might have to close some 'forgotten' tags
- while (!nstyle->allowedInContext(curtag.style)) {
- TQString msg;
- msg.sprintf("QText Warning: Document not valid ('%s' not allowed in '%s' #%d)",
- tagname.ascii(), curtag.style->name().ascii(), pos);
- sheet_->error(msg);
- if (tags.isEmpty())
- break;
- curtag = tags.pop();
- }
-
- /* special handling for p and li for HTML
- compatibility. We do not want to embed blocks in
- p, and we do not want new blocks inside non-empty
- lis. Plus we want to merge empty lis sometimes. */
- if(nstyle->displayMode() == TQStyleSheetItem::DisplayListItem) {
- canMergeLi = true;
- } else if (nstyle->displayMode() == TQStyleSheetItem::DisplayBlock) {
- while (curtag.style->name() == TQLatin1String("p")) {
- if (tags.isEmpty())
- break;
- curtag = tags.pop();
- }
-
- if (curtag.style->displayMode() == TQStyleSheetItem::DisplayListItem) {
- // we are in a li and a new block comes along
- if (nstyle->name() == TQLatin1String("ul") || nstyle->name() == TQLatin1String("ol"))
- hasNewPar = false; // we want an empty li (like most browsers)
- if (!hasNewPar) {
- /* do not add new blocks inside
- non-empty lis */
- while (curtag.style->displayMode() == TQStyleSheetItem::DisplayListItem) {
- if (tags.isEmpty())
- break;
- curtag = tags.pop();
- }
- } else if (canMergeLi) {
- /* we have an empty li and a block
- comes along, merge them */
- nstyle = curtag.style;
- }
- canMergeLi = false;
- }
- }
- }
-
-#ifndef QT_NO_TEXTCUSTOMITEM
- TQTextCustomItem* custom = 0;
-#else
- bool custom = false;
-#endif
-
- // some well-known tags, some have a nstyle, some not
- if (wellKnownTags.contains(tagname)) {
- if (tagname == TQLatin1String("br")) {
- emptyTag = space = true;
- int index = qMax(curpar->length(),1) - 1;
- TQTextFormat format = curtag.format.makeTextFormat(nstyle, attr, scaleFontsFactor);
- curpar->append(TQString(TQChar(TQChar::LineSeparator)));
- curpar->setFormat(index, 1, &format);
- hasNewPar = false;
- } else if (tagname == TQLatin1String("hr")) {
- emptyTag = space = true;
-#ifndef QT_NO_TEXTCUSTOMITEM
- custom = tag(sheet_, tagname, attr, contxt, *factory_ , emptyTag, this);
-#endif
- } else if (tagname == TQLatin1String("table")) {
- emptyTag = space = true;
-#ifndef QT_NO_TEXTCUSTOMITEM
- TQTextFormat format = curtag.format.makeTextFormat( nstyle, attr, scaleFontsFactor);
- curpar->setAlignment(curtag.alignment);
- custom = parseTable(attr, format, doc, length, pos, curpar);
-#endif
- } else if (tagname == TQLatin1String("qt") || tagname == TQLatin1String("body")) {
- it = attr.find(TQLatin1String("bgcolor"));
- if (it != end) {
- TQBrush *b = new TQBrush(QColor(*it));
- setPaper(b);
- }
- it = attr.find(TQLatin1String("background"));
- if (it != end) {
-#ifndef QT_NO_MIME
- TQImage img;
- TQString bg = *it;
- const QMimeSource* m = factory_->data(bg, contxt);
- if (!m) {
- qCritical("QRichText: no mimesource for %s",
- QFile::encodeName(bg).data());
- } else {
- if (!TQImageDrag::decode(TQT_TQMIMESOURCE_CONST(m), img)) {
- qCritical("TQTextImage: cannot decode %s",
- QFile::encodeName(bg).data());
- }
- }
- if (!img.isNull()) {
- TQBrush *b = new TQBrush(QColor(), TQPixmap(img));
- setPaper(b);
- }
-#endif
- }
- it = attr.find(TQLatin1String("text"));
- if (it != end) {
- QColor c(*it);
- initag.format.setColor(c);
- curtag.format.setColor(c);
- bodyText = c;
- }
- it = attr.find(TQLatin1String("link"));
- if (it != end)
- linkColor = QColor(*it);
- it = attr.find(TQLatin1String("title"));
- if (it != end)
- attribs.insert(TQLatin1String("title"), *it);
-
- if (textEditMode) {
- it = attr.find(TQLatin1String("style"));
- if (it != end) {
- TQString a = *it;
- int count = a.count(TQLatin1Char(';')) + 1;
- for (int s = 0; s < count; s++) {
- TQString style = a.section(TQLatin1Char(';'), s, s);
- if (style.startsWith(TQLatin1String("font-size:")) && style.endsWith(TQLatin1String("pt"))) {
- scaleFontsFactor = double(formatCollection()->defaultFormat()->fn.pointSize()) /
- style.mid(10, style.length() - 12).toInt();
- }
- }
- }
- nstyle = 0; // ignore body in textEditMode
- }
- // end qt- and body-tag handling
- } else if (tagname == TQLatin1String("meta")) {
- if (attr[TQLatin1String("name")] == TQLatin1String("qrichtext") && attr[TQLatin1String("content")] == TQLatin1String("1"))
- textEditMode = true;
- } else if (tagname == TQLatin1String("title")) {
- TQString title;
- while (pos < length) {
- if (hasPrefix(doc, length, pos, TQLatin1Char('<')) && hasPrefix(doc, length, pos+1, TQLatin1Char('/')) &&
- parseCloseTag(doc, length, pos) == TQLatin1String("title"))
- break;
- title += doc[pos];
- ++pos;
- }
- attribs.insert(TQLatin1String("title"), title);
- }
- } // end of well-known tag handling
-
-#ifndef QT_NO_TEXTCUSTOMITEM
- if (!custom) // try generic custom item
- custom = tag(sheet_, tagname, attr, contxt, *factory_ , emptyTag, this);
-#endif
- if (!nstyle && !custom) // we have no clue what this tag could be, ignore it
- continue;
-
- if (custom) {
-#ifndef QT_NO_TEXTCUSTOMITEM
- int index = qMax(curpar->length(),1) - 1;
- TQTextFormat format = curtag.format.makeTextFormat(nstyle, attr, scaleFontsFactor);
- curpar->append(TQString(TQLatin1Char('*')));
- TQTextFormat* f = formatCollection()->format(&format);
- curpar->setFormat(index, 1, f);
- curpar->at(index)->setCustomItem(custom);
- if (!curtag.anchorHref.isEmpty())
- curpar->at(index)->setAnchor(TQString(), curtag.anchorHref);
- if (!anchorName.isEmpty() ) {
- curpar->at(index)->setAnchor(anchorName, curpar->at(index)->anchorHref());
- anchorName.clear();
- }
- registerCustomItem(custom, curpar);
- hasNewPar = false;
-#endif
- } else if (!emptyTag) {
- /* if we do nesting, push curtag on the stack,
- otherwise reinint curag. */
- if (curtag.style->name() != tagname || nstyle->selfNesting()) {
- tags.push(curtag);
- } else {
- if (!tags.isEmpty())
- curtag = tags.top();
- else
- curtag = initag;
- }
-
- curtag.name = tagname;
- curtag.style = nstyle;
- curtag.name = tagname;
- curtag.style = nstyle;
- if (nstyle->whiteSpaceMode() != TQStyleSheetItem::WhiteSpaceModeUndefined)
- curtag.wsm = nstyle->whiteSpaceMode();
-
- /* netscape compatibility: eat a newline and only a newline if a pre block starts */
- if (curtag.wsm == TQStyleSheetItem::WhiteSpacePre &&
- nstyle->displayMode() == TQStyleSheetItem::DisplayBlock)
- eat(doc, length, pos, TQLatin1Char('\n'));
-
- /* ignore whitespace for inline elements if there
- was already one*/
- if (!textEditMode &&
- (curtag.wsm == TQStyleSheetItem::WhiteSpaceNormal
- || curtag.wsm == TQStyleSheetItem::WhiteSpaceNoWrap)
- && (space || nstyle->displayMode() != TQStyleSheetItem::DisplayInline))
- eatSpace(doc, length, pos);
-
- curtag.format = curtag.format.makeTextFormat(nstyle, attr, scaleFontsFactor);
- if (nstyle->isAnchor()) {
- if (!anchorName.isEmpty())
- anchorName += TQLatin1Char('#') + attr[TQLatin1String("name")];
- else
- anchorName = attr[TQLatin1String("name")];
- curtag.anchorHref = attr[TQLatin1String("href")];
- }
-
- if (nstyle->alignment() != TQStyleSheetItem::Undefined)
- curtag.alignment = nstyle->alignment();
-
- if (nstyle->listStyle() != TQStyleSheetItem::ListStyleUndefined)
- curtag.liststyle = nstyle->listStyle();
-
- if (nstyle->displayMode() == TQStyleSheetItem::DisplayBlock
- || nstyle->displayMode() == TQStyleSheetItem::DisplayListItem) {
-
- if (nstyle->name() == TQLatin1String("ol") ||
- nstyle->name() == TQLatin1String("ul") ||
- nstyle->name() == TQLatin1String("li")) {
- TQString type = attr[TQLatin1String("type")];
- if (!type.isEmpty()) {
- if (type == TQLatin1String("1")) {
- curtag.liststyle = TQStyleSheetItem::ListDecimal;
- } else if (type == TQLatin1String("a")) {
- curtag.liststyle = TQStyleSheetItem::ListLowerAlpha;
- } else if (type == TQLatin1String("A")) {
- curtag.liststyle = TQStyleSheetItem::ListUpperAlpha;
- } else {
- type = type.toLower();
- if (type == TQLatin1String("square"))
- curtag.liststyle = TQStyleSheetItem::ListSquare;
- else if (type == TQLatin1String("disc"))
- curtag.liststyle = TQStyleSheetItem::ListDisc;
- else if (type == TQLatin1String("circle"))
- curtag.liststyle = TQStyleSheetItem::ListCircle;
- }
- }
- }
-
-
- /* Internally we treat ordered and bullet
- lists the same for margin calculations. In
- order to have fast pointer compares in the
- xMargin() functions we restrict ourselves to
- <ol>. Once we calculate the margins in the
- parser rathern than later, the unelegance of
- this approach goes awy
- */
- if (nstyle->name() == TQLatin1String("ul"))
- curtag.style = sheet_->item(TQLatin1String("ol"));
-
- it = attr.find(TQLatin1String("align"));
- if (it != end) {
- TQString align = (*it).toLower();
- if (align == TQLatin1String("center"))
- curtag.alignment = Qt::AlignCenter;
- else if (align == TQLatin1String("right"))
- curtag.alignment = Qt::AlignRight;
- else if (align == TQLatin1String("justify"))
- curtag.alignment = Qt::AlignJustify;
- }
- it = attr.find(TQLatin1String("dir"));
- if (it != end) {
- TQString dir = (*it).toLower();
- if (dir == TQLatin1String("rtl"))
- curtag.direction = TQChar::DirR;
- else if (dir == TQLatin1String("ltr"))
- curtag.direction = TQChar::DirL;
- }
-
- NEWPAR;
-
- if (curtag.style && curtag.style->displayMode() == TQStyleSheetItem::DisplayListItem) {
- it = attr.find(TQLatin1String("value"));
- if (it != end)
- curpar->setListValue((*it).toInt());
- }
-
- it = attr.find(TQLatin1String("style"));
- if (it != end) {
- TQString a = *it;
- bool ok = true;
- int count = a.count(TQLatin1Char(';'))+1;
- for (int s = 0; ok && s < count; s++) {
- TQString style = a.section(TQLatin1Char(';'), s, s);
- if (style.startsWith(TQLatin1String("margin-top:")) && style.endsWith(TQLatin1String("px")))
- curpar->utm = 1+style.mid(11, style.length() - 13).toInt(&ok);
- else if (style.startsWith(TQLatin1String("margin-bottom:")) && style.endsWith(TQLatin1String("px")))
- curpar->ubm = 1+style.mid(14, style.length() - 16).toInt(&ok);
- else if (style.startsWith(TQLatin1String("margin-left:")) && style.endsWith(TQLatin1String("px")))
- curpar->ulm = 1+style.mid(12, style.length() - 14).toInt(&ok);
- else if (style.startsWith(TQLatin1String("margin-right:")) && style.endsWith(TQLatin1String("px")))
- curpar->urm = 1+style.mid(13, style.length() - 15).toInt(&ok);
- else if (style.startsWith(TQLatin1String("text-indent:")) && style.endsWith(TQLatin1String("px")))
- curpar->uflm = 1+style.mid(12, style.length() - 14).toInt(&ok);
- }
- if (!ok) // be pressmistic
- curpar->utm = curpar->ubm = curpar->urm = curpar->ulm = 0;
- }
- } else if (nstyle->name() == TQLatin1String("html")) {
- it = attr.find(TQLatin1String("dir"));
- if (it != end) {
- TQString dir = (*it).toLower();
- if (dir == TQLatin1String("rtl"))
- curtag.direction = TQChar::DirR;
- else if (dir == TQLatin1String("ltr"))
- curtag.direction = TQChar::DirL;
- }
- }
- }
- } else {
- TQString tagname = parseCloseTag(doc, length, pos);
- if (tagname.isEmpty())
- continue; // nothing we could do with this, probably parse error
- if (!sheet_->item(tagname)) // ignore unknown tags
- continue;
- if (tagname == TQLatin1String("li"))
- continue;
-
- // we close a block item. Since the text may continue, we need to have a new paragraph
- bool needNewPar = curtag.style->displayMode() == TQStyleSheetItem::DisplayBlock
- || curtag.style->displayMode() == TQStyleSheetItem::DisplayListItem;
-
-
- // html slopiness: handle unbalanched tag closing
- while (curtag.name != tagname) {
- TQString msg;
- msg.sprintf("QText Warning: Document not valid ('%s' not closed before '%s' #%d)",
- curtag.name.ascii(), tagname.ascii(), pos);
- sheet_->error(msg);
- if (tags.isEmpty())
- break;
- curtag = tags.pop();
- }
-
-
- // close the tag
- if (!tags.isEmpty())
- curtag = tags.pop();
- else
- curtag = initag;
-
- if (needNewPar) {
- if (textEditMode && (tagname == TQLatin1String("p") || tagname == TQLatin1String("div"))) // preserve empty paragraphs
- hasNewPar = false;
- NEWPAR;
- }
- }
- } else {
- // normal contents
- TQString s;
- TQChar c;
- while (pos < length && !hasPrefix(doc, length, pos, TQLatin1Char('<'))){
- if (textEditMode) {
- // text edit mode: we handle all white space but ignore newlines
- c = parseChar(doc, length, pos, TQStyleSheetItem::WhiteSpacePre);
- if (c == TQChar::LineSeparator)
- break;
- } else {
- int l = pos;
- c = parseChar(doc, length, pos, curtag.wsm);
-
- // in white space pre mode: treat any space as non breakable
- // and expand tabs to eight character wide columns.
- if (curtag.wsm == TQStyleSheetItem::WhiteSpacePre) {
- if (c == TQLatin1Char('\t')) {
- c = TQLatin1Char(' ');
- while((++tabExpansionColumn)%8)
- s += c;
- }
- if (c == TQChar::LineSeparator)
- tabExpansionColumn = 0;
- else
- tabExpansionColumn++;
-
- }
- if (c == TQLatin1Char(' ') || c == TQChar::LineSeparator) {
- /* avoid overlong paragraphs by forcing a new
- paragraph after 4096 characters. This case can
- occur when loading undiscovered plain text
- documents in rich text mode. Instead of hanging
- forever, we do the trick.
- */
- if (curtag.wsm == TQStyleSheetItem::WhiteSpaceNormal && s.length() > 4096) do {
- if (doc[l] == TQLatin1Char('\n')) {
- hasNewPar = false; // for a new paragraph ...
- NEWPAR;
- hasNewPar = false; // ... and make it non-reusable
- c = TQLatin1Char('\n'); // make sure we break below
- break;
- }
- } while (++l < pos);
- }
- }
-
- if (c == TQLatin1Char('\n'))
- break; // break on newlines, pre delievers a TQChar::LineSeparator
-
- bool c_isSpace = c.isSpace() && c.unicode() != 0x00a0U && !textEditMode;
-
- if (curtag.wsm == TQStyleSheetItem::WhiteSpaceNormal && c_isSpace && space)
- continue;
- if (c == TQLatin1Char('\r'))
- continue;
- space = c_isSpace;
- s += c;
- }
- if (!s.isEmpty() && curtag.style->displayMode() != TQStyleSheetItem::DisplayNone) {
- hasNewPar = false;
- int index = qMax(curpar->length(),1) - 1;
- curpar->append(s);
- if (curtag.wsm != TQStyleSheetItem::WhiteSpaceNormal) {
- TQTextString *str = curpar->string();
- for (int i = index; i < index + s.length(); ++i)
- str->at(i).nobreak = true;
- }
-
- TQTextFormat* f = formatCollection()->format(&curtag.format);
- curpar->setFormat(index, s.length(), f, false); // do not use collection because we have done that already
- f->ref += s.length() -1; // that what friends are for...
- if (!curtag.anchorHref.isEmpty()) {
- for (int i = 0; i < int(s.length()); i++)
- curpar->at(index + i)->setAnchor(TQString(), curtag.anchorHref);
- }
- if (!anchorName.isEmpty() ) {
- for (int i = 0; i < int(s.length()); i++)
- curpar->at(index + i)->setAnchor(anchorName, curpar->at(index + i)->anchorHref());
- anchorName.clear();
- }
- }
- }
- }
-
- if (hasNewPar && curpar != fParag && !cursor && stylesPar != curpar) {
- // cleanup unused last paragraphs
- curpar = curpar->p;
- delete curpar->n;
- }
-
- if (!anchorName.isEmpty() ) {
- curpar->at(curpar->length() - 1)->setAnchor(anchorName, curpar->at(curpar->length() - 1)->anchorHref());
- anchorName.clear();
- }
-
- setRichTextMarginsInternal(styles, stylesPar);
-
- if (cursor) {
- cursor->gotoPreviousLetter();
- cursor->remove();
- }
- while (!styles.isEmpty())
- delete styles.takeFirst();
- delete vec;
-}
-
-void TQTextDocument::setRichTextMarginsInternal(QList< QVector<TQStyleSheetItem *> *>& styles, TQTextParagraph* stylesPar)
-{
- // margin and line spacing calculation
- // qDebug("setRichTextMarginsInternal: styles.size() = %d", styles.size());
- QVector<TQStyleSheetItem *>* prevStyle = 0;
- int stylesIndex = 0;
- QVector<TQStyleSheetItem *>* curStyle = styles.size() ? styles.first() : 0;
- QVector<TQStyleSheetItem *>* nextStyle =
- (++stylesIndex) < styles.size() ? styles.at(stylesIndex) : 0;
- while (stylesPar) {
- if (!curStyle) {
- stylesPar = stylesPar->next();
- prevStyle = curStyle;
- curStyle = nextStyle;
- nextStyle = (++stylesIndex) < styles.size() ? styles.at(stylesIndex) : 0;
- continue;
- }
-
- int i, mar;
- TQStyleSheetItem* mainStyle = curStyle->size() ? (*curStyle)[curStyle->size()-1] : 0;
- if (mainStyle && mainStyle->displayMode() == TQStyleSheetItem::DisplayListItem)
- stylesPar->setListItem(true);
- int numLists = 0;
- for (i = 0; i < (int)curStyle->size(); ++i) {
- if ((*curStyle)[i]->displayMode() == TQStyleSheetItem::DisplayBlock
- && (*curStyle)[i]->listStyle() != TQStyleSheetItem::ListStyleUndefined)
- numLists++;
- }
- stylesPar->ldepth = numLists;
- if (stylesPar->next() && nextStyle) {
- // also set the depth of the next paragraph, required for the margin calculation
- numLists = 0;
- for (i = 0; i < (int)nextStyle->size(); ++i) {
- if ((*nextStyle)[i]->displayMode() == TQStyleSheetItem::DisplayBlock
- && (*nextStyle)[i]->listStyle() != TQStyleSheetItem::ListStyleUndefined)
- numLists++;
- }
- stylesPar->next()->ldepth = numLists;
- }
-
- // do the top margin
- TQStyleSheetItem* item = mainStyle;
- int m;
- if (stylesPar->utm > 0) {
- m = stylesPar->utm-1;
- stylesPar->utm = 0;
- } else {
- m = qMax(0, item->margin(TQStyleSheetItem::MarginTop));
- if (stylesPar->ldepth) {
- if (item->displayMode() == TQStyleSheetItem::DisplayListItem)
- m /= stylesPar->ldepth * stylesPar->ldepth;
- else
- m = 0;
- }
- }
- for (i = (int)curStyle->size() - 2 ; i >= 0; --i) {
- item = (*curStyle)[i];
- if (prevStyle && i < (int) prevStyle->size() &&
- ( item->displayMode() == TQStyleSheetItem::DisplayBlock &&
- (*prevStyle)[i] == item))
- break;
- // emulate CSS2' standard 0 vertical margin for multiple ul or ol tags
- if (item->listStyle() != TQStyleSheetItem::ListStyleUndefined &&
- (( i> 0 && (*curStyle)[i-1] == item) || (*curStyle)[i+1] == item))
- continue;
- mar = qMax(0, item->margin(TQStyleSheetItem::MarginTop));
- m = qMax(m, mar);
- }
- stylesPar->utm = m - stylesPar->topMargin();
-
- // do the bottom margin
- item = mainStyle;
- if (stylesPar->ubm > 0) {
- m = stylesPar->ubm-1;
- stylesPar->ubm = 0;
- } else {
- m = qMax(0, item->margin(TQStyleSheetItem::MarginBottom));
- if (stylesPar->ldepth) {
- if (item->displayMode() == TQStyleSheetItem::DisplayListItem)
- m /= stylesPar->ldepth * stylesPar->ldepth;
- else
- m = 0;
- }
- }
- for (i = (int)curStyle->size() - 2 ; i >= 0; --i) {
- item = (*curStyle)[i];
- if (nextStyle && i < (int) nextStyle->size() &&
- ( item->displayMode() == TQStyleSheetItem::DisplayBlock &&
- (*nextStyle)[i] == item))
- break;
- // emulate CSS2' standard 0 vertical margin for multiple ul or ol tags
- if (item->listStyle() != TQStyleSheetItem::ListStyleUndefined &&
- (( i> 0 && (*curStyle)[i-1] == item) || (*curStyle)[i+1] == item))
- continue;
- mar = qMax(0, item->margin(TQStyleSheetItem::MarginBottom));
- m = qMax(m, mar);
- }
- stylesPar->ubm = m - stylesPar->bottomMargin();
-
- // do the left margin, simplyfied
- item = mainStyle;
- if (stylesPar->ulm > 0) {
- m = stylesPar->ulm-1;
- stylesPar->ulm = 0;
- } else {
- m = qMax(0, item->margin(TQStyleSheetItem::MarginLeft));
- }
- for (i = (int)curStyle->size() - 2 ; i >= 0; --i) {
- item = (*curStyle)[i];
- m += qMax(0, item->margin(TQStyleSheetItem::MarginLeft));
- }
- stylesPar->ulm = m - stylesPar->leftMargin();
-
- // do the right margin, simplyfied
- item = mainStyle;
- if (stylesPar->urm > 0) {
- m = stylesPar->urm-1;
- stylesPar->urm = 0;
- } else {
- m = qMax(0, item->margin(TQStyleSheetItem::MarginRight));
- }
- for (i = (int)curStyle->size() - 2 ; i >= 0; --i) {
- item = (*curStyle)[i];
- m += qMax(0, item->margin(TQStyleSheetItem::MarginRight));
- }
- stylesPar->urm = m - stylesPar->rightMargin();
-
- // do the first line margin, which really should be called text-indent
- item = mainStyle;
- if (stylesPar->uflm > 0) {
- m = stylesPar->uflm-1;
- stylesPar->uflm = 0;
- } else {
- m = qMax(0, item->margin(TQStyleSheetItem::MarginFirstLine));
- }
- for (i = (int)curStyle->size() - 2 ; i >= 0; --i) {
- item = (*curStyle)[i];
- mar = qMax(0, item->margin(TQStyleSheetItem::MarginFirstLine));
- m = qMax(m, mar);
- }
- stylesPar->uflm =m - stylesPar->firstLineMargin();
-
- // do the bogus line "spacing", which really is just an extra margin
- item = mainStyle;
- for (i = (int)curStyle->size() - 1 ; i >= 0; --i) {
- item = (*curStyle)[i];
- if (item->lineSpacing() != TQStyleSheetItem::Undefined) {
- stylesPar->ulinespacing = item->lineSpacing();
- if (formatCollection() &&
- stylesPar->ulinespacing < formatCollection()->defaultFormat()->height())
- stylesPar->ulinespacing += formatCollection()->defaultFormat()->height();
- break;
- }
- }
-
- stylesPar = stylesPar->next();
- prevStyle = curStyle;
- curStyle = nextStyle;
- nextStyle = (++stylesIndex) < styles.size() ? styles.at(stylesIndex) : 0;
- }
-}
-
-void TQTextDocument::setText(const TQString &text, const TQString &context)
-{
- focusIndicator.parag = 0;
- selections.clear();
- if ((txtFormat == TQt::AutoText && TQStyleSheet::mightBeRichText(text))
- || txtFormat == TQt::RichText)
- setRichText(text, context);
- else
- setPlainText(text);
-}
-
-TQString TQTextDocument::plainText() const
-{
- TQString buffer;
- TQString s;
- TQTextParagraph *p = fParag;
- while (p) {
- if (!p->mightHaveCustomItems) {
- const TQTextString *ts = p->string(); // workaround VC++ and Borland
- s = ts->toString(); // with false we don't fix spaces (nbsp)
- } else {
- for (int i = 0; i < p->length() - 1; ++i) {
-#ifndef QT_NO_TEXTCUSTOMITEM
- if (p->at(i)->isCustom()) {
- if (p->at(i)->customItem()->isNested()) {
- s += TQLatin1String("\n");
- TQTextTable *t = (TQTextTable*)p->at(i)->customItem();
- QList<TQTextTableCell *> cells = t->tableCells();
- for (int idx = 0; idx < cells.size(); ++idx) {
- TQTextTableCell *c = cells.at(idx);
- s += c->richText()->plainText() + TQLatin1String("\n");
- }
- s += TQLatin1String("\n");
- }
- } else
-#endif
- {
- s += p->at(i)->c;
- }
- }
- }
- s.remove(s.length() - 1, 1);
- if (p->next())
- s += TQLatin1String("\n");
- buffer += s;
- p = p->next();
- }
- return buffer;
-}
-
-static TQString align_to_string(int a)
-{
- if (a & Qt::AlignRight)
- return TQLatin1String(" align=\"right\"");
- if (a & Qt::AlignHCenter)
- return TQLatin1String(" align=\"center\"");
- if (a & Qt::AlignJustify)
- return TQLatin1String(" align=\"justify\"");
- return TQString();
-}
-
-static TQString direction_to_string(int dir)
-{
- if (dir != TQChar::DirON)
- return (dir == TQChar::DirL? TQLatin1String(" dir=\"ltr\"") : TQLatin1String(" dir=\"rtl\""));
- return TQString();
-}
-
-static TQString list_value_to_string(int v)
-{
- if (v != -1)
- return TQLatin1String(" listvalue=\"") + TQString::number(v) + TQLatin1Char('"');
- return TQString();
-}
-
-static TQString list_style_to_string(int v)
-{
- switch(v) {
- case TQStyleSheetItem::ListDecimal: return TQLatin1String("\"1\"");
- case TQStyleSheetItem::ListLowerAlpha: return TQLatin1String("\"a\"");
- case TQStyleSheetItem::ListUpperAlpha: return TQLatin1String("\"A\"");
- case TQStyleSheetItem::ListDisc: return TQLatin1String("\"disc\"");
- case TQStyleSheetItem::ListSquare: return TQLatin1String("\"square\"");
- case TQStyleSheetItem::ListCircle: return TQLatin1String("\"circle\"");
- default:
- return TQString();
- }
-}
-
-static inline bool list_is_ordered(int v)
-{
- return v == TQStyleSheetItem::ListDecimal ||
- v == TQStyleSheetItem::ListLowerAlpha ||
- v == TQStyleSheetItem::ListUpperAlpha;
-}
-
-
-static TQString margin_to_string(TQStyleSheetItem* style, int t, int b, int l, int r, int fl)
-{
- TQString s;
- if (l > 0)
- s += TQString(s.size() ? TQLatin1String(";") : TQLatin1String("")) + TQLatin1String("margin-left:") +
- TQString::number(l+qMax(0,style->margin(TQStyleSheetItem::MarginLeft))) + TQLatin1String("px");
- if (r > 0)
- s += TQString(s.size() ? TQLatin1String(";") : TQLatin1String("")) + TQLatin1String("margin-right:") +
- TQString::number(r+qMax(0,style->margin(TQStyleSheetItem::MarginRight))) + TQLatin1String("px");
- if (t > 0)
- s += TQString(s.size() ? TQLatin1String(";") : TQLatin1String("")) + TQLatin1String("margin-top:") +
- TQString::number(t+qMax(0,style->margin(TQStyleSheetItem::MarginTop))) + TQLatin1String("px");
- if (b > 0)
- s += TQString(s.size() ? TQLatin1String(";") : TQLatin1String("")) + TQLatin1String("margin-bottom:") +
- TQString::number(b+qMax(0,style->margin(TQStyleSheetItem::MarginBottom))) + TQLatin1String("px");
- if (fl > 0)
- s += TQString(s.size() ? TQLatin1String(";") : TQLatin1String("")) + TQLatin1String("text-indent:") +
- TQString::number(fl+qMax(0,style->margin(TQStyleSheetItem::MarginFirstLine))) + TQLatin1String("px");
- if (s.size())
- return TQLatin1String(" style=\"") + s + TQLatin1String("\"");
- return TQString();
-}
-
-TQString TQTextDocument::richText() const
-{
- TQString s = TQLatin1String("");
- if (!par) {
- s += TQLatin1String("<html><head><meta name=\"qrichtext\" content=\"1\" /></head><body style=\"font-size:");
- s += TQString::number(formatCollection()->defaultFormat()->font().pointSize());
- s += TQLatin1String("pt;font-family:");
- s += formatCollection()->defaultFormat()->font().family();
- s += TQLatin1String("\">");
- }
- TQTextParagraph* p = fParag;
-
- TQStyleSheetItem* item_p = styleSheet()->item(TQLatin1String("p"));
- TQStyleSheetItem* item_div = styleSheet()->item(TQLatin1String("div"));
- TQStyleSheetItem* item_ul = styleSheet()->item(TQLatin1String("ul"));
- TQStyleSheetItem* item_ol = styleSheet()->item(TQLatin1String("ol"));
- TQStyleSheetItem* item_li = styleSheet()->item(TQLatin1String("li"));
- if (!item_p || !item_div || !item_ul || !item_ol || !item_li) {
- qWarning("QTextEdit: cannot export HTML due to insufficient stylesheet (lack of p, div, ul, ol, or li)");
- return TQString();
- }
- int pastListDepth = 0;
- int listDepth = 0;
-#if 0
- int futureListDepth = 0;
-#endif
- QVector<int> listStyles(10);
-
- while (p) {
- listDepth = p->listDepth();
- if (listDepth < pastListDepth) {
- for (int i = pastListDepth; i > listDepth; i--)
- s += list_is_ordered(listStyles[i]) ? TQLatin1String("</ol>") : TQLatin1String("</ul>");
- s += TQLatin1Char('\n');
- } else if (listDepth > pastListDepth) {
- s += TQLatin1Char('\n');
- listStyles.resize(qMax((int)listStyles.size(), listDepth+1));
- TQString list_type;
- listStyles[listDepth] = p->listStyle();
- if (!list_is_ordered(p->listStyle()) || item_ol->listStyle() != p->listStyle())
- list_type = TQLatin1String(" type=") + list_style_to_string(p->listStyle());
- for (int i = pastListDepth; i < listDepth; i++) {
- s += list_is_ordered(p->listStyle()) ? TQLatin1String("<ol") : TQLatin1String("<ul");
- s += list_type + TQLatin1Char('>');
- }
- } else {
- s += TQLatin1Char('\n');
- }
-
- TQString ps = p->richText();
-
-#if 0
- // for the bottom margin we need to know whether we are at the end of a list
- futureListDepth = 0;
- if (listDepth > 0 && p->next())
- futureListDepth = p->next()->listDepth();
-#endif
-
- if (richTextExportStart && richTextExportStart->paragraph() ==p &&
- richTextExportStart->index() == 0)
- s += TQLatin1String("<!--StartFragment-->");
-
- if (p->isListItem()) {
- s += TQLatin1String("<li");
- if (p->listStyle() != listStyles[listDepth])
- s += TQLatin1String(" type=") + list_style_to_string(p->listStyle());
- s += align_to_string(p->alignment());
- s += margin_to_string(item_li, p->utm, p->ubm, p->ulm, p->urm, p->uflm);
- s += list_value_to_string(p->listValue());
- s += direction_to_string(p->direction());
- s += TQLatin1Char('>');
- s += ps;
- s += TQLatin1String("</li>");
- } else if (p->listDepth()) {
- s += TQLatin1String("<div");
- s += align_to_string(p->alignment());
- s += margin_to_string(item_div, p->utm, p->ubm, p->ulm, p->urm, p->uflm);
- s += direction_to_string(p->direction());
- s += TQLatin1Char('>');
- s += ps;
- s += TQLatin1String("</div>");
- } else {
- // normal paragraph item
- s += TQLatin1String("<p");
- s += align_to_string(p->alignment());
- s += margin_to_string(item_p, p->utm, p->ubm, p->ulm, p->urm, p->uflm);
- s += direction_to_string(p->direction());
- s += TQLatin1Char('>');
- s += ps;
- s += TQLatin1String("</p>");
- }
- pastListDepth = listDepth;
- p = p->next();
- }
- while (listDepth > 0) {
- s += list_is_ordered(listStyles[listDepth]) ? TQLatin1String("</ol>") : TQLatin1String("</ul>");
- listDepth--;
- }
-
- if (!par)
- s += TQLatin1String("\n</body></html>\n");
-
- return s;
-}
-
-TQString TQTextDocument::text() const
-{
- if ((txtFormat == TQt::AutoText && preferRichText) || txtFormat == TQt::RichText)
- return richText();
- return plainText();
-}
-
-TQString TQTextDocument::text(int parag) const
-{
- TQTextParagraph *p = paragAt(parag);
- if (!p)
- return TQString();
-
- if ((txtFormat == TQt::AutoText && preferRichText) || txtFormat == TQt::RichText)
- return p->richText();
- else
- return p->string()->toString();
-}
-
-void TQTextDocument::invalidate()
-{
- TQTextParagraph *s = fParag;
- while (s) {
- s->invalidate(0);
- s = s->next();
- }
-}
-
-void TQTextDocument::selectionStart(int id, int &paragId, int &index)
-{
- QMap<int, TQTextDocumentSelection>::Iterator it = selections.find(id);
- if (it == selections.end())
- return;
- TQTextDocumentSelection &sel = *it;
- paragId = !sel.swapped ? sel.startCursor.paragraph()->paragId() : sel.endCursor.paragraph()->paragId();
- index = !sel.swapped ? sel.startCursor.index() : sel.endCursor.index();
-}
-
-TQTextCursor TQTextDocument::selectionStartCursor(int id)
-{
- QMap<int, TQTextDocumentSelection>::Iterator it = selections.find(id);
- if (it == selections.end())
- return TQTextCursor(this);
- TQTextDocumentSelection &sel = *it;
- if (sel.swapped)
- return sel.endCursor;
- return sel.startCursor;
-}
-
-TQTextCursor TQTextDocument::selectionEndCursor(int id)
-{
- QMap<int, TQTextDocumentSelection>::Iterator it = selections.find(id);
- if (it == selections.end())
- return TQTextCursor(this);
- TQTextDocumentSelection &sel = *it;
- if (!sel.swapped)
- return sel.endCursor;
- return sel.startCursor;
-}
-
-void TQTextDocument::selectionEnd(int id, int &paragId, int &index)
-{
- QMap<int, TQTextDocumentSelection>::Iterator it = selections.find(id);
- if (it == selections.end())
- return;
- TQTextDocumentSelection &sel = *it;
- paragId = sel.swapped ? sel.startCursor.paragraph()->paragId() : sel.endCursor.paragraph()->paragId();
- index = sel.swapped ? sel.startCursor.index() : sel.endCursor.index();
-}
-
-void TQTextDocument::addSelection(int id)
-{
- nSelections = qMax(nSelections, id + 1);
-}
-
-static void setSelectionEndHelper(int id, TQTextDocumentSelection &sel, TQTextCursor &start, TQTextCursor &end)
-{
- TQTextCursor c1 = start;
- TQTextCursor c2 = end;
- if (sel.swapped) {
- c1 = end;
- c2 = start;
- }
-
- c1.paragraph()->removeSelection(id);
- c2.paragraph()->removeSelection(id);
- if (c1.paragraph() != c2.paragraph()) {
- c1.paragraph()->setSelection(id, c1.index(), c1.paragraph()->length() - 1);
- c2.paragraph()->setSelection(id, 0, c2.index());
- } else {
- c1.paragraph()->setSelection(id, qMin(c1.index(), c2.index()), qMax(c1.index(), c2.index()));
- }
-
- sel.startCursor = start;
- sel.endCursor = end;
- if (sel.startCursor.paragraph() == sel.endCursor.paragraph())
- sel.swapped = sel.startCursor.index() > sel.endCursor.index();
-}
-
-bool TQTextDocument::setSelectionEnd(int id, const TQTextCursor &cursor)
-{
- QMap<int, TQTextDocumentSelection>::Iterator it = selections.find(id);
- if (it == selections.end())
- return false;
- TQTextDocumentSelection &sel = *it;
-
- TQTextCursor start = sel.startCursor;
- TQTextCursor end = cursor;
-
- if (start == end) {
- removeSelection(id);
- setSelectionStart(id, cursor);
- return true;
- }
-
- if (sel.endCursor.paragraph() == end.paragraph()) {
- setSelectionEndHelper(id, sel, start, end);
- return true;
- }
-
- bool inSelection = false;
- TQTextCursor c(this);
- TQTextCursor tmp = sel.startCursor;
- if (sel.swapped)
- tmp = sel.endCursor;
- tmp.restoreState();
- TQTextCursor tmp2 = cursor;
- tmp2.restoreState();
- c.setParagraph(tmp.paragraph()->paragId() < tmp2.paragraph()->paragId() ? tmp.paragraph() : tmp2.paragraph());
- bool hadStart = false;
- bool hadEnd = false;
- bool hadStartParag = false;
- bool hadEndParag = false;
- bool hadOldStart = false;
- bool hadOldEnd = false;
- bool leftSelection = false;
- sel.swapped = false;
- for (;;) {
- if (c == start)
- hadStart = true;
- if (c == end)
- hadEnd = true;
- if (c.paragraph() == start.paragraph())
- hadStartParag = true;
- if (c.paragraph() == end.paragraph())
- hadEndParag = true;
- if (c == sel.startCursor)
- hadOldStart = true;
- if (c == sel.endCursor)
- hadOldEnd = true;
-
- if (!sel.swapped &&
- ((hadEnd && !hadStart)
- || (hadEnd && hadStart && start.paragraph() == end.paragraph() && start.index() > end.index())))
- sel.swapped = true;
-
- if ((c == end && hadStartParag) || (c == start && hadEndParag)) {
- TQTextCursor tmp = c;
- tmp.restoreState();
- if (tmp.paragraph() != c.paragraph()) {
- int sstart = tmp.paragraph()->selectionStart(id);
- tmp.paragraph()->removeSelection(id);
- tmp.paragraph()->setSelection(id, sstart, tmp.index());
- }
- }
-
- if (inSelection &&
- ((c == end && hadStart) || (c == start && hadEnd)))
- leftSelection = true;
- else if (!leftSelection && !inSelection && (hadStart || hadEnd))
- inSelection = true;
-
- bool noSelectionAnymore = hadOldStart && hadOldEnd && leftSelection && !inSelection && !c.paragraph()->hasSelection(id) && c.atParagEnd();
- c.paragraph()->removeSelection(id);
- if (inSelection) {
- if (c.paragraph() == start.paragraph() && start.paragraph() == end.paragraph()) {
- c.paragraph()->setSelection(id, qMin(start.index(), end.index()), qMax(start.index(), end.index()));
- } else if (c.paragraph() == start.paragraph() && !hadEndParag) {
- c.paragraph()->setSelection(id, start.index(), c.paragraph()->length() - 1);
- } else if (c.paragraph() == end.paragraph() && !hadStartParag) {
- c.paragraph()->setSelection(id, end.index(), c.paragraph()->length() - 1);
- } else if (c.paragraph() == end.paragraph() && hadEndParag) {
- c.paragraph()->setSelection(id, 0, end.index());
- } else if (c.paragraph() == start.paragraph() && hadStartParag) {
- c.paragraph()->setSelection(id, 0, start.index());
- } else {
- c.paragraph()->setSelection(id, 0, c.paragraph()->length() - 1);
- }
- }
-
- if (leftSelection)
- inSelection = false;
-
- if (noSelectionAnymore)
- break;
- // *ugle*hack optimization
- TQTextParagraph *p = c.paragraph();
- if ( p->mightHaveCustomItems || p == start.paragraph() || p == end.paragraph() || p == lastParagraph()) {
- c.gotoNextLetter();
- if (p == lastParagraph() && c.atParagEnd())
- break;
- } else {
- if (p->document()->parent())
- do {
- c.gotoNextLetter();
- } while (c.paragraph() == p);
- else
- c.setParagraph(p->next());
- }
- }
-
- if (!sel.swapped)
- sel.startCursor.paragraph()->setSelection(id, sel.startCursor.index(), sel.startCursor.paragraph()->length() - 1);
-
- sel.startCursor = start;
- sel.endCursor = end;
- if (sel.startCursor.paragraph() == sel.endCursor.paragraph())
- sel.swapped = sel.startCursor.index() > sel.endCursor.index();
-
- setSelectionEndHelper(id, sel, start, end);
-
- return true;
-}
-
-void TQTextDocument::selectAll(int id)
-{
- removeSelection(id);
-
- TQTextDocumentSelection sel;
- sel.swapped = false;
- TQTextCursor c(this);
-
- c.setParagraph(fParag);
- c.setIndex(0);
- sel.startCursor = c;
-
- c.setParagraph(lParag);
- c.setIndex(lParag->length() - 1);
- sel.endCursor = c;
-
- selections.insert(id, sel);
-
- TQTextParagraph *p = fParag;
- while (p) {
- p->setSelection(id, 0, p->length() - 1);
- p = p->next();
- }
-
- for (int idx = 0; idx < childList.size(); ++idx) {
- TQTextDocument *dc = childList.at(idx);
- dc->selectAll(id);
- }
-}
-
-bool TQTextDocument::removeSelection(int id)
-{
- if (!selections.contains(id))
- return false;
-
- TQTextDocumentSelection &sel = selections[id];
-
- TQTextCursor start = sel.swapped ? sel.endCursor : sel.startCursor;
- TQTextCursor end = sel.swapped ? sel.startCursor : sel.endCursor;
- TQTextParagraph* p = 0;
- while (start != end) {
- if (p != start.paragraph()) {
- p = start.paragraph();
- p->removeSelection(id);
- //### avoid endless loop by all means necessary, did somebody mention refactoring?
- if (!parent() && p == lParag)
- break;
- }
- start.gotoNextLetter();
- }
- p = start.paragraph();
- p->removeSelection(id);
- selections.remove(id);
- return true;
-}
-
-TQString TQTextDocument::selectedText(int id, bool asRichText) const
-{
- QMap<int, TQTextDocumentSelection>::ConstIterator it = selections.find(id);
- if (it == selections.end())
- return TQString();
-
- TQTextDocumentSelection sel = *it;
-
-
- TQTextCursor c1 = sel.startCursor;
- TQTextCursor c2 = sel.endCursor;
- if (sel.swapped) {
- c2 = sel.startCursor;
- c1 = sel.endCursor;
- }
-
- /* 3.0.3 improvement: Make it possible to get a reasonable
- selection inside a table. This approach is very conservative:
- make sure that both cursors have the same depth level and point
- to paragraphs within the same text document.
-
- Meaning if you select text in two table cells, you will get the
- entire table. This is still far better than the 3.0.2, where
- you always got the entire table.
-
- ### Fix this properly when refactoring
- */
- while (c2.nestedDepth() > c1.nestedDepth())
- c2.oneUp();
- while (c1.nestedDepth() > c2.nestedDepth())
- c1.oneUp();
- while (c1.nestedDepth() && c2.nestedDepth() &&
- c1.paragraph()->document() != c2.paragraph()->document()) {
- c1.oneUp();
- c2.oneUp();
- }
- // do not trust sel_swapped with tables. Fix this properly when refactoring as well
- if (c1.paragraph()->paragId() > c2.paragraph()->paragId() ||
- (c1.paragraph() == c2.paragraph() && c1.index() > c2.index())) {
- TQTextCursor tmp = c1;
- c2 = c1;
- c1 = tmp;
- }
-
- // end selection 3.0.3 improvement
-
- if (asRichText && !parent()) {
- richTextExportStart = &c1;
- richTextExportEnd = &c2;
-
- TQString sel = richText();
- int from = sel.indexOf(TQLatin1String("<!--StartFragment-->"));
- if (from >= 0) {
- from += 20;
- // find the previous span and move it into the start fragment before we clip it
- TQString prevspan;
- int pspan = sel.lastIndexOf(TQLatin1String("<span"), from-21);
- if (pspan > sel.lastIndexOf(TQLatin1String("</span"), from-21)) {
- int spanend = sel.indexOf(TQLatin1Char('>'), pspan);
- prevspan = sel.mid(pspan, spanend - pspan + 1);
- }
- int to = sel.lastIndexOf(TQLatin1String("<!--EndFragment-->"));
- if (from <= to)
- sel = TQLatin1String("<!--StartFragment-->") + prevspan + sel.mid(from, to - from);
- }
- richTextExportStart = richTextExportEnd = 0;
- return sel;
- }
-
- TQString s;
- if (c1.paragraph() == c2.paragraph()) {
- TQTextParagraph *p = c1.paragraph();
- int end = c2.index();
- if (p->at(qMax(0, end - 1))->isCustom())
- ++end;
- if (!p->mightHaveCustomItems) {
- s += p->string()->toString().mid(c1.index(), end - c1.index());
- } else {
- for (int i = c1.index(); i < end; ++i) {
-#ifndef QT_NO_TEXTCUSTOMITEM
- if (p->at(i)->isCustom()) {
- if (p->at(i)->customItem()->isNested()) {
- s += TQLatin1String("\n");
- TQTextTable *t = (TQTextTable*)p->at(i)->customItem();
- QList<TQTextTableCell *> cells = t->tableCells();
- for (int idx = 0; idx < cells.size(); ++idx) {
- TQTextTableCell *c = cells.at(idx);
- s += c->richText()->plainText() + TQLatin1String("\n");
- }
- s += TQLatin1String("\n");
- }
- } else
-#endif
- {
- s += p->at(i)->c;
- }
- }
- }
- } else {
- TQTextParagraph *p = c1.paragraph();
- int start = c1.index();
- while (p) {
- int end = p == c2.paragraph() ? c2.index() : p->length() - 1;
- if (p == c2.paragraph() && p->at(qMax(0, end - 1))->isCustom())
- ++end;
- if (!p->mightHaveCustomItems) {
- s += p->string()->toString().mid(start, end - start);
- if (p != c2.paragraph())
- s += TQLatin1String("\n");
- } else {
- for (int i = start; i < end; ++i) {
-#ifndef QT_NO_TEXTCUSTOMITEM
- if (p->at(i)->isCustom()) {
- if (p->at(i)->customItem()->isNested()) {
- s += TQLatin1String(TQLatin1String("\n"));
- TQTextTable *t = (TQTextTable*)p->at(i)->customItem();
- QList<TQTextTableCell *> cells = t->tableCells();
- for (int idx = 0; idx < cells.size(); ++idx) {
- TQTextTableCell *c = cells.at(idx);
- s += c->richText()->plainText() + TQLatin1String("\n");
- }
- s += TQLatin1String("\n");
- }
- } else
-#endif
- {
- s += p->at(i)->c;
- }
- }
- }
- start = 0;
- if (p == c2.paragraph())
- break;
- p = p->next();
- }
- }
- // ### workaround for plain text export until we get proper
- // mime types: turn unicode line seperators into the more
- // widely understood \n. Makes copy and pasting code snipplets
- // from within Assistent possible
- TQChar* uc = (TQChar*) s.unicode();
- for (int ii = 0; ii < s.length(); ii++) {
- if (uc[(int)ii] == TQChar::LineSeparator)
- uc[(int)ii] = TQLatin1Char('\n');
- else if ( uc[(int)ii] == TQChar::Nbsp )
- uc[(int)ii] = TQLatin1Char(' ');
- }
- return s;
-}
-
-void TQTextDocument::setFormat(int id, TQTextFormat *f, int flags)
-{
- QMap<int, TQTextDocumentSelection>::ConstIterator it = selections.constFind(id);
- if (it == selections.constEnd())
- return;
-
- TQTextDocumentSelection sel = *it;
-
- TQTextCursor c1 = sel.startCursor;
- TQTextCursor c2 = sel.endCursor;
- if (sel.swapped) {
- c2 = sel.startCursor;
- c1 = sel.endCursor;
- }
-
- c2.restoreState();
- c1.restoreState();
-
- if (c1.paragraph() == c2.paragraph()) {
- c1.paragraph()->setFormat(c1.index(), c2.index() - c1.index(), f, true, flags);
- return;
- }
-
- c1.paragraph()->setFormat(c1.index(), c1.paragraph()->length() - c1.index(), f, true, flags);
- TQTextParagraph *p = c1.paragraph()->next();
- while (p && p != c2.paragraph()) {
- p->setFormat(0, p->length(), f, true, flags);
- p = p->next();
- }
- c2.paragraph()->setFormat(0, c2.index(), f, true, flags);
-}
-
-void TQTextDocument::removeSelectedText(int id, TQTextCursor *cursor)
-{
- QMap<int, TQTextDocumentSelection>::Iterator it = selections.find(id);
- if (it == selections.end())
- return;
-
- TQTextDocumentSelection sel = *it;
- TQTextCursor c1 = sel.startCursor;
- TQTextCursor c2 = sel.endCursor;
- if (sel.swapped) {
- c2 = sel.startCursor;
- c1 = sel.endCursor;
- }
-
- // ### no support for editing tables yet
- if (c1.nestedDepth() || c2.nestedDepth())
- return;
-
- c2.restoreState();
- c1.restoreState();
-
- *cursor = c1;
- removeSelection(id);
-
- if (c1.paragraph() == c2.paragraph()) {
- c1.paragraph()->remove(c1.index(), c2.index() - c1.index());
- return;
- }
-
- if (c1.paragraph() == fParag && c1.index() == 0 &&
- c2.paragraph() == lParag && c2.index() == lParag->length() - 1)
- cursor->setValid(false);
-
- bool didGoLeft = false;
- if ( c1.index() == 0 && c1.paragraph() != fParag) {
- cursor->gotoPreviousLetter();
- didGoLeft = cursor->isValid();
- }
-
- c1.paragraph()->remove(c1.index(), c1.paragraph()->length() - 1 - c1.index());
- TQTextParagraph *p = c1.paragraph()->next();
- int dy = 0;
- TQTextParagraph *tmp;
- while (p && p != c2.paragraph()) {
- tmp = p->next();
- dy -= p->rect().height();
- delete p;
- p = tmp;
- }
- c2.paragraph()->remove(0, c2.index());
- while (p) {
- p->move(dy);
- p->invalidate(0);
- p->setEndState(-1);
- p = p->next();
- }
-
-
- c1.paragraph()->join(c2.paragraph());
-
- if (didGoLeft)
- cursor->gotoNextLetter();
-}
-
-void TQTextDocument::indentSelection(int id)
-{
- QMap<int, TQTextDocumentSelection>::Iterator it = selections.find(id);
- if (it == selections.end())
- return;
-
- TQTextDocumentSelection sel = *it;
- TQTextParagraph *startParag = sel.startCursor.paragraph();
- TQTextParagraph *endParag = sel.endCursor.paragraph();
- if (sel.endCursor.paragraph()->paragId() < sel.startCursor.paragraph()->paragId()) {
- endParag = sel.startCursor.paragraph();
- startParag = sel.endCursor.paragraph();
- }
-
- TQTextParagraph *p = startParag;
- while (p && p != endParag) {
- p->indent();
- p = p->next();
- }
-}
-
-void TQTextCommandHistory::clear()
-{
- while (!history.isEmpty())
- delete history.takeFirst();
- current = -1;
-}
-
-void TQTextDocument::addCommand(TQTextCommand *cmd)
-{
- commandHistory->addCommand(cmd);
-}
-
-TQTextCursor *TQTextDocument::undo(TQTextCursor *c)
-{
- return commandHistory->undo(c);
-}
-
-TQTextCursor *TQTextDocument::redo(TQTextCursor *c)
-{
- return commandHistory->redo(c);
-}
-
-bool TQTextDocument::find(TQTextCursor& cursor, const TQString &expr, bool cs, bool wo, bool forward)
-{
- Qt::CaseSensitivity caseSensitive = cs ? Qt::CaseSensitive : Qt::CaseInsensitive;
- removeSelection(Standard);
- if (expr.isEmpty())
- return false;
- for (;;) {
- TQString s = cursor.paragraph()->string()->toString();
- int start = cursor.index();
- for (;;) {
- int res = forward
- ? s.indexOf(expr, start, caseSensitive)
- : s.lastIndexOf(expr, start, caseSensitive);
- int end = res + expr.length();
- if (res == -1 || (!forward && start <= res))
- break;
- if (!wo || ((res == 0 || !s[res-1].isLetterOrNumber())
- && (end == (int)s.length() || !s[end].isLetterOrNumber()))) {
- removeSelection(Standard);
- cursor.setIndex(forward ? end : res);
- setSelectionStart(Standard, cursor);
- cursor.setIndex(forward ? res : end);
- setSelectionEnd(Standard, cursor);
- if (!forward)
- cursor.setIndex(res);
- return true;
- }
- start = res + (forward ? 1 : -1);
- }
- if (forward) {
- if (cursor.paragraph() == lastParagraph() && cursor.atParagEnd())
- break;
- cursor.gotoNextLetter();
- } else {
- if (cursor.paragraph() == firstParagraph() && cursor.atParagStart())
- break;
- cursor.gotoPreviousLetter();
- }
- }
- return false;
-}
-
-void TQTextDocument::setTextFormat(TQt::TextFormat f)
-{
- txtFormat = f;
- if (fParag == lParag && fParag->length() <= 1)
- fParag->rtext = (f == TQt::RichText);
-}
-
-TQt::TextFormat TQTextDocument::textFormat() const
-{
- return txtFormat;
-}
-
-bool TQTextDocument::inSelection(int selId, const QPoint &pos) const
-{
- QMap<int, TQTextDocumentSelection>::ConstIterator it = selections.find(selId);
- if (it == selections.end())
- return false;
-
- TQTextDocumentSelection sel = *it;
- TQTextParagraph *startParag = sel.startCursor.paragraph();
- TQTextParagraph *endParag = sel.endCursor.paragraph();
- if (sel.startCursor.paragraph() == sel.endCursor.paragraph() &&
- sel.startCursor.paragraph()->selectionStart(selId) == sel.endCursor.paragraph()->selectionEnd(selId))
- return false;
- if (sel.endCursor.paragraph()->paragId() < sel.startCursor.paragraph()->paragId()) {
- endParag = sel.startCursor.paragraph();
- startParag = sel.endCursor.paragraph();
- }
-
- TQTextParagraph *p = startParag;
- while (p) {
- if (p->rect().contains(pos)) {
- bool inSel = false;
- int selStart = p->selectionStart(selId);
- int selEnd = p->selectionEnd(selId);
- int y = 0;
- int h = 0;
- for (int i = 0; i < p->length(); ++i) {
- if (i == selStart)
- inSel = true;
- if (i == selEnd)
- break;
- if (p->at(i)->lineStart) {
- y = (*p->lineStarts.find(i))->y;
- h = (*p->lineStarts.find(i))->h;
- }
- if (pos.y() - p->rect().y() >= y && pos.y() - p->rect().y() <= y + h) {
- if (inSel && pos.x() >= p->at(i)->x &&
- pos.x() <= p->at(i)->x + p->at(i)->format()->width(p->at(i)->c))
- return true;
- }
- }
- }
- if (pos.y() < p->rect().y())
- break;
- if (p == endParag)
- break;
- p = p->next();
- }
-
- return false;
-}
-
-void TQTextDocument::doLayout(TQPainter *p, int w)
-{
- minw = wused = 0;
- if (!is_printer(p))
- p = 0;
- withoutDoubleBuffer = (p != 0);
- TQPainter * oldPainter = TQTextFormat::painter();
- TQTextFormat::setPainter(p);
- tStopWidth = formatCollection()->defaultFormat()->width( TQLatin1Char('x') ) * 8;
- flow_->setWidth(w);
- cw = w;
- vw = w;
- TQTextParagraph *parag = fParag;
- while (parag) {
- parag->invalidate(0);
- if (p)
- parag->adjustToPainter(p);
- parag->format();
- parag = parag->next();
- }
- TQTextFormat::setPainter(oldPainter);
-}
-
-TQPixmap *TQTextDocument::bufferPixmap(const QSize &s)
-{
- if (!buf_pixmap)
- buf_pixmap = new TQPixmap(s.expandedTo(QSize(1,1)));
- else if (buf_pixmap->size() != s)
- buf_pixmap->resize(s.expandedTo(buf_pixmap->size()));
- return buf_pixmap;
-}
-
-void TQTextDocument::draw(TQPainter *p, const TQRect &rect, const QPalette &pal,
- const TQBrush *paper)
-{
- if (!firstParagraph())
- return;
-
- if (paper) {
- p->setBrushOrigin(-qIntCast(p->translationX()),
- -qIntCast(p->translationY()));
-
- p->fillRect(rect, *paper);
- }
-
- TQPainter * oldPainter = TQTextFormat::painter();
- TQTextFormat::setPainter(p);
-
- if (formatCollection()->defaultFormat()->color() != pal.text().color())
- setDefaultFormat(formatCollection()->defaultFormat()->font(), pal.text().color());
-
- TQTextParagraph *parag = firstParagraph();
- while (parag) {
- if (!parag->isValid())
- parag->format();
- int y = parag->rect().y();
- TQRect pr(parag->rect());
- pr.setX(0);
- pr.setWidth(QWIDGETSIZE_MAX);
- if (!rect.isNull() && !rect.intersects(pr)) {
- parag = parag->next();
- continue;
- }
- p->translate(0, y);
- if (rect.isValid())
- parag->paint(*p, pal, 0, false, rect.x(), rect.y(), rect.width(), rect.height());
- else
- parag->paint(*p, pal, 0, false);
- p->translate(0, -y);
- parag = parag->next();
- if (!flow()->isEmpty())
- flow()->drawFloatingItems(p, rect.x(), rect.y(), rect.width(), rect.height(), pal, false);
- }
- TQTextFormat::setPainter(oldPainter);
-}
-
-void TQTextDocument::drawParagraph(TQPainter *painter, TQTextParagraph *parag, int cx, int cy,
- int cw, int ch,
- TQPixmap *&/*doubleBuffer*/, const QPalette &pal,
- bool drawCursor, TQTextCursor *cursor, bool resetChanged)
-{
- if (resetChanged)
- parag->setChanged(false);
- TQRect ir(parag->rect());
-#ifndef QT_NO_TEXTCUSTOMITEM
- if (!parag->tableCell())
-#endif
- ir.setWidth(width());
-
- painter->translate(ir.x(), ir.y());
-
- if (!parag->document()->parent()) {
- const QPoint oldOrigin = painter->brushOrigin();
- painter->setBrushOrigin(-ir.topLeft());
- painter->fillRect(TQRect(0, 0, ir.width(), ir.height()), parag->backgroundBrush(pal));
- painter->setBrushOrigin(oldOrigin);
- }
-
- painter->translate(-(ir.x() - parag->rect().x()),
- -(ir.y() - parag->rect().y()));
- parag->paint(*painter, pal, drawCursor ? cursor : 0, true, cx, cy, cw, ch);
-
- painter->translate(-ir.x(), -ir.y());
-
- parag->document()->nextDoubleBuffered = false;
-}
-
-TQTextParagraph *TQTextDocument::draw(TQPainter *p, int cx, int cy, int cw, int ch,
- const QPalette &pal, bool onlyChanged, bool drawCursor,
- TQTextCursor *cursor, bool resetChanged)
-{
- if (withoutDoubleBuffer || (par && par->withoutDoubleBuffer)) {
- withoutDoubleBuffer = true;
- TQRect r;
- draw(p, r, pal);
- return 0;
- }
- withoutDoubleBuffer = false;
-
- if (!firstParagraph())
- return 0;
-
- TQPainter * oldPainter = TQTextFormat::painter();
- TQTextFormat::setPainter(p);
- if (formatCollection()->defaultFormat()->color() != pal.text().color())
- setDefaultFormat(formatCollection()->defaultFormat()->font(), pal.text().color());
-
- if (cx < 0 && cy < 0) {
- cx = 0;
- cy = 0;
- cw = width();
- ch = height();
- }
-
- TQTextParagraph *lastFormatted = 0;
- TQTextParagraph *parag = firstParagraph();
-
- TQPixmap *doubleBuffer = 0;
-
- while (parag) {
- lastFormatted = parag;
- if (!parag->isValid())
- parag->format();
-
- TQRect pr = parag->rect();
- pr.setWidth(parag->document()->width());
- if (pr.y() > cy + ch)
- goto floating;
- TQRect clipr(cx, cy, cw, ch);
- if (!pr.intersects(clipr) || (onlyChanged && !parag->hasChanged())) {
- pr.setWidth(parag->document()->width());
- parag = parag->next();
- continue;
- }
-
- drawParagraph(p, parag, cx, cy, cw, ch, doubleBuffer, pal, drawCursor,
- cursor, resetChanged);
- parag = parag->next();
- }
-
- parag = lastParagraph();
-
- floating:
- if (parag->rect().y() + parag->rect().height() < parag->document()->height()) {
- if (!parag->document()->parent()) {
- TQRect fillRect = TQRect(0, parag->rect().y() + parag->rect().height(), parag->document()->width(),
- parag->document()->height() - (parag->rect().y() + parag->rect().height()));
- if (TQRect(cx, cy, cw, ch).intersects(fillRect))
- p->fillRect(fillRect, pal.brush(QPalette::Base));
- }
- if (!flow()->isEmpty()) {
- TQRect cr(cx, cy, cw, ch);
- flow()->drawFloatingItems(p, cr.x(), cr.y(), cr.width(), cr.height(), pal, false);
- }
- }
-
- if (buf_pixmap && buf_pixmap->height() > 300) {
- delete buf_pixmap;
- buf_pixmap = 0;
- }
-
- TQTextFormat::setPainter(oldPainter);
- return lastFormatted;
-}
-
-/*
- #### this function only sets the default font size in the format collection
- */
-void TQTextDocument::setDefaultFormat(const QFont &font, const QColor &color)
-{
- bool reformat = font != fCollection->defaultFormat()->font();
- for (int idx = 0; idx < childList.size(); ++idx) {
- TQTextDocument *dc = childList.at(idx);
- dc->setDefaultFormat(font, color);
- }
- fCollection->updateDefaultFormat(font, color, sheet_);
-
- if (!reformat)
- return;
- tStopWidth = formatCollection()->defaultFormat()->width(TQLatin1Char('x')) * 8;
-
- // invalidate paragraphs and custom items
- TQTextParagraph *p = fParag;
- while (p) {
- p->invalidate(0);
-#ifndef QT_NO_TEXTCUSTOMITEM
- for (int i = 0; i < p->length() - 1; ++i)
- if (p->at(i)->isCustom())
- p->at(i)->customItem()->invalidate();
-#endif
- p = p->next();
- }
-}
-
-
-/*!
- \preliminary
-
- Generates an internal object for the tag called \a name, given the
- attributes \a attr, and using additional information provided by
- the mime source factory \a factory.
-
- \a context is the optional context of the document, i.e. the path
- to look for relative links. This becomes important if the text
- contains relative references, for example within image tags.
- QSimpleRichText always uses the default mime source factory (see
- \l{TQMimeSourceFactory::defaultFactory()}) to resolve these
- references. The context will then be used to calculate the
- absolute path. See TQMimeSourceFactory::makeAbsolute() for details.
-
- \a emptyTag and \a doc are for internal use only.
-
- This function should not be used in application code.
-*/
-#ifndef QT_NO_TEXTCUSTOMITEM
-TQTextCustomItem* TQTextDocument::tag(TQStyleSheet *sheet, const TQString& name,
- const QMap<TQString, TQString> &attr,
- const TQString& context,
- const TQMimeSourceFactory& factory,
- bool /*emptyTag */, TQTextDocument *doc)
-{
- const TQStyleSheetItem* style = sheet->item(name);
- // first some known tags
- if (!style)
- return 0;
- if (style->name() == TQLatin1String("img"))
- return new TQTextImage(doc, attr, context, (TQMimeSourceFactory&)factory);
- if (style->name() == TQLatin1String("hr"))
- return new TQTextHorizontalLine(doc, attr, context, (TQMimeSourceFactory&)factory );
- return 0;
-}
-#endif
-
-
-#ifndef QT_NO_TEXTCUSTOMITEM
-void TQTextDocument::registerCustomItem(TQTextCustomItem *i, TQTextParagraph *p)
-{
- if (i && i->placement() != TQTextCustomItem::PlaceInline) {
- flow_->registerFloatingItem(i);
- p->registerFloatingItem(i);
- i->setParagraph(p);
- }
- p->mightHaveCustomItems = mightHaveCustomItems = true;
-}
-
-void TQTextDocument::unregisterCustomItem(TQTextCustomItem *i, TQTextParagraph *p)
-{
- p->unregisterFloatingItem(i);
- i->setParagraph(0);
- flow_->unregisterFloatingItem(i);
-}
-#endif
-
-bool TQTextDocument::hasFocusParagraph() const
-{
- return !!focusIndicator.parag;
-}
-
-TQString TQTextDocument::focusHref() const
-{
- return focusIndicator.href;
-}
-
-TQString TQTextDocument::focusName() const
-{
- return focusIndicator.name;
-}
-
-bool TQTextDocument::focusNextPrevChild(bool next)
-{
- if (!focusIndicator.parag) {
- if (next) {
- focusIndicator.parag = fParag;
- focusIndicator.start = 0;
- focusIndicator.len = 0;
- } else {
- focusIndicator.parag = lParag;
- focusIndicator.start = lParag->length();
- focusIndicator.len = 0;
- }
- } else {
- focusIndicator.parag->setChanged(true);
- }
- focusIndicator.href.clear();
- focusIndicator.name.clear();
-
- if (next) {
- TQTextParagraph *p = focusIndicator.parag;
- int index = focusIndicator.start + focusIndicator.len;
- while (p) {
- for (int i = index; i < p->length(); ++i) {
- if (p->at(i)->isAnchor()) {
- p->setChanged(true);
- focusIndicator.parag = p;
- focusIndicator.start = i;
- focusIndicator.len = 0;
- focusIndicator.href = p->at(i)->anchorHref();
- focusIndicator.name = p->at(i)->anchorName();
- while (i < p->length()) {
- if (!p->at(i)->isAnchor())
- return true;
- focusIndicator.len++;
- i++;
- }
-#ifndef QT_NO_TEXTCUSTOMITEM
- } else if (p->at(i)->isCustom()) {
- if (p->at(i)->customItem()->isNested()) {
- TQTextTable *t = (TQTextTable*)p->at(i)->customItem();
- QList<TQTextTableCell *> cells = t->tableCells();
- // first try to continue
- int idx;
- bool resetCells = true;
- for (idx = 0; idx < cells.size(); ++idx) {
- TQTextTableCell *c = cells.at(idx);
- if (c->richText()->hasFocusParagraph()) {
- if (c->richText()->focusNextPrevChild(next)) {
- p->setChanged(true);
- focusIndicator.parag = p;
- focusIndicator.start = i;
- focusIndicator.len = 0;
- focusIndicator.href = c->richText()->focusHref();
- focusIndicator.name = c->richText()->focusName();
- return true;
- } else {
- resetCells = false;
- ++idx;
- break;
- }
- }
- }
- // now really try
- if (resetCells)
- idx = 0;
- for (; idx < cells.size(); ++idx) {
- TQTextTableCell *c = cells.at(idx);
- if (c->richText()->focusNextPrevChild(next)) {
- p->setChanged(true);
- focusIndicator.parag = p;
- focusIndicator.start = i;
- focusIndicator.len = 0;
- focusIndicator.href = c->richText()->focusHref();
- focusIndicator.name = c->richText()->focusName();
- return true;
- }
- }
- }
-#endif
- }
- }
- index = 0;
- p = p->next();
- }
- } else {
- TQTextParagraph *p = focusIndicator.parag;
- int index = focusIndicator.start - 1;
- if (focusIndicator.len == 0 && index < focusIndicator.parag->length() - 1)
- index++;
- while (p) {
- for (int i = index; i >= 0; --i) {
- if (p->at(i)->isAnchor()) {
- p->setChanged(true);
- focusIndicator.parag = p;
- focusIndicator.start = i;
- focusIndicator.len = 0;
- focusIndicator.href = p->at(i)->anchorHref();
- focusIndicator.name = p->at(i)->anchorName();
- while (i >= -1) {
- if (i < 0 || !p->at(i)->isAnchor()) {
- focusIndicator.start++;
- return true;
- }
- if (i < 0)
- break;
- focusIndicator.len++;
- focusIndicator.start--;
- i--;
- }
-#ifndef QT_NO_TEXTCUSTOMITEM
- } else if (p->at(i)->isCustom()) {
- if (p->at(i)->customItem()->isNested()) {
- TQTextTable *t = (TQTextTable*)p->at(i)->customItem();
- QList<TQTextTableCell *> cells = t->tableCells();
- // first try to continue
- int idx;
- bool resetCells = true;
- for (idx = cells.size()-1; idx >= 0; --idx) {
- TQTextTableCell *c = cells.at(idx);
- if (c->richText()->hasFocusParagraph()) {
- if (c->richText()->focusNextPrevChild(next)) {
- p->setChanged(true);
- focusIndicator.parag = p;
- focusIndicator.start = i;
- focusIndicator.len = 0;
- focusIndicator.href = c->richText()->focusHref();
- focusIndicator.name = c->richText()->focusName();
- return true;
- } else {
- resetCells = false;
- --idx;
- break;
- }
- }
- }
- // now really try
- if (resetCells)
- idx = cells.size()-1;
- for (; idx >= 0; --idx) {
- TQTextTableCell *c = cells.at(idx);
- if (c->richText()->focusNextPrevChild(next)) {
- p->setChanged(true);
- focusIndicator.parag = p;
- focusIndicator.start = i;
- focusIndicator.len = 0;
- focusIndicator.href = c->richText()->focusHref();
- focusIndicator.name = c->richText()->focusName();
- return true;
- }
- }
- }
-#endif
- }
- }
- p = p->prev();
- if (p)
- index = p->length() - 1;
- }
- }
-
- focusIndicator.parag = 0;
-
- return false;
-}
-
-int TQTextDocument::length() const
-{
- int l = -1;
- TQTextParagraph *p = fParag;
- while (p) {
- l += p->length();
- p = p->next();
- }
- return qMax(0,l);
-}
-
-// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-int TQTextFormat::width(const TQChar &c) const
-{
- if (c.unicode() == 0xad) // soft hyphen
- return 0;
- if (!pntr || !pntr->isActive()) {
- if (c == TQLatin1Char('\t'))
- return fm.width(TQLatin1Char(' '));
- if (ha == AlignNormal) {
- int w;
- if (c.row())
- w = fm.width(c);
- else
- w = widths[c.unicode()];
- if (w == 0 && !c.row()) {
- w = fm.width(c);
- ((TQTextFormat*)this)->widths[c.unicode()] = w;
- }
- return w;
- } else {
- QFont f(fn);
- if (usePixelSizes)
- f.setPixelSize((f.pixelSize() * 2) / 3);
- else
- f.setPointSize((f.pointSize() * 2) / 3);
- QFontMetrics fm_(f);
- return fm_.width(c);
- }
- }
-
- QFont f(fn);
- if (ha != AlignNormal) {
- if (usePixelSizes)
- f.setPixelSize((f.pixelSize() * 2) / 3);
- else
- f.setPointSize((f.pointSize() * 2) / 3);
- }
- applyFont(f);
-
- return pntr_fm->width(c);
-}
-
-int TQTextFormat::width(const TQString &str, int pos) const
-{
- int w = 0;
- if (str.unicode()[pos].unicode() == 0xad)
- return w;
- if (!pntr || !pntr->isActive()) {
- if (ha == AlignNormal) {
- w = fm.charWidth(str, pos);
- } else {
- QFont f(fn);
- if (usePixelSizes)
- f.setPixelSize((f.pixelSize() * 2) / 3);
- else
- f.setPointSize((f.pointSize() * 2) / 3);
- QFontMetrics fm_(f);
- w = fm_.charWidth(str, pos);
- }
- } else {
- QFont f(fn);
- if (ha != AlignNormal) {
- if (usePixelSizes)
- f.setPixelSize((f.pixelSize() * 2) / 3);
- else
- f.setPointSize((f.pointSize() * 2) / 3);
- }
- applyFont(f);
- w = pntr_fm->charWidth(str, pos);
- }
- return w;
-}
-
-// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-TQTextString::TQTextString()
-{
- bidiDirty = true;
- bidi = false;
- rightToLeft = false;
- dir = TQChar::DirON;
-}
-
-TQTextString::TQTextString(const TQTextString &s)
-{
- bidiDirty = true;
- bidi = s.bidi;
- rightToLeft = s.rightToLeft;
- dir = s.dir;
- data = s.data;
- data.detach();
- for (int i = 0; i < (int)data.size(); ++i) {
- TQTextFormat *f = data[i].format();
- if (f)
- f->addRef();
- }
-}
-
-void TQTextString::insert(int index, const QString &s, TQTextFormat *f)
-{
- insert(index, s.unicode(), s.length(), f);
-}
-
-void TQTextString::insert(int index, const QChar *unicode, int len, TQTextFormat *f)
-{
- int os = data.size();
- data.resize(data.size() + len);
- if (index < os) {
- memmove(data.data() + index + len, data.data() + index,
- sizeof(TQTextStringChar) * (os - index));
- }
- TQTextStringChar *ch = data.data() + index;
- for (int i = 0; i < len; ++i) {
- ch->x = 0;
- ch->lineStart = 0;
- ch->nobreak = false;
- ch->type = TQTextStringChar::Regular;
- ch->p.format = f;
- ch->rightToLeft = 0;
- ch->c = unicode[i];
- ++ch;
- }
- bidiDirty = true;
-}
-
-TQTextString::~TQTextString()
-{
- clear();
-}
-
-void TQTextString::insert(int index, TQTextStringChar *c, bool doAddRefFormat )
-{
- int os = data.size();
- data.resize(data.size() + 1);
- if (index < os) {
- memmove(data.data() + index + 1, data.data() + index,
- sizeof(TQTextStringChar) * (os - index));
- }
- TQTextStringChar &ch = data[(int)index];
- ch.c = c->c;
- ch.x = 0;
- ch.lineStart = 0;
- ch.rightToLeft = 0;
- ch.p.format = 0;
- ch.type = TQTextStringChar::Regular;
- ch.nobreak = false;
- if (doAddRefFormat && c->format())
- c->format()->addRef();
- ch.setFormat(c->format());
- bidiDirty = true;
-}
-
-int TQTextString::appendParagraphs( TQTextParagraph *start, TQTextParagraph *end )
-{
- int paragCount = 0;
- int newLength = data.size();
- for (TQTextParagraph *p = start; p != end; p = p->next()) {
- newLength += p->length();
- ++paragCount;
- }
-
- const int oldLength = data.size();
- data.resize(newLength);
-
- TQTextStringChar *d = &data[oldLength];
- for (TQTextParagraph *p = start; p != end; p = p->next()) {
- const TQTextStringChar * const src = p->at(0);
- int i = 0;
- for (; i < p->length() - 1; ++i) {
- d[i].c = src[i].c;
- d[i].x = 0;
- d[i].lineStart = 0;
- d[i].rightToLeft = 0;
- d[i].type = TQTextStringChar::Regular;
- d[i].nobreak = false;
- d[i].p.format = src[i].format();
- if (d[i].p.format)
- d[i].p.format->addRef();
- }
- d[i].x = 0;
- d[i].lineStart = 0;
- d[i].nobreak = false;
- d[i].type = TQTextStringChar::Regular;
- d[i].p.format = 0;
- d[i].rightToLeft = 0;
- d[i].c = TQLatin1Char('\n');
- d += p->length();
- }
-
- bidiDirty = true;
- return paragCount;
-}
-
-void TQTextString::truncate(int index)
-{
- index = qMax(index, 0);
- index = qMin(index, (int)data.size() - 1);
- if (index < (int)data.size()) {
- for (int i = index + 1; i < (int)data.size(); ++i) {
- TQTextStringChar &ch = data[i];
-#ifndef QT_NO_TEXTCUSTOMITEM
- if (!(ch.type == TQTextStringChar::Regular)) {
- delete ch.customItem();
- if (ch.p.custom->format)
- ch.p.custom->format->removeRef();
- delete ch.p.custom;
- ch.p.custom = 0;
- } else
-#endif
- if (ch.format()) {
- ch.format()->removeRef();
- }
- }
- }
- data.resize(index);
- bidiDirty = true;
-}
-
-void TQTextString::remove(int index, int len)
-{
- for (int i = index; i < (int)data.size() && i - index < len; ++i) {
- TQTextStringChar &ch = data[i];
-#ifndef QT_NO_TEXTCUSTOMITEM
- if (!(ch.type == TQTextStringChar::Regular)) {
- delete ch.customItem();
- if (ch.p.custom->format)
- ch.p.custom->format->removeRef();
- delete ch.p.custom;
- ch.p.custom = 0;
- } else
-#endif
- if (ch.format()) {
- ch.format()->removeRef();
- }
- }
- memmove(data.data() + index, data.data() + index + len,
- sizeof(TQTextStringChar) * (data.size() - index - len));
- data.resize(data.size() - len);
- bidiDirty = true;
-}
-
-void TQTextString::clear()
-{
- for (int i = 0; i < (int)data.count(); ++i) {
- TQTextStringChar &ch = data[i];
-#ifndef QT_NO_TEXTCUSTOMITEM
- if (!(ch.type == TQTextStringChar::Regular)) {
- if (ch.customItem() && ch.customItem()->placement() == TQTextCustomItem::PlaceInline)
- delete ch.customItem();
- if (ch.p.custom->format)
- ch.p.custom->format->removeRef();
- delete ch.p.custom;
- ch.p.custom = 0;
- } else
-#endif
- if (ch.format()) {
- ch.format()->removeRef();
- }
- }
- data.resize(0);
- bidiDirty = true;
-}
-
-void TQTextString::setFormat(int index, TQTextFormat *f, bool useCollection)
-{
- TQTextStringChar &ch = data[index];
- if (useCollection && ch.format())
- ch.format()->removeRef();
- ch.setFormat(f);
-}
-
-void TQTextString::checkBidi() const
-{
- // ############ fix BIDI handling
- TQTextString *that = (TQTextString *)this;
- that->bidiDirty = false;
- int length = data.size();
- if (!length) {
- that->bidi = rightToLeft;
- that->rightToLeft = (dir == TQChar::DirR);
- return;
- }
-
- if (dir == TQChar::DirR) {
- that->rightToLeft = true;
- } else if (dir == TQChar::DirL) {
- that->rightToLeft = false;
- } else {
- that->rightToLeft = (QApplication::layoutDirection() == Qt::RightToLeft);
- }
-
- const TQTextStringChar *start = data.data();
- const TQTextStringChar *end = start + length;
-
- ((TQTextString *)this)->stringCache = toString(data);
-
- // determines the properties we need for layouting
- QTextEngine textEngine;
- textEngine.text = toString();
- textEngine.option.setTextDirection(rightToLeft ? Qt::RightToLeft : Qt::LeftToRight);
- textEngine.itemize();
- const HB_CharAttributes *ca = textEngine.attributes() + length-1;
- TQTextStringChar *ch = (TQTextStringChar *)end - 1;
- QScriptItem *item = &textEngine.layoutData->items[textEngine.layoutData->items.size()-1];
- unsigned char bidiLevel = item->analysis.bidiLevel;
- that->bidi = (bidiLevel || rightToLeft);
- int pos = length-1;
- while (ch >= start) {
- if (item->position > pos) {
- --item;
- Q_ASSERT(item >= &textEngine.layoutData->items[0]);
- bidiLevel = item->analysis.bidiLevel;
- if (bidiLevel)
- that->bidi = true;
- }
- ch->softBreak = ca->lineBreakType >= HB_Break;
- ch->whiteSpace = ca->whiteSpace;
- ch->charStop = ca->charStop;
- ch->bidiLevel = bidiLevel;
- ch->rightToLeft = (bidiLevel%2);
- --ch;
- --ca;
- --pos;
- }
-}
-
-void TQTextDocument::setStyleSheet(TQStyleSheet *s)
-{
- if (!s)
- return;
- sheet_ = s;
- list_tm = list_bm = par_tm = par_bm = 12;
- list_lm = 40;
- li_tm = li_bm = 0;
- TQStyleSheetItem* item = s->item(TQLatin1String("ol"));
- if (item) {
- list_tm = qMax(0,item->margin(TQStyleSheetItem::MarginTop));
- list_bm = qMax(0,item->margin(TQStyleSheetItem::MarginBottom));
- list_lm = qMax(0,item->margin(TQStyleSheetItem::MarginLeft));
- }
- if ((item = s->item(TQLatin1String("li")))) {
- li_tm = qMax(0,item->margin(TQStyleSheetItem::MarginTop));
- li_bm = qMax(0,item->margin(TQStyleSheetItem::MarginBottom));
- }
- if ((item = s->item(TQLatin1String("p")))) {
- par_tm = qMax(0,item->margin(TQStyleSheetItem::MarginTop));
- par_bm = qMax(0,item->margin(TQStyleSheetItem::MarginBottom));
- }
-}
-
-void TQTextDocument::setUnderlineLinks(bool b) {
- underlLinks = b;
- for (int idx = 0; idx < childList.size(); ++idx) {
- TQTextDocument *dc = childList.at(idx);
- dc->setUnderlineLinks(b);
- }
-}
-
-void TQTextStringChar::setFormat(TQTextFormat *f)
-{
- if (type == Regular) {
- p.format = f;
- } else {
-#ifndef QT_NO_TEXTCUSTOMITEM
- if (!p.custom) {
- p.custom = new CustomData;
- p.custom->custom = 0;
- }
- p.custom->format = f;
-#endif
- }
-}
-
-#ifndef QT_NO_TEXTCUSTOMITEM
-void TQTextStringChar::setCustomItem(TQTextCustomItem *i)
-{
- if (type == Regular) {
- TQTextFormat *f = format();
- p.custom = new CustomData;
- p.custom->format = f;
- } else {
- delete p.custom->custom;
- }
- p.custom->custom = i;
- type = (type == Anchor ? CustomAnchor : Custom);
-}
-
-void TQTextStringChar::loseCustomItem()
-{
- if (type == Custom) {
- TQTextFormat *f = p.custom->format;
- p.custom->custom = 0;
- delete p.custom;
- type = Regular;
- p.format = f;
- } else if (type == CustomAnchor) {
- p.custom->custom = 0;
- type = Anchor;
- }
-}
-
-#endif
-
-TQString TQTextStringChar::anchorName() const
-{
- if (type == Regular)
- return TQString();
- else
- return p.custom->anchorName;
-}
-
-TQString TQTextStringChar::anchorHref() const
-{
- if (type == Regular)
- return TQString();
- else
- return p.custom->anchorHref;
-}
-
-void TQTextStringChar::setAnchor(const TQString& name, const TQString& href)
-{
- if (type == Regular) {
- TQTextFormat *f = format();
- p.custom = new CustomData;
-#ifndef QT_NO_TEXTCUSTOMITEM
- p.custom->custom = 0;
-#endif
- p.custom->format = f;
- type = Anchor;
- } else if (type == Custom) {
- type = CustomAnchor;
- }
- p.custom->anchorName = name;
- p.custom->anchorHref = href;
-}
-
-
-int TQTextString::width(int idx) const
-{
- int w = 0;
- TQTextStringChar *c = &at(idx);
- if (!c->charStop || c->c.unicode() == 0xad || c->c.unicode() == 0x2028)
- return 0;
-#ifndef QT_NO_TEXTCUSTOMITEM
- if(c->isCustom()) {
- if(c->customItem()->placement() == TQTextCustomItem::PlaceInline)
- w = c->customItem()->width;
- } else
-#endif
- {
- int r = c->c.row();
- if(r < 0x06
-#ifndef Q_WS_WIN
- // Uniscribe's handling of Asian makes the condition below fail.
- || (r > 0x1f && !(r > 0xd7 && r < 0xe0))
-#endif
- ) {
- w = c->format()->width(c->c);
- } else {
- // complex text. We need some hacks to get the right metric here
- w = c->format()->width(toString(), idx);
- }
- }
- return w;
-}
-
-// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-TQTextParagraph::TQTextParagraph(TQTextDocument *dc, TQTextParagraph *pr, TQTextParagraph *nx, bool updateIds)
- : p(pr), n(nx), docOrPseudo(dc),
- changed(false), firstFormat(true), firstPProcess(true), needPreProcess(false), fullWidth(true),
- lastInFrame(false), visible(true), breakable(true), movedDown(false),
- mightHaveCustomItems(false), hasdoc(dc != 0), litem(false), rtext(false),
- align(0), lstyle(TQStyleSheetItem::ListDisc), invalid(0), mSelections(0),
-#ifndef QT_NO_TEXTCUSTOMITEM
- mFloatingItems(0),
-#endif
- utm(0), ubm(0), ulm(0), urm(0), uflm(0), ulinespacing(0),
- tabStopWidth(0), minwidth(0), tArray(0), eData(0), ldepth(0)
-{
- lstyle = TQStyleSheetItem::ListDisc;
- if (!hasdoc)
- docOrPseudo = new TQTextParagraphPseudoDocument;
- bgcol = 0;
- list_val = -1;
- paintdevice = 0;
- TQTextFormat* defFormat = formatCollection()->defaultFormat();
- if (!hasdoc) {
- tabStopWidth = defFormat->width(TQLatin1Char('x')) * 8;
- pseudoDocument()->commandHistory = new TQTextCommandHistory(100);
- }
-
- if (p)
- p->n = this;
- if (n)
- n->p = this;
-
- if (!p && hasdoc)
- document()->setFirstParagraph(this);
- if (!n && hasdoc)
- document()->setLastParagraph(this);
-
- state = -1;
-
- if (p)
- id = p->id + 1;
- else
- id = 0;
- if (n && updateIds) {
- TQTextParagraph *s = n;
- while (s) {
- s->id = s->p->id + 1;
- s->invalidateStyleCache();
- s = s->n;
- }
- }
-
- str = new TQTextString();
- const TQChar ch(TQLatin1Char(' '));
- str->insert(0, &ch, 1, formatCollection()->defaultFormat());
-}
-
-TQTextParagraph::~TQTextParagraph()
-{
- delete str;
- if (hasdoc) {
- register TQTextDocument *doc = document();
- if (this == doc->minwParag) {
- doc->minwParag = 0;
- doc->minw = 0;
- }
- if (this == doc->curParag)
- doc->curParag = 0;
- } else {
- delete pseudoDocument();
- }
- delete [] tArray;
- delete eData;
- QMap<int, QTextLineStart*>::Iterator it = lineStarts.begin();
- for (; it != lineStarts.end(); ++it)
- delete *it;
- if (mSelections)
- delete mSelections;
-#ifndef QT_NO_TEXTCUSTOMITEM
- if (mFloatingItems)
- delete mFloatingItems;
-#endif
- if (p)
- p->setNext(n);
- if (n)
- n->setPrev(p);
- delete bgcol;
-}
-
-void TQTextParagraph::setNext(TQTextParagraph *s)
-{
- n = s;
- if (!n && hasdoc)
- document()->setLastParagraph(this);
-}
-
-void TQTextParagraph::setPrev(TQTextParagraph *s)
-{
- p = s;
- if (!p && hasdoc)
- document()->setFirstParagraph(this);
-}
-
-void TQTextParagraph::invalidate(int chr)
-{
- if (invalid < 0)
- invalid = chr;
- else
- invalid = qMin(invalid, chr);
-#ifndef QT_NO_TEXTCUSTOMITEM
- if (mFloatingItems) {
- for (int idx = 0; idx < mFloatingItems->size(); ++idx) {
- TQTextCustomItem *i = mFloatingItems->at(idx);
- i->ypos = -1;
- }
- }
-#endif
- invalidateStyleCache();
-}
-
-void TQTextParagraph::invalidateStyleCache()
-{
- if (list_val < 0)
- list_val = -1;
-}
-
-
-void TQTextParagraph::insert(int index, const QString &s)
-{
- insert(index, s.unicode(), s.length());
-}
-
-void TQTextParagraph::insert(int index, const QChar *unicode, int len)
-{
- if (hasdoc && !document()->useFormatCollection() && document()->preProcessor())
- str->insert(index, unicode, len,
- document()->preProcessor()->format(TQTextPreProcessor::Standard));
- else
- str->insert(index, unicode, len, formatCollection()->defaultFormat());
- invalidate(index);
- needPreProcess = true;
-}
-
-void TQTextParagraph::truncate(int index)
-{
- str->truncate(index);
- insert(length(), TQLatin1String(" "));
- needPreProcess = true;
-}
-
-void TQTextParagraph::remove(int index, int len)
-{
- if (index + len - str->length() > 0)
- return;
-#ifndef QT_NO_TEXTCUSTOMITEM
- for (int i = index; i < index + len; ++i) {
- TQTextStringChar *c = at(i);
- if (hasdoc && c->isCustom()) {
- document()->unregisterCustomItem(c->customItem(), this);
- }
- }
-#endif
- str->remove(index, len);
- invalidate(0);
- needPreProcess = true;
-}
-
-void TQTextParagraph::join(TQTextParagraph *s)
-{
- int oh = r.height() + s->r.height();
- n = s->n;
- if (n)
- n->p = this;
- else if (hasdoc)
- document()->setLastParagraph(this);
-
- int start = str->length();
- if (length() > 0 && at(length() - 1)->c == TQLatin1Char(' ')) {
- remove(length() - 1, 1);
- --start;
- }
- append(s->str->toString(), true);
-
- for (int i = 0; i < s->length(); ++i) {
- if (!hasdoc || document()->useFormatCollection()) {
- s->str->at(i).format()->addRef();
- str->setFormat(i + start, s->str->at(i).format(), true);
- }
-#ifndef QT_NO_TEXTCUSTOMITEM
- if (s->str->at(i).isCustom()) {
- TQTextCustomItem * item = s->str->at(i).customItem();
- str->at(i + start).setCustomItem(item);
- s->str->at(i).loseCustomItem();
- if (hasdoc) {
- document()->unregisterCustomItem(item, s);
- document()->registerCustomItem(item, this);
- }
- }
- if (s->str->at(i).isAnchor()) {
- str->at(i + start).setAnchor(s->str->at(i).anchorName(),
- s->str->at(i).anchorHref());
- }
-#endif
- }
-
- if (!extraData() && s->extraData()) {
- setExtraData(s->extraData());
- s->setExtraData(0);
- } else if (extraData() && s->extraData()) {
- extraData()->join(s->extraData());
- }
- delete s;
- invalidate(0);
- r.setHeight(oh);
- needPreProcess = true;
- if (n) {
- TQTextParagraph *s = n;
- s->invalidate(0);
- while (s) {
- s->id = s->p->id + 1;
- s->state = -1;
- s->needPreProcess = true;
- s->changed = true;
- s->invalidateStyleCache();
- s = s->n;
- }
- }
- format();
- state = -1;
-}
-
-void TQTextParagraph::move(int &dy)
-{
- if (dy == 0)
- return;
- changed = true;
- r.moveBy(0, dy);
-#ifndef QT_NO_TEXTCUSTOMITEM
- if (mFloatingItems) {
- for (int idx = 0; idx < mFloatingItems->size(); ++idx) {
- TQTextCustomItem *i = mFloatingItems->at(idx);
- i->ypos += dy;
- }
- }
-#endif
- if (p)
- p->lastInFrame = true;
-
- // do page breaks if required
- if (hasdoc && document()->isPageBreakEnabled()) {
- int shift;
- if ((shift = document()->formatter()->formatVertically( document(), this))) {
- if (p)
- p->setChanged(true);
- dy += shift;
- }
- }
-}
-
-void TQTextParagraph::format(int start, bool doMove)
-{
- if (!str || str->length() == 0 || !formatter())
- return;
-
- if (hasdoc &&
- document()->preProcessor() &&
- (needPreProcess || state == -1))
- document()->preProcessor()->process(document(), this, invalid <= 0 ? 0 : invalid);
- needPreProcess = false;
-
- if (invalid == -1)
- return;
-
- r.moveTopLeft(QPoint(documentX(), p ? p->r.y() + p->r.height() : documentY()));
- if (p)
- p->lastInFrame = false;
-
- movedDown = false;
- bool formattedAgain = false;
-
- formatAgain:
-
- r.setWidth(documentWidth());
-#ifndef QT_NO_TEXTCUSTOMITEM
- if (hasdoc && mFloatingItems) {
- for (int idx = 0; idx < mFloatingItems->size(); ++idx) {
- TQTextCustomItem *i = mFloatingItems->at(idx);
- i->ypos = r.y();
- if (i->placement() == TQTextCustomItem::PlaceRight) {
- i->xpos = r.x() + r.width() - i->width;
- }
- }
- }
-#endif
- QMap<int, QTextLineStart*> oldLineStarts = lineStarts;
- lineStarts.clear();
- int y = formatter()->format(document(), this, start, oldLineStarts);
-
-
- r.setWidth(qMax(r.width(), formatter()->minimumWidth()));
-
-
- QMap<int, QTextLineStart*>::Iterator it = oldLineStarts.begin();
-
- for (; it != oldLineStarts.end(); ++it)
- delete *it;
-
- if (!hasdoc) { // qt_format_text bounding rect handling
- it = lineStarts.begin();
- int usedw = 0;
- for (; it != lineStarts.end(); ++it)
- usedw = qMax(usedw, (*it)->w);
- if (r.width() <= 0) {
- // if the user specifies an invalid rect, this means that the
- // bounding box should grow to the width that the text actually
- // needs
- r.setWidth(usedw);
- } else {
- r.setWidth(qMin(usedw, r.width()));
- }
- }
-
- if (y != r.height())
- r.setHeight(y);
-
- if (!visible) {
- r.setHeight(0);
- } else {
- int minw = minwidth = formatter()->minimumWidth();
- int wused = formatter()->widthUsed();
- wused = qMax(minw, wused);
- if (hasdoc) {
- document()->setMinimumWidth(minw, wused, this);
- } else {
- pseudoDocument()->minw = qMax(pseudoDocument()->minw, minw);
- pseudoDocument()->wused = qMax(pseudoDocument()->wused, wused);
- }
- }
-
- // do page breaks if required
- if (hasdoc && document()->isPageBreakEnabled()) {
- int shift = document()->formatter()->formatVertically(document(), this);
- if (shift && !formattedAgain) {
- formattedAgain = true;
- goto formatAgain;
- }
- }
-
- if (n && doMove && n->invalid == -1 && r.y() + r.height() != n->r.y()) {
- int dy = (r.y() + r.height()) - n->r.y();
- TQTextParagraph *s = n;
- bool makeInvalid = p && p->lastInFrame;
- while (s && dy) {
- if (!s->isFullWidth())
- makeInvalid = true;
- if (makeInvalid)
- s->invalidate(0);
- s->move(dy);
- if (s->lastInFrame)
- makeInvalid = true;
- s = s->n;
- }
- }
-
- firstFormat = false;
- changed = true;
- invalid = -1;
- //##### string()->setTextChanged(false);
-}
-
-int TQTextParagraph::lineHeightOfChar(int i, int *bl, int *y) const
-{
- if (!isValid())
- ((TQTextParagraph*)this)->format();
-
- QMap<int, QTextLineStart*>::ConstIterator it = lineStarts.end();
- --it;
- for (;;) {
- if (i >= it.key()) {
- if (bl)
- *bl = (*it)->baseLine;
- if (y)
- *y = (*it)->y;
- return (*it)->h;
- }
- if (it == lineStarts.begin())
- break;
- --it;
- }
-
- qWarning("TQTextParagraph::lineHeightOfChar: couldn't find lh for %d", i);
- return 15;
-}
-
-TQTextStringChar *TQTextParagraph::lineStartOfChar(int i, int *index, int *line) const
-{
- if (!isValid())
- ((TQTextParagraph*)this)->format();
-
- int l = (int)lineStarts.count() - 1;
- QMap<int, QTextLineStart*>::ConstIterator it = lineStarts.end();
- --it;
- for (;;) {
- if (i >= it.key()) {
- if (index)
- *index = it.key();
- if (line)
- *line = l;
- return &str->at(it.key());
- }
- if (it == lineStarts.begin())
- break;
- --it;
- --l;
- }
-
- qWarning("TQTextParagraph::lineStartOfChar: couldn't find %d", i);
- return 0;
-}
-
-int TQTextParagraph::lines() const
-{
- if (!isValid())
- ((TQTextParagraph*)this)->format();
-
- return (int)lineStarts.count();
-}
-
-TQTextStringChar *TQTextParagraph::lineStartOfLine(int line, int *index) const
-{
- if (!isValid())
- ((TQTextParagraph*)this)->format();
-
- if (line >= 0 && line < (int)lineStarts.count()) {
- QMap<int, QTextLineStart*>::ConstIterator it = lineStarts.begin();
- while (line-- > 0)
- ++it;
- int i = it.key();
- if (index)
- *index = i;
- return &str->at(i);
- }
-
- qWarning("TQTextParagraph::lineStartOfLine: couldn't find %d", line);
- return 0;
-}
-
-int TQTextParagraph::leftGap() const
-{
- if (!isValid())
- ((TQTextParagraph*)this)->format();
-
- if (str->length() == 0)
- return 0;
-
- int line = 0;
- int x = str->length() ? str->at(0).x : 0; /* set x to x of first char */
- if (str->isBidi()) {
- for (int i = 1; i < str->length()-1; ++i)
- x = qMin(x, str->at(i).x);
- return x;
- }
-
- QMap<int, QTextLineStart*>::ConstIterator it = lineStarts.begin();
- while (line < (int)lineStarts.count()) {
- int i = it.key(); /* char index */
- x = qMin(x, str->at(i).x);
- ++it;
- ++line;
- }
- return x;
-}
-
-void TQTextParagraph::setFormat(int index, int len, TQTextFormat *f, bool useCollection, int flags)
-{
- if (!f)
- return;
- if (index < 0)
- index = 0;
- if (index > str->length() - 1)
- index = str->length() - 1;
- if (index + len >= str->length())
- len = str->length() - index;
-
- TQTextFormatCollection *fc = 0;
- if (useCollection)
- fc = formatCollection();
- TQTextFormat *of;
- for (int i = 0; i < len; ++i) {
- of = str->at(i + index).format();
- if (!changed && (!of || f->key() != of->key()))
- changed = true;
- if (invalid == -1 &&
- (f->font().family() != of->font().family() ||
- f->font().pointSize() != of->font().pointSize() ||
- f->font().weight() != of->font().weight() ||
- f->font().italic() != of->font().italic() ||
- f->vAlign() != of->vAlign())) {
- invalidate(0);
- }
- if (flags == -1 || flags == TQTextFormat::Format || !fc) {
- if (fc)
- f = fc->format(f);
- str->setFormat(i + index, f, useCollection);
- } else {
- TQTextFormat *fm = fc->format(of, f, flags);
- str->setFormat(i + index, fm, useCollection);
- }
- }
-}
-
-void TQTextParagraph::indent(int *oldIndent, int *newIndent)
-{
- if (!hasdoc || !document()->indent() || isListItem()) {
- if (oldIndent)
- *oldIndent = 0;
- if (newIndent)
- *newIndent = 0;
- if (oldIndent && newIndent)
- *newIndent = *oldIndent;
- return;
- }
- document()->indent()->indent(document(), this, oldIndent, newIndent);
-}
-
-void TQTextParagraph::paint(TQPainter &painter, const QPalette &pal, TQTextCursor *cursor,
- bool drawSelections, int clipx, int clipy, int clipw, int cliph)
-{
- if (!visible)
- return;
- int i, y, h, baseLine, xstart, xend = 0;
- i = y =h = baseLine = 0;
- TQRect cursorRect;
- drawSelections &= (mSelections != 0);
- // macintosh full-width selection style
- bool fullWidthStyle = QApplication::style()->styleHint(QStyle::SH_RichText_FullWidthSelection);
- int fullSelectionWidth = 0;
- if (drawSelections && fullWidthStyle)
- fullSelectionWidth = (hasdoc ? document()->width() : r.width());
-
- TQString qstr = str->toString();
- qstr.detach();
- // ### workaround so that \n are not drawn, actually this should
- // be fixed in QFont somewhere (under Windows you get ugly boxes
- // otherwise)
- TQChar* uc = (TQChar*) qstr.unicode();
- for (int ii = 0; ii < qstr.length(); ii++)
- if (uc[(int)ii]== TQLatin1Char(TQLatin1Char('\n')) || uc[(int)ii] == TQLatin1Char('\t'))
- uc[(int)ii] = 0x20;
-
- int line = -1;
- int paintStart = 0;
- TQTextStringChar *chr = 0;
- TQTextStringChar *nextchr = at(0);
- for (i = 0; i < length(); i++) {
- chr = nextchr;
- if (i < length()-1)
- nextchr = at(i+1);
-
- // we flush at end of document
- bool flush = (i == length()-1);
- bool ignoreSoftHyphen = false;
- if (!flush) {
- // we flush at end of line
- flush |= nextchr->lineStart;
- // we flush on format changes
- flush |= (nextchr->format() != chr->format());
- // we flush on link changes
- flush |= (nextchr->isLink() != chr->isLink());
- // we flush on start of run
- flush |= (nextchr->bidiLevel != chr->bidiLevel);
- // we flush on bidi changes
- flush |= (nextchr->rightToLeft != chr->rightToLeft);
- // we flush before and after tabs
- flush |= (chr->c == TQLatin1Char('\t') || nextchr->c == TQLatin1Char('\t'));
- // we flush on soft hyphens
- if (chr->c.unicode() == 0xad) {
- flush = true;
- if (!nextchr->lineStart)
- ignoreSoftHyphen = true;
- }
- // we flush on custom items
- flush |= chr->isCustom();
- // we flush before custom items
- flush |= nextchr->isCustom();
- // when painting justified, we flush on spaces
- if ((alignment() & Qt::AlignJustify) == Qt::AlignJustify)
- flush |= chr->whiteSpace;
- }
-
- // init a new line
- if (chr->lineStart) {
- ++line;
- paintStart = i;
- lineInfo(line, y, h, baseLine);
- if (clipy != -1 && cliph != 0 && y + r.y() - h > clipy + cliph) { // outside clip area, leave
- break;
- }
-
- // if this is the first line and we are a list item, draw the the bullet label
- if (line == 0 && isListItem()) {
- int x = chr->x;
- if (str->isBidi()) {
- if (str->isRightToLeft()) {
- x = chr->x + str->width(0);
- for (int k = 1; k < length(); ++k) {
- if (str->at(k).lineStart)
- break;
- x = qMax(x, str->at(k).x + str->width(k));
- }
- } else {
- x = chr->x;
- for (int k = 1; k < length(); ++k) {
- if (str->at(k).lineStart)
- break;
- x = qMin(x, str->at(k).x);
- }
- }
- }
- drawLabel(&painter, x, y, 0, 0, baseLine, pal);
- }
- }
-
- // check for cursor mark
- if (cursor && this == cursor->paragraph() && i == cursor->index()) {
- TQTextStringChar *c = i == 0 ? chr : chr - 1;
- cursorRect.setRect(cursor->x() , y + baseLine - c->format()->ascent(),
- 1, c->format()->height());
- }
-
- if (flush) { // something changed, draw what we have so far
- if (chr->rightToLeft) {
- xstart = chr->x;
- xend = at(paintStart)->x + str->width(paintStart);
- } else {
- xstart = at(paintStart)->x;
- xend = chr->x;
- if (i < length() - 1) {
- if (!str->at(i + 1).lineStart &&
- str->at(i + 1).rightToLeft == chr->rightToLeft)
- xend = str->at(i + 1).x;
- else
- xend += str->width(i);
- }
- }
-
- if ((clipx == -1 || clipw <= 0 || (xend >= clipx && xstart <= clipx + clipw)) &&
- (clipy == -1 || clipy < y+r.y()+h)) {
- if (!chr->isCustom())
- drawString(painter, qstr, paintStart, i - paintStart + (ignoreSoftHyphen ? 0 : 1), xstart, y,
- baseLine, xend-xstart, h, drawSelections, fullSelectionWidth,
- chr, pal, chr->rightToLeft);
-#ifndef QT_NO_TEXTCUSTOMITEM
- else if (chr->customItem()->placement() == TQTextCustomItem::PlaceInline) {
- bool inSelection = false;
- if (drawSelections) {
- QMap<int, TQTextParagraphSelection>::ConstIterator it = mSelections->constFind(TQTextDocument::Standard);
- inSelection = (it != mSelections->constEnd() && (*it).start <= i && (*it).end > i);
- }
- chr->customItem()->draw(&painter, chr->x, y,
- clipx == -1 ? clipx : (clipx - r.x()),
- clipy == -1 ? clipy : (clipy - r.y()),
- clipw, cliph, pal, inSelection);
- }
-#endif
- }
- paintStart = i+1;
- }
-
- }
-
- // time to draw the cursor
- const int cursor_extent = 4;
- if (!cursorRect.isNull() && cursor &&
- ((clipx == -1 || clipw == -1) || (cursorRect.right()+cursor_extent >= clipx && cursorRect.left()-cursor_extent <= clipx + clipw))) {
- painter.fillRect(cursorRect, pal.color(QPalette::Text));
- painter.save();
- if (string()->isBidi()) {
- if (at(cursor->index())->rightToLeft) {
- painter.setPen(Qt::black);
- painter.drawLine(cursorRect.x(), cursorRect.y(), cursorRect.x() - cursor_extent / 2, cursorRect.y() + cursor_extent / 2);
- painter.drawLine(cursorRect.x(), cursorRect.y() + cursor_extent, cursorRect.x() - cursor_extent / 2, cursorRect.y() + cursor_extent / 2);
- } else {
- painter.setPen(Qt::black);
- painter.drawLine(cursorRect.x(), cursorRect.y(), cursorRect.x() + cursor_extent / 2, cursorRect.y() + cursor_extent / 2);
- painter.drawLine(cursorRect.x(), cursorRect.y() + cursor_extent, cursorRect.x() + cursor_extent / 2, cursorRect.y() + cursor_extent / 2);
- }
- }
- painter.restore();
- }
-}
-
-//#define BIDI_DEBUG
-
-void TQTextParagraph::setColorForSelection(QColor &color, TQPainter &painter,
- const QPalette &pal, int selection)
-{
- if (selection < 0)
- return;
- color = (hasdoc && selection != TQTextDocument::Standard) ?
- document()->selectionColor(selection) :
- pal.color(QPalette::Highlight);
- QColor text = (hasdoc && document()->hasSelectionTextColor(selection)) ? document()->selectionTextColor(selection) : pal.color(QPalette::HighlightedText);
- if (text.isValid())
- painter.setPen(text);
-}
-
-void TQTextParagraph::drawString(TQPainter &painter, const TQString &str, int start, int len,
- int xstart, int y, int baseLine, int w, int h,
- bool drawSelections, int fullSelectionWidth,
- TQTextStringChar *formatChar, const QPalette& pal,
- bool rightToLeft)
-{
- bool plainText = hasdoc ? document()->textFormat() == TQt::PlainText : false;
- TQTextFormat* format = formatChar->format();
-
- int textFlags = int(rightToLeft ? Qt::TextForceRightToLeft : Qt::TextForceLeftToRight);
-
- if (!plainText || (hasdoc && format->color() != document()->formatCollection()->defaultFormat()->color()))
- painter.setPen(QPen(format->color()));
- else
- painter.setPen(pal.text().color());
- painter.setFont(format->font());
-
- if (hasdoc && formatChar->isAnchor() && !formatChar->anchorHref().isEmpty()) {
- if (format->useLinkColor())
- painter.setPen(document()->linkColor.isValid() ? document()->linkColor :
- pal.link().color());
- if (document()->underlineLinks()) {
- QFont fn = format->font();
- fn.setUnderline(true);
- painter.setFont(fn);
- }
- }
-
- int real_length = len;
- if (len && !rightToLeft && start + len == length()) // don't draw the last character (trailing space)
- len--;
- if (len && str.unicode()[start+len-1] == TQChar::LineSeparator)
- len--;
-
-
- TQTextFormat::VerticalAlignment vAlign = format->vAlign();
- if (vAlign != TQTextFormat::AlignNormal) {
- // sub or superscript
- QFont f(painter.font());
- if (format->fontSizesInPixels())
- f.setPixelSize((f.pixelSize() * 2) / 3);
- else
- f.setPointSize((f.pointSize() * 2) / 3);
- painter.setFont(f);
- int h = painter.fontMetrics().height();
- baseLine += (vAlign == TQTextFormat::AlignSubScript) ? h/6 : -h/2;
- }
-
- bool allSelected = false;
- if (drawSelections) {
- QMap<int, TQTextParagraphSelection>::ConstIterator it = mSelections->constFind(TQTextDocument::Standard);
- allSelected = (it != mSelections->constEnd() && (*it).start <= start && (*it).end >= start+len);
- }
- if (!allSelected)
- painter.drawText(QPointF(xstart, y + baseLine), str.mid(start, len), textFlags, /*justificationPadding*/0);
-
-#ifdef BIDI_DEBUG
- painter.save();
- painter.setPen (Qt::red);
- painter.drawLine(xstart, y, xstart, y + baseLine);
- painter.drawLine(xstart, y + baseLine/2, xstart + 10, y + baseLine/2);
- int w = 0;
- int i = 0;
- while(i < len)
- w += painter.fontMetrics().charWidth(str, start + i++);
- painter.setPen (Qt::blue);
- painter.drawLine(xstart + w - 1, y, xstart + w - 1, y + baseLine);
- painter.drawLine(xstart + w - 1, y + baseLine/2, xstart + w - 1 - 10, y + baseLine/2);
- painter.restore();
-#endif
-
- // check if we are in a selection and draw it
- if (drawSelections) {
- QMap<int, TQTextParagraphSelection>::ConstIterator it = mSelections->constEnd();
- while (it != mSelections->constBegin()) {
- --it;
- int selStart = (*it).start;
- int selEnd = (*it).end;
- int tmpw = w;
-
- selStart = qMax(selStart, start);
- int real_selEnd = qMin(selEnd, start+real_length);
- selEnd = qMin(selEnd, start+len);
- bool extendRight = false;
- bool extendLeft = false;
- bool selWrap = (real_selEnd == length()-1 && n && n->hasSelection(it.key()));
- if (selWrap
- || ((real_selEnd < this->str->length()) && this->str->at(real_selEnd).lineStart)) {
- extendRight = (fullSelectionWidth != 0);
- if (!extendRight && !rightToLeft)
- tmpw += painter.fontMetrics().width(TQLatin1Char(' '));
- }
- if (fullSelectionWidth && (selStart == 0 || this->str->at(selStart).lineStart)) {
- extendLeft = true;
- }
- if (this->str->isRightToLeft() != rightToLeft)
- extendLeft = extendRight = false;
-
- if (this->str->isRightToLeft()) {
- bool tmp = extendLeft;
- extendLeft = extendRight;
- extendRight = tmp;
- }
-
- if (selStart < real_selEnd ||
- (selWrap && fullSelectionWidth && extendRight &&
- // don't draw the standard selection on a printer=
- (it.key() != TQTextDocument::Standard || !is_printer(&painter)))) {
- int selection = it.key();
- QColor color;
- setColorForSelection(color, painter, pal, selection);
- if (selStart != start || selEnd != start + len || selWrap) {
- // have to clip
- painter.save();
- int cs, ce;
- if (rightToLeft) {
- cs = (selEnd != start + len) ?
- this->str->at(this->str->previousCursorPosition(selEnd)).x : xstart;
- ce = (selStart != start) ?
- this->str->at(this->str->previousCursorPosition(selStart)).x : xstart+tmpw;
- } else {
- cs = (selStart != start) ? this->str->at(selStart).x : xstart;
- ce = (selEnd != start + len) ? this->str->at(selEnd).x : xstart+tmpw;
- }
- TQRect r(cs, y, ce-cs, h);
- if (extendLeft)
- r.setLeft(0);
- if (extendRight)
- r.setRight(fullSelectionWidth);
- QRegion reg(r);
- if (painter.hasClipping())
- reg &= painter.clipRegion();
- painter.setClipRegion(reg);
- }
- int xleft = xstart;
- if (extendLeft) {
- tmpw += xstart;
- xleft = 0;
- }
- if (extendRight)
- tmpw = fullSelectionWidth - xleft;
- if(color.isValid())
- painter.fillRect(xleft, y, tmpw, h, color);
- painter.drawText(QPointF(xstart, y + baseLine), str.mid(start, len), textFlags, /*justificationPadding*/0);
- if (selStart != start || selEnd != start + len || selWrap)
- painter.restore();
- }
- }
- }
-
- if (format->isMisspelled()) {
- painter.save();
- painter.setPen(QPen(Qt::red, 1, Qt::DotLine));
- painter.drawLine(xstart, y + baseLine + 1, xstart + w, y + baseLine + 1);
- painter.restore();
- }
-
- if (hasdoc && formatChar->isAnchor() && !formatChar->anchorHref().isEmpty() &&
- document()->focusIndicator.parag == this &&
- ((document()->focusIndicator.start >= start &&
- document()->focusIndicator.start + document()->focusIndicator.len <= start + len)
- || (document()->focusIndicator.start <= start &&
- document()->focusIndicator.start + document()->focusIndicator.len >= start + len))) {
- QStyleOptionFocusRect opt;
- opt.rect.setRect(xstart, y, w, h);
-#ifndef Q_WS_WIN
- opt.state = QStyle::State_None;
-#else
- // force drawing a focus rect but only on windows because it's
- // configurable by the user in windows settings (see
- // SH_UnderlineShortcut style hint) and we want to override
- // this settings.
- opt.state = QStyle::State_KeyboardFocusChange;
-#endif
- opt.palette = pal;
- QApplication::style()->drawPrimitive(QStyle::PE_FrameFocusRect, &opt, &painter);
- }
-}
-
-void TQTextParagraph::drawLabel(TQPainter* p, int x, int y, int w, int h, int base,
- const QPalette& pal)
-{
- TQRect r (x, y, w, h);
- TQStyleSheetItem::ListStyle s = listStyle();
-
- p->save();
- TQTextFormat *format = at(0)->format();
- if (format) {
- p->setPen(format->color());
- p->setFont(format->font());
- }
- QFontMetrics fm(p->fontMetrics());
- int size = fm.lineSpacing() / 3;
-
- bool rtl = str->isRightToLeft();
-
- switch (s) {
- case TQStyleSheetItem::ListDecimal:
- case TQStyleSheetItem::ListLowerAlpha:
- case TQStyleSheetItem::ListUpperAlpha:
- {
- if (list_val == -1) { // uninitialised list value, calcluate the right one
- int depth = listDepth();
- list_val--;
- // ### evil, square and expensive. This needs to be done when formatting, not when painting
- TQTextParagraph* s = prev();
- int depth_s;
- while (s && (depth_s = s->listDepth()) >= depth) {
- if (depth_s == depth && s->isListItem())
- list_val--;
- s = s->prev();
- }
- }
-
- int n = list_val;
- if (n < -1)
- n = -n - 1;
- TQString l;
- switch (s) {
- case TQStyleSheetItem::ListLowerAlpha:
- if (n < 27) {
- l = TQLatin1Char(('a' + (char) (n-1)));
- break;
- }
- case TQStyleSheetItem::ListUpperAlpha:
- if (n < 27) {
- l = TQLatin1Char(('A' + (char) (n-1)));
- break;
- }
- break;
- default: //TQStyleSheetItem::ListDecimal:
- l.setNum(n);
- break;
- }
- if (rtl)
- l.prepend(TQLatin1String(" ."));
- else
- l += TQString::fromLatin1(". ");
- int x = (rtl ? r.left() : r.right() - fm.width(l));
- p->drawText(x, r.top() + base, l);
- }
- break;
- case TQStyleSheetItem::ListSquare:
- {
- int x = rtl ? r.left() + size : r.right() - size*2;
- TQRect er(x, r.top() + fm.height() / 2 - size / 2, size, size);
- p->fillRect(er , pal.brush(QPalette::Text));
- }
- break;
- case TQStyleSheetItem::ListCircle:
- {
- int x = rtl ? r.left() + size : r.right() - size*2;
- TQRect er(x, r.top() + fm.height() / 2 - size / 2, size, size);
- p->drawEllipse(er);
- }
- break;
- case TQStyleSheetItem::ListDisc:
- default:
- {
- p->setBrush(pal.brush(QPalette::Text));
- int x = rtl ? r.left() + size : r.right() - size*2;
- TQRect er(x, r.top() + fm.height() / 2 - size / 2, size, size);
- p->drawEllipse(er);
- p->setBrush(Qt::NoBrush);
- }
- break;
- }
-
- p->restore();
-}
-
-#ifndef QT_NO_DATASTREAM
-void TQTextParagraph::readStyleInformation(QDataStream &stream)
-{
- int int_align, int_lstyle;
- uchar uchar_litem, uchar_rtext, uchar_dir;
- stream >> int_align >> int_lstyle >> utm >> ubm >> ulm >> urm >> uflm
- >> ulinespacing >> ldepth >> uchar_litem >> uchar_rtext >> uchar_dir;
- align = int_align; lstyle = (TQStyleSheetItem::ListStyle) int_lstyle;
- litem = uchar_litem; rtext = uchar_rtext; str->setDirection((TQChar::Direction)uchar_dir);
- TQTextParagraph* s = prev() ? prev() : this;
- while (s) {
- s->invalidate(0);
- s = s->next();
- }
-}
-
-void TQTextParagraph::writeStyleInformation(QDataStream& stream) const
-{
- stream << (int) align << (int) lstyle << utm << ubm << ulm << urm << uflm << ulinespacing << ldepth << (uchar)litem << (uchar)rtext << (uchar)str->direction();
-}
-#endif
-
-
-void TQTextParagraph::setListItem(bool li)
-{
- if ((bool)litem == li)
- return;
- litem = li;
- changed = true;
- TQTextParagraph* s = prev() ? prev() : this;
- while (s) {
- s->invalidate(0);
- s = s->next();
- }
-}
-
-void TQTextParagraph::setListDepth(int depth) {
- if (!hasdoc || depth == ldepth)
- return;
- ldepth = depth;
- TQTextParagraph* s = prev() ? prev() : this;
- while (s) {
- s->invalidate(0);
- s = s->next();
- }
-}
-
-int *TQTextParagraph::tabArray() const
-{
- int *ta = tArray;
- if (!ta && hasdoc)
- ta = document()->tabArray();
- return ta;
-}
-
-int TQTextParagraph::nextTab(int, int x)
-{
- int *ta = tArray;
- if (hasdoc) {
- if (!ta)
- ta = document()->tabArray();
- tabStopWidth = document()->tabStopWidth();
- }
- if (ta) {
- int i = 0;
- while (ta[i]) {
- if (ta[i] >= x)
- return tArray[i];
- ++i;
- }
- return tArray[0];
- } else {
- int n;
- if (tabStopWidth != 0)
- n = x / tabStopWidth;
- else
- return x;
- return tabStopWidth * (n + 1);
- }
-}
-
-void TQTextParagraph::adjustToPainter(TQPainter *p)
-{
-#ifndef QT_NO_TEXTCUSTOMITEM
- for (int i = 0; i < length(); ++i) {
- if (at(i)->isCustom())
- at(i)->customItem()->adjustToPainter(p);
- }
-#endif
-}
-
-TQTextFormatCollection *TQTextParagraph::formatCollection() const
-{
- if (hasdoc)
- return document()->formatCollection();
- TQTextFormatCollection* fc = &pseudoDocument()->collection;
- if (paintdevice != fc->paintDevice())
- fc->setPaintDevice(paintdevice);
- return fc;
-}
-
-TQString TQTextParagraph::richText() const
-{
- TQString s;
- TQTextStringChar *formatChar = 0;
- TQString spaces;
- bool doStart = richTextExportStart && richTextExportStart->paragraph() == this;
- bool doEnd = richTextExportEnd && richTextExportEnd->paragraph() == this;
- int i;
- TQString lastAnchorName;
- for (i = 0; i < length()-1; ++i) {
- if (doStart && i && richTextExportStart->index() == i)
- s += TQLatin1String("<!--StartFragment-->");
- if (doEnd && richTextExportEnd->index() == i)
- s += TQLatin1String("<!--EndFragment-->");
- TQTextStringChar *c = &str->at(i);
- if (c->isAnchor() && !c->anchorName().isEmpty() && c->anchorName() != lastAnchorName) {
- lastAnchorName = c->anchorName();
- if (c->anchorName().contains(TQLatin1Char('#'))) {
-// TQStringList l = c->anchorName().split(TQLatin1Char('#'));
- TQStringList l = TQStringList::split(TQLatin1Char('#'), c->anchorName());
- for (TQStringList::ConstIterator it = l.constBegin(); it != l.constEnd(); ++it)
- s += TQLatin1String("<a name=\"") + *it + TQLatin1String("\"></a>");
- } else {
- s += TQLatin1String("<a name=\"") + c->anchorName() + TQLatin1String("\"></a>");
- }
- }
- if (!formatChar) {
- s += c->format()->makeFormatChangeTags(formatCollection()->defaultFormat(),
- 0, TQString(), c->anchorHref());
- formatChar = c;
- } else if ((formatChar->format()->key() != c->format()->key()) ||
- (c->anchorHref() != formatChar->anchorHref())) {
- s += c->format()->makeFormatChangeTags(formatCollection()->defaultFormat(),
- formatChar->format() , formatChar->anchorHref(), c->anchorHref());
- formatChar = c;
- }
- if (c->c == TQLatin1Char('<'))
- s += TQLatin1String("&lt;");
- else if (c->c == TQLatin1Char('>'))
- s += TQLatin1String("&gt;");
- else if (c->c == TQLatin1Char('&'))
- s += TQLatin1String("&amp;");
- else if (c->c == TQLatin1Char('\"'))
- s += TQLatin1String("&quot;");
-#ifndef QT_NO_TEXTCUSTOMITEM
- else if (c->isCustom())
- s += c->customItem()->richText();
-#endif
- else if (c->c == TQLatin1Char('\n') || c->c == TQChar::LineSeparator)
- s += TQLatin1String("<br />"); // space on purpose for compatibility with Netscape, Lynx & Co.
- else
- s += c->c;
- }
- if (doEnd && richTextExportEnd->index() == i)
- s += TQLatin1String("<!--EndFragment-->");
- if (formatChar)
- s += formatChar->format()->makeFormatEndTags(formatCollection()->defaultFormat(), formatChar->anchorHref());
- return s;
-}
-
-void TQTextParagraph::addCommand(TQTextCommand *cmd)
-{
- if (!hasdoc)
- pseudoDocument()->commandHistory->addCommand(cmd);
- else
- document()->commands()->addCommand(cmd);
-}
-
-TQTextCursor *TQTextParagraph::undo(TQTextCursor *c)
-{
- if (!hasdoc)
- return pseudoDocument()->commandHistory->undo(c);
- return document()->commands()->undo(c);
-}
-
-TQTextCursor *TQTextParagraph::redo(TQTextCursor *c)
-{
- if (!hasdoc)
- return pseudoDocument()->commandHistory->redo(c);
- return document()->commands()->redo(c);
-}
-
-int TQTextParagraph::topMargin() const
-{
- int m = 0;
- if (rtext) {
- m = isListItem() ? (document()->li_tm/qMax(1,listDepth()*listDepth())) :
- (listDepth() ? 0 : document()->par_tm);
- if (listDepth() == 1 &&( !prev() || prev()->listDepth() < listDepth()))
- m = qMax<int>(m, document()->list_tm);
- }
- m += utm;
- return scale(m, TQTextFormat::painter());
-}
-
-int TQTextParagraph::bottomMargin() const
-{
- int m = 0;
- if (rtext) {
- m = isListItem() ? (document()->li_bm/qMax(1,listDepth()*listDepth())) :
- (listDepth() ? 0 : document()->par_bm);
- if (listDepth() == 1 &&( !next() || next()->listDepth() < listDepth()))
- m = qMax<int>(m, document()->list_bm);
- }
- m += ubm;
- return scale(m, TQTextFormat::painter());
-}
-
-int TQTextParagraph::leftMargin() const
-{
- int m = ulm;
- if (listDepth() && !string()->isRightToLeft())
- m += listDepth() * document()->list_lm;
- return scale(m, TQTextFormat::painter());
-}
-
-int TQTextParagraph::firstLineMargin() const
-{
- int m = uflm;
- return scale(m, TQTextFormat::painter());
-}
-
-int TQTextParagraph::rightMargin() const
-{
- int m = urm;
- if (listDepth() && string()->isRightToLeft())
- m += listDepth() * document()->list_lm;
- return scale(m, TQTextFormat::painter());
-}
-
-int TQTextParagraph::lineSpacing() const
-{
- int l = ulinespacing;
- l = scale(l, TQTextFormat::painter());
- return l;
-}
-
-void TQTextParagraph::copyParagData(TQTextParagraph *parag)
-{
- rtext = parag->rtext;
- lstyle = parag->lstyle;
- ldepth = parag->ldepth;
- litem = parag->litem;
- align = parag->align;
- utm = parag->utm;
- ubm = parag->ubm;
- urm = parag->urm;
- ulm = parag->ulm;
- uflm = parag->uflm;
- ulinespacing = parag->ulinespacing;
- QColor *c = parag->backgroundColor();
- if (c)
- setBackgroundColor(*c);
- str->setDirection(parag->str->direction());
-}
-
-void TQTextParagraph::show()
-{
- if (visible || !hasdoc)
- return;
- visible = true;
-}
-
-void TQTextParagraph::hide()
-{
- if (!visible || !hasdoc)
- return;
- visible = false;
-}
-
-void TQTextParagraph::setDirection(TQChar::Direction dir)
-{
- if (str && str->direction() != dir) {
- str->setDirection(dir);
- invalidate(0);
- }
-}
-
-TQChar::Direction TQTextParagraph::direction() const
-{
- return (str ? str->direction() : TQChar::DirON);
-}
-
-void TQTextParagraph::setChanged(bool b, bool recursive)
-{
- changed = b;
- if (recursive) {
- if (document() && document()->parentParagraph())
- document()->parentParagraph()->setChanged(b, recursive);
- }
-}
-
-// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-
-TQTextPreProcessor::TQTextPreProcessor()
-{
-}
-
-// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-TQTextFormatter::TQTextFormatter()
- : thisminw(0), thiswused(0), wrapEnabled(true), wrapColumn(-1), biw(false)
-{
-}
-
-QTextLineStart *TQTextFormatter::formatLine(TQTextParagraph *parag, TQTextString *string, QTextLineStart *line,
- TQTextStringChar *startChar, TQTextStringChar *lastChar, int align, int space)
-{
- if (lastChar < startChar)
- return new QTextLineStart;
-#ifndef QT_NO_COMPLEXTEXT
- if(string->isBidi())
- return bidiReorderLine(parag, string, line, startChar, lastChar, align, space);
-#endif
- int start = (startChar - &string->at(0));
- int last = (lastChar - &string->at(0));
-
- // ignore white space at the end of the line.
- TQTextStringChar *ch = lastChar;
- while (ch > startChar && ch->whiteSpace) {
- space += ch->format()->width(TQLatin1Char(' '));
- --ch;
- }
-
- if (space < 0)
- space = 0;
-
- // do alignment Auto == Left in this case
- if (align & Qt::AlignHCenter || align & Qt::AlignRight) {
- if (align & Qt::AlignHCenter)
- space /= 2;
- for (int j = start; j <= last; ++j)
- string->at(j).x += space;
- } else if (align & Qt::AlignJustify) {
- int numSpaces = 0;
- // End at "last-1", the last space ends up with a width of 0
- for (int j = last-1; j >= start; --j) {
- // Start at last tab, if any.
- TQTextStringChar &ch = string->at(j);
- if (ch.c == TQLatin1Char('\t')) {
- start = j+1;
- break;
- }
- if(ch.whiteSpace)
- numSpaces++;
- }
- int toAdd = 0;
- for (int k = start + 1; k <= last; ++k) {
- TQTextStringChar &ch = string->at(k);
- if(numSpaces && ch.whiteSpace) {
- int s = space / numSpaces;
- toAdd += s;
- space -= s;
- numSpaces--;
- }
- string->at(k).x += toAdd;
- }
- }
-
- if (last >= 0 && last < string->length())
- line->w = string->at(last).x + string->width(last);
- else
- line->w = 0;
-
- return new QTextLineStart;
-}
-
-#ifndef QT_NO_COMPLEXTEXT
-
-#ifdef BIDI_DEBUG
-QT_BEGIN_INCLUDE_NAMESPACE
-#include <iostream>
-QT_END_INCLUDE_NAMESPACE
-#endif
-
-// collects one line of the paragraph and transforms it to visual order
-QTextLineStart *TQTextFormatter::bidiReorderLine(TQTextParagraph * /*parag*/, TQTextString *text, QTextLineStart *line,
- TQTextStringChar *startChar, TQTextStringChar *lastChar, int align, int space)
-{
- // ignore white space at the end of the line.
- int endSpaces = 0;
- while (lastChar > startChar && lastChar->whiteSpace) {
- space += lastChar->format()->width(TQLatin1Char(' '));
- --lastChar;
- ++endSpaces;
- }
-
- int start = (startChar - &text->at(0));
- int last = (lastChar - &text->at(0));
-
- int length = lastChar - startChar + 1;
-
-
- int x = startChar->x;
-
- unsigned char _levels[256];
- int _visual[256];
-
- unsigned char *levels = _levels;
- int *visual = _visual;
-
- if (length > 255) {
- levels = (unsigned char *)malloc(length*sizeof(unsigned char));
- visual = (int *)malloc(length*sizeof(int));
- }
-
- //qDebug("bidiReorderLine: length=%d (%d-%d)", length, start, last);
-
- TQTextStringChar *ch = startChar;
- unsigned char *l = levels;
- while (ch <= lastChar) {
- //qDebug(" level: %d", ch->bidiLevel);
- *(l++) = (ch++)->bidiLevel;
- }
-
- QTextEngine::bidiReorder(length, levels, visual);
-
- // now construct the reordered string out of the runs...
-
- int numSpaces = 0;
- align = QStyle::visualAlignment(text->isRightToLeft() ? Qt::RightToLeft : Qt::LeftToRight, QFlag(align));
-
- // This is not really correct, but as we can't make the scroll bar move to the left of the origin,
- // this ensures all text can be scrolled to and read.
- if (space < 0)
- space = 0;
-
- if (align & Qt::AlignHCenter)
- x += space/2;
- else if (align & Qt::AlignRight)
- x += space;
- else if (align & Qt::AlignJustify) {
- // End at "last-1", the last space ends up with a width of 0
- for (int j = last-1; j >= start; --j) {
- // Start at last tab, if any.
- TQTextStringChar &ch = text->at(j);
- if (ch.c == TQLatin1Char('\t')) {
- start = j+1;
- break;
- }
- if(ch.whiteSpace)
- numSpaces++;
- }
- }
-
- int toAdd = 0;
- int xorig = x;
- TQTextStringChar *lc = startChar + visual[0];
- for (int i = 0; i < length; i++) {
- TQTextStringChar *ch = startChar + visual[i];
- if (numSpaces && ch->whiteSpace) {
- int s = space / numSpaces;
- toAdd += s;
- space -= s;
- numSpaces--;
- }
-
- if (lc->format() != ch->format() && !ch->c.isSpace()
- && lc->format()->font().italic() && !ch->format()->font().italic()) {
- int rb = lc->format()->fontMetrics().rightBearing(lc->c);
- if (rb < 0)
- x -= rb;
- }
-
- ch->x = x + toAdd;
- ch->rightToLeft = ch->bidiLevel % 2;
- //qDebug("visual: %d (%p) placed at %d rightToLeft=%d", visual[i], ch, x +toAdd, ch->rightToLeft );
- int ww = 0;
- if (ch->c.unicode() >= 32 || ch->c == TQLatin1Char(TQLatin1Char('\t')) || ch->c == TQLatin1Char('\n') || ch->isCustom()) {
- ww = text->width(start+visual[i]);
- } else {
- ww = ch->format()->width(TQLatin1Char(' '));
- }
- x += ww;
- lc = ch;
- }
- x += toAdd;
-
- while (endSpaces--) {
- ++lastChar;
- int sw = lastChar->format()->width(TQLatin1Char(' '));
- if (text->isRightToLeft()) {
- xorig -= sw;
- lastChar->x = xorig;
- ch->rightToLeft = true;
- } else {
- lastChar->x = x;
- x += sw;
- ch->rightToLeft = false;
- }
- }
-
- line->w = x;
-
- if (length > 255) {
- free(levels);
- free(visual);
- }
-
- return new QTextLineStart;
-}
-#endif
-
-
-void TQTextFormatter::insertLineStart(TQTextParagraph *parag, int index, QTextLineStart *ls)
-{
- QMap<int, QTextLineStart*>::Iterator it;
- if ((it = parag->lineStartList().find(index)) == parag->lineStartList().end()) {
- parag->lineStartList().insert(index, ls);
- } else {
- delete *it;
- parag->lineStartList().erase(it);
- parag->lineStartList().insert(index, ls);
- }
-}
-
-
-/* Standard pagebreak algorithm using TQTextFlow::adjustFlow. Returns
- the shift of the paragraphs bottom line.
- */
-int TQTextFormatter::formatVertically(TQTextDocument* doc, TQTextParagraph* parag)
-{
- int oldHeight = parag->rect().height();
- QMap<int, QTextLineStart*>& lineStarts = parag->lineStartList();
- QMap<int, QTextLineStart*>::Iterator it = lineStarts.begin();
- int h = parag->prev() ? qMax(parag->prev()->bottomMargin(),parag->topMargin()) / 2: 0;
- for (; it != lineStarts.end() ; ++it ) {
- QTextLineStart * ls = it.value();
- ls->y = h;
- TQTextStringChar *c = &parag->string()->at(it.key());
-#ifndef QT_NO_TEXTCUSTOMITEM
- if (c && c->customItem() && c->customItem()->ownLine()) {
- int h = c->customItem()->height;
- c->customItem()->pageBreak(parag->rect().y() + ls->y + ls->baseLine - h, doc->flow());
- int delta = c->customItem()->height - h;
- ls->h += delta;
- if (delta)
- parag->setMovedDown(true);
- } else
-#endif
- {
-
- int shift = doc->flow()->adjustFlow(parag->rect().y() + ls->y, ls->w, ls->h);
- ls->y += shift;
- if (shift)
- parag->setMovedDown(true);
- }
- h = ls->y + ls->h;
- }
- int m = parag->bottomMargin();
- if (!parag->next())
- m = 0;
- else
- m = qMax(m, parag->next()->topMargin()) / 2;
- h += m;
- parag->setHeight(h);
- return h - oldHeight;
-}
-
-// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-TQTextFormatterBreakInWords::TQTextFormatterBreakInWords()
-{
-}
-
-#define SPACE(s) s
-
-int TQTextFormatterBreakInWords::format(TQTextDocument *doc,TQTextParagraph *parag,
- int start, const QMap<int, QTextLineStart*> &)
-{
- // make sure bidi information is correct.
- (void)parag->string()->isBidi();
-
- TQTextStringChar *c = 0;
- TQTextStringChar *firstChar = 0;
- int left = doc ? parag->leftMargin() + doc->leftMargin() : 0;
- int x = left + (doc ? parag->firstLineMargin() : 0);
- int dw = parag->documentVisibleWidth() - (doc ? doc->rightMargin() : 0);
- int y = parag->prev() ? qMax(parag->prev()->bottomMargin(),parag->topMargin()) / 2: 0;
- int h = y;
- int len = parag->length();
- if (doc)
- x = doc->flow()->adjustLMargin(y + parag->rect().y(), parag->rect().height(), x, 4);
- int rm = parag->rightMargin();
- int w = dw - (doc ? doc->flow()->adjustRMargin(y + parag->rect().y(), parag->rect().height(), rm, 4) : 0);
- bool fullWidth = true;
- int minw = 0;
- int wused = 0;
- bool wrapEnabled = isWrapEnabled(parag);
-
- start = 0; //######### what is the point with start?! (Matthias)
- if (start == 0)
- c = &parag->string()->at(0);
-
- int i = start;
- QTextLineStart *lineStart = new QTextLineStart(y, y, 0);
- insertLineStart(parag, 0, lineStart);
-
- TQPainter *painter = TQTextFormat::painter();
-
- int col = 0;
- int ww = 0;
- TQChar lastChr;
- int tabBase = left < x ? left : x;
- for (; i < len; ++i, ++col) {
- if (c)
- lastChr = c->c;
- c = &parag->string()->at(i);
- // ### the lines below should not be needed
- if (painter)
- c->format()->setPainter(painter);
- if (i > 0) {
- c->lineStart = 0;
- } else {
- c->lineStart = 1;
- firstChar = c;
- }
- if (c->c.unicode() >= 32 || c->isCustom()) {
- ww = parag->string()->width(i);
- } else if (c->c == TQLatin1Char('\t')) {
- int nx = parag->nextTab(i, x - tabBase) + tabBase;
- if (nx < x)
- ww = w - x;
- else
- ww = nx - x;
- } else {
- ww = c->format()->width(TQLatin1Char(' '));
- }
-
-#ifndef QT_NO_TEXTCUSTOMITEM
- if (c->isCustom() && c->customItem()->ownLine()) {
- x = doc ? doc->flow()->adjustLMargin(y + parag->rect().y(), parag->rect().height(), left, 4) : left;
- w = dw - (doc ? doc->flow()->adjustRMargin(y + parag->rect().y(), parag->rect().height(), rm, 4) : 0);
- c->customItem()->resize(w - x);
- w = dw;
- y += h;
- h = c->height();
- lineStart = new QTextLineStart(y, h, h);
- insertLineStart(parag, i, lineStart);
- c->lineStart = 1;
- firstChar = c;
- x = 0xffffff;
- continue;
- }
-#endif
-
- if (wrapEnabled &&
- ((wrapAtColumn() == -1 && x + ww > w) ||
- (wrapAtColumn() != -1 && col >= wrapAtColumn()))) {
- x = doc ? parag->document()->flow()->adjustLMargin(y + parag->rect().y(), parag->rect().height(), left, 4) : left;
- w = dw;
- y += h;
- h = c->height();
- lineStart = formatLine(parag, parag->string(), lineStart, firstChar, c-1);
- lineStart->y = y;
- insertLineStart(parag, i, lineStart);
- lineStart->baseLine = c->ascent();
- lineStart->h = c->height();
- c->lineStart = 1;
- firstChar = c;
- col = 0;
- if (wrapAtColumn() != -1)
- minw = qMax(minw, w);
- } else if (lineStart) {
- lineStart->baseLine = qMax(lineStart->baseLine, c->ascent());
- h = qMax(h, c->height());
- lineStart->h = h;
- }
-
- c->x = x;
- x += ww;
- wused = qMax(wused, x);
- }
-
- int m = parag->bottomMargin();
- if (!parag->next())
- m = 0;
- else
- m = qMax(m, parag->next()->topMargin()) / 2;
- parag->setFullWidth(fullWidth);
- y += h + m;
- if (doc)
- minw += doc->rightMargin();
- if (!wrapEnabled)
- minw = qMax(minw, wused);
-
- thisminw = minw;
- thiswused = wused;
- return y;
-}
-
-// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-TQTextFormatterBreakWords::TQTextFormatterBreakWords()
-{
-}
-
-#define DO_FLOW(lineStart) do{ if (doc && doc->isPageBreakEnabled()) { \
- int yflow = lineStart->y + parag->rect().y();\
- int shift = doc->flow()->adjustFlow(yflow, dw, lineStart->h); \
- lineStart->y += shift;\
- y += shift;\
- }}while(false)
-
-int TQTextFormatterBreakWords::format(TQTextDocument *doc, TQTextParagraph *parag,
- int start, const QMap<int, QTextLineStart*> &)
-{
- // make sure bidi information is correct.
- (void)parag->string()->isBidi();
-
- TQTextStringChar *c = 0;
- TQTextStringChar *firstChar = 0;
- TQTextString *string = parag->string();
- int left = doc ? parag->leftMargin() + doc->leftMargin() : 0;
- int x = left + (doc ? parag->firstLineMargin() : 0);
- int y = parag->prev() ? qMax(parag->prev()->bottomMargin(),parag->topMargin()) / 2: 0;
- int h = y;
- int len = parag->length();
- if (doc)
- x = doc->flow()->adjustLMargin(y + parag->rect().y(), parag->rect().height(), x, 0);
- int dw = parag->documentVisibleWidth() - (doc ? (left != x ? 0 : doc->rightMargin()) : 0);
-
- int curLeft = x;
- int rm = parag->rightMargin();
- int rdiff = doc ? doc->flow()->adjustRMargin(y + parag->rect().y(), parag->rect().height(), rm, 0) : 0;
- int w = dw - rdiff;
- bool fullWidth = true;
- int marg = left + rdiff;
- int minw = 0;
- int wused = 0;
- int tminw = marg;
- int linespacing = doc ? parag->lineSpacing() : 0;
- bool wrapEnabled = isWrapEnabled(parag);
-
- start = 0;
-
- int i = start;
- QTextLineStart *lineStart = new QTextLineStart(y, y, 0);
- insertLineStart(parag, 0, lineStart);
- int lastBreak = -1;
- int tmpBaseLine = 0, tmph = 0;
- bool lastWasNonInlineCustom = false;
-
- int align = parag->alignment();
- if (align == TQt::AlignAuto && doc && doc->alignment() != TQt::AlignAuto)
- align = doc->alignment();
-
- align &= Qt::AlignHorizontal_Mask;
-
- // ### hack. The last char in the paragraph is always invisible,
- // ### and somehow sometimes has a wrong format. It changes
- // ### between // layouting and printing. This corrects some
- // ### layouting errors in BiDi mode due to this.
- if (len > 1) {
- c = &parag->string()->at(len - 1);
- if (!c->isAnchor()) {
- if (c->format())
- c->format()->removeRef();
- c->setFormat(string->at(len - 2).format());
- if (c->format())
- c->format()->addRef();
- }
- }
-
- c = &parag->string()->at(0);
-
- TQPainter *painter = TQTextFormat::painter();
- int col = 0;
- int ww = 0;
- TQChar lastChr = c->c;
- TQTextFormat *lastFormat = c->format();
- int tabBase = left < x ? left : x;
- for (; i < len; ++i, ++col) {
- if (i) {
- c = &parag->string()->at(i-1);
- lastChr = c->c;
- lastFormat = c->format();
- }
- bool lastWasOwnLineCustomItem = lastBreak == -2;
- bool hadBreakableChar = lastBreak != -1;
- bool lastWasHardBreak = lastChr == TQChar::LineSeparator;
-
- // ### next line should not be needed
- if (painter)
- c->format()->setPainter(painter);
- c = &string->at(i);
-
- if (lastFormat != c->format() && !c->c.isSpace()
- && lastFormat->font().italic() && !c->format()->font().italic()) {
- int rb = lastFormat->fontMetrics().rightBearing(lastChr);
- if (rb < 0)
- x -= rb;
- }
-
- if ((i > 0 && (x > curLeft || ww == 0)) || lastWasNonInlineCustom) {
- c->lineStart = 0;
- } else {
- c->lineStart = 1;
- firstChar = c;
- }
-
- // ignore non spacing marks for column count.
- if (col != 0 && TQChar::category(c->c.unicode()) == TQChar::Mark_NonSpacing)
- --col;
-
-#ifndef QT_NO_TEXTCUSTOMITEM
- lastWasNonInlineCustom = (c->isCustom() && c->customItem()->placement() != TQTextCustomItem::PlaceInline);
-#endif
-
- if (c->c.unicode() >= 32 || c->isCustom()) {
- ww = string->width(i);
- } else if (c->c == TQLatin1Char('\t')) {
- if (align == Qt::AlignRight || align == Qt::AlignCenter) {
- // we can not (yet) do tabs
- ww = c->format()->width(TQLatin1Char(' '));
- } else {
- int tabx = lastWasHardBreak ? (left + (doc ? parag->firstLineMargin() : 0)) : x;
- int nx = parag->nextTab(i, tabx - tabBase) + tabBase;
- if (nx < tabx) // strrrange...
- ww = 0;
- else
- ww = nx - tabx;
- }
- } else {
- ww = c->format()->width(TQLatin1Char(' '));
- }
-
-#ifndef QT_NO_TEXTCUSTOMITEM
- TQTextCustomItem* ci = c->customItem();
- if (c->isCustom() && ci->ownLine()) {
- QTextLineStart *lineStart2 = formatLine(parag, string, lineStart, firstChar, c-1, align, SPACE(w - x - ww));
- x = doc ? doc->flow()->adjustLMargin(y + parag->rect().y(), parag->rect().height(), left, 4) : left;
- w = dw - (doc ? doc->flow()->adjustRMargin(y + parag->rect().y(), parag->rect().height(), rm, 4) : 0);
- ci->resize(w - x);
- if (ci->width < w - x) {
- if (align & Qt::AlignHCenter)
- x = (w - ci->width) / 2;
- else if (align & Qt::AlignRight) {
- x = w - ci->width;
- }
- }
- c->x = x;
- curLeft = x;
- if (i == 0 || !isBreakable(string, i-1) ||
- string->at(i - 1).lineStart == 0) {
- y += qMax(h, qMax(tmph, linespacing));
- tmph = c->height();
- h = tmph;
- lineStart = lineStart2;
- lineStart->y = y;
- insertLineStart(parag, i, lineStart);
- c->lineStart = 1;
- firstChar = c;
- } else {
- tmph = c->height();
- h = tmph;
- delete lineStart2;
- }
- lineStart->h = h;
- lineStart->baseLine = h;
- tmpBaseLine = lineStart->baseLine;
- lastBreak = -2;
- x = w;
- minw = qMax(minw, tminw);
-
- int tw = ci->minimumWidth() + (doc ? doc->leftMargin() : 0);
- if (tw < QWIDGETSIZE_MAX)
- tminw = tw;
- else
- tminw = marg;
- wused = qMax(wused, ci->width);
- continue;
- } else if (c->isCustom() && ci->placement() != TQTextCustomItem::PlaceInline) {
- int tw = ci->minimumWidth();
- if (tw < QWIDGETSIZE_MAX)
- minw = qMax(minw, tw);
- }
-#endif
- // we break if
- // 1. the last character was a hard break (TQChar::LineSeparator) or
- // 2. the last character was a own-line custom item (eg. table or ruler) or
- // 3. wrapping was enabled, it was not a space and following
- // condition is true: We either had a breakable character
- // previously or we ar allowed to break in words and - either
- // we break at w pixels and the current char would exceed that
- // or - we break at a column and the current character would
- // exceed that.
- if (lastWasHardBreak || lastWasOwnLineCustomItem ||
- (wrapEnabled &&
- ((!c->c.isSpace() && (hadBreakableChar || allowBreakInWords()) &&
- ((wrapAtColumn() == -1 && x + ww > w) ||
- (wrapAtColumn() != -1 && col >= wrapAtColumn()))))
- )
- ) {
- if (wrapAtColumn() != -1)
- minw = qMax(minw, x + ww);
- // if a break was forced (no breakable char, hard break or own line custom item), break immediately....
- if (!hadBreakableChar || lastWasHardBreak || lastWasOwnLineCustomItem) {
- if (lineStart) {
- lineStart->baseLine = qMax(lineStart->baseLine, tmpBaseLine);
- h = qMax(h, tmph);
- lineStart->h = h;
- DO_FLOW(lineStart);
- }
- lineStart = formatLine(parag, string, lineStart, firstChar, c-1, align, SPACE(w - x));
- x = doc ? doc->flow()->adjustLMargin(y + parag->rect().y(), parag->rect().height(), left, 4) : left;
- w = dw - (doc ? doc->flow()->adjustRMargin(y + parag->rect().y(), parag->rect().height(), rm, 4) : 0);
- if (!doc && c->c == TQLatin1Char('\t')) { // qt_format_text tab handling
- int nx = parag->nextTab(i, x - tabBase) + tabBase;
- if (nx < x)
- ww = w - x;
- else
- ww = nx - x;
- }
- curLeft = x;
- y += qMax(h, linespacing);
- tmph = c->height();
- h = 0;
- lineStart->y = y;
- insertLineStart(parag, i, lineStart);
- lineStart->baseLine = c->ascent();
- lineStart->h = c->height();
- c->lineStart = 1;
- firstChar = c;
- tmpBaseLine = lineStart->baseLine;
- lastBreak = -1;
- col = 0;
- if (allowBreakInWords() || lastWasHardBreak) {
- minw = qMax(minw, tminw);
- tminw = marg + ww;
- }
- } else { // ... otherwise if we had a breakable char, break there
- DO_FLOW(lineStart);
- c->x = x;
- i = lastBreak;
- lineStart = formatLine(parag, string, lineStart, firstChar, parag->at(lastBreak),align, SPACE(w - string->at(i+1).x));
- x = doc ? doc->flow()->adjustLMargin(y + parag->rect().y(), parag->rect().height(), left, 4) : left;
- w = dw - (doc ? doc->flow()->adjustRMargin(y + parag->rect().y(), parag->rect().height(), rm, 4) : 0);
- if (!doc && c->c == TQLatin1Char('\t')) { // qt_format_text tab handling
- int nx = parag->nextTab(i, x - tabBase) + tabBase;
- if (nx < x)
- ww = w - x;
- else
- ww = nx - x;
- }
- curLeft = x;
- y += qMax(h, linespacing);
- tmph = c->height();
- h = tmph;
- lineStart->y = y;
- insertLineStart(parag, i + 1, lineStart);
- lineStart->baseLine = c->ascent();
- lineStart->h = c->height();
- c->lineStart = 1;
- firstChar = c;
- tmpBaseLine = lineStart->baseLine;
- lastBreak = -1;
- col = 0;
- minw = qMax(minw, tminw);
- tminw = marg;
- continue;
- }
- } else if (lineStart && isBreakable(string, i)) {
- if (len <= 2 || i < len - 1) {
- tmpBaseLine = qMax(tmpBaseLine, c->ascent());
- tmph = qMax(tmph, c->height());
- }
- minw = qMax(minw, tminw);
-
- tminw = marg + ww;
- lineStart->baseLine = qMax(lineStart->baseLine, tmpBaseLine);
- h = qMax(h, tmph);
- lineStart->h = h;
- if (i < len - 2 || c->c != TQLatin1Char(' '))
- lastBreak = i;
- } else {
- tminw += ww;
- int cascent = c->ascent();
- int cheight = c->height();
- int belowBaseLine = qMax(tmph - tmpBaseLine, cheight-cascent);
- tmpBaseLine = qMax(tmpBaseLine, cascent);
- tmph = tmpBaseLine + belowBaseLine;
- }
-
- c->x = x;
- x += ww;
- wused = qMax(wused, x);
- }
-
- if (lineStart) {
- lineStart->baseLine = qMax(lineStart->baseLine, tmpBaseLine);
- h = qMax(h, tmph);
- lineStart->h = h;
- // last line in a paragraph is not justified
- if (align & Qt::AlignJustify) {
- align |= Qt::AlignLeft;
- align &= ~(Qt::AlignJustify|Qt::AlignAbsolute);
- }
- DO_FLOW(lineStart);
- lineStart = formatLine(parag, string, lineStart, firstChar, c, align, SPACE(w - x));
- delete lineStart;
- }
-
- minw = qMax(minw, tminw);
- if (doc)
- minw += doc->rightMargin();
-
- int m = parag->bottomMargin();
- if (!parag->next())
- m = 0;
- else
- m = qMax(m, parag->next()->topMargin()) / 2;
- parag->setFullWidth(fullWidth);
- y += qMax(h, linespacing) + m;
-
- wused += rm;
- if (!wrapEnabled || wrapAtColumn() != -1)
- minw = qMax(minw, wused);
-
- // This is the case where we are breaking wherever we darn well please
- // in cases like that, the minw should not be the length of the entire
- // word, because we necessarily want to show the word on the whole line.
- // example: word wrap in iconview
- if (allowBreakInWords() && minw > wused)
- minw = wused;
-
- thisminw = minw;
- thiswused = wused;
- return y;
-}
-
-// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-TQTextIndent::TQTextIndent()
-{
-}
-
-// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-TQTextFormatCollection::TQTextFormatCollection()
- : paintdevice(0)
-{
- defFormat = new TQTextFormat(QApplication::font(),
- QApplication::palette().color(QPalette::Active, QPalette::Text));
- lastFormat = cres = 0;
- cflags = -1;
- cachedFormat = 0;
-}
-
-TQTextFormatCollection::~TQTextFormatCollection()
-{
- QHash<TQString, TQTextFormat *>::ConstIterator it = cKey.constBegin();
- while (it != cKey.constEnd()) {
- delete it.value();
- ++it;
- }
- delete defFormat;
-}
-
-void TQTextFormatCollection::setPaintDevice(QPaintDevice *pd)
-{
- paintdevice = TQT_TQPAINTDEVICE(pd);
-
-#if defined(Q_WS_X11)
- int scr = (paintdevice) ? paintdevice->x11Screen() : QX11Info::appScreen();
-
- defFormat->fn.tqt_x11SetScreen(scr);
- defFormat->update();
-
- QHash<TQString, TQTextFormat *>::Iterator it = cKey.begin();
- for (; it != cKey.end(); ++it) {
- TQTextFormat *format = *it;
- format->fn.tqt_x11SetScreen(scr);
- format->update();
- }
-#endif // Q_WS_X11
-}
-
-TQTextFormat *TQTextFormatCollection::format(TQTextFormat *f)
-{
- if (f->parent() == this || f == defFormat) {
- lastFormat = f;
- lastFormat->addRef();
- return lastFormat;
- }
-
- if (f == lastFormat || (lastFormat && f->key() == lastFormat->key())) {
- lastFormat->addRef();
- return lastFormat;
- }
-
- TQTextFormat *fm = cKey.value(f->key());
- if (fm) {
- lastFormat = fm;
- lastFormat->addRef();
- return lastFormat;
- }
-
- if (f->key() == defFormat->key())
- return defFormat;
-
- lastFormat = createFormat(*f);
- lastFormat->collection = this;
- cKey.insert(lastFormat->key(), lastFormat);
- return lastFormat;
-}
-
-TQTextFormat *TQTextFormatCollection::format(TQTextFormat *of, TQTextFormat *nf, int flags)
-{
- if (cres && kof == of->key() && knf == nf->key() && cflags == flags) {
- cres->addRef();
- return cres;
- }
-
- cres = createFormat(*of);
- kof = of->key();
- knf = nf->key();
- cflags = flags;
- if (flags & TQTextFormat::Bold)
- cres->fn.setBold(nf->fn.bold());
- if (flags & TQTextFormat::Italic)
- cres->fn.setItalic(nf->fn.italic());
- if (flags & TQTextFormat::Underline)
- cres->fn.setUnderline(nf->fn.underline());
- if (flags & TQTextFormat::StrikeOut)
- cres->fn.setStrikeOut(nf->fn.strikeOut());
- if (flags & TQTextFormat::Family)
- cres->fn.setFamily(nf->fn.family());
- if (flags & TQTextFormat::Size) {
- if (of->usePixelSizes)
- cres->fn.setPixelSize(nf->fn.pixelSize());
- else
- cres->fn.setPointSize(nf->fn.pointSize());
- }
- if (flags & TQTextFormat::Color)
- cres->col = nf->col;
- if (flags & TQTextFormat::Misspelled)
- cres->missp = nf->missp;
- if (flags & TQTextFormat::VAlign)
- cres->ha = nf->ha;
- cres->update();
-
- TQTextFormat *fm = cKey.value(cres->key());
- if (!fm) {
- cres->collection = this;
- cKey.insert(cres->key(), cres);
- } else {
- delete cres;
- cres = fm;
- cres->addRef();
- }
-
- return cres;
-}
-
-TQTextFormat *TQTextFormatCollection::format(const QFont &f, const QColor &c)
-{
- if (cachedFormat && cfont == f && ccol == c) {
- cachedFormat->addRef();
- return cachedFormat;
- }
-
- TQString key = TQTextFormat::getKey(f, c, false, TQTextFormat::AlignNormal);
- cachedFormat = cKey.value(key);
- cfont = f;
- ccol = c;
-
- if (cachedFormat) {
- cachedFormat->addRef();
- return cachedFormat;
- }
-
- if (key == defFormat->key())
- return defFormat;
-
- cachedFormat = createFormat(f, c);
- cachedFormat->collection = this;
- cKey.insert(cachedFormat->key(), cachedFormat);
- if (cachedFormat->key() != key)
- qWarning("ASSERT: keys for format not identical: '%s '%s'", cachedFormat->key().latin1(), key.latin1());
- return cachedFormat;
-}
-
-void TQTextFormatCollection::remove(TQTextFormat *f)
-{
- if (lastFormat == f)
- lastFormat = 0;
- if (cres == f)
- cres = 0;
- if (cachedFormat == f)
- cachedFormat = 0;
- if (cKey.value(f->key()) == f)
- delete cKey.take(f->key());
-}
-
-#define UPDATE(up, lo, rest) \
- if (font.lo##rest() != defFormat->fn.lo##rest() && fm->fn.lo##rest() == defFormat->fn.lo##rest()) \
- fm->fn.set##up##rest(font.lo##rest())
-
-void TQTextFormatCollection::updateDefaultFormat(const QFont &font, const QColor &color, TQStyleSheet *sheet)
-{
- bool usePixels = font.pointSize() == -1;
- bool changeSize = usePixels ? font.pixelSize() != defFormat->fn.pixelSize() :
- font.pointSize() != defFormat->fn.pointSize();
- int base = usePixels ? font.pixelSize() : font.pointSize();
- QHash<TQString, TQTextFormat *>::Iterator it = cKey.begin();
- for (; it != cKey.end(); ++it) {
- TQTextFormat *fm = *it;
- UPDATE(F, f, amily);
- UPDATE(W, w, eight);
- UPDATE(B, b, old);
- UPDATE(I, i, talic);
- UPDATE(U, u, nderline);
- if (changeSize) {
- fm->stdSize = base;
- fm->usePixelSizes = usePixels;
- if (usePixels)
- fm->fn.setPixelSize(fm->stdSize);
- else
- fm->fn.setPointSize(fm->stdSize);
- sheet->scaleFont(fm->fn, fm->logicalFontSize);
- }
- if (color.isValid() && color != defFormat->col && fm->col == defFormat->col)
- fm->col = color;
- fm->update();
- }
-
- defFormat->fn = font;
- defFormat->col = color;
- defFormat->update();
- defFormat->stdSize = base;
- defFormat->usePixelSizes = usePixels;
-
- updateKeys();
-}
-
-// the keys in cKey have changed, rebuild the hashtable
-void TQTextFormatCollection::updateKeys()
-{
- if (cKey.isEmpty())
- return;
- TQTextFormat** formats = new TQTextFormat *[cKey.count() + 1];
- TQTextFormat **f = formats;
- for (QHash<TQString, TQTextFormat *>::Iterator it = cKey.begin(); it != cKey.end(); ++it, ++f)
- *f = *it;
- *f = 0;
- cKey.clear();
- for (f = formats; *f; f++)
- cKey.insert((*f)->key(), *f);
- delete [] formats;
-}
-
-
-
-// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-void TQTextFormat::setBold(bool b)
-{
- if (b == fn.bold())
- return;
- fn.setBold(b);
- update();
-}
-
-void TQTextFormat::setMisspelled(bool b)
-{
- if (b == (bool)missp)
- return;
- missp = b;
- update();
-}
-
-void TQTextFormat::setVAlign(VerticalAlignment a)
-{
- if (a == ha)
- return;
- ha = a;
- update();
-}
-
-void TQTextFormat::setItalic(bool b)
-{
- if (b == fn.italic())
- return;
- fn.setItalic(b);
- update();
-}
-
-void TQTextFormat::setUnderline(bool b)
-{
- if (b == fn.underline())
- return;
- fn.setUnderline(b);
- update();
-}
-
-void TQTextFormat::setStrikeOut(bool b)
-{
- if (b == fn.strikeOut())
- return;
- fn.setStrikeOut(b);
- update();
-}
-
-void TQTextFormat::setFamily(const TQString &f)
-{
- if (f == fn.family())
- return;
- fn.setFamily(f);
- update();
-}
-
-void TQTextFormat::setPointSize(int s)
-{
- if (s == fn.pointSize())
- return;
- fn.setPointSize(s);
- usePixelSizes = false;
- update();
-}
-
-void TQTextFormat::setFont(const QFont &f)
-{
- if (f == fn && !k.isEmpty())
- return;
- fn = f;
- update();
-}
-
-void TQTextFormat::setColor(const QColor &c)
-{
- if (c == col)
- return;
- col = c;
- update();
-}
-
-TQString TQTextFormat::makeFormatChangeTags(TQTextFormat* defaultFormat, TQTextFormat *f,
- const TQString& oldAnchorHref, const TQString& anchorHref ) const
-{
- TQString tag;
- if (f)
- tag += f->makeFormatEndTags(defaultFormat, oldAnchorHref);
-
- if (!anchorHref.isEmpty())
- tag += TQLatin1String("<a href=\"") + anchorHref + TQLatin1String("\">");
-
- if (font() != defaultFormat->font()
- || vAlign() != defaultFormat->vAlign()
- || color().rgb() != defaultFormat->color().rgb()) {
- TQString s;
- if (font().family() != defaultFormat->font().family())
- s += TQString(s.size()?TQLatin1String(";"):TQLatin1String("")) + TQLatin1String("font-family:") + fn.family();
- if (font().italic() && font().italic() != defaultFormat->font().italic())
- s += TQString(s.size()?TQLatin1String(";"):TQLatin1String("")) + TQLatin1String("font-style:") + (font().italic() ? TQLatin1String("italic") : TQLatin1String("normal"));
- if (font().pointSize() != defaultFormat->font().pointSize())
- s += TQString(s.size()?TQLatin1String(";"):TQLatin1String("")) + TQLatin1String("font-size:") + TQString::number(fn.pointSize()) + TQLatin1String("pt");
- if (font().weight() != defaultFormat->font().weight())
- s += TQString(s.size()?TQLatin1String(";"):TQLatin1String("")) + TQLatin1String("font-weight:") + TQString::number(fn.weight() * 8);
- TQString textDecoration;
- bool none = false;
- if ( font().underline() != defaultFormat->font().underline() ) {
- if (font().underline())
- textDecoration = TQLatin1String("underline");
- else
- none = true;
- }
- if ( font().overline() != defaultFormat->font().overline() ) {
- if (font().overline())
- textDecoration += TQLatin1String(" overline");
- else
- none = true;
- }
- if ( font().strikeOut() != defaultFormat->font().strikeOut() ) {
- if (font().strikeOut())
- textDecoration += TQLatin1String(" line-through");
- else
- none = true;
- }
- if (none && textDecoration.isEmpty())
- textDecoration = TQLatin1String("none");
- if (!textDecoration.isEmpty())
- s += TQString(s.size()?TQLatin1String(";"):TQLatin1String("")) + TQLatin1String("text-decoration:") + textDecoration;
- if (vAlign() != defaultFormat->vAlign()) {
- s += TQString(s.size()?TQLatin1String(";"):TQLatin1String("")) + TQLatin1String("vertical-align:");
- if (vAlign() == TQTextFormat::AlignSuperScript)
- s += TQLatin1String("super");
- else if (vAlign() == TQTextFormat::AlignSubScript)
- s += TQLatin1String("sub");
- else
- s += TQLatin1String("normal");
- }
- if (color().rgb() != defaultFormat->color().rgb())
- s += TQString(s.size()?TQLatin1String(";"):TQLatin1String("")) + TQLatin1String("color:") + col.name();
- if (!s.isEmpty())
- tag += TQLatin1String("<span style=\"") + s + TQLatin1String("\">");
- }
-
- return tag;
-}
-
-TQString TQTextFormat::makeFormatEndTags(TQTextFormat* defaultFormat, const TQString& anchorHref) const
-{
- TQString tag;
- if (font().family() != defaultFormat->font().family()
- || font().pointSize() != defaultFormat->font().pointSize()
- || font().weight() != defaultFormat->font().weight()
- || font().italic() != defaultFormat->font().italic()
- || font().underline() != defaultFormat->font().underline()
- || font().strikeOut() != defaultFormat->font().strikeOut()
- || vAlign() != defaultFormat->vAlign()
- || color().rgb() != defaultFormat->color().rgb())
- tag += TQLatin1String("</span>");
- if (!anchorHref.isEmpty())
- tag += TQLatin1String("</a>");
- return tag;
-}
-
-TQTextFormat TQTextFormat::makeTextFormat(const TQStyleSheetItem *style, const QMap<TQString,TQString>& attr, double scaleFontsFactor) const
-{
- TQTextFormat format(*this);
- if (!style)
- return format;
-
- if (!style->isAnchor() && style->color().isValid()) {
- // the style is not an anchor and defines a color.
- // It might be used inside an anchor and it should
- // override the link color.
- format.linkColor = false;
- }
- switch (style->verticalAlignment()) {
- case TQStyleSheetItem::VAlignBaseline:
- format.setVAlign(TQTextFormat::AlignNormal);
- break;
- case TQStyleSheetItem::VAlignSuper:
- format.setVAlign(TQTextFormat::AlignSuperScript);
- break;
- case TQStyleSheetItem::VAlignSub:
- format.setVAlign(TQTextFormat::AlignSubScript);
- break;
- }
-
- if (style->fontWeight() != TQStyleSheetItem::Undefined)
- format.fn.setWeight(style->fontWeight());
- if (style->fontSize() != TQStyleSheetItem::Undefined) {
- format.fn.setPointSize(style->fontSize());
- } else if (style->logicalFontSize() != TQStyleSheetItem::Undefined) {
- format.logicalFontSize = style->logicalFontSize();
- if (format.usePixelSizes)
- format.fn.setPixelSize(format.stdSize);
- else
- format.fn.setPointSize(format.stdSize);
- style->styleSheet()->scaleFont(format.fn, format.logicalFontSize);
- } else if (style->logicalFontSizeStep()) {
- format.logicalFontSize += style->logicalFontSizeStep();
- if (format.usePixelSizes)
- format.fn.setPixelSize(format.stdSize);
- else
- format.fn.setPointSize(format.stdSize);
- style->styleSheet()->scaleFont(format.fn, format.logicalFontSize);
- }
- if (!style->fontFamily().isEmpty())
- format.fn.setFamily(style->fontFamily());
- if (style->color().isValid())
- format.col = style->color();
- if (style->definesFontItalic())
- format.fn.setItalic(style->fontItalic());
- if (style->definesFontUnderline())
- format.fn.setUnderline(style->fontUnderline());
- if (style->definesFontStrikeOut())
- format.fn.setStrikeOut(style->fontStrikeOut());
-
- QMap<TQString, TQString>::ConstIterator it, end = attr.end();
-
- if (style->name() == TQLatin1String("font")) {
- it = attr.find(TQLatin1String("color"));
- if (it != end && ! (*it).isEmpty()){
- format.col.setNamedColor(*it);
- format.linkColor = false;
- }
- it = attr.find(TQLatin1String("face"));
- if (it != end) {
- TQString family = (*it).section(TQLatin1Char(','), 0, 0);
- if (family.size())
- format.fn.setFamily(family);
- }
- it = attr.find(TQLatin1String("size"));
- if (it != end) {
- TQString a = *it;
- int n = a.toInt();
- if (a[0] == TQLatin1Char('+') || a[0] == TQLatin1Char('-'))
- n += 3;
- format.logicalFontSize = n;
- if (format.usePixelSizes)
- format.fn.setPixelSize(format.stdSize);
- else
- format.fn.setPointSize(format.stdSize);
- style->styleSheet()->scaleFont(format.fn, format.logicalFontSize);
- }
- }
-
- it = attr.find(TQLatin1String("style"));
- if (it != end) {
- TQString a = *it;
- int count = a.count(TQLatin1Char(';'))+1;
- for (int s = 0; s < count; s++) {
- TQString style = a.section(TQLatin1Char(';'), s, s);
- if (style.startsWith(TQLatin1String("font-size:")) && style.endsWith(TQLatin1String("pt"))) {
- format.logicalFontSize = 0;
- int size = int(scaleFontsFactor * style.mid(10, style.length() - 12).toDouble());
- format.setPointSize(size);
- } else if (style.startsWith(TQLatin1String("font-style:"))) {
- TQString s = style.mid(11).trimmed();
- if (s == TQLatin1String("normal"))
- format.fn.setItalic(false);
- else if (s == TQLatin1String("italic") || s == TQLatin1String("oblique"))
- format.fn.setItalic(true);
- } else if (style.startsWith(TQLatin1String("font-weight:"))) {
- TQString s = style.mid(12);
- bool ok = true;
- int n = s.toInt(&ok);
- if (ok)
- format.fn.setWeight(n/8);
- } else if (style.startsWith(TQLatin1String("font-family:"))) {
- TQString family = style.mid(12).section(TQLatin1Char(','),0,0);
- family.replace(TQLatin1Char('\"'), TQLatin1Char(' '));
- family.replace(TQLatin1Char('\''), TQLatin1Char(' '));
- family = family.trimmed();
- format.fn.setFamily(family);
- } else if (style.startsWith(TQLatin1String("text-decoration:"))) {
- TQString s = style.mid( 16 );
- format.fn.setOverline(s.contains(TQLatin1String("overline")));
- format.fn.setStrikeOut(s.contains(TQLatin1String("line-through")));
- format.fn.setUnderline(s.contains(TQLatin1String("underline")));
- } else if (style.startsWith(TQLatin1String("vertical-align:"))) {
- TQString s = style.mid(15).trimmed();
- if (s == TQLatin1String("sub"))
- format.setVAlign(TQTextFormat::AlignSubScript);
- else if (s == TQLatin1String("super"))
- format.setVAlign(TQTextFormat::AlignSuperScript);
- else
- format.setVAlign(TQTextFormat::AlignNormal);
- } else if (style.startsWith(TQLatin1String("color:"))) {
- format.col.setNamedColor(style.mid(6));
- format.linkColor = false;
- }
- }
- }
-
- format.update();
- return format;
-}
-
-#ifndef QT_NO_TEXTCUSTOMITEM
-
-struct TQPixmapInt
-{
- TQPixmapInt() : ref(0) {}
- TQPixmap pm;
- int ref;
- Q_DUMMY_COMPARISON_OPERATOR(TQPixmapInt)
-};
-
-static QMap<TQString, TQPixmapInt> *pixmap_map = 0;
-
-TQTextImage::TQTextImage(TQTextDocument *p, const QMap<TQString, TQString> &attr, const TQString& context,
- TQMimeSourceFactory &factory)
- : TQTextCustomItem(p)
-{
- width = height = 0;
-
- QMap<TQString, TQString>::ConstIterator it, end = attr.end();
- it = attr.find(TQLatin1String("width"));
- if (it != end)
- width = (*it).toInt();
- it = attr.find(TQLatin1String("height"));
- if (it != end)
- height = (*it).toInt();
-
- reg = 0;
- TQString imageName = attr[TQLatin1String("src")];
-
- if (imageName.size() == 0)
- imageName = attr[TQLatin1String("source")];
-
- if (!imageName.isEmpty()) {
- imgId = TQString::fromLatin1("%1,%2,%3,%4").arg(imageName).arg(width).arg(height).arg((quintptr)&factory);
- if (!pixmap_map)
- pixmap_map = new QMap<TQString, TQPixmapInt>;
- if (pixmap_map->contains(imgId)) {
- TQPixmapInt& pmi = pixmap_map->operator[](imgId);
- pm = pmi.pm;
- pmi.ref++;
- width = pm.width();
- height = pm.height();
- } else {
- TQImage img;
- const QMimeSource* m =
- factory.data(imageName, context);
- if (!m) {
- qCritical("TQTextImage: no mimesource for %s", imageName.latin1());
- }
- else {
- if (!TQImageDrag::decode(TQT_TQMIMESOURCE_CONST(m), img)) {
- qCritical("TQTextImage: cannot decode %s", imageName.latin1());
- }
- }
-
- if (!img.isNull()) {
- if (width == 0) {
- width = img.width();
- if (height != 0) {
- width = img.width() * height / img.height();
- }
- }
- if (height == 0) {
- height = img.height();
- if (width != img.width()) {
- height = img.height() * width / img.width();
- }
- }
- if (img.width() != width || img.height() != height){
-#ifndef QT_NO_IMAGE_SMOOTHSCALE
- img = img.smoothScale(width, height);
-#endif
- width = img.width();
- height = img.height();
- }
- pm.convertFromImage(img);
- }
- if (!pm.isNull()) {
- TQPixmapInt& pmi = pixmap_map->operator[](imgId);
- pmi.pm = pm;
- pmi.ref++;
- }
- }
- if (pm.hasAlphaChannel()) {
- QRegion mask(pm.QPixmap::mask());
- QRegion all(0, 0, pm.width(), pm.height());
- reg = new QRegion(all.subtracted(mask));
- }
- }
-
- if (pm.isNull() && (width*height)==0)
- width = height = 50;
-
- place = PlaceInline;
- if (attr[TQLatin1String("align")] == TQLatin1String("left"))
- place = PlaceLeft;
- else if (attr[TQLatin1String("align")] == TQLatin1String("right"))
- place = PlaceRight;
-
- tmpwidth = width;
- tmpheight = height;
-
- attributes = attr;
-}
-
-TQTextImage::~TQTextImage()
-{
- if (pixmap_map && pixmap_map->contains(imgId)) {
- TQPixmapInt& pmi = pixmap_map->operator[](imgId);
- pmi.ref--;
- if (!pmi.ref) {
- pixmap_map->remove(imgId);
- if (pixmap_map->isEmpty()) {
- delete pixmap_map;
- pixmap_map = 0;
- }
- }
- }
- delete reg;
-}
-
-TQString TQTextImage::richText() const
-{
- TQString s;
- s += TQLatin1String("<img ");
- QMap<TQString, TQString>::ConstIterator it = attributes.begin();
- for (; it != attributes.end(); ++it) {
- s += it.key() + TQLatin1Char('=');
- if ((*it).contains(TQLatin1Char(' ')))
- s += TQLatin1Char('\"') + *it + TQLatin1String("\" ");
- else
- s += *it + TQLatin1Char(' ');
- }
- s += TQLatin1Char('>');
- return s;
-}
-
-void TQTextImage::adjustToPainter(TQPainter* p)
-{
- width = scale(tmpwidth, p);
- height = scale(tmpheight, p);
-}
-
-#if !defined(Q_WS_X11)
-static TQPixmap *qrt_selection = 0;
-static TQSingleCleanupHandler<TQPixmap> qrt_cleanup_pixmap;
-static void qrt_createSelectionPixmap(const QPalette &pal)
-{
- qrt_selection = new TQPixmap(2, 2);
- qrt_cleanup_pixmap.set(&qrt_selection);
- qrt_selection->fill(Qt::color0);
- QBitmap m(2, 2);
- m.fill(Qt::color1);
- TQPainter p(&m);
- p.setPen(Qt::color0);
- for (int j = 0; j < 2; ++j) {
- p.drawPoint(j % 2, j);
- }
- p.end();
- qrt_selection->setMask(m);
- qrt_selection->fill(pal.highlight().color());
-}
-#endif
-
-void TQTextImage::draw(TQPainter* p, int x, int y, int cx, int cy, int cw, int ch,
- const QPalette &pal, bool selected)
-{
- if (placement() != PlaceInline) {
- x = xpos;
- y = ypos;
- }
-
- if (pm.isNull()) {
- p->fillRect(x , y, width, height, pal.dark());
- return;
- }
-
- if (is_printer(p)) {
- p->drawPixmap(TQRect(x, y, width, height), pm);
- return;
- }
-
- if (placement() != PlaceInline && !TQRect(xpos, ypos, width, height).intersects(TQRect(cx, cy, cw, ch)))
- return;
-
- if (placement() == PlaceInline)
- p->drawPixmap(x , y, pm);
- else
- p->drawPixmap(cx , cy, pm, cx - x, cy - y, cw, ch);
-
- if (selected && placement() == PlaceInline && is_printer(p)) {
-#if defined(Q_WS_X11)
- p->fillRect(TQRect(QPoint(x, y), pm.size()), TQBrush(pal.Highlight,
- Qt::Dense4Pattern));
-#else // in WIN32 Qt::Dense4Pattern doesn't work correctly (transparency problem), so work around it
- if (!qrt_selection)
- qrt_createSelectionPixmap(pal);
- p->drawTiledPixmap(x, y, pm.width(), pm.height(), *qrt_selection);
-#endif
- }
-}
-
-void TQTextHorizontalLine::adjustToPainter(TQPainter* p)
-{
- height = scale(tmpheight, p);
-}
-
-
-TQTextHorizontalLine::TQTextHorizontalLine(TQTextDocument *p, const QMap<TQString, TQString> &attr,
- const TQString &,
- TQMimeSourceFactory &)
- : TQTextCustomItem(p)
-{
- height = tmpheight = 8;
- QMap<TQString, TQString>::ConstIterator it, end = attr.end();
- it = attr.find(TQLatin1String("color"));
- if (it != end)
- color = QColor(*it);
- shade = attr.find(TQLatin1String("noshade")) == end;
-}
-
-TQTextHorizontalLine::~TQTextHorizontalLine()
-{
-}
-
-TQString TQTextHorizontalLine::richText() const
-{
- return TQLatin1String("<hr>");
-}
-
-void TQTextHorizontalLine::draw(TQPainter* p, int x, int y, int , int , int , int ,
- const QPalette& pal, bool selected)
-{
- TQRect r(x, y, width, height);
- if (is_printer(p) || !shade) {
- QPen oldPen = p->pen();
- if (!color.isValid())
- p->setPen(QPen(pal.text().color(), is_printer(p) ? height/8 : qMax(2, height/4)));
- else
- p->setPen(QPen(color, is_printer(p) ? height/8 : qMax(2, height/4)));
- p->drawLine(r.left()-1, y + height / 2, r.right() + 1, y + height / 2);
- p->setPen(oldPen);
- } else {
- if (selected)
- p->fillRect(r, pal.highlight());
- QPalette pal2(pal);
- if (color.isValid())
- pal2.setColor(pal2.currentColorGroup(), QPalette::Dark, color);
- qDrawShadeLine(p, r.left() - 1, y + height / 2, r.right() + 1, y + height / 2, pal2,
- true, height / 8);
- }
-}
-#endif //QT_NO_TEXTCUSTOMITEM
-
-/*****************************************************************/
-// Small set of utility functions to make the parser a bit simpler
-//
-
-bool TQTextDocument::hasPrefix(const TQChar* doc, int length, int pos, TQChar c)
-{
- if (pos + 1 > length)
- return false;
- return doc[pos].toLower() == c.toLower();
-}
-
-bool TQTextDocument::hasPrefix(const TQChar* doc, int length, int pos, const TQString& s)
-{
- if (pos + (int) s.length() > length)
- return false;
- for (int i = 0; i < (int)s.length(); i++) {
- if (doc[pos + i].toLower() != s[i].toLower())
- return false;
- }
- return true;
-}
-
-#ifndef QT_NO_TEXTCUSTOMITEM
-static bool qt_is_cell_in_use(QList<TQTextTableCell *>& cells, int row, int col)
-{
- for (int idx = 0; idx < cells.size(); ++idx) {
- TQTextTableCell *c = cells.at(idx);
- if (row >= c->row() && row < c->row() + c->rowspan()
- && col >= c->column() && col < c->column() + c->colspan())
- return true;
- }
- return false;
-}
-
-TQTextCustomItem* TQTextDocument::parseTable(const QMap<TQString, TQString> &attr, const TQTextFormat &fmt,
- const TQChar* doc, int length, int& pos, TQTextParagraph *curpar)
-{
-
- TQTextTable* table = new TQTextTable(this, attr);
- int row = -1;
- int col = -1;
-
- TQString rowbgcolor;
- TQString rowalign;
- TQString tablebgcolor = attr[TQLatin1String("bgcolor")];
-
- QList<TQTextTableCell *> multicells;
-
- TQString tagname;
- (void) eatSpace(doc, length, pos);
- while (pos < length) {
- if (hasPrefix(doc, length, pos, TQLatin1Char('<'))){
- if (hasPrefix(doc, length, pos+1, TQLatin1Char('/'))) {
- tagname = parseCloseTag(doc, length, pos);
- if (tagname == TQLatin1String("table")) {
- return table;
- }
- } else {
- QMap<TQString, TQString> attr2;
- bool emptyTag = false;
- tagname = parseOpenTag(doc, length, pos, attr2, emptyTag);
- if (tagname == TQLatin1String("tr")) {
- rowbgcolor = attr2[TQLatin1String("bgcolor")];
- rowalign = attr2[TQLatin1String("align")];
- row++;
- col = -1;
- }
- else if (tagname == TQLatin1String("td") || tagname == TQLatin1String("th")) {
- col++;
- while (qt_is_cell_in_use(multicells, row, col)) {
- col++;
- }
-
- if (row >= 0 && col >= 0) {
- const TQStyleSheetItem* s = sheet_->item(tagname);
- if (!attr2.contains(TQLatin1String("bgcolor"))) {
- if (!rowbgcolor.isEmpty())
- attr2[TQLatin1String("bgcolor")] = rowbgcolor;
- else if (!tablebgcolor.isEmpty())
- attr2[TQLatin1String("bgcolor")] = tablebgcolor;
- }
- if (!attr2.contains(TQLatin1String("align"))) {
- if (!rowalign.isEmpty())
- attr2[TQLatin1String("align")] = rowalign;
- }
-
- // extract the cell contents
- int end = pos;
- while (end < length
- && !hasPrefix(doc, length, end, TQLatin1String("</td"))
- && !hasPrefix(doc, length, end, TQLatin1String("<td"))
- && !hasPrefix(doc, length, end, TQLatin1String("</th"))
- && !hasPrefix(doc, length, end, TQLatin1String("<th"))
- && !hasPrefix(doc, length, end, TQLatin1String("<td"))
- && !hasPrefix(doc, length, end, TQLatin1String("</tr"))
- && !hasPrefix(doc, length, end, TQLatin1String("<tr"))
- && !hasPrefix(doc, length, end, TQLatin1String("</table"))) {
- if (hasPrefix(doc, length, end, TQLatin1String("<table"))) { // nested table
- int nested = 1;
- ++end;
- while (end < length && nested != 0) {
- if (hasPrefix(doc, length, end, TQLatin1String("</table")))
- nested--;
- if (hasPrefix(doc, length, end, TQLatin1String("<table")))
- nested++;
- end++;
- }
- }
- end++;
- }
- TQTextTableCell* cell = new TQTextTableCell(table, row, col,
- attr2, s, fmt.makeTextFormat(s, attr2, scaleFontsFactor),
- contxt, *factory_, sheet_,
- TQString::fromRawData(doc + pos, end - pos));
- cell->richText()->parentPar = curpar;
- if (cell->colspan() > 1 || cell->rowspan() > 1)
- multicells.append(cell);
- col += cell->colspan()-1;
- pos = end;
- }
- }
- }
-
- } else {
- ++pos;
- }
- }
- return table;
-}
-#endif // QT_NO_TEXTCUSTOMITEM
-
-bool TQTextDocument::eatSpace(const TQChar* doc, int length, int& pos, bool includeNbsp)
-{
- int old_pos = pos;
- while (pos < length && doc[pos].isSpace() && (includeNbsp || (doc[pos] != TQChar(TQChar::nbsp))))
- pos++;
- return old_pos < pos;
-}
-
-bool TQTextDocument::eat(const TQChar* doc, int length, int& pos, TQChar c)
-{
- bool ok = pos < length && doc[pos] == c;
- if (ok)
- pos++;
- return ok;
-}
-/*****************************************************************/
-
-struct Entity {
- const char * name;
- Q_UINT16 code;
-};
-
-static const Entity entitylist [] = {
- { "AElig", 0x00c6 },
- { "Aacute", 0x00c1 },
- { "Acirc", 0x00c2 },
- { "Agrave", 0x00c0 },
- { "Alpha", 0x0391 },
- { "AMP", 38 },
- { "Aring", 0x00c5 },
- { "Atilde", 0x00c3 },
- { "Auml", 0x00c4 },
- { "Beta", 0x0392 },
- { "Ccedil", 0x00c7 },
- { "Chi", 0x03a7 },
- { "Dagger", 0x2021 },
- { "Delta", 0x0394 },
- { "ETH", 0x00d0 },
- { "Eacute", 0x00c9 },
- { "Ecirc", 0x00ca },
- { "Egrave", 0x00c8 },
- { "Epsilon", 0x0395 },
- { "Eta", 0x0397 },
- { "Euml", 0x00cb },
- { "Gamma", 0x0393 },
- { "GT", 62 },
- { "Iacute", 0x00cd },
- { "Icirc", 0x00ce },
- { "Igrave", 0x00cc },
- { "Iota", 0x0399 },
- { "Iuml", 0x00cf },
- { "Kappa", 0x039a },
- { "Lambda", 0x039b },
- { "LT", 60 },
- { "Mu", 0x039c },
- { "Ntilde", 0x00d1 },
- { "Nu", 0x039d },
- { "OElig", 0x0152 },
- { "Oacute", 0x00d3 },
- { "Ocirc", 0x00d4 },
- { "Ograve", 0x00d2 },
- { "Omega", 0x03a9 },
- { "Omicron", 0x039f },
- { "Oslash", 0x00d8 },
- { "Otilde", 0x00d5 },
- { "Ouml", 0x00d6 },
- { "Phi", 0x03a6 },
- { "Pi", 0x03a0 },
- { "Prime", 0x2033 },
- { "Psi", 0x03a8 },
- { "QUOT", 34 },
- { "Rho", 0x03a1 },
- { "Scaron", 0x0160 },
- { "Sigma", 0x03a3 },
- { "THORN", 0x00de },
- { "Tau", 0x03a4 },
- { "Theta", 0x0398 },
- { "Uacute", 0x00da },
- { "Ucirc", 0x00db },
- { "Ugrave", 0x00d9 },
- { "Upsilon", 0x03a5 },
- { "Uuml", 0x00dc },
- { "Xi", 0x039e },
- { "Yacute", 0x00dd },
- { "Yuml", 0x0178 },
- { "Zeta", 0x0396 },
- { "aacute", 0x00e1 },
- { "acirc", 0x00e2 },
- { "acute", 0x00b4 },
- { "aelig", 0x00e6 },
- { "agrave", 0x00e0 },
- { "alefsym", 0x2135 },
- { "alpha", 0x03b1 },
- { "amp", 38 },
- { "and", 0x22a5 },
- { "ang", 0x2220 },
- { "apos", 0x0027 },
- { "aring", 0x00e5 },
- { "asymp", 0x2248 },
- { "atilde", 0x00e3 },
- { "auml", 0x00e4 },
- { "bdquo", 0x201e },
- { "beta", 0x03b2 },
- { "brvbar", 0x00a6 },
- { "bull", 0x2022 },
- { "cap", 0x2229 },
- { "ccedil", 0x00e7 },
- { "cedil", 0x00b8 },
- { "cent", 0x00a2 },
- { "chi", 0x03c7 },
- { "circ", 0x02c6 },
- { "clubs", 0x2663 },
- { "cong", 0x2245 },
- { "copy", 0x00a9 },
- { "crarr", 0x21b5 },
- { "cup", 0x222a },
- { "cur" "ren", 0x00a4 },
- { "dArr", 0x21d3 },
- { "dagger", 0x2020 },
- { "darr", 0x2193 },
- { "deg", 0x00b0 },
- { "delta", 0x03b4 },
- { "diams", 0x2666 },
- { "divide", 0x00f7 },
- { "eacute", 0x00e9 },
- { "ecirc", 0x00ea },
- { "egrave", 0x00e8 },
- { "empty", 0x2205 },
- { "emsp", 0x2003 },
- { "ensp", 0x2002 },
- { "epsilon", 0x03b5 },
- { "equiv", 0x2261 },
- { "eta", 0x03b7 },
- { "eth", 0x00f0 },
- { "euml", 0x00eb },
- { "euro", 0x20ac },
- { "exist", 0x2203 },
- { "fnof", 0x0192 },
- { "forall", 0x2200 },
- { "frac12", 0x00bd },
- { "frac14", 0x00bc },
- { "frac34", 0x00be },
- { "frasl", 0x2044 },
- { "gamma", 0x03b3 },
- { "ge", 0x2265 },
- { "gt", 62 },
- { "hArr", 0x21d4 },
- { "harr", 0x2194 },
- { "hearts", 0x2665 },
- { "hellip", 0x2026 },
- { "iacute", 0x00ed },
- { "icirc", 0x00ee },
- { "iexcl", 0x00a1 },
- { "igrave", 0x00ec },
- { "image", 0x2111 },
- { "infin", 0x221e },
- { "int", 0x222b },
- { "iota", 0x03b9 },
- { "iquest", 0x00bf },
- { "isin", 0x2208 },
- { "iuml", 0x00ef },
- { "kappa", 0x03ba },
- { "lArr", 0x21d0 },
- { "lambda", 0x03bb },
- { "lang", 0x2329 },
- { "laquo", 0x00ab },
- { "larr", 0x2190 },
- { "lceil", 0x2308 },
- { "ldquo", 0x201c },
- { "le", 0x2264 },
- { "lfloor", 0x230a },
- { "lowast", 0x2217 },
- { "loz", 0x25ca },
- { "lrm", 0x200e },
- { "lsaquo", 0x2039 },
- { "lsquo", 0x2018 },
- { "lt", 60 },
- { "macr", 0x00af },
- { "mdash", 0x2014 },
- { "micro", 0x00b5 },
- { "middot", 0x00b7 },
- { "minus", 0x2212 },
- { "mu", 0x03bc },
- { "nabla", 0x2207 },
- { "nbsp", 0x00a0 },
- { "ndash", 0x2013 },
- { "ne", 0x2260 },
- { "ni", 0x220b },
- { "not", 0x00ac },
- { "notin", 0x2209 },
- { "nsub", 0x2284 },
- { "ntilde", 0x00f1 },
- { "nu", 0x03bd },
- { "oacute", 0x00f3 },
- { "ocirc", 0x00f4 },
- { "oelig", 0x0153 },
- { "ograve", 0x00f2 },
- { "oline", 0x203e },
- { "omega", 0x03c9 },
- { "omicron", 0x03bf },
- { "oplus", 0x2295 },
- { "or", 0x22a6 },
- { "ordf", 0x00aa },
- { "ordm", 0x00ba },
- { "oslash", 0x00f8 },
- { "otilde", 0x00f5 },
- { "otimes", 0x2297 },
- { "ouml", 0x00f6 },
- { "para", 0x00b6 },
- { "part", 0x2202 },
- { "percnt", 0x0025 },
- { "permil", 0x2030 },
- { "perp", 0x22a5 },
- { "phi", 0x03c6 },
- { "pi", 0x03c0 },
- { "piv", 0x03d6 },
- { "plusmn", 0x00b1 },
- { "pound", 0x00a3 },
- { "prime", 0x2032 },
- { "prod", 0x220f },
- { "prop", 0x221d },
- { "psi", 0x03c8 },
- { "quot", 34 },
- { "rArr", 0x21d2 },
- { "radic", 0x221a },
- { "rang", 0x232a },
- { "raquo", 0x00bb },
- { "rarr", 0x2192 },
- { "rceil", 0x2309 },
- { "rdquo", 0x201d },
- { "real", 0x211c },
- { "reg", 0x00ae },
- { "rfloor", 0x230b },
- { "rho", 0x03c1 },
- { "rlm", 0x200f },
- { "rsaquo", 0x203a },
- { "rsquo", 0x2019 },
- { "sbquo", 0x201a },
- { "scaron", 0x0161 },
- { "sdot", 0x22c5 },
- { "sect", 0x00a7 },
- { "shy", 0x00ad },
- { "sigma", 0x03c3 },
- { "sigmaf", 0x03c2 },
- { "sim", 0x223c },
- { "spades", 0x2660 },
- { "sub", 0x2282 },
- { "sube", 0x2286 },
- { "sum", 0x2211 },
- { "sup1", 0x00b9 },
- { "sup2", 0x00b2 },
- { "sup3", 0x00b3 },
- { "sup", 0x2283 },
- { "supe", 0x2287 },
- { "szlig", 0x00df },
- { "tau", 0x03c4 },
- { "there4", 0x2234 },
- { "theta", 0x03b8 },
- { "thetasym", 0x03d1 },
- { "thinsp", 0x2009 },
- { "thorn", 0x00fe },
- { "tilde", 0x02dc },
- { "times", 0x00d7 },
- { "trade", 0x2122 },
- { "uArr", 0x21d1 },
- { "uacute", 0x00fa },
- { "uarr", 0x2191 },
- { "ucirc", 0x00fb },
- { "ugrave", 0x00f9 },
- { "uml", 0x00a8 },
- { "upsih", 0x03d2 },
- { "upsilon", 0x03c5 },
- { "uuml", 0x00fc },
- { "weierp", 0x2118 },
- { "xi", 0x03be },
- { "yacute", 0x00fd },
- { "yen", 0x00a5 },
- { "yuml", 0x00ff },
- { "zeta", 0x03b6 },
- { "zwj", 0x200d },
- { "zwnj", 0x200c },
- { "", 0x0000 }
-};
-
-
-
-
-
-static QMap<QByteArray, TQChar> *html_map = 0;
-static void qt_cleanup_html_map()
-{
- delete html_map;
- html_map = 0;
-}
-
-static QMap<QByteArray, TQChar> *htmlMap()
-{
- if (!html_map) {
- html_map = new QMap<QByteArray, TQChar>;
- qAddPostRoutine(qt_cleanup_html_map);
-
- const Entity *ent = entitylist;
- while(ent->code) {
- html_map->insert(QByteArray(ent->name), TQChar(ent->code));
- ent++;
- }
- }
- return html_map;
-}
-
-TQChar TQTextDocument::parseHTMLSpecialChar(const TQChar* doc, int length, int& pos)
-{
- TQString s;
- pos++;
- int recoverpos = pos;
- while (pos < length && doc[pos] != TQLatin1Char(';') && !doc[pos].isSpace() && pos < recoverpos + 8) {
- s += doc[pos];
- pos++;
- }
- if (doc[pos] != TQLatin1Char(';') && !doc[pos].isSpace()) {
- pos = recoverpos;
- return TQLatin1Char('&');
- }
- pos++;
-
- if (s.length() > 1 && s[0] == TQLatin1Char('#')) {
- int off = 1;
- int base = 10;
- if (s[1] == TQLatin1Char('x')) {
- off = 2;
- base = 16;
- }
- bool ok;
- int num = s.mid(off).toInt(&ok, base);
- if (num == 151) // ### hack for designer manual
- return TQLatin1Char('-');
- return num;
- }
-
- QMap<QByteArray, TQChar>::Iterator it = htmlMap()->find(s.toLatin1());
- if (it != htmlMap()->end()) {
- return *it;
- }
-
- pos = recoverpos;
- return TQLatin1Char('&');
-}
-
-TQString TQTextDocument::parseWord(const TQChar* doc, int length, int& pos, bool lower)
-{
- TQString s;
-
- if (doc[pos] == TQLatin1Char('"')) {
- pos++;
- while (pos < length && doc[pos] != TQLatin1Char('"')) {
- if (doc[pos] == TQLatin1Char('&')) {
- s += parseHTMLSpecialChar(doc, length, pos);
- } else {
- s += doc[pos];
- pos++;
- }
- }
- eat(doc, length, pos, TQLatin1Char('"'));
- } else if (doc[pos] == TQLatin1Char('\'')) {
- pos++;
- while (pos < length && doc[pos] != TQLatin1Char('\'')) {
- s += doc[pos];
- pos++;
- }
- eat(doc, length, pos, TQLatin1Char('\''));
- } else {
- static TQString term = TQString::fromLatin1("/>");
- while (pos < length
- && doc[pos] != TQLatin1Char('>')
- && !hasPrefix(doc, length, pos, term)
- && doc[pos] != TQLatin1Char('<')
- && doc[pos] != TQLatin1Char('=')
- && !doc[pos].isSpace())
- {
- if (doc[pos] == TQLatin1Char('&')) {
- s += parseHTMLSpecialChar(doc, length, pos);
- } else {
- s += doc[pos];
- pos++;
- }
- }
- if (lower)
- s = s.toLower();
- }
- return s;
-}
-
-TQChar TQTextDocument::parseChar(const TQChar* doc, int length, int& pos, TQStyleSheetItem::WhiteSpaceMode wsm)
-{
- if (pos >= length)
- return TQChar::null;
-
- TQChar c = doc[pos++];
-
- if (c == TQLatin1Char('<'))
- return TQChar::null;
-
- if (c.isSpace() && c != TQChar(TQChar::nbsp)) {
- if (wsm == TQStyleSheetItem::WhiteSpacePre) {
- if (c == TQLatin1Char('\n'))
- return TQChar::LineSeparator;
- else
- return c;
- } else { // non-pre mode: collapse whitespace except nbsp
- while (pos< length &&
- doc[pos].isSpace() && doc[pos] != TQChar(TQChar::nbsp))
- pos++;
- return TQLatin1Char(' ');
- }
- }
- else if (c == TQLatin1Char('&'))
- return parseHTMLSpecialChar(doc, length, --pos);
- else
- return c;
-}
-
-TQString TQTextDocument::parseOpenTag(const TQChar* doc, int length, int& pos,
- QMap<TQString, TQString> &attr, bool& emptyTag)
-{
- emptyTag = false;
- pos++;
- if (hasPrefix(doc, length, pos, TQLatin1Char('!'))) {
- if (hasPrefix(doc, length, pos+1, TQLatin1String("--"))) {
- pos += 3;
- // eat comments
- TQString pref = TQString::fromLatin1("-->");
- while (!hasPrefix(doc, length, pos, pref) && pos < length)
- pos++;
- if (hasPrefix(doc, length, pos, pref)) {
- pos += 3;
- eatSpace(doc, length, pos, true);
- }
- emptyTag = true;
- return TQString();
- }
- else {
- // eat strange internal tags
- while (!hasPrefix(doc, length, pos, TQLatin1Char('>')) && pos < length)
- pos++;
- if (hasPrefix(doc, length, pos, TQLatin1Char('>'))) {
- pos++;
- eatSpace(doc, length, pos, true);
- }
- return TQString();
- }
- }
-
- TQString tag = parseWord(doc, length, pos);
- eatSpace(doc, length, pos, true);
- static TQString term = TQString::fromLatin1("/>");
- static TQString s_TRUE = TQString::fromLatin1("TRUE");
-
- while (doc[pos] != TQLatin1Char('>') && ! (emptyTag = hasPrefix(doc, length, pos, term))) {
- TQString key = parseWord(doc, length, pos);
- eatSpace(doc, length, pos, true);
- if (key.isEmpty()) {
- // error recovery
- while (pos < length && doc[pos] != TQLatin1Char('>'))
- pos++;
- break;
- }
- TQString value;
- if (hasPrefix(doc, length, pos, TQLatin1Char('='))){
- pos++;
- eatSpace(doc, length, pos);
- value = parseWord(doc, length, pos, false);
- }
- else
- value = s_TRUE;
- attr.insert(key.toLower(), value);
- eatSpace(doc, length, pos, true);
- }
-
- if (emptyTag) {
- eat(doc, length, pos, TQLatin1Char('/'));
- eat(doc, length, pos, TQLatin1Char('>'));
- }
- else
- eat(doc, length, pos, TQLatin1Char('>'));
-
- return tag;
-}
-
-TQString TQTextDocument::parseCloseTag(const TQChar* doc, int length, int& pos)
-{
- pos++;
- pos++;
- TQString tag = parseWord(doc, length, pos);
- eatSpace(doc, length, pos, true);
- eat(doc, length, pos, TQLatin1Char('>'));
- return tag;
-}
-
-TQTextFlow::TQTextFlow()
-{
- w = pagesize = 0;
-}
-
-TQTextFlow::~TQTextFlow()
-{
- clear();
-}
-
-void TQTextFlow::clear()
-{
-#ifndef QT_NO_TEXTCUSTOMITEM
- while (!leftItems.isEmpty())
- delete leftItems.takeFirst();
- while (!rightItems.isEmpty())
- delete rightItems.takeFirst();
-#endif
-}
-
-void TQTextFlow::setWidth(int width)
-{
- w = width;
-}
-
-int TQTextFlow::adjustLMargin(int yp, int, int margin, int space)
-{
-#ifndef QT_NO_TEXTCUSTOMITEM
- for (int idx = 0; idx < leftItems.size(); ++idx) {
- TQTextCustomItem* item = leftItems.at(idx);
- if (item->ypos == -1)
- continue;
- if (yp >= item->ypos && yp < item->ypos + item->height)
- margin = qMax(margin, item->xpos + item->width + space);
- }
-#endif
- return margin;
-}
-
-int TQTextFlow::adjustRMargin(int yp, int, int margin, int space)
-{
-#ifndef QT_NO_TEXTCUSTOMITEM
- for (int idx = 0; idx < rightItems.size(); ++idx) {
- TQTextCustomItem* item = rightItems.at(idx);
- if (item->ypos == -1)
- continue;
- if (yp >= item->ypos && yp < item->ypos + item->height)
- margin = qMax(margin, w - item->xpos - space);
- }
-#endif
- return margin;
-}
-
-
-int TQTextFlow::adjustFlow(int y, int /*w*/, int h)
-{
- if (pagesize > 0) { // check pages
- int yinpage = y % pagesize;
- if (yinpage <= border_tolerance)
- return border_tolerance - yinpage;
- else
- if (yinpage + h > pagesize - border_tolerance)
- return (pagesize - yinpage) + border_tolerance;
- }
- return 0;
-}
-
-#ifndef QT_NO_TEXTCUSTOMITEM
-void TQTextFlow::unregisterFloatingItem(TQTextCustomItem* item)
-{
- leftItems.removeAll(item);
- rightItems.removeAll(item);
-}
-
-void TQTextFlow::registerFloatingItem(TQTextCustomItem* item)
-{
- if (item->placement() == TQTextCustomItem::PlaceRight) {
- if (!rightItems.contains(item))
- rightItems.append(item);
- } else if (item->placement() == TQTextCustomItem::PlaceLeft &&
- !leftItems.contains(item)) {
- leftItems.append(item);
- }
-}
-#endif // QT_NO_TEXTCUSTOMITEM
-
-TQRect TQTextFlow::boundingRect() const
-{
- TQRect br;
-#ifndef QT_NO_TEXTCUSTOMITEM
- for (int idx = 0; idx < leftItems.size(); ++idx) {
- TQTextCustomItem* item = leftItems.at(idx);
- br = br.united(item->geometry());
- }
- for (int idx = 0; idx < rightItems.size(); ++idx) {
- TQTextCustomItem* item = rightItems.at(idx);
- br = br.united(item->geometry());
- }
-#endif
- return br;
-}
-
-
-void TQTextFlow::drawFloatingItems(TQPainter* p, int cx, int cy, int cw, int ch,
- const QPalette &pal, bool selected)
-{
-#ifndef QT_NO_TEXTCUSTOMITEM
- for (int idx = 0; idx < leftItems.size(); ++idx) {
- TQTextCustomItem* item = leftItems.at(idx);
- if (item->xpos == -1 || item->ypos == -1)
- continue;
- item->draw(p, item->xpos, item->ypos, cx, cy, cw, ch, pal, selected);
- }
-
- for (int idx = 0; idx < rightItems.size(); ++idx) {
- TQTextCustomItem* item = rightItems.at(idx);
- if (item->xpos == -1 || item->ypos == -1)
- continue;
- item->draw(p, item->xpos, item->ypos, cx, cy, cw, ch, pal, selected);
- }
-#endif
-}
-
-// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-#ifndef QT_NO_TEXTCUSTOMITEM
-void TQTextCustomItem::pageBreak(int /*y*/ , TQTextFlow* /*flow*/)
-{
-}
-#endif
-
-#ifndef QT_NO_TEXTCUSTOMITEM
-TQTextTable::TQTextTable(TQTextDocument *p, const QMap<TQString, TQString> & attr )
- : TQTextCustomItem(p)
-{
- cellspacing = 2;
- cellpadding = 1;
- border = innerborder = 0;
-
- QMap<TQString, TQString>::ConstIterator it, end = attr.end();
- it = attr.find(TQLatin1String("cellspacing"));
- if (it != end)
- cellspacing = (*it).toInt();
- it = attr.find(TQLatin1String("cellpadding"));
- if (it != end)
- cellpadding = (*it).toInt();
- it = attr.find(TQLatin1String("border"));
- if (it != end) {
- if (*it == TQLatin1String("TRUE"))
- border = 1;
- else
- border = (*it).toInt();
- }
- us_b = border;
-
- innerborder = us_ib = border ? 1 : 0;
-
- if (border)
- cellspacing += 2;
-
- us_ib = innerborder;
- us_cs = cellspacing;
- us_cp = cellpadding;
- outerborder = cellspacing + border;
- us_ob = outerborder;
- layout = new TQGridLayout(1, 1, cellspacing);
-
- fixwidth = 0;
- stretch = 0;
- it = attr.find(TQLatin1String("width"));
- if (it != end) {
- bool b;
- TQString s(*it);
- int w = s.toInt(&b);
- if (b) {
- fixwidth = w;
- } else {
- s = s.trimmed();
- if (s.length() > 1 && s[(int)s.length()-1] == TQLatin1Char('%'))
- stretch = s.left(s.length()-1).toInt();
- }
- }
- us_fixwidth = fixwidth;
-
- place = PlaceInline;
- if (attr[TQLatin1String("align")] == TQLatin1String("left"))
- place = PlaceLeft;
- else if (attr[TQLatin1String("align")] == TQLatin1String("right"))
- place = PlaceRight;
- cachewidth = 0;
- attributes = attr;
- pageBreakFor = -1;
-}
-
-TQTextTable::~TQTextTable()
-{
- delete layout;
-}
-
-TQString TQTextTable::richText() const
-{
- TQString s;
- s = TQLatin1String("<table ");
- QMap<TQString, TQString>::ConstIterator it = attributes.begin();
- for (; it != attributes.end(); ++it)
- s += it.key() + TQLatin1Char('=') + *it + TQLatin1Char(' ');
- s += TQLatin1String(">\n");
-
- int lastRow = -1;
- bool needEnd = false;
- for (int idx = 0; idx < cells.size(); ++idx) {
- TQTextTableCell *cell = cells.at(idx);
- if (lastRow != cell->row()) {
- if (lastRow != -1)
- s += TQLatin1String("</tr>\n");
- s += TQLatin1String("<tr>");
- lastRow = cell->row();
- needEnd = true;
- }
- s += TQLatin1String("<td");
- it = cell->attributes.constBegin();
- for (; it != cell->attributes.constEnd(); ++it)
- s += TQLatin1Char(' ') + it.key() + TQLatin1Char('=') + *it;
- s += TQLatin1Char('>');
- s += cell->richText()->richText();
- s += TQLatin1String("</td>");
- }
- if (needEnd)
- s += TQLatin1String("</tr>\n");
- s += TQLatin1String("</table>\n");
- return s;
-}
-
-void TQTextTable::adjustToPainter(TQPainter* p)
-{
- cellspacing = scale(us_cs, p);
- cellpadding = scale(us_cp, p);
- border = scale(us_b , p);
- innerborder = scale(us_ib, p);
- outerborder = scale(us_ob ,p);
- fixwidth = scale( us_fixwidth, p);
- width = 0;
- cachewidth = 0;
- for (int idx = 0; idx < cells.size(); ++idx) {
- TQTextTableCell *cell = cells.at(idx);
- cell->adjustToPainter(p);
- }
-}
-
-void TQTextTable::adjustCells(int y , int shift)
-{
- bool enlarge = false;
- for (int idx = 0; idx < cells.size(); ++idx) {
- TQTextTableCell *cell = cells.at(idx);
- TQRect r = cell->geometry();
- if (y <= r.top()) {
- r.moveBy(0, shift);
- cell->setGeometry(r);
- enlarge = true;
- } else if (y <= r.bottom()) {
- r.rBottom() += shift;
- cell->setGeometry(r);
- enlarge = true;
- }
- }
- if (enlarge)
- height += shift;
-}
-
-void TQTextTable::pageBreak(int yt, TQTextFlow* flow)
-{
- if (flow->pageSize() <= 0)
- return;
- if (layout && pageBreakFor > 0 && pageBreakFor != yt) {
- layout->invalidate();
- int h = layout->heightForWidth(width-2*outerborder);
- layout->setGeometry(TQRect(0, 0, width-2*outerborder, h) );
- height = layout->geometry().height()+2*outerborder;
- }
- pageBreakFor = yt;
- for (int idx = 0; idx < cells.size(); ++idx) {
- TQTextTableCell *cell = cells.at(idx);
- int y = yt + outerborder + cell->geometry().y();
- int shift = flow->adjustFlow(y - cellspacing, width, cell->richText()->height() + 2*cellspacing);
- adjustCells(y - outerborder - yt, shift);
- }
-}
-
-
-void TQTextTable::draw(TQPainter* p, int x, int y, int cx, int cy, int cw, int ch,
- const QPalette &pal, bool selected)
-{
- if (placement() != PlaceInline) {
- x = xpos;
- y = ypos;
- }
-
- for (int idx = 0; idx < cells.size(); ++idx) {
- TQTextTableCell *cell = cells.at(idx);
- if ((cx < 0 && cy < 0) ||
- TQRect(cx, cy, cw, ch).intersects(TQRect(x + outerborder + cell->geometry().x(),
- y + outerborder + cell->geometry().y(),
- cell->geometry().width(),
- cell->geometry().height()))) {
- cell->draw(p, x+outerborder, y+outerborder, cx, cy, cw, ch, pal, selected);
- if (border) {
- TQRect r(x+outerborder+cell->geometry().x() - innerborder,
- y+outerborder+cell->geometry().y() - innerborder,
- cell->geometry().width() + 2 * innerborder,
- cell->geometry().height() + 2 * innerborder);
- if (is_printer(p)) {
- QPen oldPen = p->pen();
- TQRect r2 = r;
- r2.adjust(innerborder/2, innerborder/2, -innerborder/2, -innerborder/2);
- p->setPen(QPen(pal.text().color(), innerborder));
- p->drawRect(r2);
- p->setPen(oldPen);
- } else {
- int s = qMax(cellspacing-2*innerborder, 0);
- if (s) {
- p->fillRect(r.left()-s, r.top(), s+1, r.height(), pal.button());
- p->fillRect(r.right(), r.top(), s+1, r.height(), pal.button());
- p->fillRect(r.left()-s, r.top()-s, r.width()+2*s, s, pal.button());
- p->fillRect(r.left()-s, r.bottom(), r.width()+2*s, s, pal.button());
- }
- qDrawShadePanel(p, r, pal, true, innerborder);
- }
- }
- }
- }
- if (border) {
- TQRect r (x, y, width, height);
- if (is_printer(p)) {
- TQRect r2 = r;
- r2.adjust(border/2, border/2, -border/2, -border/2);
- QPen oldPen = p->pen();
- p->setPen(QPen(pal.text().color(), border));
- p->drawRect(r2);
- p->setPen(oldPen);
- } else {
- int s = border+qMax(cellspacing-2*innerborder, 0);
- if (s) {
- p->fillRect(r.left(), r.top(), s, r.height(), pal.button());
- p->fillRect(r.right()-s, r.top(), s, r.height(), pal.button());
- p->fillRect(r.left(), r.top(), r.width(), s, pal.button());
- p->fillRect(r.left(), r.bottom()-s, r.width(), s, pal.button());
- }
- qDrawShadePanel(p, r, pal, false, border);
- }
- }
-
-}
-
-int TQTextTable::minimumWidth() const
-{
- return qMax(fixwidth, ((layout ? layout->minimumSize().width() : 0) + 2 * outerborder));
-}
-
-void TQTextTable::resize(int nwidth)
-{
- if (fixwidth && cachewidth != 0)
- return;
- if (nwidth == cachewidth)
- return;
-
-
- cachewidth = nwidth;
- int w = nwidth;
-
- format(w);
-
- if (stretch)
- nwidth = nwidth * stretch / 100;
-
- width = nwidth;
- layout->invalidate();
- int shw = layout->sizeHint().width() + 2*outerborder;
- int mw = layout->minimumSize().width() + 2*outerborder;
- if (stretch)
- width = qMax(mw, nwidth);
- else
- width = qMax(mw, qMin(nwidth, shw));
-
- if (fixwidth)
- width = fixwidth;
-
- layout->invalidate();
- mw = layout->minimumSize().width() + 2*outerborder;
- width = qMax(width, mw);
-
- int h = layout->heightForWidth(width-2*outerborder);
- layout->setGeometry(TQRect(0, 0, width-2*outerborder, h) );
- height = layout->geometry().height()+2*outerborder;
-}
-
-void TQTextTable::format(int w)
-{
- for (int i = 0; i < (int)cells.count(); ++i) {
- TQTextTableCell *cell = cells.at(i);
- TQRect r = cell->geometry();
- r.setWidth(w - 2*outerborder);
- cell->setGeometry(r);
- }
-}
-
-void TQTextTable::addCell(TQTextTableCell* cell)
-{
- cells.append(cell);
- layout->addMultiCell(cell, cell->row(), cell->row() + cell->rowspan()-1,
- cell->column(), cell->column() + cell->colspan()-1);
-}
-
-bool TQTextTable::enter(TQTextCursor *c, TQTextDocument *&doc, TQTextParagraph *&parag, int &idx, int &ox, int &oy, bool atEnd)
-{
- currCell.remove(c);
- if (!atEnd)
- return next(c, doc, parag, idx, ox, oy);
- currCell.insert(c, cells.count());
- return prev(c, doc, parag, idx, ox, oy);
-}
-
-bool TQTextTable::enterAt(TQTextCursor *c, TQTextDocument *&doc, TQTextParagraph *&parag, int &idx, int &ox, int &oy, const QPoint &pos)
-{
- currCell.remove(c);
- int lastCell = -1;
- int lastY = -1;
- int i;
- for (i = 0; i < (int)cells.count(); ++i) {
- TQTextTableCell *cell = cells.at(i);
- if (!cell)
- continue;
- TQRect r(cell->geometry().x(),
- cell->geometry().y(),
- cell->geometry().width() + 2 * innerborder + 2 * outerborder,
- cell->geometry().height() + 2 * innerborder + 2 * outerborder);
-
- if (r.left() <= pos.x() && r.right() >= pos.x()) {
- if (cell->geometry().y() > lastY) {
- lastCell = i;
- lastY = cell->geometry().y();
- }
- if (r.top() <= pos.y() && r.bottom() >= pos.y()) {
- currCell.insert(c, i);
- break;
- }
- }
- }
- if (i == (int) cells.count())
- return false; // no cell found
-
- if (currCell.find(c) == currCell.end()) {
- if (lastY != -1)
- currCell.insert(c, lastCell);
- else
- return false;
- }
-
- TQTextTableCell *cell = cells.at(*currCell.find(c));
- if (!cell)
- return false;
- doc = cell->richText();
- parag = doc->firstParagraph();
- idx = 0;
- ox += cell->geometry().x() + cell->horizontalAlignmentOffset() + outerborder + parent->x();
- oy += cell->geometry().y() + cell->verticalAlignmentOffset() + outerborder;
- return true;
-}
-
-bool TQTextTable::next(TQTextCursor *c, TQTextDocument *&doc, TQTextParagraph *&parag, int &idx, int &ox, int &oy)
-{
- int cc = -1;
- if (currCell.find(c) != currCell.end())
- cc = *currCell.find(c);
- if (cc > (int)cells.count() - 1 || cc < 0)
- cc = -1;
- currCell.remove(c);
- currCell.insert(c, ++cc);
- if (cc >= (int)cells.count()) {
- currCell.insert(c, 0);
- TQTextCustomItem::next(c, doc, parag, idx, ox, oy);
- TQTextTableCell *cell = cells.first();
- if (!cell)
- return false;
- doc = cell->richText();
- idx = -1;
- return true;
- }
-
- if (currCell.find(c) == currCell.end())
- return false;
- TQTextTableCell *cell = cells.at(*currCell.find(c));
- if (!cell)
- return false;
- doc = cell->richText();
- parag = doc->firstParagraph();
- idx = 0;
- ox += cell->geometry().x() + cell->horizontalAlignmentOffset() + outerborder + parent->x();
- oy += cell->geometry().y() + cell->verticalAlignmentOffset() + outerborder;
- return true;
-}
-
-bool TQTextTable::prev(TQTextCursor *c, TQTextDocument *&doc, TQTextParagraph *&parag, int &idx, int &ox, int &oy)
-{
- int cc = -1;
- if (currCell.find(c) != currCell.end())
- cc = *currCell.find(c);
- if (cc > (int)cells.count() - 1 || cc < 0)
- cc = cells.count();
- currCell.remove(c);
- currCell.insert(c, --cc);
- if (cc < 0) {
- currCell.insert(c, 0);
- TQTextCustomItem::prev(c, doc, parag, idx, ox, oy);
- TQTextTableCell *cell = cells.first();
- if (!cell)
- return false;
- doc = cell->richText();
- idx = -1;
- return true;
- }
-
- if (currCell.find(c) == currCell.end())
- return false;
- TQTextTableCell *cell = cells.at(*currCell.find(c));
- if (!cell)
- return false;
- doc = cell->richText();
- parag = doc->lastParagraph();
- idx = parag->length() - 1;
- ox += cell->geometry().x() + cell->horizontalAlignmentOffset() + outerborder + parent->x();
- oy += cell->geometry().y() + cell->verticalAlignmentOffset() + outerborder;
- return true;
-}
-
-bool TQTextTable::down(TQTextCursor *c, TQTextDocument *&doc, TQTextParagraph *&parag, int &idx, int &ox, int &oy)
-{
- if (currCell.find(c) == currCell.end())
- return false;
- TQTextTableCell *cell = cells.at(*currCell.find(c));
- if (cell->row_ == layout->numRows() - 1) {
- currCell.insert(c, 0);
- TQTextCustomItem::down(c, doc, parag, idx, ox, oy);
- TQTextTableCell *cell = cells.first();
- if (!cell)
- return false;
- doc = cell->richText();
- idx = -1;
- return true;
- }
-
- int oldRow = cell->row_;
- int oldCol = cell->col_;
- if (currCell.find(c) == currCell.end())
- return false;
- int cc = *currCell.find(c);
- for (int i = cc; i < (int)cells.count(); ++i) {
- cell = cells.at(i);
- if (cell->row_ > oldRow && cell->col_ == oldCol) {
- currCell.insert(c, i);
- break;
- }
- }
- doc = cell->richText();
- if (!cell)
- return false;
- parag = doc->firstParagraph();
- idx = 0;
- ox += cell->geometry().x() + cell->horizontalAlignmentOffset() + outerborder + parent->x();
- oy += cell->geometry().y() + cell->verticalAlignmentOffset() + outerborder;
- return true;
-}
-
-bool TQTextTable::up(TQTextCursor *c, TQTextDocument *&doc, TQTextParagraph *&parag, int &idx, int &ox, int &oy)
-{
- if (currCell.find(c) == currCell.end())
- return false;
- TQTextTableCell *cell = cells.at(*currCell.find(c));
- if (cell->row_ == 0) {
- currCell.insert(c, 0);
- TQTextCustomItem::up(c, doc, parag, idx, ox, oy);
- TQTextTableCell *cell = cells.first();
- if (!cell)
- return false;
- doc = cell->richText();
- idx = -1;
- return true;
- }
-
- int oldRow = cell->row_;
- int oldCol = cell->col_;
- if (currCell.find(c) == currCell.end())
- return false;
- int cc = *currCell.find(c);
- for (int i = cc; i >= 0; --i) {
- cell = cells.at(i);
- if (cell->row_ < oldRow && cell->col_ == oldCol) {
- currCell.insert(c, i);
- break;
- }
- }
- doc = cell->richText();
- if (!cell)
- return false;
- parag = doc->lastParagraph();
- idx = parag->length() - 1;
- ox += cell->geometry().x() + cell->horizontalAlignmentOffset() + outerborder + parent->x();
- oy += cell->geometry().y() + cell->verticalAlignmentOffset() + outerborder;
- return true;
-}
-
-TQTextTableCell::TQTextTableCell(TQTextTable* table,
- int row, int column,
- const QMap<TQString, TQString> &attr,
- const TQStyleSheetItem* style,
- const TQTextFormat& fmt, const TQString& context,
- TQMimeSourceFactory &factory, TQStyleSheet *sheet,
- const TQString& doc)
-{
- cached_width = -1;
- cached_sizehint = -1;
-
- maxw = QWIDGETSIZE_MAX;
- minw = 0;
-
- parent = table;
- row_ = row;
- col_ = column;
- stretch_ = 0;
- richtext = new TQTextDocument(table->parent);
- richtext->formatCollection()->setPaintDevice(table->parent->formatCollection()->paintDevice());
- richtext->bodyText = fmt.color();
- richtext->setTableCell(this);
-
- QMap<TQString,TQString>::ConstIterator it, end = attr.end();
- int halign = style->alignment();
- if (halign != TQStyleSheetItem::Undefined)
- richtext->setAlignment(halign);
- it = attr.find(TQLatin1String("align"));
- if (it != end && ! (*it).isEmpty()) {
- TQString a = (*it).toLower();
- if (a == TQLatin1String("left"))
- richtext->setAlignment(Qt::AlignLeft);
- else if (a == TQLatin1String("center"))
- richtext->setAlignment(Qt::AlignHCenter);
- else if (a == TQLatin1String("right"))
- richtext->setAlignment(Qt::AlignRight);
- }
- align = 0;
- it = attr.find(TQLatin1String("valign"));
- if (it != end && ! (*it).isEmpty()) {
- TQString va = (*it).toLower();
- if ( va == TQLatin1String("top") )
- align |= Qt::AlignTop;
- else if ( va == TQLatin1String("center") || va == TQLatin1String("middle") )
- align |= Qt::AlignVCenter;
- else if (va == TQLatin1String("bottom"))
- align |= Qt::AlignBottom;
- }
- richtext->setFormatter(table->parent->formatter());
- richtext->setUseFormatCollection(table->parent->useFormatCollection());
- richtext->setMimeSourceFactory(&factory);
- richtext->setStyleSheet(sheet);
- richtext->setRichText(doc, context, &fmt);
- rowspan_ = 1;
- colspan_ = 1;
-
- it = attr.find(TQLatin1String("colspan"));
- if (it != end)
- colspan_ = (*it).toInt();
- it = attr.find(TQLatin1String("rowspan"));
- if (it != end)
- rowspan_ = (*it).toInt();
-
- background = 0;
- it = attr.find(TQLatin1String("bgcolor"));
- if (it != end) {
- background = new TQBrush(QColor(*it));
- }
-
- hasFixedWidth = false;
- it = attr.find(TQLatin1String("width"));
- if (it != end) {
- bool b;
- TQString s(*it);
- int w = s.toInt(&b);
- if (b) {
- maxw = w;
- minw = maxw;
- hasFixedWidth = true;
- } else {
- s = s.trimmed();
- if (s.length() > 1 && s[(int)s.length()-1] == TQLatin1Char('%'))
- stretch_ = s.left(s.length()-1).toInt();
- }
- }
-
- attributes = attr;
-
- parent->addCell(this);
-}
-
-TQTextTableCell::~TQTextTableCell()
-{
- delete background;
- background = 0;
- delete richtext;
- richtext = 0;
-}
-
-TQSize TQTextTableCell::tqsizeHint() const
-{
- int extra = 2 * (parent->innerborder + parent->cellpadding + border_tolerance);
- int used = richtext->widthUsed() + extra;
-
- if (stretch_) {
- int w = parent->width * stretch_ / 100 - 2*parent->cellspacing - 2*parent->cellpadding;
- return QSize(qMin(w, maxw), 0).expandedTo(minimumSize());
- }
-
- return QSize(used, 0).expandedTo(minimumSize());
-}
-
-TQSize TQTextTableCell::tqminimumSize() const
-{
- int extra = 2 * (parent->innerborder + parent->cellpadding + border_tolerance);
- return QSize(qMax(richtext->minimumWidth() + extra, minw), 0);
-}
-
-TQSize TQTextTableCell::tqmaximumSize() const
-{
- return QSize(maxw, QWIDGETSIZE_MAX);
-}
-
-Qt::Orientations TQTextTableCell::expandingDirections() const
-{
- return Qt::Horizontal | Qt::Vertical;
-}
-
-bool TQTextTableCell::isEmpty() const
-{
- return false;
-}
-void TQTextTableCell::setGeometry(const TQRect& r)
-{
- int extra = 2 * (parent->innerborder + parent->cellpadding);
- if (r.width() != cached_width)
- richtext->doLayout(TQTextFormat::painter(), r.width() - extra);
- cached_width = r.width();
- geom = r;
-}
-
-TQRect TQTextTableCell::tqgeometry() const
-{
- return geom;
-}
-
-bool TQTextTableCell::hasHeightForWidth() const
-{
- return true;
-}
-
-int TQTextTableCell::heightForWidth(int w) const
-{
- int extra = 2 * (parent->innerborder + parent->cellpadding);
- w = qMax(minw, w);
-
- if (cached_width != w) {
- TQTextTableCell* that = (TQTextTableCell*) this;
- that->richtext->doLayout(TQTextFormat::painter(), w - extra);
- that->cached_width = w;
- }
- return richtext->height() + extra;
-}
-
-void TQTextTableCell::adjustToPainter(TQPainter* p)
-{
- TQTextParagraph *parag = richtext->firstParagraph();
- while (parag) {
- parag->adjustToPainter(p);
- parag = parag->next();
- }
-}
-
-int TQTextTableCell::horizontalAlignmentOffset() const
-{
- return parent->cellpadding;
-}
-
-int TQTextTableCell::verticalAlignmentOffset() const
-{
- if ((align & Qt::AlignVCenter) == Qt::AlignVCenter)
- return (geom.height() - richtext->height()) / 2;
- else if ((align & Qt::AlignBottom) == Qt::AlignBottom)
- return geom.height() - parent->cellpadding - richtext->height() ;
- return parent->cellpadding;
-}
-
-void TQTextTableCell::draw(TQPainter* p, int x, int y, int cx, int cy, int cw, int ch,
- const QPalette &pal, bool)
-{
- if (cached_width != geom.width()) {
- int extra = 2 * (parent->innerborder + parent->cellpadding);
- richtext->doLayout(p, geom.width() - extra);
- cached_width = geom.width();
- }
- QPalette pal2(pal);
- if (background)
- pal2.setBrush(QPalette::Base, *background);
- else if (richtext->paper())
- pal2.setBrush(QPalette::Base, *richtext->paper());
-
- p->save();
- p->translate(x + geom.x(), y + geom.y());
- if (background)
- p->fillRect(0, 0, geom.width(), geom.height(), *background);
- else if (richtext->paper())
- p->fillRect(0, 0, geom.width(), geom.height(), *richtext->paper());
-
- p->translate(horizontalAlignmentOffset(), verticalAlignmentOffset());
-
- QRegion r;
- if (cx >= 0 && cy >= 0)
- richtext->draw(p, cx - (x + horizontalAlignmentOffset() + geom.x()),
- cy - (y + geom.y() + verticalAlignmentOffset()),
- cw, ch, pal2, false, false, 0);
- else
- richtext->draw(p, -1, -1, -1, -1, pal2, false, false, 0);
-
- p->restore();
-}
-#endif
-
-QT_END_NAMESPACE
-
-#endif //QT_NO_RICHTEXT
-
-#else // USE_QT4
-
-/****************************************************************************
-**
-** Implementation of the internal TQt classes dealing with rich text
-**
-** Created : 990101
-**
-** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
-**
-** This file is part of the kernel module of the TQt GUI Toolkit.
-**
-** This file may be used under the terms of the GNU General
-** Public License versions 2.0 or 3.0 as published by the Free
-** Software Foundation and appearing in the files LICENSE.GPL2
-** and LICENSE.GPL3 included in the packaging of this file.
-** Alternatively you may (at your option) use any later version
-** of the GNU General Public License if such license has been
-** publicly approved by Trolltech ASA (or its successors, if any)
-** and the KDE Free TQt Foundation.
-**
-** Please review the following information to ensure GNU General
-** Public Licensing requirements will be met:
-** http://trolltech.com/products/qt/licenses/licensing/opensource/.
-** If you are unsure which license is appropriate for your use, please
-** review the following information:
-** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
-** or contact the sales department at sales@trolltech.com.
-**
-** This file may be used under the terms of the Q Public License as
-** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
-** included in the packaging of this file. Licensees holding valid TQt
-** Commercial licenses may use this file in accordance with the TQt
-** Commercial License Agreement provided with the Software.
-**
-** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
-** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
-** herein.
-**
-**********************************************************************/
-
-#include "tqrichtext_p.h"
-
-#ifndef TQT_NO_RICHTEXT
-
-
-#include "tqstringlist.h"
-#include "tqfont.h"
-#include "tqtextstream.h"
-#include "tqfile.h"
-#include "tqapplication.h"
-#include "tqmap.h"
-#include "tqfileinfo.h"
-#include "tqstylesheet.h"
-#include "tqmime.h"
-#include "tqimage.h"
-#include "tqdragobject.h"
-#include "tqpaintdevicemetrics.h"
-#include "tqpainter.h"
-#include "tqdrawutil.h"
-#include "tqcursor.h"
-#include "tqptrstack.h"
-#include "tqptrdict.h"
-#include "tqstyle.h"
-#include "tqcleanuphandler.h"
-#include "tqtextengine_p.h"
-#include <private/tqunicodetables_p.h>
-
-#include <stdlib.h>
-
-static TQTextCursor* richTextExportStart = 0;
-static TQTextCursor* richTextExportEnd = 0;
-
-class TQTextFormatCollection;
-
-const int border_tolerance = 2;
-
-#ifdef TQ_WS_WIN
-#include "tqt_windows.h"
-#endif
-
-#define TQChar_linesep TQChar(0x2028U)
-
-static inline bool is_printer( TQPainter *p )
-{
- if ( !p || !p->tqdevice() )
- return FALSE;
- return p->tqdevice()->devType() == TQInternal::Printer;
-}
-
-static inline int scale( int value, TQPainter *painter )
-{
- if ( is_printer( painter ) ) {
- TQPaintDeviceMetrics metrics( painter->tqdevice() );
-#if defined(TQ_WS_X11)
- value = value * metrics.logicalDpiY() /
- TQPaintDevice::x11AppDpiY( painter->tqdevice()->x11Screen() );
-#elif defined (TQ_WS_WIN)
- HDC hdc = GetDC( 0 );
- int gdc = GetDeviceCaps( hdc, LOGPIXELSY );
- if ( gdc )
- value = value * metrics.logicalDpiY() / gdc;
- ReleaseDC( 0, hdc );
-#elif defined (TQ_WS_MAC)
- value = value * metrics.logicalDpiY() / 75; // ##### FIXME
-#elif defined (TQ_WS_TQWS)
- value = value * metrics.logicalDpiY() / 75;
-#endif
- }
- return value;
-}
-
-
-inline bool isBreakable( TQTextString *string, int pos )
-{
- if (string->at(pos).nobreak)
- return FALSE;
- return (pos < string->length()-1 && string->at(pos+1).softBreak);
-}
-
-// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-void TQTextCommandHistory::addCommand( TQTextCommand *cmd )
-{
- if ( current < (int)history.count() - 1 ) {
- TQPtrList<TQTextCommand> commands;
- commands.setAutoDelete( FALSE );
-
- for( int i = 0; i <= current; ++i ) {
- commands.insert( i, history.at( 0 ) );
- history.take( 0 );
- }
-
- commands.append( cmd );
- history.clear();
- history = commands;
- history.setAutoDelete( TRUE );
- } else {
- history.append( cmd );
- }
-
- if ( (int)history.count() > steps )
- history.removeFirst();
- else
- ++current;
-}
-
-TQTextCursor *TQTextCommandHistory::undo( TQTextCursor *c )
-{
- if ( current > -1 ) {
- TQTextCursor *c2 = history.at( current )->unexecute( c );
- --current;
- return c2;
- }
- return 0;
-}
-
-TQTextCursor *TQTextCommandHistory::redo( TQTextCursor *c )
-{
- if ( current > -1 ) {
- if ( current < (int)history.count() - 1 ) {
- ++current;
- return history.at( current )->execute( c );
- }
- } else {
- if ( history.count() > 0 ) {
- ++current;
- return history.at( current )->execute( c );
- }
- }
- return 0;
-}
-
-bool TQTextCommandHistory::isUndoAvailable()
-{
- return current > -1;
-}
-
-bool TQTextCommandHistory::isRedoAvailable()
-{
- return ((current > -1) && current < ((int)history.count() - 1)) || ((current == -1) && (history.count()) > 0);
-}
-
-// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-TQTextDeleteCommand::TQTextDeleteCommand( TQTextDocument *d, int i, int idx, const TQMemArray<TQTextStringChar> &str,
- const TQByteArray& oldStyleInfo )
- : TQTextCommand( d ), id( i ), index( idx ), parag( 0 ), text( str ), styleInformation( oldStyleInfo )
-{
- for ( int j = 0; j < (int)text.size(); ++j ) {
- if ( text[ j ].format() )
- text[ j ].format()->addRef();
- }
-}
-
-TQTextDeleteCommand::TQTextDeleteCommand( TQTextParagraph *p, int idx, const TQMemArray<TQTextStringChar> &str )
- : TQTextCommand( 0 ), id( -1 ), index( idx ), parag( p ), text( str )
-{
- for ( int i = 0; i < (int)text.size(); ++i ) {
- if ( text[ i ].format() )
- text[ i ].format()->addRef();
- }
-}
-
-TQTextDeleteCommand::~TQTextDeleteCommand()
-{
- for ( int i = 0; i < (int)text.size(); ++i ) {
- if ( text[ i ].format() )
- text[ i ].format()->removeRef();
- }
- text.resize( 0 );
-}
-
-TQTextCursor *TQTextDeleteCommand::execute( TQTextCursor *c )
-{
- TQTextParagraph *s = doc ? doc->paragAt( id ) : parag;
- if ( !s ) {
- qWarning( "can't locate parag at %d, last parag: %d", id, doc->lastParagraph()->paragId() );
- return 0;
- }
-
- cursor.setParagraph( s );
- cursor.setIndex( index );
- int len = text.size();
- if ( c )
- *c = cursor;
- if ( doc ) {
- doc->setSelectionStart( TQTextDocument::Temp, cursor );
- for ( int i = 0; i < len; ++i )
- cursor.gotoNextLetter();
- doc->setSelectionEnd( TQTextDocument::Temp, cursor );
- doc->removeSelectedText( TQTextDocument::Temp, &cursor );
- if ( c )
- *c = cursor;
- } else {
- s->remove( index, len );
- }
-
- return c;
-}
-
-TQTextCursor *TQTextDeleteCommand::unexecute( TQTextCursor *c )
-{
- TQTextParagraph *s = doc ? doc->paragAt( id ) : parag;
- if ( !s ) {
- qWarning( "can't locate parag at %d, last parag: %d", id, doc->lastParagraph()->paragId() );
- return 0;
- }
-
- cursor.setParagraph( s );
- cursor.setIndex( index );
- TQString str = TQTextString::toString( text );
- cursor.insert( str, TRUE, &text );
- if ( c )
- *c = cursor;
- cursor.setParagraph( s );
- cursor.setIndex( index );
-
-#ifndef TQT_NO_DATASTREAM
- if ( !styleInformation.isEmpty() ) {
- TQDataStream styleStream( styleInformation, IO_ReadOnly );
- int num;
- styleStream >> num;
- TQTextParagraph *p = s;
- while ( num-- && p ) {
- p->readStyleInformation( styleStream );
- p = p->next();
- }
- }
-#endif
- s = cursor.paragraph();
- while ( s ) {
- s->format();
- s->setChanged( TRUE );
- if ( s == c->paragraph() )
- break;
- s = s->next();
- }
-
- return &cursor;
-}
-
-TQTextFormatCommand::TQTextFormatCommand( TQTextDocument *d, int sid, int sidx, int eid, int eidx,
- const TQMemArray<TQTextStringChar> &old, TQTextFormat *f, int fl )
- : TQTextCommand( d ), startId( sid ), startIndex( sidx ), endId( eid ), endIndex( eidx ), format( f ), oldFormats( old ), flags( fl )
-{
- format = d->formatCollection()->format( f );
- for ( int j = 0; j < (int)oldFormats.size(); ++j ) {
- if ( oldFormats[ j ].format() )
- oldFormats[ j ].format()->addRef();
- }
-}
-
-TQTextFormatCommand::~TQTextFormatCommand()
-{
- format->removeRef();
- for ( int j = 0; j < (int)oldFormats.size(); ++j ) {
- if ( oldFormats[ j ].format() )
- oldFormats[ j ].format()->removeRef();
- }
-}
-
-TQTextCursor *TQTextFormatCommand::execute( TQTextCursor *c )
-{
- TQTextParagraph *sp = doc->paragAt( startId );
- TQTextParagraph *ep = doc->paragAt( endId );
- if ( !sp || !ep )
- return c;
-
- TQTextCursor start( doc );
- start.setParagraph( sp );
- start.setIndex( startIndex );
- TQTextCursor end( doc );
- end.setParagraph( ep );
- end.setIndex( endIndex );
-
- doc->setSelectionStart( TQTextDocument::Temp, start );
- doc->setSelectionEnd( TQTextDocument::Temp, end );
- doc->setFormat( TQTextDocument::Temp, format, flags );
- doc->removeSelection( TQTextDocument::Temp );
- if ( endIndex == ep->length() )
- end.gotoLeft();
- *c = end;
- return c;
-}
-
-TQTextCursor *TQTextFormatCommand::unexecute( TQTextCursor *c )
-{
- TQTextParagraph *sp = doc->paragAt( startId );
- TQTextParagraph *ep = doc->paragAt( endId );
- if ( !sp || !ep )
- return 0;
-
- int idx = startIndex;
- int fIndex = 0;
- while ( fIndex < int(oldFormats.size()) ) {
- if ( oldFormats.at( fIndex ).c == '\n' ) {
- if ( idx > 0 ) {
- if ( idx < sp->length() && fIndex > 0 )
- sp->setFormat( idx, 1, oldFormats.at( fIndex - 1 ).format() );
- if ( sp == ep )
- break;
- sp = sp->next();
- idx = 0;
- }
- fIndex++;
- }
- if ( oldFormats.at( fIndex ).format() )
- sp->setFormat( idx, 1, oldFormats.at( fIndex ).format() );
- idx++;
- fIndex++;
- if ( fIndex >= (int)oldFormats.size() )
- break;
- if ( idx >= sp->length() ) {
- if ( sp == ep )
- break;
- sp = sp->next();
- idx = 0;
- }
- }
-
- TQTextCursor end( doc );
- end.setParagraph( ep );
- end.setIndex( endIndex );
- if ( endIndex == ep->length() )
- end.gotoLeft();
- *c = end;
- return c;
-}
-
-TQTextStyleCommand::TQTextStyleCommand( TQTextDocument *d, int fParag, int lParag, const TQByteArray& beforeChange )
- : TQTextCommand( d ), firstParag( fParag ), lastParag( lParag ), before( beforeChange )
-{
- after = readStyleInformation( d, fParag, lParag );
-}
-
-
-TQByteArray TQTextStyleCommand::readStyleInformation( TQTextDocument* doc, int fParag, int lParag )
-{
- TQByteArray style;
-#ifndef TQT_NO_DATASTREAM
- TQTextParagraph *p = doc->paragAt( fParag );
- if ( !p )
- return style;
- TQDataStream styleStream( style, IO_WriteOnly );
- int num = lParag - fParag + 1;
- styleStream << num;
- while ( num -- && p ) {
- p->writeStyleInformation( styleStream );
- p = p->next();
- }
-#endif
- return style;
-}
-
-void TQTextStyleCommand::writeStyleInformation( TQTextDocument* doc, int fParag, const TQByteArray& style )
-{
-#ifndef TQT_NO_DATASTREAM
- TQTextParagraph *p = doc->paragAt( fParag );
- if ( !p )
- return;
- TQDataStream styleStream( style, IO_ReadOnly );
- int num;
- styleStream >> num;
- while ( num-- && p ) {
- p->readStyleInformation( styleStream );
- p = p->next();
- }
-#endif
-}
-
-TQTextCursor *TQTextStyleCommand::execute( TQTextCursor *c )
-{
- writeStyleInformation( doc, firstParag, after );
- return c;
-}
-
-TQTextCursor *TQTextStyleCommand::unexecute( TQTextCursor *c )
-{
- writeStyleInformation( doc, firstParag, before );
- return c;
-}
-
-// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-TQTextCursor::TQTextCursor( TQTextDocument *d )
- : idx( 0 ), tmpX( -1 ), ox( 0 ), oy( 0 ),
- valid( TRUE )
-{
- para = d ? d->firstParagraph() : 0;
-}
-
-TQTextCursor::TQTextCursor( const TQTextCursor &c )
-{
- ox = c.ox;
- oy = c.oy;
- idx = c.idx;
- para = c.para;
- tmpX = c.tmpX;
- indices = c.indices;
- paras = c.paras;
- xOffsets = c.xOffsets;
- yOffsets = c.yOffsets;
- valid = c.valid;
-}
-
-TQTextCursor &TQTextCursor::operator=( const TQTextCursor &c )
-{
- ox = c.ox;
- oy = c.oy;
- idx = c.idx;
- para = c.para;
- tmpX = c.tmpX;
- indices = c.indices;
- paras = c.paras;
- xOffsets = c.xOffsets;
- yOffsets = c.yOffsets;
- valid = c.valid;
-
- return *this;
-}
-
-bool TQTextCursor::operator==( const TQTextCursor &c ) const
-{
- return para == c.para && idx == c.idx;
-}
-
-int TQTextCursor::totalOffsetX() const
-{
- int xoff = ox;
- for ( TQValueStack<int>::ConstIterator xit = xOffsets.begin(); xit != xOffsets.end(); ++xit )
- xoff += *xit;
- return xoff;
-}
-
-int TQTextCursor::totalOffsetY() const
-{
- int yoff = oy;
- for ( TQValueStack<int>::ConstIterator yit = yOffsets.begin(); yit != yOffsets.end(); ++yit )
- yoff += *yit;
- return yoff;
-}
-
-#ifndef TQT_NO_TEXTCUSTOMITEM
-void TQTextCursor::gotoIntoNested( const TQPoint &globalPos )
-{
- if ( !para )
- return;
- TQ_ASSERT( para->at( idx )->isCustom() );
- push();
- ox = 0;
- int bl, y;
- para->lineHeightOfChar( idx, &bl, &y );
- oy = y + para->rect().y();
- ox = para->at( idx )->x;
- TQTextDocument* doc = document();
- para->at( idx )->customItem()->enterAt( this, doc, para, idx, ox, oy, globalPos-TQPoint(ox,oy) );
-}
-#endif
-
-void TQTextCursor::invalidateNested()
-{
- if ( nestedDepth() ) {
- TQValueStack<TQTextParagraph*>::Iterator it = paras.begin();
- TQValueStack<int>::Iterator it2 = indices.begin();
- for ( ; it != paras.end(); ++it, ++it2 ) {
- if ( *it == para )
- continue;
- (*it)->tqinvalidate( 0 );
-#ifndef TQT_NO_TEXTCUSTOMITEM
- if ( (*it)->at( *it2 )->isCustom() )
- (*it)->at( *it2 )->customItem()->tqinvalidate();
-#endif
- }
- }
-}
-
-void TQTextCursor::insert( const QString &str, bool checkNewLine, TQMemArray<TQTextStringChar> *formatting )
-{
- tmpX = -1;
- bool justInsert = TRUE;
- TQString s( str );
-#if defined(TQ_WS_WIN)
- if ( checkNewLine ) {
- int i = 0;
- while ( ( i = s.find( '\r', i ) ) != -1 )
- s.remove( i ,1 );
- }
-#endif
- if ( checkNewLine )
- justInsert = s.find( '\n' ) == -1;
- if ( justInsert ) { // we ignore new lines and insert all in the current para at the current index
- para->insert( idx, s.tqunicode(), s.length() );
- if ( formatting ) {
- for ( int i = 0; i < (int)s.length(); ++i ) {
- if ( formatting->at( i ).format() ) {
- formatting->at( i ).format()->addRef();
- para->string()->setFormat( idx + i, formatting->at( i ).format(), TRUE );
- }
- }
- }
- idx += s.length();
- } else { // we split at new lines
- int start = -1;
- int end;
- int y = para->rect().y() + para->rect().height();
- int lastIndex = 0;
- do {
- end = s.find( '\n', start + 1 ); // find line break
- if ( end == -1 ) // didn't find one, so end of line is end of string
- end = s.length();
- int len = (start == -1 ? end : end - start - 1);
- if ( len > 0 ) // insert the line
- para->insert( idx, s.tqunicode() + start + 1, len );
- else
- para->tqinvalidate( 0 );
- if ( formatting ) { // set formats to the chars of the line
- for ( int i = 0; i < len; ++i ) {
- if ( formatting->at( i + lastIndex ).format() ) {
- formatting->at( i + lastIndex ).format()->addRef();
- para->string()->setFormat( i + idx, formatting->at( i + lastIndex ).format(), TRUE );
- }
- }
- lastIndex += len;
- }
- start = end; // next start is at the end of this line
- idx += len; // increase the index of the cursor to the end of the inserted text
- if ( s[end] == '\n' ) { // if at the end was a line break, break the line
- splitAndInsertEmptyParagraph( FALSE, TRUE );
- para->setEndState( -1 );
- para->prev()->format( -1, FALSE );
- lastIndex++;
- }
-
- } while ( end < (int)s.length() );
-
- para->format( -1, FALSE );
- int dy = para->rect().y() + para->rect().height() - y;
- TQTextParagraph *p = para;
- p->setParagId( p->prev() ? p->prev()->paragId() + 1 : 0 );
- p = p->next();
- while ( p ) {
- p->setParagId( p->prev()->paragId() + 1 );
- p->move( dy );
- p->tqinvalidate( 0 );
- p->setEndState( -1 );
- p = p->next();
- }
- }
-
- int h = para->rect().height();
- para->format( -1, TRUE );
- if ( h != para->rect().height() )
- invalidateNested();
- else if ( para->document() && para->document()->parent() )
- para->document()->nextDoubleBuffered = TRUE;
-
- fixCursorPosition();
-}
-
-void TQTextCursor::gotoLeft()
-{
- if ( para->string()->isRightToLeft() )
- gotoNextLetter();
- else
- gotoPreviousLetter();
-}
-
-void TQTextCursor::gotoPreviousLetter()
-{
- tmpX = -1;
-
- if ( idx > 0 ) {
- idx = para->string()->previousCursorPosition( idx );
-#ifndef TQT_NO_TEXTCUSTOMITEM
- const TQTextStringChar *tsc = para->at( idx );
- if ( tsc && tsc->isCustom() && tsc->customItem()->isNested() )
- processNesting( EnterEnd );
-#endif
- } else if ( para->prev() ) {
- para = para->prev();
- while ( !para->isVisible() && para->prev() )
- para = para->prev();
- idx = para->length() - 1;
- } else if ( nestedDepth() ) {
- pop();
- processNesting( Prev );
- if ( idx == -1 ) {
- pop();
- if ( idx > 0 ) {
- idx = para->string()->previousCursorPosition( idx );
-#ifndef TQT_NO_TEXTCUSTOMITEM
- const TQTextStringChar *tsc = para->at( idx );
- if ( tsc && tsc->isCustom() && tsc->customItem()->isNested() )
- processNesting( EnterEnd );
-#endif
- } else if ( para->prev() ) {
- para = para->prev();
- idx = para->length() - 1;
- }
- }
- }
-}
-
-void TQTextCursor::push()
-{
- indices.push( idx );
- paras.push( para );
- xOffsets.push( ox );
- yOffsets.push( oy );
-}
-
-void TQTextCursor::pop()
-{
- if ( indices.isEmpty() )
- return;
- idx = indices.pop();
- para = paras.pop();
- ox = xOffsets.pop();
- oy = yOffsets.pop();
-}
-
-void TQTextCursor::restoreState()
-{
- while ( !indices.isEmpty() )
- pop();
-}
-
-bool TQTextCursor::place( const TQPoint &p, TQTextParagraph *s, bool link, bool loosePlacing, bool matchBetweenCharacters )
-{
- TQPoint pos( p );
- TQRect r;
- TQTextParagraph *str = s;
- if ( pos.y() < s->rect().y() ) {
- pos.setY( s->rect().y() );
-#ifdef TQ_WS_MACX
- pos.setX( s->rect().x() );
-#endif
- }
- while ( s ) {
- r = s->rect();
- r.setWidth( document() ? document()->width() : TQWIDGETSIZE_MAX );
- if ( s->isVisible() )
- str = s;
- if ( pos.y() >= r.y() && pos.y() <= r.y() + r.height() )
- break;
- if ( loosePlacing == TRUE && !s->next() ) {
-#ifdef TQ_WS_MACX
- pos.setX( s->rect().x() + s->rect().width() );
-#endif
- break;
- }
- s = s->next();
- }
-
- if ( !s || !str )
- return FALSE;
-
- s = str;
-
- setParagraph( s );
- int y = s->rect().y();
- int lines = s->lines();
- TQTextStringChar *chr = 0;
- int index = 0;
- int i = 0;
- int cy = 0;
- int ch = 0;
- for ( ; i < lines; ++i ) {
- chr = s->lineStartOfLine( i, &index );
- cy = s->lineY( i );
- ch = s->lineHeight( i );
- if ( !chr )
- return FALSE;
- if ( pos.y() <= y + cy + ch )
- break;
- }
- int nextLine;
- if ( i < lines - 1 )
- s->lineStartOfLine( i+1, &nextLine );
- else
- nextLine = s->length();
- i = index;
- int x = s->rect().x();
- if ( pos.x() < x )
- pos.setX( x + 1 );
- int cw;
- int curpos = -1;
- int dist = 10000000;
- bool inCustom = FALSE;
- while ( i < nextLine ) {
- chr = s->at(i);
- int cpos = x + chr->x;
- cw = s->string()->width( i );
-#ifndef TQT_NO_TEXTCUSTOMITEM
- if ( chr->isCustom() && chr->customItem()->isNested() ) {
- if ( pos.x() >= cpos && pos.x() <= cpos + cw &&
- pos.y() >= y + cy && pos.y() <= y + cy + chr->height() ) {
- inCustom = TRUE;
- curpos = i;
- break;
- }
- } else
-#endif
- {
- if( chr->rightToLeft )
- cpos += cw;
- int d = cpos - pos.x();
- bool dm = d < 0 ? !chr->rightToLeft : chr->rightToLeft;
- if ( ( matchBetweenCharacters == TRUE && (TQABS( d ) < dist || (dist == d && dm == TRUE )) && para->string()->validCursorPosition( i ) ) ||
- ( matchBetweenCharacters == FALSE && ( d == 0 || dm == TRUE ) ) ) {
- dist = TQABS( d );
- if ( !link || ( pos.x() >= x + chr->x && ( loosePlacing == TRUE || pos.x() < cpos ) ) )
- curpos = i;
- }
- }
- i++;
- }
- if ( curpos == -1 ) {
- if ( loosePlacing == TRUE )
- curpos = s->length()-1;
- else
- return FALSE;
- }
- setIndex( curpos );
-
-#ifndef TQT_NO_TEXTCUSTOMITEM
- if ( inCustom && para->document() && para->at( curpos )->isCustom() && para->at( curpos )->customItem()->isNested() ) {
- TQTextDocument *oldDoc = para->document();
- gotoIntoNested( pos );
- if ( oldDoc == para->document() )
- return TRUE;
- TQPoint p( pos.x() - offsetX(), pos.y() - offsetY() );
- if ( !place( p, document()->firstParagraph(), link ) )
- pop();
- }
-#endif
- return TRUE;
-}
-
-bool TQTextCursor::processNesting( Operation op )
-{
- if ( !para->document() )
- return FALSE;
- TQTextDocument* doc = para->document();
- push();
- ox = para->at( idx )->x;
- int bl, y;
- para->lineHeightOfChar( idx, &bl, &y );
- oy = y + para->rect().y();
- bool ok = FALSE;
-
-#ifndef TQT_NO_TEXTCUSTOMITEM
- switch ( op ) {
- case EnterBegin:
- ok = para->at( idx )->customItem()->enter( this, doc, para, idx, ox, oy );
- break;
- case EnterEnd:
- ok = para->at( idx )->customItem()->enter( this, doc, para, idx, ox, oy, TRUE );
- break;
- case Next:
- ok = para->at( idx )->customItem()->next( this, doc, para, idx, ox, oy );
- break;
- case Prev:
- ok = para->at( idx )->customItem()->prev( this, doc, para, idx, ox, oy );
- break;
- case Down:
- ok = para->at( idx )->customItem()->down( this, doc, para, idx, ox, oy );
- break;
- case Up:
- ok = para->at( idx )->customItem()->up( this, doc, para, idx, ox, oy );
- break;
- }
- if ( !ok )
-#endif
- pop();
- return ok;
-}
-
-void TQTextCursor::gotoRight()
-{
- if ( para->string()->isRightToLeft() )
- gotoPreviousLetter();
- else
- gotoNextLetter();
-}
-
-void TQTextCursor::gotoNextLetter()
-{
- tmpX = -1;
-
-#ifndef TQT_NO_TEXTCUSTOMITEM
- const TQTextStringChar *tsc = para->at( idx );
- if ( tsc && tsc->isCustom() && tsc->customItem()->isNested() ) {
- if ( processNesting( EnterBegin ) )
- return;
- }
-#endif
-
- if ( idx < para->length() - 1 ) {
- idx = para->string()->nextCursorPosition( idx );
- } else if ( para->next() ) {
- para = para->next();
- while ( !para->isVisible() && para->next() )
- para = para->next();
- idx = 0;
- } else if ( nestedDepth() ) {
- pop();
- processNesting( Next );
- if ( idx == -1 ) {
- pop();
- if ( idx < para->length() - 1 ) {
- idx = para->string()->nextCursorPosition( idx );
- } else if ( para->next() ) {
- para = para->next();
- idx = 0;
- }
- }
- }
-}
-
-void TQTextCursor::gotoUp()
-{
- int indexOfLineStart;
- int line;
- TQTextStringChar *c = para->lineStartOfChar( idx, &indexOfLineStart, &line );
- if ( !c )
- return;
-
- if (tmpX < 0)
- tmpX = x();
-
- if ( indexOfLineStart == 0 ) {
- if ( !para->prev() ) {
- if ( !nestedDepth() )
- return;
- pop();
- processNesting( Up );
- if ( idx == -1 ) {
- pop();
- if ( !para->prev() )
- return;
- idx = tmpX = 0;
- } else {
- tmpX = -1;
- return;
- }
- }
- TQTextParagraph *p = para->prev();
- while ( p && !p->isVisible() )
- p = p->prev();
- if ( p )
- para = p;
- int lastLine = para->lines() - 1;
- if ( !para->lineStartOfLine( lastLine, &indexOfLineStart ) )
- return;
- idx = indexOfLineStart;
- while (idx < para->length()-1 && para->at(idx)->x < tmpX)
- ++idx;
- if (idx > indexOfLineStart &&
- para->at(idx)->x - tmpX > tmpX - para->at(idx-1)->x)
- --idx;
- } else {
- --line;
- int oldIndexOfLineStart = indexOfLineStart;
- if ( !para->lineStartOfLine( line, &indexOfLineStart ) )
- return;
- idx = indexOfLineStart;
- while (idx < oldIndexOfLineStart-1 && para->at(idx)->x < tmpX)
- ++idx;
- if (idx > indexOfLineStart &&
- para->at(idx)->x - tmpX > tmpX - para->at(idx-1)->x)
- --idx;
- }
- fixCursorPosition();
-}
-
-void TQTextCursor::gotoDown()
-{
- int indexOfLineStart;
- int line;
- TQTextStringChar *c = para->lineStartOfChar( idx, &indexOfLineStart, &line );
- if ( !c )
- return;
-
- if (tmpX < 0)
- tmpX = x();
- if ( line == para->lines() - 1 ) {
- if ( !para->next() ) {
- if ( !nestedDepth() )
- return;
- pop();
- processNesting( Down );
- if ( idx == -1 ) {
- pop();
- if ( !para->next() )
- return;
- idx = tmpX = 0;
- } else {
- tmpX = -1;
- return;
- }
- }
- TQTextParagraph *s = para->next();
- while ( s && !s->isVisible() )
- s = s->next();
- if ( s )
- para = s;
- if ( !para->lineStartOfLine( 0, &indexOfLineStart ) )
- return;
- int end;
- if ( para->lines() == 1 )
- end = para->length();
- else
- para->lineStartOfLine( 1, &end );
-
- idx = indexOfLineStart;
- while (idx < end-1 && para->at(idx)->x < tmpX)
- ++idx;
- if (idx > indexOfLineStart &&
- para->at(idx)->x - tmpX > tmpX - para->at(idx-1)->x)
- --idx;
- } else {
- ++line;
- int end;
- if ( line == para->lines() - 1 )
- end = para->length();
- else
- para->lineStartOfLine( line + 1, &end );
- if ( !para->lineStartOfLine( line, &indexOfLineStart ) )
- return;
- idx = indexOfLineStart;
- while (idx < end-1 && para->at(idx)->x < tmpX)
- ++idx;
- if (idx > indexOfLineStart &&
- para->at(idx)->x - tmpX > tmpX - para->at(idx-1)->x)
- --idx;
- }
- fixCursorPosition();
-}
-
-void TQTextCursor::gotoLineEnd()
-{
- tmpX = -1;
- int indexOfLineStart;
- int line;
- TQTextStringChar *c = para->lineStartOfChar( idx, &indexOfLineStart, &line );
- if ( !c )
- return;
-
- if ( line == para->lines() - 1 ) {
- idx = para->length() - 1;
- } else {
- c = para->lineStartOfLine( ++line, &indexOfLineStart );
- indexOfLineStart--;
- idx = indexOfLineStart;
- }
-}
-
-void TQTextCursor::gotoLineStart()
-{
- tmpX = -1;
- int indexOfLineStart;
- int line;
- TQTextStringChar *c = para->lineStartOfChar( idx, &indexOfLineStart, &line );
- if ( !c )
- return;
-
- idx = indexOfLineStart;
-}
-
-void TQTextCursor::gotoHome()
-{
- if ( topParagraph()->document() )
- gotoPosition( topParagraph()->document()->firstParagraph() );
- else
- gotoLineStart();
-}
-
-void TQTextCursor::gotoEnd()
-{
- if ( topParagraph()->document() && topParagraph()->document()->lastParagraph()->isValid() )
- gotoPosition( topParagraph()->document()->lastParagraph(),
- topParagraph()->document()->lastParagraph()->length() - 1);
- else
- gotoLineEnd();
-}
-
-void TQTextCursor::gotoPageUp( int visibleHeight )
-{
- int targetY = globalY() - visibleHeight;
- TQTextParagraph* old; int index;
- do {
- old = para; index = idx;
- gotoUp();
- } while ( (old != para || index != idx) && globalY() > targetY );
-}
-
-void TQTextCursor::gotoPageDown( int visibleHeight )
-{
- int targetY = globalY() + visibleHeight;
- TQTextParagraph* old; int index;
- do {
- old = para; index = idx;
- gotoDown();
- } while ( (old != para || index != idx) && globalY() < targetY );
-}
-
-void TQTextCursor::gotoWordRight()
-{
- if ( para->string()->isRightToLeft() )
- gotoPreviousWord();
- else
- gotoNextWord();
-}
-
-void TQTextCursor::gotoWordLeft()
-{
- if ( para->string()->isRightToLeft() )
- gotoNextWord();
- else
- gotoPreviousWord();
-}
-
-static bool is_seperator( const TQChar &c, bool onlySpace )
-{
- if ( onlySpace )
- return c.isSpace();
- return c.isSpace() ||
- c == '\t' ||
- c == '.' ||
- c == ',' ||
- c == ':' ||
- c == ';' ||
- c == '-' ||
- c == '<' ||
- c == '>' ||
- c == '[' ||
- c == ']' ||
- c == '(' ||
- c == ')' ||
- c == '{' ||
- c == '}';
-}
-
-void TQTextCursor::gotoPreviousWord( bool onlySpace )
-{
- gotoPreviousLetter();
- tmpX = -1;
- TQTextString *s = para->string();
- bool allowSame = FALSE;
- if ( idx == ((int)s->length()-1) )
- return;
- for ( int i = idx; i >= 0; --i ) {
- if ( is_seperator( s->at( i ).c, onlySpace ) ) {
- if ( !allowSame )
- continue;
- idx = i + 1;
- return;
- }
- if ( !allowSame && !is_seperator( s->at( i ).c, onlySpace ) )
- allowSame = TRUE;
- }
- idx = 0;
-}
-
-void TQTextCursor::gotoNextWord( bool onlySpace )
-{
- tmpX = -1;
- TQTextString *s = para->string();
- bool allowSame = FALSE;
- for ( int i = idx; i < (int)s->length(); ++i ) {
- if ( !is_seperator( s->at( i ).c, onlySpace ) ) {
- if ( !allowSame )
- continue;
- idx = i;
- return;
- }
- if ( !allowSame && is_seperator( s->at( i ).c, onlySpace ) )
- allowSame = TRUE;
-
- }
-
- if ( idx < ((int)s->length()-1) ) {
- gotoLineEnd();
- } else if ( para->next() ) {
- TQTextParagraph *p = para->next();
- while ( p && !p->isVisible() )
- p = p->next();
- if ( s ) {
- para = p;
- idx = 0;
- }
- } else {
- gotoLineEnd();
- }
-}
-
-bool TQTextCursor::atParagStart()
-{
- return idx == 0;
-}
-
-bool TQTextCursor::atParagEnd()
-{
- return idx == para->length() - 1;
-}
-
-void TQTextCursor::splitAndInsertEmptyParagraph( bool ind, bool updateIds )
-{
- if ( !para->document() )
- return;
- tmpX = -1;
- TQTextFormat *f = 0;
- if ( para->document()->useFormatCollection() ) {
- f = para->at( idx )->format();
- if ( idx == para->length() - 1 && idx > 0 )
- f = para->at( idx - 1 )->format();
- if ( f->isMisspelled() ) {
- f->removeRef();
- f = para->document()->formatCollection()->format( f->font(), f->color() );
- }
- }
-
- if ( atParagEnd() ) {
- TQTextParagraph *n = para->next();
- TQTextParagraph *s = para->document()->createParagraph( para->document(), para, n, updateIds );
- if ( f )
- s->setFormat( 0, 1, f, TRUE );
- s->copyParagData( para );
- if ( ind ) {
- int oi, ni;
- s->indent( &oi, &ni );
- para = s;
- idx = ni;
- } else {
- para = s;
- idx = 0;
- }
- } else if ( atParagStart() ) {
- TQTextParagraph *p = para->prev();
- TQTextParagraph *s = para->document()->createParagraph( para->document(), p, para, updateIds );
- if ( f )
- s->setFormat( 0, 1, f, TRUE );
- s->copyParagData( para );
- if ( ind ) {
- s->indent();
- s->format();
- indent();
- para->format();
- }
- } else {
- TQString str = para->string()->toString().mid( idx, 0xFFFFFF );
- TQTextParagraph *n = para->next();
- TQTextParagraph *s = para->document()->createParagraph( para->document(), para, n, updateIds );
- s->copyParagData( para );
- s->remove( 0, 1 );
- s->append( str, TRUE );
- for ( int i = 0; i < str.length(); ++i ) {
- TQTextStringChar* tsc = para->at( idx + i );
- s->setFormat( i, 1, tsc->format(), TRUE );
-#ifndef TQT_NO_TEXTCUSTOMITEM
- if ( tsc->isCustom() ) {
- TQTextCustomItem * item = tsc->customItem();
- s->at( i )->setCustomItem( item );
- tsc->loseCustomItem();
- }
-#endif
- if ( tsc->isAnchor() )
- s->at( i )->setAnchor( tsc->anchorName(),
- tsc->anchorHref() );
- }
- para->truncate( idx );
- if ( ind ) {
- int oi, ni;
- s->indent( &oi, &ni );
- para = s;
- idx = ni;
- } else {
- para = s;
- idx = 0;
- }
- }
-
- invalidateNested();
-}
-
-bool TQTextCursor::remove()
-{
- tmpX = -1;
- if ( !atParagEnd() ) {
- int next = para->string()->nextCursorPosition( idx );
- para->remove( idx, next-idx );
- int h = para->rect().height();
- para->format( -1, TRUE );
- if ( h != para->rect().height() )
- invalidateNested();
- else if ( para->document() && para->document()->parent() )
- para->document()->nextDoubleBuffered = TRUE;
- return FALSE;
- } else if ( para->next() ) {
- para->join( para->next() );
- invalidateNested();
- return TRUE;
- }
- return FALSE;
-}
-
-/* needed to implement backspace the correct way */
-bool TQTextCursor::removePreviousChar()
-{
- tmpX = -1;
- if ( !atParagStart() ) {
- para->remove( idx-1, 1 );
- int h = para->rect().height();
- idx--;
- // shouldn't be needed, just to make sure.
- fixCursorPosition();
- para->format( -1, TRUE );
- if ( h != para->rect().height() )
- invalidateNested();
- else if ( para->document() && para->document()->parent() )
- para->document()->nextDoubleBuffered = TRUE;
- return FALSE;
- } else if ( para->prev() ) {
- para = para->prev();
- para->join( para->next() );
- invalidateNested();
- return TRUE;
- }
- return FALSE;
-}
-
-void TQTextCursor::indent()
-{
- int oi = 0, ni = 0;
- para->indent( &oi, &ni );
- if ( oi == ni )
- return;
-
- if ( idx >= oi )
- idx += ni - oi;
- else
- idx = ni;
-}
-
-void TQTextCursor::fixCursorPosition()
-{
- // searches for the closest valid cursor position
- if ( para->string()->validCursorPosition( idx ) )
- return;
-
- int lineIdx;
- TQTextStringChar *start = para->lineStartOfChar( idx, &lineIdx, 0 );
- int x = para->string()->at( idx ).x;
- int diff = TQABS(start->x - x);
- int best = lineIdx;
-
- TQTextStringChar *c = start;
- ++c;
-
- TQTextStringChar *end = &para->string()->at( para->length()-1 );
- while ( c <= end && !c->lineStart ) {
- int xp = c->x;
- if ( c->rightToLeft )
- xp += para->string()->width( lineIdx + (c-start) );
- int ndiff = TQABS(xp - x);
- if ( ndiff < diff && para->string()->validCursorPosition(lineIdx + (c-start)) ) {
- diff = ndiff;
- best = lineIdx + (c-start);
- }
- ++c;
- }
- idx = best;
-}
-
-
-// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-TQTextDocument::TQTextDocument( TQTextDocument *p )
- : par( p ), parentPar( 0 )
-#ifndef TQT_NO_TEXTCUSTOMITEM
- , tc( 0 )
-#endif
- , tArray( 0 ), tStopWidth( 0 )
-{
- fCollection = par ? par->fCollection : new TQTextFormatCollection;
- init();
-}
-
-void TQTextDocument::init()
-{
- oTextValid = TRUE;
- mightHaveCustomItems = FALSE;
- if ( par )
- par->insertChild( this );
- pProcessor = 0;
- useFC = TRUE;
- pFormatter = 0;
- indenter = 0;
- fParag = 0;
- txtFormat = TQt::AutoText;
- preferRichText = FALSE;
- pages = FALSE;
- focusIndicator.parag = 0;
- minw = 0;
- wused = 0;
- minwParag = curParag = 0;
- align = TQt::AlignAuto;
- nSelections = 1;
-
- setStyleSheet( TQStyleSheet::defaultSheet() );
-#ifndef TQT_NO_MIME
- factory_ = TQMimeSourceFactory::defaultFactory();
-#endif
- contxt = TQString::null;
-
- underlLinks = par ? par->underlLinks : TRUE;
- backBrush = 0;
- buf_pixmap = 0;
- nextDoubleBuffered = FALSE;
-
- if ( par )
- withoutDoubleBuffer = par->withoutDoubleBuffer;
- else
- withoutDoubleBuffer = FALSE;
-
- lParag = fParag = createParagraph( this, 0, 0 );
-
- cx = 0;
- cy = 2;
- if ( par )
- cx = cy = 0;
- cw = 600;
- vw = 0;
- flow_ = new TQTextFlow;
- flow_->setWidth( cw );
-
- leftmargin = rightmargin = 4;
- scaleFontsFactor = 1;
-
-
- selectionColors[ Standard ] = TQApplication::palette().color( TQPalette::Active, TQColorGroup::Highlight );
- selectionText[ Standard ] = TRUE;
- selectionText[ IMSelectionText ] = TRUE;
- selectionText[ IMCompositionText ] = FALSE;
- commandHistory = new TQTextCommandHistory( 100 );
- tStopWidth = formatCollection()->defaultFormat()->width( 'x' ) * 8;
-}
-
-TQTextDocument::~TQTextDocument()
-{
- delete commandHistory;
- if ( par )
- par->removeChild( this );
- clear();
- delete flow_;
- if ( !par ) {
- delete pFormatter;
- delete fCollection;
- }
- delete pProcessor;
- delete buf_pixmap;
- delete indenter;
- delete backBrush;
- delete [] tArray;
-}
-
-void TQTextDocument::clear( bool createEmptyParag )
-{
- while ( fParag ) {
- TQTextParagraph *p = fParag->next();
- delete fParag;
- fParag = p;
- }
- if ( flow_ )
- flow_->clear();
- fParag = lParag = 0;
- if ( createEmptyParag )
- fParag = lParag = createParagraph( this );
- focusIndicator.parag = 0;
- selections.clear();
- oText = TQString::null;
- oTextValid = FALSE;
-}
-
-int TQTextDocument::widthUsed() const
-{
- return wused + 2*border_tolerance;
-}
-
-int TQTextDocument::height() const
-{
- int h = 0;
- if ( lParag )
- h = lParag->rect().top() + lParag->rect().height() + 1;
- int fh = flow_->boundingRect().bottom();
- return TQMAX( h, fh );
-}
-
-
-
-TQTextParagraph *TQTextDocument::createParagraph( TQTextDocument *d, TQTextParagraph *pr, TQTextParagraph *nx, bool updateIds )
-{
- return new TQTextParagraph( d, pr, nx, updateIds );
-}
-
-bool TQTextDocument::setMinimumWidth( int needed, int used, TQTextParagraph *p )
-{
- if ( needed == -1 ) {
- minw = 0;
- wused = 0;
- p = 0;
- }
- if ( p == minwParag ) {
- if (minw > needed) {
- TQTextParagraph *tp = fParag;
- while (tp) {
- if (tp != p && tp->minwidth > needed) {
- needed = tp->minwidth;
- minwParag = tp;
- }
- tp = tp->n;
- }
- }
- minw = needed;
- emit minimumWidthChanged( minw );
- } else if ( needed > minw ) {
- minw = needed;
- minwParag = p;
- emit minimumWidthChanged( minw );
- }
- wused = TQMAX( wused, used );
- wused = TQMAX( wused, minw );
- cw = TQMAX( minw, cw );
- return TRUE;
-}
-
-void TQTextDocument::setPlainText( const TQString &text )
-{
- preferRichText = FALSE;
- clear();
- oTextValid = TRUE;
- oText = text;
-
- int lastNl = 0;
- int nl = text.find( '\n' );
- if ( nl == -1 ) {
- lParag = createParagraph( this, lParag, 0 );
- if ( !fParag )
- fParag = lParag;
- TQString s = text;
- if ( !s.isEmpty() ) {
- if ( s[ (int)s.length() - 1 ] == '\r' )
- s.remove( s.length() - 1, 1 );
- lParag->append( s );
- }
- } else {
- for (;;) {
- lParag = createParagraph( this, lParag, 0 );
- if ( !fParag )
- fParag = lParag;
- int l = nl - lastNl;
- if ( l > 0 ) {
- if (text.tqunicode()[nl-1] == '\r')
- l--;
- TQConstString cs(text.tqunicode()+lastNl, l);
- lParag->append( cs.string() );
- }
- if ( nl == (int)text.length() )
- break;
- lastNl = nl + 1;
- nl = text.find( '\n', nl + 1 );
- if ( nl == -1 )
- nl = text.length();
- }
- }
- if ( !lParag )
- lParag = fParag = createParagraph( this, 0, 0 );
-}
-
-struct TQ_EXPORT TQTextDocumentTag {
- TQTextDocumentTag(){}
- TQTextDocumentTag( const TQString&n, const TQStyleSheetItem* s, const TQTextFormat& f )
- :name(n),style(s), format(f), tqalignment(TQt::AlignAuto), direction(TQChar::DirON),liststyle(TQStyleSheetItem::ListDisc) {
- wsm = TQStyleSheetItem::WhiteSpaceNormal;
- }
- TQString name;
- const TQStyleSheetItem* style;
- TQString anchorHref;
- TQStyleSheetItem::WhiteSpaceMode wsm;
- TQTextFormat format;
- int tqalignment : 16;
- int direction : 5;
- TQStyleSheetItem::ListStyle liststyle;
-
- TQTextDocumentTag( const TQTextDocumentTag& t ) {
- name = t.name;
- style = t.style;
- anchorHref = t.anchorHref;
- wsm = t.wsm;
- format = t.format;
- tqalignment = t.tqalignment;
- direction = t.direction;
- liststyle = t.liststyle;
- }
- TQTextDocumentTag& operator=(const TQTextDocumentTag& t) {
- name = t.name;
- style = t.style;
- anchorHref = t.anchorHref;
- wsm = t.wsm;
- format = t.format;
- tqalignment = t.tqalignment;
- direction = t.direction;
- liststyle = t.liststyle;
- return *this;
- }
-
- TQ_DUMMY_COMPARISON_OPERATOR(TQTextDocumentTag)
-};
-
-
-#define NEWPAR do{ if ( !hasNewPar) { \
- if ( !textEditMode && curpar && curpar->length()>1 && curpar->at( curpar->length()-2)->c == TQChar_linesep ) \
- curpar->remove( curpar->length()-2, 1 ); \
- curpar = createParagraph( this, curpar, curpar->next() ); styles.append( vec ); vec = 0;} \
- hasNewPar = TRUE; \
- curpar->rtext = TRUE; \
- curpar->align = curtag.tqalignment; \
- curpar->lstyle = curtag.liststyle; \
- curpar->litem = ( curtag.style->displayMode() == TQStyleSheetItem::DisplayListItem ); \
- curpar->str->setDirection( (TQChar::Direction)curtag.direction ); \
- space = TRUE; \
- tabExpansionColumn = 0; \
- delete vec; vec = new TQPtrVector<TQStyleSheetItem>( (uint)tags.count() + 1); \
- int i = 0; \
- for ( TQValueStack<TQTextDocumentTag>::Iterator it = tags.begin(); it != tags.end(); ++it ) \
- vec->insert( i++, (*it).style ); \
- vec->insert( i, curtag.style ); \
- }while(FALSE);
-
-
-void TQTextDocument::setRichText( const TQString &text, const TQString &context, const TQTextFormat *initialFormat )
-{
- preferRichText = TRUE;
- if ( !context.isEmpty() )
- setContext( context );
- clear();
- fParag = lParag = createParagraph( this );
- oTextValid = TRUE;
- oText = text;
- setRichTextInternal( text, 0, initialFormat );
- fParag->rtext = TRUE;
-}
-
-void TQTextDocument::setRichTextInternal( const TQString &text, TQTextCursor* cursor, const TQTextFormat *initialFormat )
-{
- TQTextParagraph* curpar = lParag;
- int pos = 0;
- TQValueStack<TQTextDocumentTag> tags;
- if ( !initialFormat )
- initialFormat = formatCollection()->defaultFormat();
- TQTextDocumentTag initag( "", sheet_->item(""), *initialFormat );
- if ( bodyText.isValid() )
- initag.format.setColor( bodyText );
- TQTextDocumentTag curtag = initag;
- bool space = TRUE;
- bool canMergeLi = FALSE;
-
- bool textEditMode = FALSE;
- int tabExpansionColumn = 0;
-
- const TQChar* doc = text.tqunicode();
- int length = text.length();
- bool hasNewPar = curpar->length() <= 1;
- TQString anchorName;
-
- // style sheet handling for margin and line spacing calculation below
- TQTextParagraph* stylesPar = curpar;
- TQPtrVector<TQStyleSheetItem>* vec = 0;
- TQPtrList< TQPtrVector<TQStyleSheetItem> > styles;
- styles.setAutoDelete( TRUE );
-
- if ( cursor ) {
- cursor->splitAndInsertEmptyParagraph();
- TQTextCursor tmp = *cursor;
- tmp.gotoPreviousLetter();
- stylesPar = curpar = tmp.paragraph();
- hasNewPar = TRUE;
- textEditMode = TRUE;
- } else {
- NEWPAR;
- }
-
- // set rtext spacing to FALSE for the initial paragraph.
- curpar->rtext = FALSE;
-
- TQString wellKnownTags = "br hr wsp table qt body meta title";
-
- while ( pos < length ) {
- if ( hasPrefix(doc, length, pos, '<' ) ){
- if ( !hasPrefix( doc, length, pos+1, TQChar('/') ) ) {
- // open tag
- QMap<TQString, TQString> attr;
- bool emptyTag = FALSE;
- TQString tagname = parseOpenTag(doc, length, pos, attr, emptyTag);
- if ( tagname.isEmpty() )
- continue; // nothing we could do with this, probably parse error
-
- const TQStyleSheetItem* nstyle = sheet_->item(tagname);
-
- if ( nstyle ) {
- // we might have to close some 'forgotten' tags
- while ( !nstyle->allowedInContext( curtag.style ) ) {
- TQString msg;
- msg.sprintf( "TQText Warning: Document not valid ( '%s' not allowed in '%s' #%d)",
- tagname.ascii(), curtag.style->name().ascii(), pos);
- sheet_->error( msg );
- if ( tags.isEmpty() )
- break;
- curtag = tags.pop();
- }
-
- /* special handling for p and li for HTML
- compatibility. We do not want to embed blocks in
- p, and we do not want new blocks inside non-empty
- lis. Plus we want to merge empty lis sometimes. */
- if( nstyle->displayMode() == TQStyleSheetItem::DisplayListItem ) {
- canMergeLi = TRUE;
- } else if ( nstyle->displayMode() == TQStyleSheetItem::DisplayBlock ) {
- while ( curtag.style->name() == "p" ) {
- if ( tags.isEmpty() )
- break;
- curtag = tags.pop();
- }
-
- if ( curtag.style->displayMode() == TQStyleSheetItem::DisplayListItem ) {
- // we are in a li and a new block comes along
- if ( nstyle->name() == "ul" || nstyle->name() == "ol" )
- hasNewPar = FALSE; // we want an empty li (like most browsers)
- if ( !hasNewPar ) {
- /* do not add new blocks inside
- non-empty lis */
- while ( curtag.style->displayMode() == TQStyleSheetItem::DisplayListItem ) {
- if ( tags.isEmpty() )
- break;
- curtag = tags.pop();
- }
- } else if ( canMergeLi ) {
- /* we have an empty li and a block
- comes along, merge them */
- nstyle = curtag.style;
- }
- canMergeLi = FALSE;
- }
- }
- }
-
-#ifndef TQT_NO_TEXTCUSTOMITEM
- TQTextCustomItem* custom = 0;
-#else
- bool custom = FALSE;
-#endif
-
- // some well-known tags, some have a nstyle, some not
- if ( wellKnownTags.find( tagname ) != -1 ) {
- if ( tagname == "br" ) {
- emptyTag = space = TRUE;
- int index = TQMAX( curpar->length(),1) - 1;
- TQTextFormat format = curtag.format.makeTextFormat( nstyle, attr, scaleFontsFactor );
- curpar->append( TQChar_linesep );
- curpar->setFormat( index, 1, &format );
- hasNewPar = false;
- } else if ( tagname == "hr" ) {
- emptyTag = space = TRUE;
-#ifndef TQT_NO_TEXTCUSTOMITEM
- custom = sheet_->tag( tagname, attr, contxt, *factory_ , emptyTag, this );
-#endif
- } else if ( tagname == "table" ) {
- emptyTag = space = TRUE;
-#ifndef TQT_NO_TEXTCUSTOMITEM
- TQTextFormat format = curtag.format.makeTextFormat( nstyle, attr, scaleFontsFactor );
- curpar->tqsetAlignment( curtag.tqalignment );
- custom = parseTable( attr, format, doc, length, pos, curpar );
-#endif
- } else if ( tagname == "qt" || tagname == "body" ) {
- if ( attr.contains( "bgcolor" ) ) {
- TQBrush *b = new TQBrush( TQColor( attr["bgcolor"] ) );
- setPaper( b );
- }
- if ( attr.contains( "background" ) ) {
-#ifndef TQT_NO_MIME
- TQImage img;
- TQString bg = attr["background"];
- const TQMimeSource* m = factory_->data( bg, contxt );
- if ( !m ) {
- qWarning("TQRichText: no mimesource for %s", bg.latin1() );
- } else {
- if ( !TQImageDrag::decode( m, img ) ) {
- qWarning("TQTextImage: cannot decode %s", bg.latin1() );
- }
- }
- if ( !img.isNull() ) {
- TQBrush *b = new TQBrush( TQColor(), TQPixmap( img ) );
- setPaper( b );
- }
-#endif
- }
- if ( attr.contains( "text" ) ) {
- TQColor c( attr["text"] );
- initag.format.setColor( c );
- curtag.format.setColor( c );
- bodyText = c;
- }
- if ( attr.contains( "link" ) )
- linkColor = TQColor( attr["link"] );
- if ( attr.contains( "title" ) )
- attribs.replace( "title", attr["title"] );
-
- if ( textEditMode ) {
- if ( attr.contains("style" ) ) {
- TQString a = attr["style"];
- for ( int s = 0; s < a.contains(';')+1; s++ ) {
- TQString style = a.section( ';', s, s );
- if ( style.startsWith("font-size:" ) && style.endsWith("pt") ) {
- scaleFontsFactor = double( formatCollection()->defaultFormat()->fn.pointSize() ) /
- style.mid( 10, style.length() - 12 ).toInt();
- }
- }
- }
- nstyle = 0; // ignore body in textEditMode
- }
- // end qt- and body-tag handling
- } else if ( tagname == "meta" ) {
- if ( attr["name"] == "qrichtext" && attr["content"] == "1" )
- textEditMode = TRUE;
- } else if ( tagname == "title" ) {
- TQString title;
- while ( pos < length ) {
- if ( hasPrefix( doc, length, pos, TQChar('<') ) && hasPrefix( doc, length, pos+1, TQChar('/') ) &&
- parseCloseTag( doc, length, pos ) == "title" )
- break;
- title += doc[ pos ];
- ++pos;
- }
- attribs.replace( "title", title );
- }
- } // end of well-known tag handling
-
-#ifndef TQT_NO_TEXTCUSTOMITEM
- if ( !custom ) // try generic custom item
- custom = sheet_->tag( tagname, attr, contxt, *factory_ , emptyTag, this );
-#endif
- if ( !nstyle && !custom ) // we have no clue what this tag could be, ignore it
- continue;
-
- if ( custom ) {
-#ifndef TQT_NO_TEXTCUSTOMITEM
- int index = TQMAX( curpar->length(),1) - 1;
- TQTextFormat format = curtag.format.makeTextFormat( nstyle, attr, scaleFontsFactor );
- curpar->append( TQChar('*') );
- TQTextFormat* f = formatCollection()->format( &format );
- curpar->setFormat( index, 1, f );
- curpar->at( index )->setCustomItem( custom );
- if ( !curtag.anchorHref.isEmpty() )
- curpar->at(index)->setAnchor( TQString::null, curtag.anchorHref );
- if ( !anchorName.isEmpty() ) {
- curpar->at(index)->setAnchor( anchorName, curpar->at(index)->anchorHref() );
- anchorName = TQString::null;
- }
- registerCustomItem( custom, curpar );
- hasNewPar = FALSE;
-#endif
- } else if ( !emptyTag ) {
- /* if we do nesting, push curtag on the stack,
- otherwise reinint curag. */
- if ( curtag.style->name() != tagname || nstyle->selfNesting() ) {
- tags.push( curtag );
- } else {
- if ( !tags.isEmpty() )
- curtag = tags.top();
- else
- curtag = initag;
- }
-
- curtag.name = tagname;
- curtag.style = nstyle;
- curtag.name = tagname;
- curtag.style = nstyle;
- if ( nstyle->whiteSpaceMode() != TQStyleSheetItem::WhiteSpaceModeUndefined )
- curtag.wsm = nstyle->whiteSpaceMode();
-
- /* netscape compatibility: eat a newline and only a newline if a pre block starts */
- if ( curtag.wsm == TQStyleSheetItem::WhiteSpacePre &&
- nstyle->displayMode() == TQStyleSheetItem::DisplayBlock )
- eat( doc, length, pos, '\n' );
-
- /* ignore whitespace for inline elements if there
- was already one*/
- if ( !textEditMode &&
- (curtag.wsm == TQStyleSheetItem::WhiteSpaceNormal
- || curtag.wsm == TQStyleSheetItem::WhiteSpaceNoWrap)
- && ( space || nstyle->displayMode() != TQStyleSheetItem::DisplayInline ) )
- eatSpace( doc, length, pos );
-
- curtag.format = curtag.format.makeTextFormat( nstyle, attr, scaleFontsFactor );
- if ( nstyle->isAnchor() ) {
- if ( !anchorName.isEmpty() )
- anchorName += "#" + attr["name"];
- else
- anchorName = attr["name"];
- curtag.anchorHref = attr["href"];
- }
-
- if ( nstyle->tqalignment() != TQStyleSheetItem::Undefined )
- curtag.tqalignment = nstyle->tqalignment();
-
- if ( nstyle->listStyle() != TQStyleSheetItem::ListStyleUndefined )
- curtag.liststyle = nstyle->listStyle();
-
- if ( nstyle->displayMode() == TQStyleSheetItem::DisplayBlock
- || nstyle->displayMode() == TQStyleSheetItem::DisplayListItem ) {
-
- if ( nstyle->name() == "ol" || nstyle->name() == "ul" || nstyle->name() == "li") {
- TQString type = attr["type"];
- if ( !type.isEmpty() ) {
- if ( type == "1" ) {
- curtag.liststyle = TQStyleSheetItem::ListDecimal;
- } else if ( type == "a" ) {
- curtag.liststyle = TQStyleSheetItem::ListLowerAlpha;
- } else if ( type == "A" ) {
- curtag.liststyle = TQStyleSheetItem::ListUpperAlpha;
- } else {
- type = type.lower();
- if ( type == "square" )
- curtag.liststyle = TQStyleSheetItem::ListSquare;
- else if ( type == "disc" )
- curtag.liststyle = TQStyleSheetItem::ListDisc;
- else if ( type == "circle" )
- curtag.liststyle = TQStyleSheetItem::ListCircle;
- }
- }
- }
-
-
- /* Internally we treat ordered and bullet
- lists the same for margin calculations. In
- order to have fast pointer compares in the
- xMargin() functions we restrict ourselves to
- <ol>. Once we calculate the margins in the
- parser rathern than later, the unelegance of
- this approach goes awy
- */
- if ( nstyle->name() == "ul" )
- curtag.style = sheet_->item( "ol" );
-
- if ( attr.contains( "align" ) ) {
- TQString align = attr["align"].lower();
- if ( align == "center" )
- curtag.tqalignment = TQt::AlignCenter;
- else if ( align == "right" )
- curtag.tqalignment = TQt::AlignRight;
- else if ( align == "justify" )
- curtag.tqalignment = TQt::AlignJustify;
- }
- if ( attr.contains( "dir" ) ) {
- TQString dir = attr["dir"];
- if ( dir == "rtl" )
- curtag.direction = TQChar::DirR;
- else if ( dir == "ltr" )
- curtag.direction = TQChar::DirL;
- }
-
- NEWPAR;
-
- if ( curtag.style->displayMode() == TQStyleSheetItem::DisplayListItem ) {
- if ( attr.contains( "value " ) )
- curpar->setListValue( attr["value"].toInt() );
- }
-
- if ( attr.contains( "style" ) ) {
- TQString a = attr["style"];
- bool ok = TRUE;
- for ( int s = 0; ok && s < a.contains(';')+1; s++ ) {
- TQString style = a.section( ';', s, s );
- if ( style.startsWith("margin-top:" ) && style.endsWith("px") )
- curpar->utm = 1+style.mid(11, style.length() - 13).toInt(&ok);
- else if ( style.startsWith("margin-bottom:" ) && style.endsWith("px") )
- curpar->ubm = 1+style.mid(14, style.length() - 16).toInt(&ok);
- else if ( style.startsWith("margin-left:" ) && style.endsWith("px") )
- curpar->ulm = 1+style.mid(12, style.length() - 14).toInt(&ok);
- else if ( style.startsWith("margin-right:" ) && style.endsWith("px") )
- curpar->urm = 1+style.mid(13, style.length() - 15).toInt(&ok);
- else if ( style.startsWith("text-indent:" ) && style.endsWith("px") )
- curpar->uflm = 1+style.mid(12, style.length() - 14).toInt(&ok);
- }
- if ( !ok ) // be pressmistic
- curpar->utm = curpar->ubm = curpar->urm = curpar->ulm = 0;
- }
- }
- }
- } else {
- TQString tagname = parseCloseTag( doc, length, pos );
- if ( tagname.isEmpty() )
- continue; // nothing we could do with this, probably parse error
- if ( !sheet_->item( tagname ) ) // ignore unknown tags
- continue;
- if ( tagname == "li" )
- continue;
-
- // we close a block item. Since the text may continue, we need to have a new paragraph
- bool needNewPar = curtag.style->displayMode() == TQStyleSheetItem::DisplayBlock
- || curtag.style->displayMode() == TQStyleSheetItem::DisplayListItem;
-
-
- // html slopiness: handle unbalanched tag closing
- while ( curtag.name != tagname ) {
- TQString msg;
- msg.sprintf( "TQText Warning: Document not valid ( '%s' not closed before '%s' #%d)",
- curtag.name.ascii(), tagname.ascii(), pos);
- sheet_->error( msg );
- if ( tags.isEmpty() )
- break;
- curtag = tags.pop();
- }
-
-
- // close the tag
- if ( !tags.isEmpty() )
- curtag = tags.pop();
- else
- curtag = initag;
-
- if ( needNewPar ) {
- if ( textEditMode && (tagname == "p" || tagname == "div" ) ) // preserve empty paragraphs
- hasNewPar = FALSE;
- NEWPAR;
- }
- }
- } else {
- // normal contents
- TQString s;
- TQChar c;
- while ( pos < length && !hasPrefix(doc, length, pos, TQChar('<') ) ){
- if ( textEditMode ) {
- // text edit mode: we handle all white space but ignore newlines
- c = parseChar( doc, length, pos, TQStyleSheetItem::WhiteSpacePre );
- if ( c == TQChar_linesep )
- break;
- } else {
- int l = pos;
- c = parseChar( doc, length, pos, curtag.wsm );
-
- // in white space pre mode: treat any space as non breakable
- // and expand tabs to eight character wide columns.
- if ( curtag.wsm == TQStyleSheetItem::WhiteSpacePre ) {
- if ( c == '\t' ) {
- c = ' ';
- while( (++tabExpansionColumn)%8 )
- s += c;
- }
- if ( c == TQChar_linesep )
- tabExpansionColumn = 0;
- else
- tabExpansionColumn++;
-
- }
- if ( c == ' ' || c == TQChar_linesep ) {
- /* avoid overlong paragraphs by forcing a new
- paragraph after 4096 characters. This case can
- occur when loading undiscovered plain text
- documents in rich text mode. Instead of hanging
- forever, we do the trick.
- */
- if ( curtag.wsm == TQStyleSheetItem::WhiteSpaceNormal && s.length() > 4096 ) do {
- if ( doc[l] == '\n' ) {
- hasNewPar = FALSE; // for a new paragraph ...
- NEWPAR;
- hasNewPar = FALSE; // ... and make it non-reusable
- c = '\n'; // make sure we break below
- break;
- }
- } while ( ++l < pos );
- }
- }
-
- if ( c == '\n' )
- break; // break on newlines, pre delievers a TQChar_linesep
-
- bool c_isSpace = c.isSpace() && c.tqunicode() != 0x00a0U && !textEditMode;
-
- if ( curtag.wsm == TQStyleSheetItem::WhiteSpaceNormal && c_isSpace && space )
- continue;
- if ( c == '\r' )
- continue;
- space = c_isSpace;
- s += c;
- }
- if ( !s.isEmpty() && curtag.style->displayMode() != TQStyleSheetItem::DisplayNone ) {
- hasNewPar = FALSE;
- int index = TQMAX( curpar->length(),1) - 1;
- curpar->append( s );
- if (curtag.wsm != TQStyleSheetItem::WhiteSpaceNormal) {
- TQTextString *str = curpar->string();
- for (int i = index; i < index + s.length(); ++i)
- str->at(i).nobreak = TRUE;
- }
-
- TQTextFormat* f = formatCollection()->format( &curtag.format );
- curpar->setFormat( index, s.length(), f, FALSE ); // do not use collection because we have done that already
- f->ref += s.length() -1; // that what friends are for...
- if ( !curtag.anchorHref.isEmpty() ) {
- for ( int i = 0; i < int(s.length()); i++ )
- curpar->at(index + i)->setAnchor( TQString::null, curtag.anchorHref );
- }
- if ( !anchorName.isEmpty() ) {
- for ( int i = 0; i < int(s.length()); i++ )
- curpar->at(index + i)->setAnchor( anchorName, curpar->at(index + i)->anchorHref() );
- anchorName = TQString::null;
- }
- }
- }
- }
-
- if ( hasNewPar && curpar != fParag && !cursor && stylesPar != curpar ) {
- // cleanup unused last paragraphs
- curpar = curpar->p;
- delete curpar->n;
- }
-
- if ( !anchorName.isEmpty() ) {
- curpar->at(curpar->length() - 1)->setAnchor( anchorName, curpar->at( curpar->length() - 1 )->anchorHref() );
- anchorName = TQString::null;
- }
-
-
- setRichTextMarginsInternal( styles, stylesPar );
-
- if ( cursor ) {
- cursor->gotoPreviousLetter();
- cursor->remove();
- }
- delete vec;
-}
-
-void TQTextDocument::setRichTextMarginsInternal( TQPtrList< TQPtrVector<TQStyleSheetItem> >& styles, TQTextParagraph* stylesPar )
-{
- // margin and line spacing calculation
- TQPtrVector<TQStyleSheetItem>* prevStyle = 0;
- TQPtrVector<TQStyleSheetItem>* curStyle = styles.first();
- TQPtrVector<TQStyleSheetItem>* nextStyle = styles.next();
- while ( stylesPar ) {
- if ( !curStyle ) {
- stylesPar = stylesPar->next();
- prevStyle = curStyle;
- curStyle = nextStyle;
- nextStyle = styles.next();
- continue;
- }
-
- int i, mar;
- TQStyleSheetItem* mainStyle = curStyle->size() ? (*curStyle)[curStyle->size()-1] : 0;
- if ( mainStyle && mainStyle->displayMode() == TQStyleSheetItem::DisplayListItem )
- stylesPar->setListItem( TRUE );
- int numLists = 0;
- for ( i = 0; i < (int)curStyle->size(); ++i ) {
- if ( (*curStyle)[ i ]->displayMode() == TQStyleSheetItem::DisplayBlock
- && (*curStyle)[ i ]->listStyle() != TQStyleSheetItem::ListStyleUndefined )
- numLists++;
- }
- stylesPar->ldepth = numLists;
- if ( stylesPar->next() && nextStyle ) {
- // also set the depth of the next paragraph, required for the margin calculation
- numLists = 0;
- for ( i = 0; i < (int)nextStyle->size(); ++i ) {
- if ( (*nextStyle)[ i ]->displayMode() == TQStyleSheetItem::DisplayBlock
- && (*nextStyle)[ i ]->listStyle() != TQStyleSheetItem::ListStyleUndefined )
- numLists++;
- }
- stylesPar->next()->ldepth = numLists;
- }
-
- // do the top margin
- TQStyleSheetItem* item = mainStyle;
- int m;
- if (stylesPar->utm > 0 ) {
- m = stylesPar->utm-1;
- stylesPar->utm = 0;
- } else {
- m = TQMAX(0, item->margin( TQStyleSheetItem::MarginTop ) );
- if ( stylesPar->ldepth ) {
- if ( item->displayMode() == TQStyleSheetItem::DisplayListItem )
- m /= stylesPar->ldepth * stylesPar->ldepth;
- else
- m = 0;
- }
- }
- for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) {
- item = (*curStyle)[ i ];
- if ( prevStyle && i < (int) prevStyle->size() &&
- ( item->displayMode() == TQStyleSheetItem::DisplayBlock &&
- (*prevStyle)[ i ] == item ) )
- break;
- // emulate CSS2' standard 0 vertical margin for multiple ul or ol tags
- if ( item->listStyle() != TQStyleSheetItem::ListStyleUndefined &&
- ( ( i> 0 && (*curStyle)[ i-1 ] == item ) || (*curStyle)[i+1] == item ) )
- continue;
- mar = TQMAX( 0, item->margin( TQStyleSheetItem::MarginTop ) );
- m = TQMAX( m, mar );
- }
- stylesPar->utm = m - stylesPar->topMargin();
-
- // do the bottom margin
- item = mainStyle;
- if (stylesPar->ubm > 0 ) {
- m = stylesPar->ubm-1;
- stylesPar->ubm = 0;
- } else {
- m = TQMAX(0, item->margin( TQStyleSheetItem::MarginBottom ) );
- if ( stylesPar->ldepth ) {
- if ( item->displayMode() == TQStyleSheetItem::DisplayListItem )
- m /= stylesPar->ldepth * stylesPar->ldepth;
- else
- m = 0;
- }
- }
- for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) {
- item = (*curStyle)[ i ];
- if ( nextStyle && i < (int) nextStyle->size() &&
- ( item->displayMode() == TQStyleSheetItem::DisplayBlock &&
- (*nextStyle)[ i ] == item ) )
- break;
- // emulate CSS2' standard 0 vertical margin for multiple ul or ol tags
- if ( item->listStyle() != TQStyleSheetItem::ListStyleUndefined &&
- ( ( i> 0 && (*curStyle)[ i-1 ] == item ) || (*curStyle)[i+1] == item ) )
- continue;
- mar = TQMAX(0, item->margin( TQStyleSheetItem::MarginBottom ) );
- m = TQMAX( m, mar );
- }
- stylesPar->ubm = m - stylesPar->bottomMargin();
-
- // do the left margin, simplyfied
- item = mainStyle;
- if (stylesPar->ulm > 0 ) {
- m = stylesPar->ulm-1;
- stylesPar->ulm = 0;
- } else {
- m = TQMAX( 0, item->margin( TQStyleSheetItem::MarginLeft ) );
- }
- for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) {
- item = (*curStyle)[ i ];
- m += TQMAX( 0, item->margin( TQStyleSheetItem::MarginLeft ) );
- }
- stylesPar->ulm = m - stylesPar->leftMargin();
-
- // do the right margin, simplyfied
- item = mainStyle;
- if (stylesPar->urm > 0 ) {
- m = stylesPar->urm-1;
- stylesPar->urm = 0;
- } else {
- m = TQMAX( 0, item->margin( TQStyleSheetItem::MarginRight ) );
- }
- for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) {
- item = (*curStyle)[ i ];
- m += TQMAX( 0, item->margin( TQStyleSheetItem::MarginRight ) );
- }
- stylesPar->urm = m - stylesPar->rightMargin();
-
- // do the first line margin, which really should be called text-indent
- item = mainStyle;
- if (stylesPar->uflm > 0 ) {
- m = stylesPar->uflm-1;
- stylesPar->uflm = 0;
- } else {
- m = TQMAX( 0, item->margin( TQStyleSheetItem::MarginFirstLine ) );
- }
- for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) {
- item = (*curStyle)[ i ];
- mar = TQMAX( 0, item->margin( TQStyleSheetItem::MarginFirstLine ) );
- m = TQMAX( m, mar );
- }
- stylesPar->uflm =m - stylesPar->firstLineMargin();
-
- // do the bogus line "spacing", which really is just an extra margin
- item = mainStyle;
- for ( i = (int)curStyle->size() - 1 ; i >= 0; --i ) {
- item = (*curStyle)[ i ];
- if ( item->lineSpacing() != TQStyleSheetItem::Undefined ) {
- stylesPar->ulinespacing = item->lineSpacing();
- if ( formatCollection() &&
- stylesPar->ulinespacing < formatCollection()->defaultFormat()->height() )
- stylesPar->ulinespacing += formatCollection()->defaultFormat()->height();
- break;
- }
- }
-
- stylesPar = stylesPar->next();
- prevStyle = curStyle;
- curStyle = nextStyle;
- nextStyle = styles.next();
- }
-}
-
-void TQTextDocument::setText( const TQString &text, const TQString &context )
-{
- focusIndicator.parag = 0;
- selections.clear();
- if ( ((txtFormat == TQt::AutoText) && (TQStyleSheet::mightBeRichText( text ))) ||
- (txtFormat == TQt::RichText) )
- setRichText( text, context );
- else
- setPlainText( text );
-}
-
-TQString TQTextDocument::plainText() const
-{
- TQString buffer;
- TQString s;
- TQTextParagraph *p = fParag;
- while ( p ) {
- if ( !p->mightHaveCustomItems ) {
- const TQTextString *ts = p->string(); // workaround VC++ and Borland
- s = ts->toString(); // with FALSE we don't fix spaces (nbsp)
- } else {
- for ( int i = 0; i < p->length() - 1; ++i ) {
-#ifndef TQT_NO_TEXTCUSTOMITEM
- if ( p->at( i )->isCustom() ) {
- if ( p->at( i )->customItem()->isNested() ) {
- s += "\n";
- TQTextTable *t = (TQTextTable*)p->at( i )->customItem();
- TQPtrList<TQTextTableCell> cells = t->tableCells();
- for ( TQTextTableCell *c = cells.first(); c; c = cells.next() )
- s += c->richText()->plainText() + "\n";
- s += "\n";
- }
- } else
-#endif
- {
- s += p->at( i )->c;
- }
- }
- }
- s.remove( s.length() - 1, 1 );
- if ( p->next() )
- s += "\n";
- buffer += s;
- p = p->next();
- }
- return buffer;
-}
-
-static TQString align_to_string( int a )
-{
- if ( a & TQt::AlignRight )
- return " align=\"right\"";
- if ( a & TQt::AlignHCenter )
- return " align=\"center\"";
- if ( a & TQt::AlignJustify )
- return " align=\"justify\"";
- return TQString::null;
-}
-
-static TQString direction_to_string( int d )
-{
- if ( d != TQChar::DirON )
- return ( d == TQChar::DirL? " dir=\"ltr\"" : " dir=\"rtl\"" );
- return TQString::null;
-}
-
-static TQString list_value_to_string( int v )
-{
- if ( v != -1 )
- return " listvalue=\"" + TQString::number( v ) + "\"";
- return TQString::null;
-}
-
-static TQString list_style_to_string( int v )
-{
- switch( v ) {
- case TQStyleSheetItem::ListDecimal: return "\"1\"";
- case TQStyleSheetItem::ListLowerAlpha: return "\"a\"";
- case TQStyleSheetItem::ListUpperAlpha: return "\"A\"";
- case TQStyleSheetItem::ListDisc: return "\"disc\"";
- case TQStyleSheetItem::ListSquare: return "\"square\"";
- case TQStyleSheetItem::ListCircle: return "\"circle\"";
- default:
- return TQString::null;
- }
-}
-
-static inline bool list_is_ordered( int v )
-{
- return v == TQStyleSheetItem::ListDecimal ||
- v == TQStyleSheetItem::ListLowerAlpha ||
- v == TQStyleSheetItem::ListUpperAlpha;
-}
-
-
-static TQString margin_to_string( TQStyleSheetItem* style, int t, int b, int l, int r, int fl )
-{
- TQString s;
- if ( l > 0 )
- s += TQString(!!s?";":"") + "margin-left:" + TQString::number(l+TQMAX(0,style->margin(TQStyleSheetItem::MarginLeft))) + "px";
- if ( r > 0 )
- s += TQString(!!s?";":"") + "margin-right:" + TQString::number(r+TQMAX(0,style->margin(TQStyleSheetItem::MarginRight))) + "px";
- if ( t > 0 )
- s += TQString(!!s?";":"") + "margin-top:" + TQString::number(t+TQMAX(0,style->margin(TQStyleSheetItem::MarginTop))) + "px";
- if ( b > 0 )
- s += TQString(!!s?";":"") + "margin-bottom:" + TQString::number(b+TQMAX(0,style->margin(TQStyleSheetItem::MarginBottom))) + "px";
- if ( fl > 0 )
- s += TQString(!!s?";":"") + "text-indent:" + TQString::number(fl+TQMAX(0,style->margin(TQStyleSheetItem::MarginFirstLine))) + "px";
- if ( !!s )
- return " style=\"" + s + "\"";
- return TQString::null;
-}
-
-TQString TQTextDocument::richText() const
-{
- TQString s = "";
- if ( !par ) {
- s += "<html><head><meta name=\"qrichtext\" content=\"1\" /></head><body style=\"font-size:" ;
- s += TQString::number( formatCollection()->defaultFormat()->font().pointSize() );
- s += "pt;font-family:";
- s += formatCollection()->defaultFormat()->font().family();
- s +="\">";
- }
- TQTextParagraph* p = fParag;
-
- TQStyleSheetItem* item_p = styleSheet()->item("p");
- TQStyleSheetItem* item_div = styleSheet()->item("div");
- TQStyleSheetItem* item_ul = styleSheet()->item("ul");
- TQStyleSheetItem* item_ol = styleSheet()->item("ol");
- TQStyleSheetItem* item_li = styleSheet()->item("li");
- if ( !item_p || !item_div || !item_ul || !item_ol || !item_li ) {
- qWarning( "TQTextEdit: cannot export HTML due to insufficient stylesheet (lack of p, div, ul, ol, or li)" );
- return TQString::null;
- }
- int pastListDepth = 0;
- int listDepth = 0;
-#if 0
- int futureListDepth = 0;
-#endif
- TQMemArray<int> listStyles(10);
-
- while ( p ) {
- listDepth = p->listDepth();
- if ( listDepth < pastListDepth ) {
- for ( int i = pastListDepth; i > listDepth; i-- )
- s += list_is_ordered( listStyles[i] ) ? "</ol>" : "</ul>";
- s += '\n';
- } else if ( listDepth > pastListDepth ) {
- s += '\n';
- listStyles.resize( TQMAX( (int)listStyles.size(), listDepth+1 ) );
- TQString list_type;
- listStyles[listDepth] = p->listStyle();
- if ( !list_is_ordered( p->listStyle() ) || item_ol->listStyle() != p->listStyle() )
- list_type = " type=" + list_style_to_string( p->listStyle() );
- for ( int i = pastListDepth; i < listDepth; i++ ) {
- s += list_is_ordered( p->listStyle() ) ? "<ol" : "<ul" ;
- s += list_type + ">";
- }
- } else {
- s += '\n';
- }
-
- TQString ps = p->richText();
-
-#if 0
- // for the bottom margin we need to know whether we are at the end of a list
- futureListDepth = 0;
- if ( listDepth > 0 && p->next() )
- futureListDepth = p->next()->listDepth();
-#endif
-
- if ( richTextExportStart && richTextExportStart->paragraph() ==p &&
- richTextExportStart->index() == 0 )
- s += "<!--StartFragment-->";
-
- if ( p->isListItem() ) {
- s += "<li";
- if ( p->listStyle() != listStyles[listDepth] )
- s += " type=" + list_style_to_string( p->listStyle() );
- s +=align_to_string( p->tqalignment() );
- s += margin_to_string( item_li, p->utm, p->ubm, p->ulm, p->urm, p->uflm );
- s += list_value_to_string( p->listValue() );
- s += direction_to_string( p->direction() );
- s +=">";
- s += ps;
- s += "</li>";
- } else if ( p->listDepth() ) {
- s += "<div";
- s += align_to_string( p->tqalignment() );
- s += margin_to_string( item_div, p->utm, p->ubm, p->ulm, p->urm, p->uflm );
- s +=direction_to_string( p->direction() );
- s += ">";
- s += ps;
- s += "</div>";
- } else {
- // normal paragraph item
- s += "<p";
- s += align_to_string( p->tqalignment() );
- s += margin_to_string( item_p, p->utm, p->ubm, p->ulm, p->urm, p->uflm );
- s +=direction_to_string( p->direction() );
- s += ">";
- s += ps;
- s += "</p>";
- }
- pastListDepth = listDepth;
- p = p->next();
- }
- while ( listDepth > 0 ) {
- s += list_is_ordered( listStyles[listDepth] ) ? "</ol>" : "</ul>";
- listDepth--;
- }
-
- if ( !par )
- s += "\n</body></html>\n";
-
- return s;
-}
-
-TQString TQTextDocument::text() const
-{
- if ( ((txtFormat == TQt::AutoText) && preferRichText) || (txtFormat == TQt::RichText) )
- return richText();
- return plainText();
-}
-
-TQString TQTextDocument::text( int parag ) const
-{
- TQTextParagraph *p = paragAt( parag );
- if ( !p )
- return TQString::null;
-
- if ( ((txtFormat == TQt::AutoText) && preferRichText) || (txtFormat == TQt::RichText) )
- return p->richText();
- else
- return p->string()->toString();
-}
-
-void TQTextDocument::tqinvalidate()
-{
- TQTextParagraph *s = fParag;
- while ( s ) {
- s->tqinvalidate( 0 );
- s = s->next();
- }
-}
-
-void TQTextDocument::selectionStart( int id, int &paragId, int &index )
-{
- QMap<int, TQTextDocumentSelection>::Iterator it = selections.find( id );
- if ( it == selections.end() )
- return;
- TQTextDocumentSelection &sel = *it;
- paragId = !sel.swapped ? sel.startCursor.paragraph()->paragId() : sel.endCursor.paragraph()->paragId();
- index = !sel.swapped ? sel.startCursor.index() : sel.endCursor.index();
-}
-
-TQTextCursor TQTextDocument::selectionStartCursor( int id)
-{
- QMap<int, TQTextDocumentSelection>::Iterator it = selections.find( id );
- if ( it == selections.end() )
- return TQTextCursor( this );
- TQTextDocumentSelection &sel = *it;
- if ( sel.swapped )
- return sel.endCursor;
- return sel.startCursor;
-}
-
-TQTextCursor TQTextDocument::selectionEndCursor( int id)
-{
- QMap<int, TQTextDocumentSelection>::Iterator it = selections.find( id );
- if ( it == selections.end() )
- return TQTextCursor( this );
- TQTextDocumentSelection &sel = *it;
- if ( !sel.swapped )
- return sel.endCursor;
- return sel.startCursor;
-}
-
-void TQTextDocument::selectionEnd( int id, int &paragId, int &index )
-{
- QMap<int, TQTextDocumentSelection>::Iterator it = selections.find( id );
- if ( it == selections.end() )
- return;
- TQTextDocumentSelection &sel = *it;
- paragId = sel.swapped ? sel.startCursor.paragraph()->paragId() : sel.endCursor.paragraph()->paragId();
- index = sel.swapped ? sel.startCursor.index() : sel.endCursor.index();
-}
-
-void TQTextDocument::addSelection( int id )
-{
- nSelections = TQMAX( nSelections, id + 1 );
-}
-
-static void setSelectionEndHelper( int id, TQTextDocumentSelection &sel, TQTextCursor &start, TQTextCursor &end )
-{
- TQTextCursor c1 = start;
- TQTextCursor c2 = end;
- if ( sel.swapped ) {
- c1 = end;
- c2 = start;
- }
-
- c1.paragraph()->removeSelection( id );
- c2.paragraph()->removeSelection( id );
- if ( c1.paragraph() != c2.paragraph() ) {
- c1.paragraph()->setSelection( id, c1.index(), c1.paragraph()->length() - 1 );
- c2.paragraph()->setSelection( id, 0, c2.index() );
- } else {
- c1.paragraph()->setSelection( id, TQMIN( c1.index(), c2.index() ), TQMAX( c1.index(), c2.index() ) );
- }
-
- sel.startCursor = start;
- sel.endCursor = end;
- if ( sel.startCursor.paragraph() == sel.endCursor.paragraph() )
- sel.swapped = sel.startCursor.index() > sel.endCursor.index();
-}
-
-bool TQTextDocument::setSelectionEnd( int id, const TQTextCursor &cursor )
-{
- QMap<int, TQTextDocumentSelection>::Iterator it = selections.find( id );
- if ( it == selections.end() )
- return FALSE;
- TQTextDocumentSelection &sel = *it;
-
- TQTextCursor start = sel.startCursor;
- TQTextCursor end = cursor;
-
- if ( start == end ) {
- removeSelection( id );
- setSelectionStart( id, cursor );
- return TRUE;
- }
-
- if ( sel.endCursor.paragraph() == end.paragraph() ) {
- setSelectionEndHelper( id, sel, start, end );
- return TRUE;
- }
-
- bool inSelection = FALSE;
- TQTextCursor c( this );
- TQTextCursor tmp = sel.startCursor;
- if ( sel.swapped )
- tmp = sel.endCursor;
- tmp.restoreState();
- TQTextCursor tmp2 = cursor;
- tmp2.restoreState();
- c.setParagraph( tmp.paragraph()->paragId() < tmp2.paragraph()->paragId() ? tmp.paragraph() : tmp2.paragraph() );
- bool hadStart = FALSE;
- bool hadEnd = FALSE;
- bool hadStartParag = FALSE;
- bool hadEndParag = FALSE;
- bool hadOldStart = FALSE;
- bool hadOldEnd = FALSE;
- bool leftSelection = FALSE;
- sel.swapped = FALSE;
- for ( ;; ) {
- if ( c == start )
- hadStart = TRUE;
- if ( c == end )
- hadEnd = TRUE;
- if ( c.paragraph() == start.paragraph() )
- hadStartParag = TRUE;
- if ( c.paragraph() == end.paragraph() )
- hadEndParag = TRUE;
- if ( c == sel.startCursor )
- hadOldStart = TRUE;
- if ( c == sel.endCursor )
- hadOldEnd = TRUE;
-
- if ( !sel.swapped &&
- ( (hadEnd && !hadStart) ||
- (hadEnd && hadStart && (start.paragraph() == end.paragraph()) && start.index() > end.index()) ) )
- sel.swapped = TRUE;
-
- if ( ((c == end) && hadStartParag) ||
- ((c == start) && hadEndParag )) {
- TQTextCursor tmp = c;
- tmp.restoreState();
- if ( tmp.paragraph() != c.paragraph() ) {
- int sstart = tmp.paragraph()->selectionStart( id );
- tmp.paragraph()->removeSelection( id );
- tmp.paragraph()->setSelection( id, sstart, tmp.index() );
- }
- }
-
- if ( inSelection &&
- ( ((c == end) && hadStart) || ((c == start) && hadEnd) ) )
- leftSelection = TRUE;
- else if ( !leftSelection && !inSelection && ( hadStart || hadEnd ) )
- inSelection = TRUE;
-
- bool noSelectionAnymore = hadOldStart && hadOldEnd && leftSelection && !inSelection && !c.paragraph()->hasSelection( id ) && c.atParagEnd();
- c.paragraph()->removeSelection( id );
- if ( inSelection ) {
- if ( c.paragraph() == start.paragraph() && start.paragraph() == end.paragraph() ) {
- c.paragraph()->setSelection( id, TQMIN( start.index(), end.index() ), TQMAX( start.index(), end.index() ) );
- } else if ( c.paragraph() == start.paragraph() && !hadEndParag ) {
- c.paragraph()->setSelection( id, start.index(), c.paragraph()->length() - 1 );
- } else if ( c.paragraph() == end.paragraph() && !hadStartParag ) {
- c.paragraph()->setSelection( id, end.index(), c.paragraph()->length() - 1 );
- } else if ( c.paragraph() == end.paragraph() && hadEndParag ) {
- c.paragraph()->setSelection( id, 0, end.index() );
- } else if ( c.paragraph() == start.paragraph() && hadStartParag ) {
- c.paragraph()->setSelection( id, 0, start.index() );
- } else {
- c.paragraph()->setSelection( id, 0, c.paragraph()->length() - 1 );
- }
- }
-
- if ( leftSelection )
- inSelection = FALSE;
-
- if ( noSelectionAnymore )
- break;
- // *ugle*hack optimization
- TQTextParagraph *p = c.paragraph();
- if ( p->mightHaveCustomItems || p == start.paragraph() || p == end.paragraph() || p == lastParagraph() ) {
- c.gotoNextLetter();
- if ( p == lastParagraph() && c.atParagEnd() )
- break;
- } else {
- if ( p->document()->parent() )
- do {
- c.gotoNextLetter();
- } while ( c.paragraph() == p );
- else
- c.setParagraph( p->next() );
- }
- }
-
- if ( !sel.swapped )
- sel.startCursor.paragraph()->setSelection( id, sel.startCursor.index(), sel.startCursor.paragraph()->length() - 1 );
-
- sel.startCursor = start;
- sel.endCursor = end;
- if ( sel.startCursor.paragraph() == sel.endCursor.paragraph() )
- sel.swapped = sel.startCursor.index() > sel.endCursor.index();
-
- setSelectionEndHelper( id, sel, start, end );
-
- return TRUE;
-}
-
-void TQTextDocument::selectAll( int id )
-{
- removeSelection( id );
-
- TQTextDocumentSelection sel;
- sel.swapped = FALSE;
- TQTextCursor c( this );
-
- c.setParagraph( fParag );
- c.setIndex( 0 );
- sel.startCursor = c;
-
- c.setParagraph( lParag );
- c.setIndex( lParag->length() - 1 );
- sel.endCursor = c;
-
- selections.insert( id, sel );
-
- TQTextParagraph *p = fParag;
- while ( p ) {
- p->setSelection( id, 0, p->length() - 1 );
- p = p->next();
- }
-
- for ( TQTextDocument *d = childList.first(); d; d = childList.next() )
- d->selectAll( id );
-}
-
-bool TQTextDocument::removeSelection( int id )
-{
- if ( !selections.contains( id ) )
- return FALSE;
-
- TQTextDocumentSelection &sel = selections[ id ];
-
- TQTextCursor start = sel.swapped ? sel.endCursor : sel.startCursor;
- TQTextCursor end = sel.swapped ? sel.startCursor : sel.endCursor;
- TQTextParagraph* p = 0;
- while ( start != end ) {
- if ( p != start.paragraph() ) {
- p = start.paragraph();
- p->removeSelection( id );
- //### avoid endless loop by all means necessary, did somebody mention refactoring?
- if ( !parent() && p == lParag )
- break;
- }
- start.gotoNextLetter();
- }
- p = start.paragraph();
- p->removeSelection( id );
- selections.remove( id );
- return TRUE;
-}
-
-TQString TQTextDocument::selectedText( int id, bool asRichText ) const
-{
- QMap<int, TQTextDocumentSelection>::ConstIterator it = selections.find( id );
- if ( it == selections.end() )
- return TQString::null;
-
- TQTextDocumentSelection sel = *it;
-
-
- TQTextCursor c1 = sel.startCursor;
- TQTextCursor c2 = sel.endCursor;
- if ( sel.swapped ) {
- c2 = sel.startCursor;
- c1 = sel.endCursor;
- }
-
- /* 3.0.3 improvement: Make it possible to get a reasonable
- selection inside a table. This approach is very conservative:
- make sure that both cursors have the same depth level and point
- to paragraphs within the same text document.
-
- Meaning if you select text in two table cells, you will get the
- entire table. This is still far better than the 3.0.2, where
- you always got the entire table.
-
- ### Fix this properly when refactoring
- */
- while ( c2.nestedDepth() > c1.nestedDepth() )
- c2.oneUp();
- while ( c1.nestedDepth() > c2.nestedDepth() )
- c1.oneUp();
- while ( c1.nestedDepth() && c2.nestedDepth() &&
- c1.paragraph()->document() != c2.paragraph()->document() ) {
- c1.oneUp();
- c2.oneUp();
- }
- // do not trust sel_swapped with tables. Fix this properly when refactoring as well
- if ( c1.paragraph()->paragId() > c2.paragraph()->paragId() ||
- (c1.paragraph() == c2.paragraph() && c1.index() > c2.index() ) ) {
- TQTextCursor tmp = c1;
- c2 = c1;
- c1 = tmp;
- }
-
- // end selection 3.0.3 improvement
-
- if ( asRichText && !parent() ) {
- richTextExportStart = &c1;
- richTextExportEnd = &c2;
-
- TQString sel = richText();
- int from = sel.find( "<!--StartFragment-->" );
- if ( from >= 0 ) {
- from += 20;
- // find the previous span and move it into the start fragment before we clip it
- TQString prevspan;
- int pspan = sel.findRev( "<span", from-21 );
- if ( pspan > sel.findRev( "</span", from-21 ) ) {
- int spanend = sel.find( '>', pspan );
- prevspan = sel.mid( pspan, spanend - pspan + 1 );
- }
- int to = sel.findRev( "<!--EndFragment-->" );
- if ( from <= to )
- sel = "<!--StartFragment-->" + prevspan + sel.mid( from, to - from );
- }
- richTextExportStart = richTextExportEnd = 0;
- return sel;
- }
-
- TQString s;
- if ( c1.paragraph() == c2.paragraph() ) {
- TQTextParagraph *p = c1.paragraph();
- int end = c2.index();
- if ( p->at( TQMAX( 0, end - 1 ) )->isCustom() )
- ++end;
- if ( !p->mightHaveCustomItems ) {
- s += p->string()->toString().mid( c1.index(), end - c1.index() );
- } else {
- for ( int i = c1.index(); i < end; ++i ) {
-#ifndef TQT_NO_TEXTCUSTOMITEM
- if ( p->at( i )->isCustom() ) {
- if ( p->at( i )->customItem()->isNested() ) {
- s += "\n";
- TQTextTable *t = (TQTextTable*)p->at( i )->customItem();
- TQPtrList<TQTextTableCell> cells = t->tableCells();
- for ( TQTextTableCell *c = cells.first(); c; c = cells.next() )
- s += c->richText()->plainText() + "\n";
- s += "\n";
- }
- } else
-#endif
- {
- s += p->at( i )->c;
- }
- }
- }
- } else {
- TQTextParagraph *p = c1.paragraph();
- int start = c1.index();
- while ( p ) {
- int end = p == c2.paragraph() ? c2.index() : p->length() - 1;
- if ( p == c2.paragraph() && p->at( TQMAX( 0, end - 1 ) )->isCustom() )
- ++end;
- if ( !p->mightHaveCustomItems ) {
- s += p->string()->toString().mid( start, end - start );
- if ( p != c2.paragraph() )
- s += "\n";
- } else {
- for ( int i = start; i < end; ++i ) {
-#ifndef TQT_NO_TEXTCUSTOMITEM
- if ( p->at( i )->isCustom() ) {
- if ( p->at( i )->customItem()->isNested() ) {
- s += "\n";
- TQTextTable *t = (TQTextTable*)p->at( i )->customItem();
- TQPtrList<TQTextTableCell> cells = t->tableCells();
- for ( TQTextTableCell *c = cells.first(); c; c = cells.next() )
- s += c->richText()->plainText() + "\n";
- s += "\n";
- }
- } else
-#endif
- {
- s += p->at( i )->c;
- }
- }
- }
- start = 0;
- if ( p == c2.paragraph() )
- break;
- p = p->next();
- }
- }
- // ### workaround for plain text export until we get proper
- // mime types: turn tqunicode line seperators into the more
- // widely understood \n. Makes copy and pasting code snipplets
- // from within Assistent possible
- TQChar* uc = (TQChar*) s.tqunicode();
- for ( int ii = 0; ii < s.length(); ii++ ) {
- if ( uc[(int)ii] == TQChar_linesep )
- uc[(int)ii] = TQChar('\n');
- else if ( uc[(int)ii] == TQChar::nbsp )
- uc[(int)ii] = TQChar(' ');
- }
- return s;
-}
-
-void TQTextDocument::setFormat( int id, TQTextFormat *f, int flags )
-{
- QMap<int, TQTextDocumentSelection>::ConstIterator it = selections.find( id );
- if ( it == selections.end() )
- return;
-
- TQTextDocumentSelection sel = *it;
-
- TQTextCursor c1 = sel.startCursor;
- TQTextCursor c2 = sel.endCursor;
- if ( sel.swapped ) {
- c2 = sel.startCursor;
- c1 = sel.endCursor;
- }
-
- c2.restoreState();
- c1.restoreState();
-
- if ( c1.paragraph() == c2.paragraph() ) {
- c1.paragraph()->setFormat( c1.index(), c2.index() - c1.index(), f, TRUE, flags );
- return;
- }
-
- c1.paragraph()->setFormat( c1.index(), c1.paragraph()->length() - c1.index(), f, TRUE, flags );
- TQTextParagraph *p = c1.paragraph()->next();
- while ( p && p != c2.paragraph() ) {
- p->setFormat( 0, p->length(), f, TRUE, flags );
- p = p->next();
- }
- c2.paragraph()->setFormat( 0, c2.index(), f, TRUE, flags );
-}
-
-void TQTextDocument::removeSelectedText( int id, TQTextCursor *cursor )
-{
- QMap<int, TQTextDocumentSelection>::Iterator it = selections.find( id );
- if ( it == selections.end() )
- return;
-
- TQTextDocumentSelection sel = *it;
- TQTextCursor c1 = sel.startCursor;
- TQTextCursor c2 = sel.endCursor;
- if ( sel.swapped ) {
- c2 = sel.startCursor;
- c1 = sel.endCursor;
- }
-
- // ### no support for editing tables yet
- if ( c1.nestedDepth() || c2.nestedDepth() )
- return;
-
- c2.restoreState();
- c1.restoreState();
-
- *cursor = c1;
- removeSelection( id );
-
- if ( c1.paragraph() == c2.paragraph() ) {
- c1.paragraph()->remove( c1.index(), c2.index() - c1.index() );
- return;
- }
-
- if ( c1.paragraph() == fParag && c1.index() == 0 &&
- c2.paragraph() == lParag && c2.index() == lParag->length() - 1 )
- cursor->setValid( FALSE );
-
- bool didGoLeft = FALSE;
- if ( c1.index() == 0 && c1.paragraph() != fParag ) {
- cursor->gotoPreviousLetter();
- didGoLeft = cursor->isValid();
- }
-
- c1.paragraph()->remove( c1.index(), c1.paragraph()->length() - 1 - c1.index() );
- TQTextParagraph *p = c1.paragraph()->next();
- int dy = 0;
- TQTextParagraph *tmp;
- while ( p && p != c2.paragraph() ) {
- tmp = p->next();
- dy -= p->rect().height();
- delete p;
- p = tmp;
- }
- c2.paragraph()->remove( 0, c2.index() );
- while ( p ) {
- p->move( dy );
- p->tqinvalidate( 0 );
- p->setEndState( -1 );
- p = p->next();
- }
-
-
- c1.paragraph()->join( c2.paragraph() );
-
- if ( didGoLeft )
- cursor->gotoNextLetter();
-}
-
-void TQTextDocument::indentSelection( int id )
-{
- QMap<int, TQTextDocumentSelection>::Iterator it = selections.find( id );
- if ( it == selections.end() )
- return;
-
- TQTextDocumentSelection sel = *it;
- TQTextParagraph *startParag = sel.startCursor.paragraph();
- TQTextParagraph *endParag = sel.endCursor.paragraph();
- if ( sel.endCursor.paragraph()->paragId() < sel.startCursor.paragraph()->paragId() ) {
- endParag = sel.startCursor.paragraph();
- startParag = sel.endCursor.paragraph();
- }
-
- TQTextParagraph *p = startParag;
- while ( p && p != endParag ) {
- p->indent();
- p = p->next();
- }
-}
-
-void TQTextDocument::addCommand( TQTextCommand *cmd )
-{
- commandHistory->addCommand( cmd );
-}
-
-TQTextCursor *TQTextDocument::undo( TQTextCursor *c )
-{
- return commandHistory->undo( c );
-}
-
-TQTextCursor *TQTextDocument::redo( TQTextCursor *c )
-{
- return commandHistory->redo( c );
-}
-
-bool TQTextDocument::find( TQTextCursor& cursor, const TQString &expr, bool cs, bool wo, bool forward )
-{
- removeSelection( Standard );
- TQTextParagraph *p = 0;
- if ( expr.isEmpty() )
- return FALSE;
- for (;;) {
- if ( p != cursor.paragraph() ) {
- p = cursor.paragraph();
- TQString s = cursor.paragraph()->string()->toString();
- int start = cursor.index();
- for ( ;; ) {
- int res = forward ? s.find( expr, start, cs ) : s.findRev( expr, start, cs );
- int end = res + expr.length();
- if ( res == -1 || ( !forward && start <= res ) )
- break;
- if ( !wo || ( ( res == 0 || s[ res - 1 ].isSpace() || s[ res - 1 ].isPunct() ) &&
- ( end == (int)s.length() || s[ end ].isSpace() || s[ end ].isPunct() ) ) ) {
- removeSelection( Standard );
- cursor.setIndex( forward ? end : res );
- setSelectionStart( Standard, cursor );
- cursor.setIndex( forward ? res : end );
- setSelectionEnd( Standard, cursor );
- if ( !forward )
- cursor.setIndex( res );
- return TRUE;
- }
- start = res + (forward ? 1 : -1);
- }
- }
- if ( forward ) {
- if ( cursor.paragraph() == lastParagraph() && cursor.atParagEnd() )
- break;
- cursor.gotoNextLetter();
- } else {
- if ( cursor.paragraph() == firstParagraph() && cursor.atParagStart() )
- break;
- cursor.gotoPreviousLetter();
- }
- }
- return FALSE;
-}
-
-void TQTextDocument::setTextFormat( TQt::TextFormat f )
-{
- txtFormat = f;
- if ( fParag == lParag && fParag->length() <= 1 )
- fParag->rtext = ( f == TQt::RichText );
-}
-
-TQt::TextFormat TQTextDocument::textFormat() const
-{
- return txtFormat;
-}
-
-bool TQTextDocument::inSelection( int selId, const TQPoint &pos ) const
-{
- QMap<int, TQTextDocumentSelection>::ConstIterator it = selections.find( selId );
- if ( it == selections.end() )
- return FALSE;
-
- TQTextDocumentSelection sel = *it;
- TQTextParagraph *startParag = sel.startCursor.paragraph();
- TQTextParagraph *endParag = sel.endCursor.paragraph();
- if ( sel.startCursor.paragraph() == sel.endCursor.paragraph() &&
- sel.startCursor.paragraph()->selectionStart( selId ) == sel.endCursor.paragraph()->selectionEnd( selId ) )
- return FALSE;
- if ( sel.endCursor.paragraph()->paragId() < sel.startCursor.paragraph()->paragId() ) {
- endParag = sel.startCursor.paragraph();
- startParag = sel.endCursor.paragraph();
- }
-
- TQTextParagraph *p = startParag;
- while ( p ) {
- if ( p->rect().contains( pos ) ) {
- bool inSel = FALSE;
- int selStart = p->selectionStart( selId );
- int selEnd = p->selectionEnd( selId );
- int y = 0;
- int h = 0;
- for ( int i = 0; i < p->length(); ++i ) {
- if ( i == selStart )
- inSel = TRUE;
- if ( i == selEnd )
- break;
- if ( p->at( i )->lineStart ) {
- y = (*p->lineStarts.find( i ))->y;
- h = (*p->lineStarts.find( i ))->h;
- }
- if ( pos.y() - p->rect().y() >= y && pos.y() - p->rect().y() <= y + h ) {
- if ( inSel && pos.x() >= p->at( i )->x &&
- pos.x() <= p->at( i )->x + p->at( i )->format()->width( p->at( i )->c ) )
- return TRUE;
- }
- }
- }
- if ( pos.y() < p->rect().y() )
- break;
- if ( p == endParag )
- break;
- p = p->next();
- }
-
- return FALSE;
-}
-
-void TQTextDocument::doLayout( TQPainter *p, int w )
-{
- minw = wused = 0;
- if ( !is_printer( p ) )
- p = 0;
- withoutDoubleBuffer = ( p != 0 );
- TQPainter * oldPainter = TQTextFormat::painter();
- TQTextFormat::setPainter( p );
- tStopWidth = formatCollection()->defaultFormat()->width( 'x' ) * 8;
- flow_->setWidth( w );
- cw = w;
- vw = w;
- TQTextParagraph *parag = fParag;
- while ( parag ) {
- parag->tqinvalidate( 0 );
- if ( p )
- parag->adjustToPainter( p );
- parag->format();
- parag = parag->next();
- }
- TQTextFormat::setPainter( oldPainter );
-}
-
-TQPixmap *TQTextDocument::bufferPixmap( const TQSize &s )
-{
- if ( !buf_pixmap )
- buf_pixmap = new TQPixmap( s.expandedTo( TQSize(1,1) ) );
- else if ( buf_pixmap->size() != s )
- buf_pixmap->resize( s.expandedTo( buf_pixmap->size() ) );
- return buf_pixmap;
-}
-
-void TQTextDocument::draw( TQPainter *p, const TQRect &rect, const TQColorGroup &cg, const TQBrush *paper )
-{
- if ( !firstParagraph() )
- return;
-
- if ( paper ) {
- p->setBrushOrigin( -int( p->translationX() ),
- -int( p->translationY() ) );
-
- p->fillRect( rect, *paper );
- }
-
- TQPainter * oldPainter = TQTextFormat::painter();
- TQTextFormat::setPainter( p );
-
- if ( formatCollection()->defaultFormat()->color() != cg.text() )
- setDefaultFormat( formatCollection()->defaultFormat()->font(), cg.text() );
-
- TQTextParagraph *parag = firstParagraph();
- while ( parag ) {
- if ( !parag->isValid() )
- parag->format();
- int y = parag->rect().y();
- TQRect pr( parag->rect() );
- pr.setX( 0 );
- pr.setWidth( TQWIDGETSIZE_MAX );
- if ( !rect.isNull() && !rect.intersects( pr ) ) {
- parag = parag->next();
- continue;
- }
- p->translate( 0, y );
- if ( rect.isValid() )
- parag->paint( *p, cg, 0, FALSE, rect.x(), rect.y(), rect.width(), rect.height() );
- else
- parag->paint( *p, cg, 0, FALSE );
- p->translate( 0, -y );
- parag = parag->next();
- if ( !flow()->isEmpty() )
- flow()->drawFloatingItems( p, rect.x(), rect.y(), rect.width(), rect.height(), cg, FALSE );
- }
- TQTextFormat::setPainter(oldPainter);
-}
-
-void TQTextDocument::drawParagraph( TQPainter *p, TQTextParagraph *parag, int cx, int cy, int cw, int ch,
- TQPixmap *&doubleBuffer, const TQColorGroup &cg,
- bool drawCursor, TQTextCursor *cursor, bool resetChanged )
-{
- TQPainter *painter = 0;
- if ( resetChanged )
- parag->setChanged( FALSE );
- TQRect ir( parag->rect() );
-#ifndef TQT_NO_TEXTCUSTOMITEM
- if (!parag->tableCell())
-#endif
- ir.setWidth(width());
-
- bool uDoubleBuffer = useDoubleBuffer( parag, p );
-
- if ( uDoubleBuffer ) {
- painter = new TQPainter;
- if ( cx >= 0 && cy >= 0 )
- ir = ir.intersect( TQRect( cx, cy, cw, ch ) );
- if ( !doubleBuffer ||
- ir.width() > doubleBuffer->width() ||
- ir.height() > doubleBuffer->height() ) {
- doubleBuffer = bufferPixmap( ir.size() );
- painter->begin( doubleBuffer );
- } else {
- painter->begin( doubleBuffer );
- }
- } else {
- painter = p;
- painter->translate( ir.x(), ir.y() );
- }
-
- painter->setBrushOrigin( -ir.x(), -ir.y() );
-
- if ( uDoubleBuffer || is_printer( painter ) )
- painter->fillRect( TQRect( 0, 0, ir.width(), ir.height() ), parag->backgroundBrush( cg ) );
- else if ( cursor && cursor->paragraph() == parag )
- painter->fillRect( TQRect( parag->at( cursor->index() )->x, 0, 2, ir.height() ),
- parag->backgroundBrush( cg ) );
-
- painter->translate( -( ir.x() - parag->rect().x() ),
- -( ir.y() - parag->rect().y() ) );
- parag->paint( *painter, cg, drawCursor ? cursor : 0, TRUE, cx, cy, cw, ch );
-
- if ( uDoubleBuffer ) {
- delete painter;
- painter = 0;
- p->drawPixmap( ir.topLeft(), *doubleBuffer, TQRect( TQPoint( 0, 0 ), ir.size() ) );
- } else {
- painter->translate( -ir.x(), -ir.y() );
- }
-
- parag->document()->nextDoubleBuffered = FALSE;
-}
-
-TQTextParagraph *TQTextDocument::draw( TQPainter *p, int cx, int cy, int cw, int ch, const TQColorGroup &cg,
- bool onlyChanged, bool drawCursor, TQTextCursor *cursor, bool resetChanged )
-{
- if ( withoutDoubleBuffer || (par && par->withoutDoubleBuffer) ) {
- withoutDoubleBuffer = TRUE;
- TQRect r;
- draw( p, r, cg );
- return 0;
- }
- withoutDoubleBuffer = FALSE;
-
- if ( !firstParagraph() )
- return 0;
-
- TQPainter * oldPainter = TQTextFormat::painter();
- TQTextFormat::setPainter( p );
- if ( formatCollection()->defaultFormat()->color() != cg.text() )
- setDefaultFormat( formatCollection()->defaultFormat()->font(), cg.text() );
-
- if ( cx < 0 && cy < 0 ) {
- cx = 0;
- cy = 0;
- cw = width();
- ch = height();
- }
-
- TQTextParagraph *lastFormatted = 0;
- TQTextParagraph *parag = firstParagraph();
-
- TQPixmap *doubleBuffer = 0;
-
- while ( parag ) {
- lastFormatted = parag;
- if ( !parag->isValid() )
- parag->format();
-
- TQRect pr = parag->rect();
- pr.setWidth( parag->document()->width() );
- if ( pr.y() > cy + ch )
- goto floating;
- TQRect clipr( cx, cy, cw, ch );
- if ( !pr.intersects( clipr ) || ( onlyChanged && !parag->hasChanged() ) ) {
- pr.setWidth( parag->document()->width() );
- parag = parag->next();
- continue;
- }
-
- drawParagraph( p, parag, cx, cy, cw, ch, doubleBuffer, cg, drawCursor, cursor, resetChanged );
- parag = parag->next();
- }
-
- parag = lastParagraph();
-
- floating:
- if ( parag->rect().y() + parag->rect().height() < parag->document()->height() ) {
- if ( !parag->document()->parent() ) {
- TQRect fillRect = TQRect( 0, parag->rect().y() + parag->rect().height(), parag->document()->width(),
- parag->document()->height() - ( parag->rect().y() + parag->rect().height() ) );
- if ( TQRect( cx, cy, cw, ch ).intersects( fillRect ) )
- p->fillRect( fillRect, cg.brush( TQColorGroup::Base ) );
- }
- if ( !flow()->isEmpty() ) {
- TQRect cr( cx, cy, cw, ch );
- flow()->drawFloatingItems( p, cr.x(), cr.y(), cr.width(), cr.height(), cg, FALSE );
- }
- }
-
- if ( buf_pixmap && buf_pixmap->height() > 300 ) {
- delete buf_pixmap;
- buf_pixmap = 0;
- }
-
- TQTextFormat::setPainter(oldPainter);
- return lastFormatted;
-}
-
-/*
- #### this function only sets the default font size in the format collection
- */
-void TQTextDocument::setDefaultFormat( const TQFont &font, const TQColor &color )
-{
- bool reformat = font != fCollection->defaultFormat()->font();
- for ( TQTextDocument *d = childList.first(); d; d = childList.next() )
- d->setDefaultFormat( font, color );
- fCollection->updateDefaultFormat( font, color, sheet_ );
-
- if ( !reformat )
- return;
- tStopWidth = formatCollection()->defaultFormat()->width( 'x' ) * 8;
-
- // tqinvalidate paragraphs and custom items
- TQTextParagraph *p = fParag;
- while ( p ) {
- p->tqinvalidate( 0 );
-#ifndef TQT_NO_TEXTCUSTOMITEM
- for ( int i = 0; i < p->length() - 1; ++i )
- if ( p->at( i )->isCustom() )
- p->at( i )->customItem()->tqinvalidate();
-#endif
- p = p->next();
- }
-}
-
-#ifndef TQT_NO_TEXTCUSTOMITEM
-void TQTextDocument::registerCustomItem( TQTextCustomItem *i, TQTextParagraph *p )
-{
- if ( i && i->placement() != TQTextCustomItem::PlaceInline ) {
- flow_->registerFloatingItem( i );
- p->registerFloatingItem( i );
- }
- if (i) i->setParagraph( p );
- p->mightHaveCustomItems = mightHaveCustomItems = TRUE;
-}
-
-void TQTextDocument::unregisterCustomItem( TQTextCustomItem *i, TQTextParagraph *p )
-{
- p->unregisterFloatingItem( i );
- i->setParagraph( 0 );
- flow_->unregisterFloatingItem( i );
-}
-#endif
-
-bool TQTextDocument::hasFocusParagraph() const
-{
- return !!focusIndicator.parag;
-}
-
-TQString TQTextDocument::focusHref() const
-{
- return focusIndicator.href;
-}
-
-TQString TQTextDocument::focusName() const
-{
- return focusIndicator.name;
-}
-
-bool TQTextDocument::focusNextPrevChild( bool next )
-{
- if ( !focusIndicator.parag ) {
- if ( next ) {
- focusIndicator.parag = fParag;
- focusIndicator.start = 0;
- focusIndicator.len = 0;
- } else {
- focusIndicator.parag = lParag;
- focusIndicator.start = lParag->length();
- focusIndicator.len = 0;
- }
- } else {
- focusIndicator.parag->setChanged( TRUE );
- }
- focusIndicator.href = TQString::null;
- focusIndicator.name = TQString::null;
-
- if ( next ) {
- TQTextParagraph *p = focusIndicator.parag;
- int index = focusIndicator.start + focusIndicator.len;
- while ( p ) {
- for ( int i = index; i < p->length(); ++i ) {
- if ( p->at( i )->isAnchor() ) {
- p->setChanged( TRUE );
- focusIndicator.parag = p;
- focusIndicator.start = i;
- focusIndicator.len = 0;
- focusIndicator.href = p->at( i )->anchorHref();
- focusIndicator.name = p->at( i )->anchorName();
- while ( i < p->length() ) {
- if ( !p->at( i )->isAnchor() )
- return TRUE;
- focusIndicator.len++;
- i++;
- }
-#ifndef TQT_NO_TEXTCUSTOMITEM
- } else if ( p->at( i )->isCustom() ) {
- if ( p->at( i )->customItem()->isNested() ) {
- TQTextTable *t = (TQTextTable*)p->at( i )->customItem();
- TQPtrList<TQTextTableCell> cells = t->tableCells();
- // first try to continue
- TQTextTableCell *c;
- bool resetCells = TRUE;
- for ( c = cells.first(); c; c = cells.next() ) {
- if ( c->richText()->hasFocusParagraph() ) {
- if ( c->richText()->focusNextPrevChild( next ) ) {
- p->setChanged( TRUE );
- focusIndicator.parag = p;
- focusIndicator.start = i;
- focusIndicator.len = 0;
- focusIndicator.href = c->richText()->focusHref();
- focusIndicator.name = c->richText()->focusName();
- return TRUE;
- } else {
- resetCells = FALSE;
- c = cells.next();
- break;
- }
- }
- }
- // now really try
- if ( resetCells )
- c = cells.first();
- for ( ; c; c = cells.next() ) {
- if ( c->richText()->focusNextPrevChild( next ) ) {
- p->setChanged( TRUE );
- focusIndicator.parag = p;
- focusIndicator.start = i;
- focusIndicator.len = 0;
- focusIndicator.href = c->richText()->focusHref();
- focusIndicator.name = c->richText()->focusName();
- return TRUE;
- }
- }
- }
-#endif
- }
- }
- index = 0;
- p = p->next();
- }
- } else {
- TQTextParagraph *p = focusIndicator.parag;
- int index = focusIndicator.start - 1;
- if ( focusIndicator.len == 0 && index < focusIndicator.parag->length() - 1 )
- index++;
- while ( p ) {
- for ( int i = index; i >= 0; --i ) {
- if ( p->at( i )->isAnchor() ) {
- p->setChanged( TRUE );
- focusIndicator.parag = p;
- focusIndicator.start = i;
- focusIndicator.len = 0;
- focusIndicator.href = p->at( i )->anchorHref();
- focusIndicator.name = p->at( i )->anchorName();
- while ( i >= -1 ) {
- if ( i < 0 || !p->at( i )->isAnchor() ) {
- focusIndicator.start++;
- return TRUE;
- }
- if ( i < 0 )
- break;
- focusIndicator.len++;
- focusIndicator.start--;
- i--;
- }
-#ifndef TQT_NO_TEXTCUSTOMITEM
- } else if ( p->at( i )->isCustom() ) {
- if ( p->at( i )->customItem()->isNested() ) {
- TQTextTable *t = (TQTextTable*)p->at( i )->customItem();
- TQPtrList<TQTextTableCell> cells = t->tableCells();
- // first try to continue
- TQTextTableCell *c;
- bool resetCells = TRUE;
- for ( c = cells.last(); c; c = cells.prev() ) {
- if ( c->richText()->hasFocusParagraph() ) {
- if ( c->richText()->focusNextPrevChild( next ) ) {
- p->setChanged( TRUE );
- focusIndicator.parag = p;
- focusIndicator.start = i;
- focusIndicator.len = 0;
- focusIndicator.href = c->richText()->focusHref();
- focusIndicator.name = c->richText()->focusName();
- return TRUE;
- } else {
- resetCells = FALSE;
- c = cells.prev();
- break;
- }
- }
- if ( cells.at() == 0 )
- break;
- }
- // now really try
- if ( resetCells )
- c = cells.last();
- for ( ; c; c = cells.prev() ) {
- if ( c->richText()->focusNextPrevChild( next ) ) {
- p->setChanged( TRUE );
- focusIndicator.parag = p;
- focusIndicator.start = i;
- focusIndicator.len = 0;
- focusIndicator.href = c->richText()->focusHref();
- focusIndicator.name = c->richText()->focusName();
- return TRUE;
- }
- if ( cells.at() == 0 )
- break;
- }
- }
-#endif
- }
- }
- p = p->prev();
- if ( p )
- index = p->length() - 1;
- }
- }
-
- focusIndicator.parag = 0;
-
- return FALSE;
-}
-
-int TQTextDocument::length() const
-{
- int l = -1;
- TQTextParagraph *p = fParag;
- while ( p ) {
- l += p->length();
- p = p->next();
- }
- return TQMAX(0,l);
-}
-
-// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-int TQTextFormat::width( const TQChar &c ) const
-{
- if ( c.tqunicode() == 0xad ) // soft hyphen
- return 0;
- if ( !pntr || !pntr->isActive() ) {
- if ( c == '\t' )
- return fm.width( ' ' );
- if ( ha == AlignNormal ) {
- int w;
- if ( c.row() )
- w = fm.width( c );
- else
- w = widths[ c.tqunicode() ];
- if ( w == 0 && !c.row() ) {
- w = fm.width( c );
- ( (TQTextFormat*)this )->widths[ c.tqunicode() ] = w;
- }
- return w;
- } else {
- TQFont f( fn );
- if ( usePixelSizes )
- f.setPixelSize( ( f.pixelSize() * 2 ) / 3 );
- else
- f.setPointSize( ( f.pointSize() * 2 ) / 3 );
- TQFontMetrics fm_( f );
- return fm_.width( c );
- }
- }
-
- TQFont f( fn );
- if ( ha != AlignNormal ) {
- if ( usePixelSizes )
- f.setPixelSize( ( f.pixelSize() * 2 ) / 3 );
- else
- f.setPointSize( ( f.pointSize() * 2 ) / 3 );
- }
- applyFont( f );
-
- return pntr_fm->width( c );
-}
-
-int TQTextFormat::width( const TQString &str, int pos ) const
-{
- int w = 0;
- if ( str.tqunicode()[ pos ].tqunicode() == 0xad )
- return w;
- if ( !pntr || !pntr->isActive() ) {
- if ( ha == AlignNormal ) {
- w = fm.charWidth( str, pos );
- } else {
- TQFont f( fn );
- if ( usePixelSizes )
- f.setPixelSize( ( f.pixelSize() * 2 ) / 3 );
- else
- f.setPointSize( ( f.pointSize() * 2 ) / 3 );
- TQFontMetrics fm_( f );
- w = fm_.charWidth( str, pos );
- }
- } else {
- TQFont f( fn );
- if ( ha != AlignNormal ) {
- if ( usePixelSizes )
- f.setPixelSize( ( f.pixelSize() * 2 ) / 3 );
- else
- f.setPointSize( ( f.pointSize() * 2 ) / 3 );
- }
- applyFont( f );
- w = pntr_fm->charWidth( str, pos );
- }
- return w;
-}
-
-// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-TQTextString::TQTextString()
-{
- bidiDirty = TRUE;
- bidi = FALSE;
- rightToLeft = FALSE;
- dir = TQChar::DirON;
-}
-
-TQTextString::TQTextString( const TQTextString &s )
-{
- bidiDirty = TRUE;
- bidi = s.bidi;
- rightToLeft = s.rightToLeft;
- dir = s.dir;
- data = s.data;
- data.detach();
- for ( int i = 0; i < (int)data.size(); ++i ) {
- TQTextFormat *f = data[i].format();
- if ( f )
- f->addRef();
- }
-}
-
-void TQTextString::insert( int index, const QString &s, TQTextFormat *f )
-{
- insert( index, s.tqunicode(), s.length(), f );
-}
-
-void TQTextString::insert( int index, const QChar *tqunicode, int len, TQTextFormat *f )
-{
- int os = data.size();
- data.resize( data.size() + len, TQGArray::SpeedOptim );
- if ( index < os ) {
- memmove( data.data() + index + len, data.data() + index,
- sizeof( TQTextStringChar ) * ( os - index ) );
- }
- TQTextStringChar *ch = data.data() + index;
- for ( int i = 0; i < len; ++i ) {
- ch->x = 0;
- ch->lineStart = 0;
- ch->d.format = 0;
- ch->nobreak = FALSE;
- ch->type = TQTextStringChar::Regular;
- ch->d.format = f;
- ch->rightToLeft = 0;
- ch->c = tqunicode[i];
- ++ch;
- }
- bidiDirty = TRUE;
-}
-
-TQTextString::~TQTextString()
-{
- clear();
-}
-
-void TQTextString::insert( int index, TQTextStringChar *c, bool doAddRefFormat )
-{
- int os = data.size();
- data.resize( data.size() + 1, TQGArray::SpeedOptim );
- if ( index < os ) {
- memmove( data.data() + index + 1, data.data() + index,
- sizeof( TQTextStringChar ) * ( os - index ) );
- }
- TQTextStringChar &ch = data[ (int)index ];
- ch.c = c->c;
- ch.x = 0;
- ch.lineStart = 0;
- ch.rightToLeft = 0;
- ch.d.format = 0;
- ch.type = TQTextStringChar::Regular;
- ch.nobreak = FALSE;
- if ( doAddRefFormat && c->format() )
- c->format()->addRef();
- ch.setFormat( c->format() );
- bidiDirty = TRUE;
-}
-
-int TQTextString::appendParagraphs( TQTextParagraph *start, TQTextParagraph *end )
-{
- int paragCount = 0;
- int newLength = data.size();
- TQTextParagraph *p = start;
- for (; p != end; p = p->next()) {
- newLength += p->length();
- ++paragCount;
- }
-
- const int oldLength = data.size();
- data.resize(newLength, TQGArray::SpeedOptim);
-
- TQTextStringChar *d = &data[oldLength];
- for (p = start; p != end; p = p->next()) {
- const TQTextStringChar * const src = p->at(0);
- int i = 0;
- for (; i < p->length() - 1; ++i) {
- d[i].c = src[i].c;
- d[i].x = 0;
- d[i].lineStart = 0;
- d[i].rightToLeft = 0;
- d[i].type = TQTextStringChar::Regular;
- d[i].nobreak = FALSE;
- d[i].d.format = src[i].format();
- if (d[i].d.format)
- d[i].d.format->addRef();
- }
- d[i].x = 0;
- d[i].lineStart = 0;
- d[i].nobreak = FALSE;
- d[i].type = TQTextStringChar::Regular;
- d[i].d.format = 0;
- d[i].rightToLeft = 0;
- d[i].c = '\n';
- d += p->length();
- }
-
- bidiDirty = TRUE;
- return paragCount;
-}
-
-void TQTextString::truncate( int index )
-{
- index = TQMAX( index, 0 );
- index = TQMIN( index, (int)data.size() - 1 );
- if ( index < (int)data.size() ) {
- for ( int i = index + 1; i < (int)data.size(); ++i ) {
- TQTextStringChar &ch = data[ i ];
-#ifndef TQT_NO_TEXTCUSTOMITEM
- if ( !(ch.type == TQTextStringChar::Regular) ) {
- delete ch.customItem();
- if ( ch.d.custom->format )
- ch.d.custom->format->removeRef();
- delete ch.d.custom;
- ch.d.custom = 0;
- } else
-#endif
- if ( ch.format() ) {
- ch.format()->removeRef();
- }
- }
- }
- data.truncate( index );
- bidiDirty = TRUE;
-}
-
-void TQTextString::remove( int index, int len )
-{
- for ( int i = index; i < (int)data.size() && i - index < len; ++i ) {
- TQTextStringChar &ch = data[ i ];
-#ifndef TQT_NO_TEXTCUSTOMITEM
- if ( !(ch.type == TQTextStringChar::Regular) ) {
- delete ch.customItem();
- if ( ch.d.custom->format )
- ch.d.custom->format->removeRef();
- delete ch.d.custom;
- ch.d.custom = 0;
- } else
-#endif
- if ( ch.format() ) {
- ch.format()->removeRef();
- }
- }
- memmove( data.data() + index, data.data() + index + len,
- sizeof( TQTextStringChar ) * ( data.size() - index - len ) );
- data.resize( data.size() - len, TQGArray::SpeedOptim );
- bidiDirty = TRUE;
-}
-
-void TQTextString::clear()
-{
- for ( int i = 0; i < (int)data.count(); ++i ) {
- TQTextStringChar &ch = data[ i ];
-#ifndef TQT_NO_TEXTCUSTOMITEM
- if ( !(ch.type == TQTextStringChar::Regular) ) {
- if ( ch.customItem() && ch.customItem()->placement() == TQTextCustomItem::PlaceInline )
- delete ch.customItem();
- if ( ch.d.custom->format )
- ch.d.custom->format->removeRef();
- delete ch.d.custom;
- ch.d.custom = 0;
- } else
-#endif
- if ( ch.format() ) {
- ch.format()->removeRef();
- }
- }
- data.resize( 0 );
- bidiDirty = TRUE;
-}
-
-void TQTextString::setFormat( int index, TQTextFormat *f, bool useCollection )
-{
- TQTextStringChar &ch = data[ index ];
- if ( useCollection && ch.format() )
- ch.format()->removeRef();
- ch.setFormat( f );
-}
-
-void TQTextString::checkBidi() const
-{
- TQTextString *that = (TQTextString *)this;
- that->bidiDirty = FALSE;
- int length = data.size();
- if ( !length ) {
- that->bidi = FALSE;
- that->rightToLeft = dir == TQChar::DirR;
- return;
- }
- const TQTextStringChar *start = data.data();
- const TQTextStringChar *end = start + length;
-
- ((TQTextString *)this)->stringCache = toString(data);
-
-
- // determines the properties we need for layouting
- TQTextEngine textEngine( toString(), 0 );
- textEngine.direction = (TQChar::Direction) dir;
- textEngine.itemize(TQTextEngine::SingleLine);
- const TQCharAttributes *ca = textEngine.attributes() + length-1;
- TQTextStringChar *ch = (TQTextStringChar *)end - 1;
- TQScriptItem *item = &textEngine.items[textEngine.items.size()-1];
- unsigned char bidiLevel = item->analysis.bidiLevel;
- if ( bidiLevel )
- that->bidi = TRUE;
- int pos = length-1;
- while ( ch >= start ) {
- if ( item->position > pos ) {
- --item;
- TQ_ASSERT( item >= &textEngine.items[0] );
- TQ_ASSERT( item < &textEngine.items[textEngine.items.size()] );
- bidiLevel = item->analysis.bidiLevel;
- if ( bidiLevel )
- that->bidi = TRUE;
- }
- ch->softBreak = ca->softBreak;
- ch->whiteSpace = ca->whiteSpace;
- ch->charStop = ca->charStop;
- ch->wordStop = ca->wordStop;
- ch->bidiLevel = bidiLevel;
- ch->rightToLeft = (bidiLevel%2);
- --ch;
- --ca;
- --pos;
- }
-
- if ( dir == TQChar::DirR ) {
- that->bidi = TRUE;
- that->rightToLeft = TRUE;
- } else if ( dir == TQChar::DirL ) {
- that->rightToLeft = FALSE;
- } else {
- that->rightToLeft = (textEngine.direction == TQChar::DirR);
- }
-}
-
-void TQTextDocument::setStyleSheet( TQStyleSheet *s )
-{
- if ( !s )
- return;
- sheet_ = s;
- list_tm = list_bm = par_tm = par_bm = 12;
- list_lm = 40;
- li_tm = li_bm = 0;
- TQStyleSheetItem* item = s->item( "ol" );
- if ( item ) {
- list_tm = TQMAX(0,item->margin( TQStyleSheetItem::MarginTop ));
- list_bm = TQMAX(0,item->margin( TQStyleSheetItem::MarginBottom ));
- list_lm = TQMAX(0,item->margin( TQStyleSheetItem::MarginLeft ));
- }
- if ( (item = s->item( "li" ) ) ) {
- li_tm = TQMAX(0,item->margin( TQStyleSheetItem::MarginTop ));
- li_bm = TQMAX(0,item->margin( TQStyleSheetItem::MarginBottom ));
- }
- if ( (item = s->item( "p" ) ) ) {
- par_tm = TQMAX(0,item->margin( TQStyleSheetItem::MarginTop ));
- par_bm = TQMAX(0,item->margin( TQStyleSheetItem::MarginBottom ));
- }
-}
-
-void TQTextDocument::setUnderlineLinks( bool b ) {
- underlLinks = b;
- for ( TQTextDocument *d = childList.first(); d; d = childList.next() )
- d->setUnderlineLinks( b );
-}
-
-void TQTextStringChar::setFormat( TQTextFormat *f )
-{
- if ( type == Regular ) {
- d.format = f;
- } else {
-#ifndef TQT_NO_TEXTCUSTOMITEM
- if ( !d.custom ) {
- d.custom = new CustomData;
- d.custom->custom = 0;
- }
- d.custom->format = f;
-#endif
- }
-}
-
-#ifndef TQT_NO_TEXTCUSTOMITEM
-void TQTextStringChar::setCustomItem( TQTextCustomItem *i )
-{
- if ( type == Regular ) {
- TQTextFormat *f = format();
- d.custom = new CustomData;
- d.custom->format = f;
- } else {
- delete d.custom->custom;
- }
- d.custom->custom = i;
- type = (type == Anchor ? CustomAnchor : Custom);
-}
-
-void TQTextStringChar::loseCustomItem()
-{
- if ( type == Custom ) {
- TQTextFormat *f = d.custom->format;
- d.custom->custom = 0;
- delete d.custom;
- type = Regular;
- d.format = f;
- } else if ( type == CustomAnchor ) {
- d.custom->custom = 0;
- type = Anchor;
- }
-}
-
-#endif
-
-TQString TQTextStringChar::anchorName() const
-{
- if ( type == Regular )
- return TQString::null;
- else
- return d.custom->anchorName;
-}
-
-TQString TQTextStringChar::anchorHref() const
-{
- if ( type == Regular )
- return TQString::null;
- else
- return d.custom->anchorHref;
-}
-
-void TQTextStringChar::setAnchor( const TQString& name, const TQString& href )
-{
- if ( type == Regular ) {
- TQTextFormat *f = format();
- d.custom = new CustomData;
-#ifndef TQT_NO_TEXTCUSTOMITEM
- d.custom->custom = 0;
-#endif
- d.custom->format = f;
- type = Anchor;
- } else if ( type == Custom ) {
- type = CustomAnchor;
- }
- d.custom->anchorName = name;
- d.custom->anchorHref = href;
-}
-
-
-int TQTextString::width( int idx ) const
-{
- int w = 0;
- TQTextStringChar *c = &at( idx );
- if ( !c->charStop || c->c.tqunicode() == 0xad || c->c.tqunicode() == 0x2028 )
- return 0;
-#ifndef TQT_NO_TEXTCUSTOMITEM
- if( c->isCustom() ) {
- if( c->customItem()->placement() == TQTextCustomItem::PlaceInline )
- w = c->customItem()->width;
- } else
-#endif
- {
- int r = c->c.row();
- if(r < 0x06
-#ifndef TQ_WS_WIN
- // Uniscribe's handling of Asian makes the condition below fail.
- || (r > 0x1f && !(r > 0xd7 && r < 0xe0))
-#endif
- ) {
- w = c->format()->width( c->c );
- } else {
- w = c->format()->width(toString(), idx);
- }
- }
- return w;
-}
-
-// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-TQTextParagraph::TQTextParagraph( TQTextDocument *d, TQTextParagraph *pr, TQTextParagraph *nx, bool updateIds )
- : p( pr ), n( nx ), docOrPseudo( d ),
- changed(FALSE), firstFormat(TRUE), firstPProcess(TRUE), needPreProcess(FALSE), fullWidth(TRUE),
- lastInFrame(FALSE), visible(TRUE), breakable(TRUE), movedDown(FALSE),
- mightHaveCustomItems(FALSE), hasdoc( d != 0 ), litem(FALSE), rtext(FALSE),
- align( 0 ), lstyle( TQStyleSheetItem::ListDisc ), invalid( 0 ), mSelections( 0 ),
-#ifndef TQT_NO_TEXTCUSTOMITEM
- mFloatingItems( 0 ),
-#endif
- utm( 0 ), ubm( 0 ), ulm( 0 ), urm( 0 ), uflm( 0 ), ulinespacing( 0 ),
- tabStopWidth(0), minwidth(0), tArray(0), eData( 0 ), ldepth( 0 )
-{
- lstyle = TQStyleSheetItem::ListDisc;
- if ( !hasdoc )
- docOrPseudo = new TQTextParagraphPseudoDocument;
- bgcol = 0;
- list_val = -1;
- painttqdevice = 0;
- TQTextFormat* defFormat = formatCollection()->defaultFormat();
- if ( !hasdoc ) {
- tabStopWidth = defFormat->width( 'x' ) * 8;
- pseudoDocument()->commandHistory = new TQTextCommandHistory( 100 );
- }
-
- if ( p )
- p->n = this;
- if ( n )
- n->p = this;
-
- if ( !p && hasdoc )
- document()->setFirstParagraph( this );
- if ( !n && hasdoc )
- document()->setLastParagraph( this );
-
- state = -1;
-
- if ( p )
- id = p->id + 1;
- else
- id = 0;
- if ( n && updateIds ) {
- TQTextParagraph *s = n;
- while ( s ) {
- s->id = s->p->id + 1;
- s->invalidateStyleCache();
- s = s->n;
- }
- }
-
- str = new TQTextString();
- TQChar ch(' ');
- str->insert( 0, &ch, 1, formatCollection()->defaultFormat() );
-}
-
-TQTextParagraph::~TQTextParagraph()
-{
- delete str;
- if ( hasdoc ) {
- register TQTextDocument *doc = document();
- if ( this == doc->minwParag ) {
- doc->minwParag = 0;
- doc->minw = 0;
- }
- if ( this == doc->curParag )
- doc->curParag = 0;
- } else {
- delete pseudoDocument();
- }
- delete [] tArray;
- delete eData;
- QMap<int, TQTextLineStart*>::Iterator it = lineStarts.begin();
- for ( ; it != lineStarts.end(); ++it )
- delete *it;
- if ( mSelections )
- delete mSelections;
-#ifndef TQT_NO_TEXTCUSTOMITEM
- if ( mFloatingItems )
- delete mFloatingItems;
-#endif
- if ( p )
- p->setNext( n );
- if ( n )
- n->setPrev( p );
- delete bgcol;
-}
-
-void TQTextParagraph::setNext( TQTextParagraph *s )
-{
- n = s;
- if ( !n && hasdoc )
- document()->setLastParagraph( this );
-}
-
-void TQTextParagraph::setPrev( TQTextParagraph *s )
-{
- p = s;
- if ( !p && hasdoc )
- document()->setFirstParagraph( this );
-}
-
-void TQTextParagraph::tqinvalidate( int chr )
-{
- if ( invalid < 0 )
- invalid = chr;
- else
- invalid = TQMIN( invalid, chr );
-#ifndef TQT_NO_TEXTCUSTOMITEM
- if ( mFloatingItems ) {
- for ( TQTextCustomItem *i = mFloatingItems->first(); i; i = mFloatingItems->next() )
- i->ypos = -1;
- }
-#endif
- invalidateStyleCache();
-}
-
-void TQTextParagraph::invalidateStyleCache()
-{
- if ( list_val < 0 )
- list_val = -1;
-}
-
-
-void TQTextParagraph::insert( int index, const QString &s )
-{
- insert( index, s.tqunicode(), s.length() );
-}
-
-void TQTextParagraph::insert( int index, const QChar *tqunicode, int len )
-{
- if ( hasdoc && !document()->useFormatCollection() && document()->preProcessor() )
- str->insert( index, tqunicode, len,
- document()->preProcessor()->format( TQTextPreProcessor::Standard ) );
- else
- str->insert( index, tqunicode, len, formatCollection()->defaultFormat() );
- tqinvalidate( index );
- needPreProcess = TRUE;
-}
-
-void TQTextParagraph::truncate( int index )
-{
- str->truncate( index );
- insert( length(), " " );
- needPreProcess = TRUE;
-}
-
-void TQTextParagraph::remove( int index, int len )
-{
- if ( index + len - str->length() > 0 )
- return;
-#ifndef TQT_NO_TEXTCUSTOMITEM
- for ( int i = index; i < index + len; ++i ) {
- TQTextStringChar *c = at( i );
- if ( hasdoc && c->isCustom() ) {
- document()->unregisterCustomItem( c->customItem(), this );
- }
- }
-#endif
- str->remove( index, len );
- tqinvalidate( 0 );
- needPreProcess = TRUE;
-}
-
-void TQTextParagraph::join( TQTextParagraph *s )
-{
- int oh = r.height() + s->r.height();
- n = s->n;
- if ( n )
- n->p = this;
- else if ( hasdoc )
- document()->setLastParagraph( this );
-
- int start = str->length();
- if ( length() > 0 && at( length() - 1 )->c == ' ' ) {
- remove( length() - 1, 1 );
- --start;
- }
- append( s->str->toString(), TRUE );
-
- for ( int i = 0; i < s->length(); ++i ) {
- if ( !hasdoc || document()->useFormatCollection() ) {
- s->str->at( i ).format()->addRef();
- str->setFormat( i + start, s->str->at( i ).format(), TRUE );
- }
-#ifndef TQT_NO_TEXTCUSTOMITEM
- if ( s->str->at( i ).isCustom() ) {
- TQTextCustomItem * item = s->str->at( i ).customItem();
- str->at( i + start ).setCustomItem( item );
- s->str->at( i ).loseCustomItem();
- if ( hasdoc ) {
- document()->unregisterCustomItem( item, s );
- document()->registerCustomItem( item, this );
- }
- }
- if ( s->str->at( i ).isAnchor() ) {
- str->at( i + start ).setAnchor( s->str->at( i ).anchorName(),
- s->str->at( i ).anchorHref() );
- }
-#endif
- }
-
- if ( !extraData() && s->extraData() ) {
- setExtraData( s->extraData() );
- s->setExtraData( 0 );
- } else if ( extraData() && s->extraData() ) {
- extraData()->join( s->extraData() );
- }
- delete s;
- tqinvalidate( 0 );
- r.setHeight( oh );
- needPreProcess = TRUE;
- if ( n ) {
- TQTextParagraph *s = n;
- s->tqinvalidate( 0 );
- while ( s ) {
- s->id = s->p->id + 1;
- s->state = -1;
- s->needPreProcess = TRUE;
- s->changed = TRUE;
- s->invalidateStyleCache();
- s = s->n;
- }
- }
- format();
- state = -1;
-}
-
-void TQTextParagraph::move( int &dy )
-{
- if ( dy == 0 )
- return;
- changed = TRUE;
- r.moveBy( 0, dy );
-#ifndef TQT_NO_TEXTCUSTOMITEM
- if ( mFloatingItems ) {
- for ( TQTextCustomItem *i = mFloatingItems->first(); i; i = mFloatingItems->next() )
- i->ypos += dy;
- }
-#endif
- if ( p )
- p->lastInFrame = TRUE;
-
- // do page breaks if required
- if ( hasdoc && document()->isPageBreakEnabled() ) {
- int shift;
- if ( ( shift = document()->formatter()->formatVertically( document(), this ) ) ) {
- if ( p )
- p->setChanged( TRUE );
- dy += shift;
- }
- }
-}
-
-void TQTextParagraph::format( int start, bool doMove )
-{
- if ( !str || str->length() == 0 || !formatter() )
- return;
-
- if ( hasdoc &&
- document()->preProcessor() &&
- ( needPreProcess || state == -1 ) )
- document()->preProcessor()->process( document(), this, invalid <= 0 ? 0 : invalid );
- needPreProcess = FALSE;
-
- if ( invalid == -1 )
- return;
-
- r.moveTopLeft( TQPoint( documentX(), p ? p->r.y() + p->r.height() : documentY() ) );
- if ( p )
- p->lastInFrame = FALSE;
-
- movedDown = FALSE;
- bool formattedAgain = FALSE;
-
- formatAgain:
-
- r.setWidth( documentWidth() );
-#ifndef TQT_NO_TEXTCUSTOMITEM
- if ( hasdoc && mFloatingItems ) {
- for ( TQTextCustomItem *i = mFloatingItems->first(); i; i = mFloatingItems->next() ) {
- i->ypos = r.y();
- if ( i->placement() == TQTextCustomItem::PlaceRight ) {
- i->xpos = r.x() + r.width() - i->width;
- }
- }
- }
-#endif
- QMap<int, TQTextLineStart*> oldLineStarts = lineStarts;
- lineStarts.clear();
- int y = formatter()->format( document(), this, start, oldLineStarts );
-
-
- r.setWidth( TQMAX( r.width(), formatter()->minimumWidth() ) );
-
-
- QMap<int, TQTextLineStart*>::Iterator it = oldLineStarts.begin();
-
- for ( ; it != oldLineStarts.end(); ++it )
- delete *it;
-
- if ( !hasdoc ) { // qt_format_text bounding rect handling
- it = lineStarts.begin();
- int usedw = 0;
- for ( ; it != lineStarts.end(); ++it )
- usedw = TQMAX( usedw, (*it)->w );
- if ( r.width() <= 0 ) {
- // if the user specifies an invalid rect, this means that the
- // bounding box should grow to the width that the text actually
- // needs
- r.setWidth( usedw );
- } else {
- r.setWidth( TQMIN( usedw, r.width() ) );
- }
- }
-
- if ( y != r.height() )
- r.setHeight( y );
-
- if ( !visible ) {
- r.setHeight( 0 );
- } else {
- int minw = minwidth = formatter()->minimumWidth();
- int wused = formatter()->widthUsed();
- wused = TQMAX( minw, wused );
- if ( hasdoc ) {
- document()->setMinimumWidth( minw, wused, this );
- } else {
- pseudoDocument()->minw = TQMAX( pseudoDocument()->minw, minw );
- pseudoDocument()->wused = TQMAX( pseudoDocument()->wused, wused );
- }
- }
-
- // do page breaks if required
- if ( hasdoc && document()->isPageBreakEnabled() ) {
- int shift = document()->formatter()->formatVertically( document(), this );
- if ( shift && !formattedAgain ) {
- formattedAgain = TRUE;
- goto formatAgain;
- }
- }
-
- if ( n && doMove && n->invalid == -1 && r.y() + r.height() != n->r.y() ) {
- int dy = ( r.y() + r.height() ) - n->r.y();
- TQTextParagraph *s = n;
- bool makeInvalid = p && p->lastInFrame;
- while ( s && dy ) {
- if ( !s->isFullWidth() )
- makeInvalid = TRUE;
- if ( makeInvalid )
- s->tqinvalidate( 0 );
- s->move( dy );
- if ( s->lastInFrame )
- makeInvalid = TRUE;
- s = s->n;
- }
- }
-
- firstFormat = FALSE;
- changed = TRUE;
- invalid = -1;
- //##### string()->setTextChanged( FALSE );
-}
-
-int TQTextParagraph::lineHeightOfChar( int i, int *bl, int *y ) const
-{
- if ( !isValid() )
- ( (TQTextParagraph*)this )->format();
-
- QMap<int, TQTextLineStart*>::ConstIterator it = lineStarts.end();
- --it;
- for ( ;; ) {
- if ( i >= it.key() ) {
- if ( bl )
- *bl = ( *it )->baseLine;
- if ( y )
- *y = ( *it )->y;
- return ( *it )->h;
- }
- if ( it == lineStarts.begin() )
- break;
- --it;
- }
-
- qWarning( "TQTextParagraph::lineHeightOfChar: couldn't find lh for %d", i );
- return 15;
-}
-
-TQTextStringChar *TQTextParagraph::lineStartOfChar( int i, int *index, int *line ) const
-{
- if ( !isValid() )
- ( (TQTextParagraph*)this )->format();
-
- int l = (int)lineStarts.count() - 1;
- QMap<int, TQTextLineStart*>::ConstIterator it = lineStarts.end();
- --it;
- for ( ;; ) {
- if ( i >= it.key() ) {
- if ( index )
- *index = it.key();
- if ( line )
- *line = l;
- return &str->at( it.key() );
- }
- if ( it == lineStarts.begin() )
- break;
- --it;
- --l;
- }
-
- qWarning( "TQTextParagraph::lineStartOfChar: couldn't find %d", i );
- return 0;
-}
-
-int TQTextParagraph::lines() const
-{
- if ( !isValid() )
- ( (TQTextParagraph*)this )->format();
-
- return (int)lineStarts.count();
-}
-
-TQTextStringChar *TQTextParagraph::lineStartOfLine( int line, int *index ) const
-{
- if ( !isValid() )
- ( (TQTextParagraph*)this )->format();
-
- if ( line >= 0 && line < (int)lineStarts.count() ) {
- QMap<int, TQTextLineStart*>::ConstIterator it = lineStarts.begin();
- while ( line-- > 0 )
- ++it;
- int i = it.key();
- if ( index )
- *index = i;
- return &str->at( i );
- }
-
- qWarning( "TQTextParagraph::lineStartOfLine: couldn't find %d", line );
- return 0;
-}
-
-int TQTextParagraph::leftGap() const
-{
- if ( !isValid() )
- ( (TQTextParagraph*)this )->format();
-
- if ( str->length() == 0)
- return 0;
-
- int line = 0;
- int x = str->length() ? str->at(0).x : 0; /* set x to x of first char */
- if ( str->isBidi() ) {
- for ( int i = 1; i < str->length()-1; ++i )
- x = TQMIN(x, str->at(i).x);
- return x;
- }
-
- QMap<int, TQTextLineStart*>::ConstIterator it = lineStarts.begin();
- while (line < (int)lineStarts.count()) {
- int i = it.key(); /* char index */
- x = TQMIN(x, str->at(i).x);
- ++it;
- ++line;
- }
- return x;
-}
-
-void TQTextParagraph::setFormat( int index, int len, TQTextFormat *f, bool useCollection, int flags )
-{
- if ( !f )
- return;
- if ( index < 0 )
- index = 0;
- if ( index > str->length() - 1 )
- index = str->length() - 1;
- if ( index + len >= str->length() )
- len = str->length() - index;
-
- TQTextFormatCollection *fc = 0;
- if ( useCollection )
- fc = formatCollection();
- TQTextFormat *of;
- for ( int i = 0; i < len; ++i ) {
- of = str->at( i + index ).format();
- if ( !changed && ( !of || f->key() != of->key() ) )
- changed = TRUE;
- if ( invalid == -1 &&
- ( f->font().family() != of->font().family() ||
- f->font().pointSize() != of->font().pointSize() ||
- f->font().weight() != of->font().weight() ||
- f->font().italic() != of->font().italic() ||
- f->vAlign() != of->vAlign() ) ) {
- tqinvalidate( 0 );
- }
- if ( flags == -1 || flags == TQTextFormat::Format || !fc ) {
- if ( fc )
- f = fc->format( f );
- str->setFormat( i + index, f, useCollection );
- } else {
- TQTextFormat *fm = fc->format( of, f, flags );
- str->setFormat( i + index, fm, useCollection );
- }
- }
-}
-
-void TQTextParagraph::indent( int *oldIndent, int *newIndent )
-{
- if ( !hasdoc || !document()->indent() || isListItem() ) {
- if ( oldIndent )
- *oldIndent = 0;
- if ( newIndent )
- *newIndent = 0;
- if ( oldIndent && newIndent )
- *newIndent = *oldIndent;
- return;
- }
- document()->indent()->indent( document(), this, oldIndent, newIndent );
-}
-
-void TQTextParagraph::paint( TQPainter &painter, const TQColorGroup &cg, TQTextCursor *cursor, bool drawSelections,
- int clipx, int clipy, int clipw, int cliph )
-{
- if ( !visible )
- return;
- int i, y, h, baseLine, xstart, xend = 0;
- i = y =h = baseLine = 0;
- TQRect cursorRect;
- drawSelections &= ( mSelections != 0 );
- // macintosh full-width selection style
- bool fullWidthStyle = TQApplication::tqstyle().tqstyleHint(TQStyle::SH_RichText_FullWidthSelection);
- int fullSelectionWidth = 0;
- if ( drawSelections && fullWidthStyle )
- fullSelectionWidth = (hasdoc ? document()->width() : r.width());
-
- TQString qstr = str->toString();
- // detach string
- qstr.setLength(qstr.length());
- // ### workaround so that \n are not drawn, actually this should
- // be fixed in TQFont somewhere (under Windows you get ugly boxes
- // otherwise)
- TQChar* uc = (TQChar*) qstr.tqunicode();
- for ( int ii = 0; ii < qstr.length(); ii++ )
- if ( uc[(int)ii]== '\n' || uc[(int)ii] == '\t' )
- uc[(int)ii] = 0x20;
-
- int line = -1;
- int paintStart = 0;
- TQTextStringChar *chr = 0;
- TQTextStringChar *nextchr = at( 0 );
- for ( i = 0; i < length(); i++ ) {
- chr = nextchr;
- if ( i < length()-1 )
- nextchr = at( i+1 );
-
- // we flush at end of document
- bool flush = (i == length()-1);
- bool ignoreSoftHyphen = FALSE;
- if ( !flush ) {
- // we flush at end of line
- flush |= nextchr->lineStart;
- // we flush on format changes
- flush |= ( nextchr->format() != chr->format() );
- // we flush on link changes
- flush |= ( nextchr->isLink() != chr->isLink() );
- // we flush on start of run
- flush |= ( nextchr->bidiLevel != chr->bidiLevel );
- // we flush on bidi changes
- flush |= ( nextchr->rightToLeft != chr->rightToLeft );
- // we flush before and after tabs
- flush |= ( chr->c == '\t' || nextchr->c == '\t' );
- // we flush on soft hypens
- if (chr->c.tqunicode() == 0xad) {
- flush = TRUE;
- if (!nextchr->lineStart)
- ignoreSoftHyphen = TRUE;
- }
- // we flush on custom items
- flush |= chr->isCustom();
- // we flush before custom items
- flush |= nextchr->isCustom();
- // when painting justified, we flush on spaces
- if ((tqalignment() & TQt::AlignJustify) == TQt::AlignJustify )
- flush |= chr->whiteSpace;
- }
-
- // init a new line
- if ( chr->lineStart ) {
- ++line;
- paintStart = i;
- lineInfo( line, y, h, baseLine );
- if ( clipy != -1 && cliph != 0 && y + r.y() - h > clipy + cliph ) { // outside clip area, leave
- break;
- }
-
- // if this is the first line and we are a list item, draw the the bullet label
- if ( line == 0 && isListItem() ) {
- int x = chr->x;
- if (str->isBidi()) {
- if (str->isRightToLeft()) {
- x = chr->x + str->width(0);
- for (int k = 1; k < length(); ++k) {
- if (str->at(k).lineStart)
- break;
- x = TQMAX(x, str->at(k).x + str->width(k));
- }
- } else {
- x = chr->x;
- for (int k = 1; k < length(); ++k) {
- if (str->at(k).lineStart)
- break;
- x = TQMIN(x, str->at(k).x);
- }
- }
- }
- drawLabel( &painter, x, y, 0, 0, baseLine, cg );
- }
- }
-
- // check for cursor mark
- if ( cursor && this == cursor->paragraph() && i == cursor->index() ) {
- TQTextStringChar *c = i == 0 ? chr : chr - 1;
- cursorRect.setRect( cursor->x() , y + baseLine - c->format()->ascent(),
- 1, c->format()->height() );
- }
-
- if ( flush ) { // something changed, draw what we have so far
- if ( chr->rightToLeft ) {
- xstart = chr->x;
- xend = at( paintStart )->x + str->width( paintStart );
- } else {
- xstart = at( paintStart )->x;
- xend = chr->x;
- if ( i < length() - 1 ) {
- if ( !str->at( i + 1 ).lineStart &&
- str->at( i + 1 ).rightToLeft == chr->rightToLeft )
- xend = str->at( i + 1 ).x;
- else
- xend += str->width( i );
- }
- }
-
- if ( (clipx == -1 || clipw <= 0 || (xend >= clipx && xstart <= clipx + clipw)) &&
- ( clipy == -1 || clipy < y+r.y()+h ) ) {
- if ( !chr->isCustom() )
- drawString( painter, qstr, paintStart, i - paintStart + (ignoreSoftHyphen ? 0 : 1), xstart, y,
- baseLine, xend-xstart, h, drawSelections, fullSelectionWidth,
- chr, cg, chr->rightToLeft );
-#ifndef TQT_NO_TEXTCUSTOMITEM
- else if ( chr->customItem()->placement() == TQTextCustomItem::PlaceInline ) {
- bool inSelection = FALSE;
- if (drawSelections) {
- QMap<int, TQTextParagraphSelection>::ConstIterator it = mSelections->find( TQTextDocument::Standard );
- inSelection = (it != mSelections->end() && (*it).start <= i && (*it).end > i);
- }
- chr->customItem()->draw( &painter, chr->x, y,
- clipx == -1 ? clipx : (clipx - r.x()),
- clipy == -1 ? clipy : (clipy - r.y()),
- clipw, cliph, cg, inSelection );
- }
-#endif
- }
- paintStart = i+1;
- }
-
- }
-
- // time to draw the cursor
- const int cursor_extent = 4;
- if ( !cursorRect.isNull() && cursor &&
- ((clipx == -1 || clipw == -1) || (cursorRect.right()+cursor_extent >= clipx && cursorRect.left()-cursor_extent <= clipx + clipw)) ) {
- painter.fillRect( cursorRect, cg.color( TQColorGroup::Text ) );
- painter.save();
- if ( string()->isBidi() ) {
- if ( at( cursor->index() )->rightToLeft ) {
- painter.setPen( TQt::black );
- painter.drawLine( cursorRect.x(), cursorRect.y(), cursorRect.x() - cursor_extent / 2, cursorRect.y() + cursor_extent / 2 );
- painter.drawLine( cursorRect.x(), cursorRect.y() + cursor_extent, cursorRect.x() - cursor_extent / 2, cursorRect.y() + cursor_extent / 2 );
- } else {
- painter.setPen( TQt::black );
- painter.drawLine( cursorRect.x(), cursorRect.y(), cursorRect.x() + cursor_extent / 2, cursorRect.y() + cursor_extent / 2 );
- painter.drawLine( cursorRect.x(), cursorRect.y() + cursor_extent, cursorRect.x() + cursor_extent / 2, cursorRect.y() + cursor_extent / 2 );
- }
- }
- painter.restore();
- }
-}
-
-//#define BIDI_DEBUG
-
-void TQTextParagraph::setColorForSelection( TQColor &color, TQPainter &painter,
- const TQColorGroup& cg, int selection )
-{
- if (selection < 0)
- return;
- color = ( hasdoc && selection != TQTextDocument::Standard ) ?
- document()->selectionColor( selection ) :
- cg.color( TQColorGroup::Highlight );
- if ( selection == TQTextDocument::IMCompositionText ) {
-#ifndef TQ_WS_MACX
- int h1, s1, v1, h2, s2, v2;
- TQT_TQCOLOR_OBJECT(cg.color( TQColorGroup::Base )).hsv( &h1, &s1, &v1 );
- TQT_TQCOLOR_OBJECT(cg.color( TQColorGroup::Background )).hsv( &h2, &s2, &v2 );
- color.setHsv( h1, s1, ( v1 + v2 ) / 2 );
-#else
- color = TQt::lightGray;
-#endif
- painter.setPen( cg.color( TQColorGroup::Text ) );
- } else if ( selection == TQTextDocument::IMSelectionText ) {
- color = cg.color( TQColorGroup::Dark );
- painter.setPen( cg.color( TQColorGroup::BrightText ) );
- } else if ( !hasdoc || document()->invertSelectionText( selection ) ) {
- painter.setPen( cg.color( TQColorGroup::HighlightedText ) );
- }
-}
-
-void TQTextParagraph::drawString( TQPainter &painter, const TQString &str, int start, int len, int xstart,
- int y, int baseLine, int w, int h, bool drawSelections, int fullSelectionWidth,
- TQTextStringChar *formatChar, const TQColorGroup& cg,
- bool rightToLeft )
-{
- bool plainText = hasdoc ? document()->textFormat() == TQt::PlainText : FALSE;
- TQTextFormat* format = formatChar->format();
-
- if ( !plainText || (hasdoc && (format->color() != document()->formatCollection()->defaultFormat()->color())) )
- painter.setPen( TQPen( format->color() ) );
- else
- painter.setPen( cg.text() );
- painter.setFont( format->font() );
-
- if ( hasdoc && formatChar->isAnchor() && !formatChar->anchorHref().isEmpty() ) {
- if ( format->useLinkColor() )
- painter.setPen(document()->linkColor.isValid() ? document()->linkColor : cg.link());
- if ( document()->underlineLinks() ) {
- TQFont fn = format->font();
- fn.setUnderline( TRUE );
- painter.setFont( fn );
- }
- }
-
- TQPainter::TextDirection dir = rightToLeft ? TQPainter::RTL : TQPainter::LTR;
-
- int real_length = len;
- if (len && dir != TQPainter::RTL && start + len == length() ) // don't draw the last character (trailing space)
- len--;
- if (len && str.tqunicode()[start+len-1] == TQChar_linesep)
- len--;
-
-
- TQTextFormat::VerticalAlignment vAlign = format->vAlign();
- if ( vAlign != TQTextFormat::AlignNormal ) {
- // sub or superscript
- TQFont f( painter.font() );
- if ( format->fontSizesInPixels() )
- f.setPixelSize( ( f.pixelSize() * 2 ) / 3 );
- else
- f.setPointSize( ( f.pointSize() * 2 ) / 3 );
- painter.setFont( f );
- int h = painter.fontMetrics().height();
- baseLine += (vAlign == TQTextFormat::AlignSubScript) ? h/6 : -h/2;
- }
-
- bool allSelected = FALSE;
- if (drawSelections) {
- QMap<int, TQTextParagraphSelection>::ConstIterator it = mSelections->find( TQTextDocument::Standard );
- allSelected = (it != mSelections->end() && (*it).start <= start && (*it).end >= start+len);
- }
- if (!allSelected)
- painter.drawText(xstart, y + baseLine, str, start, len, dir);
-
-#ifdef BIDI_DEBUG
- painter.save();
- painter.setPen ( TQt::red );
- painter.drawLine( xstart, y, xstart, y + baseLine );
- painter.drawLine( xstart, y + baseLine/2, xstart + 10, y + baseLine/2 );
- int w = 0;
- int i = 0;
- while( i < len )
- w += painter.fontMetrics().charWidth( str, start + i++ );
- painter.setPen ( TQt::blue );
- painter.drawLine( xstart + w - 1, y, xstart + w - 1, y + baseLine );
- painter.drawLine( xstart + w - 1, y + baseLine/2, xstart + w - 1 - 10, y + baseLine/2 );
- painter.restore();
-#endif
-
- // check if we are in a selection and draw it
- if (drawSelections) {
- QMap<int, TQTextParagraphSelection>::ConstIterator it = mSelections->end();
- while ( it != mSelections->begin() ) {
- --it;
- int selStart = (*it).start;
- int selEnd = (*it).end;
- int tmpw = w;
-
- selStart = TQMAX(selStart, start);
- int real_selEnd = TQMIN(selEnd, start+real_length);
- selEnd = TQMIN(selEnd, start+len);
- bool extendRight = FALSE;
- bool extendLeft = FALSE;
- bool selWrap = (real_selEnd == length()-1 && n && n->hasSelection(it.key()));
- if (selWrap || this->str->at(real_selEnd).lineStart) {
- extendRight = (fullSelectionWidth != 0);
- if (!extendRight && !rightToLeft)
- tmpw += painter.fontMetrics().width(' ');
- }
- if (fullSelectionWidth && (selStart == 0 || this->str->at(selStart).lineStart)) {
- extendLeft = TRUE;
- }
- if (this->str->isRightToLeft() != rightToLeft)
- extendLeft = extendRight = FALSE;
-
- if (this->str->isRightToLeft()) {
- bool tmp = extendLeft;
- extendLeft = extendRight;
- extendRight = tmp;
- }
-
- if ((selStart < real_selEnd) ||
- (selWrap && fullSelectionWidth && extendRight &&
- // don't draw the standard selection on a printer=
- ((it.key() != TQTextDocument::Standard) || (!is_printer( &painter))))) {
- int selection = it.key();
- TQColor color;
- setColorForSelection( color, painter, cg, selection );
- if (selStart != start || selEnd != start + len || selWrap) {
- // have to clip
- painter.save();
- int cs, ce;
- if (rightToLeft) {
- cs = (selEnd != start + len) ?
- this->str->at(this->str->previousCursorPosition(selEnd)).x : xstart;
- ce = (selStart != start) ?
- this->str->at(this->str->previousCursorPosition(selStart)).x : xstart+tmpw;
- } else {
- cs = (selStart != start) ? this->str->at(selStart).x : xstart;
- ce = (selEnd != start + len) ? this->str->at(selEnd).x : xstart+tmpw;
- }
- TQRect r(cs, y, ce-cs, h);
- if (extendLeft)
- r.setLeft(0);
- if (extendRight)
- r.setRight(fullSelectionWidth);
- TQRegion reg(r);
- if ( painter.hasClipping() )
- reg &= painter.clipRegion(TQPainter::CoordPainter);
- painter.setClipRegion(reg, TQPainter::CoordPainter);
- }
- int xleft = xstart;
- if ( extendLeft ) {
- tmpw += xstart;
- xleft = 0;
- }
- if ( extendRight )
- tmpw = fullSelectionWidth - xleft;
- painter.fillRect( xleft, y, tmpw, h, color );
- painter.drawText( xstart, y + baseLine, str, start, len, dir );
- // draw preedit's underline
- if (selection == TQTextDocument::IMCompositionText)
- painter.drawLine(xstart, y + baseLine + 1, xstart + w, y + baseLine + 1);
- if (selStart != start || selEnd != start + len || selWrap)
- painter.restore();
- }
- }
- }
-
- if ( format->isMisspelled() ) {
- painter.save();
- painter.setPen( TQPen( TQt::red, 1, TQt::DotLine ) );
- painter.drawLine( xstart, y + baseLine + 1, xstart + w, y + baseLine + 1 );
- painter.restore();
- }
-
- if ( hasdoc && formatChar->isAnchor() && !formatChar->anchorHref().isEmpty() &&
- document()->focusIndicator.parag == this &&
- ( (document()->focusIndicator.start >= start &&
- document()->focusIndicator.start + document()->focusIndicator.len <= start + len) ||
- (document()->focusIndicator.start <= start &&
- document()->focusIndicator.start + document()->focusIndicator.len >= start + len )) )
- painter.drawWinFocusRect( TQRect( xstart, y, w, h ) );
-}
-
-void TQTextParagraph::drawLabel( TQPainter* p, int x, int y, int w, int h, int base, const TQColorGroup& cg )
-{
- TQRect r ( x, y, w, h );
- TQStyleSheetItem::ListStyle s = listStyle();
-
- p->save();
- TQTextFormat *format = at( 0 )->format();
- if ( format ) {
- p->setPen( format->color() );
- p->setFont( format->font() );
- }
- TQFontMetrics fm( p->fontMetrics() );
- int size = fm.lineSpacing() / 3;
-
- bool rtl = str->isRightToLeft();
-
- switch ( s ) {
- case TQStyleSheetItem::ListDecimal:
- case TQStyleSheetItem::ListLowerAlpha:
- case TQStyleSheetItem::ListUpperAlpha:
- {
- if ( list_val == -1 ) { // uninitialised list value, calcluate the right one
- int depth = listDepth();
- list_val--;
- // ### evil, square and expensive. This needs to be done when formatting, not when painting
- TQTextParagraph* s = prev();
- int depth_s;
- while ( s && (depth_s = s->listDepth()) >= depth ) {
- if ( depth_s == depth && s->isListItem() )
- list_val--;
- s = s->prev();
- }
- }
-
- int n = list_val;
- if ( n < -1 )
- n = -n - 1;
- TQString l;
- switch ( s ) {
- case TQStyleSheetItem::ListLowerAlpha:
- if ( n < 27 ) {
- l = TQChar( ('a' + (char) (n-1)));
- break;
- }
- case TQStyleSheetItem::ListUpperAlpha:
- if ( n < 27 ) {
- l = TQChar( ('A' + (char) (n-1)));
- break;
- }
- break;
- default: //TQStyleSheetItem::ListDecimal:
- l.setNum( n );
- break;
- }
- if (rtl)
- l.prepend(" .");
- else
- l += TQString::tqfromLatin1(". ");
- int x = ( rtl ? r.left() : r.right() - fm.width(l));
- p->drawText( x, r.top() + base, l );
- }
- break;
- case TQStyleSheetItem::ListSquare:
- {
- int x = rtl ? r.left() + size : r.right() - size*2;
- TQRect er( x, r.top() + fm.height() / 2 - size / 2, size, size );
- p->fillRect( er , cg.brush( TQColorGroup::Text ) );
- }
- break;
- case TQStyleSheetItem::ListCircle:
- {
- int x = rtl ? r.left() + size : r.right() - size*2;
- TQRect er( x, r.top() + fm.height() / 2 - size / 2, size, size);
- p->drawEllipse( er );
- }
- break;
- case TQStyleSheetItem::ListDisc:
- default:
- {
- p->setBrush( cg.brush( TQColorGroup::Text ));
- int x = rtl ? r.left() + size : r.right() - size*2;
- TQRect er( x, r.top() + fm.height() / 2 - size / 2, size, size);
- p->drawEllipse( er );
- p->setBrush( TQt::NoBrush );
- }
- break;
- }
-
- p->restore();
-}
-
-#ifndef TQT_NO_DATASTREAM
-void TQTextParagraph::readStyleInformation( TQDataStream& stream )
-{
- int int_align, int_lstyle;
- uchar uchar_litem, uchar_rtext, uchar_dir;
- stream >> int_align >> int_lstyle >> utm >> ubm >> ulm >> urm >> uflm
- >> ulinespacing >> ldepth >> uchar_litem >> uchar_rtext >> uchar_dir;
- align = int_align; lstyle = (TQStyleSheetItem::ListStyle) int_lstyle;
- litem = uchar_litem; rtext = uchar_rtext; str->setDirection( (TQChar::Direction)uchar_dir );
- TQTextParagraph* s = prev() ? prev() : this;
- while ( s ) {
- s->tqinvalidate( 0 );
- s = s->next();
- }
-}
-
-void TQTextParagraph::writeStyleInformation( TQDataStream& stream ) const
-{
- stream << (int) align << (int) lstyle << utm << ubm << ulm << urm << uflm << ulinespacing << ldepth << (uchar)litem << (uchar)rtext << (uchar)str->direction();
-}
-#endif
-
-
-void TQTextParagraph::setListItem( bool li )
-{
- if ( (bool)litem == li )
- return;
- litem = li;
- changed = TRUE;
- TQTextParagraph* s = prev() ? prev() : this;
- while ( s ) {
- s->tqinvalidate( 0 );
- s = s->next();
- }
-}
-
-void TQTextParagraph::setListDepth( int depth ) {
- if ( !hasdoc || depth == ldepth )
- return;
- ldepth = depth;
- TQTextParagraph* s = prev() ? prev() : this;
- while ( s ) {
- s->tqinvalidate( 0 );
- s = s->next();
- }
-}
-
-int *TQTextParagraph::tabArray() const
-{
- int *ta = tArray;
- if ( !ta && hasdoc )
- ta = document()->tabArray();
- return ta;
-}
-
-int TQTextParagraph::nextTab( int, int x )
-{
- int *ta = tArray;
- if ( hasdoc ) {
- if ( !ta )
- ta = document()->tabArray();
- tabStopWidth = document()->tabStopWidth();
- }
- if ( ta ) {
- int i = 0;
- while ( ta[ i ] ) {
- if ( ta[ i ] >= x )
- return tArray[ i ];
- ++i;
- }
- return tArray[ 0 ];
- } else {
- int d;
- if ( tabStopWidth != 0 )
- d = x / tabStopWidth;
- else
- return x;
- return tabStopWidth * ( d + 1 );
- }
-}
-
-void TQTextParagraph::adjustToPainter( TQPainter *p )
-{
-#ifndef TQT_NO_TEXTCUSTOMITEM
- for ( int i = 0; i < length(); ++i ) {
- if ( at( i )->isCustom() )
- at( i )->customItem()->adjustToPainter( p );
- }
-#endif
-}
-
-TQTextFormatCollection *TQTextParagraph::formatCollection() const
-{
- if ( hasdoc )
- return document()->formatCollection();
- TQTextFormatCollection* fc = &pseudoDocument()->collection;
- if ( painttqdevice != fc->paintDevice() )
- fc->setPaintDevice( painttqdevice );
- return fc;
-}
-
-TQString TQTextParagraph::richText() const
-{
- TQString s;
- TQTextStringChar *formatChar = 0;
- TQString spaces;
- bool doStart = richTextExportStart && richTextExportStart->paragraph() == this;
- bool doEnd = richTextExportEnd && richTextExportEnd->paragraph() == this;
- int i;
- TQString lastAnchorName;
- for ( i = 0; i < length()-1; ++i ) {
- if ( doStart && i && richTextExportStart->index() == i )
- s += "<!--StartFragment-->";
- if ( doEnd && richTextExportEnd->index() == i )
- s += "<!--EndFragment-->";
- TQTextStringChar *c = &str->at( i );
- if ( c->isAnchor() && !c->anchorName().isEmpty() && c->anchorName() != lastAnchorName ) {
- lastAnchorName = c->anchorName();
- if ( c->anchorName().contains( '#' ) ) {
- TQStringList l = TQStringList::split( '#', c->anchorName() );
- for ( TQStringList::ConstIterator it = l.begin(); it != l.end(); ++it )
- s += "<a name=\"" + *it + "\"></a>";
- } else {
- s += "<a name=\"" + c->anchorName() + "\"></a>";
- }
- }
- if ( !formatChar ) {
- s += c->format()->makeFormatChangeTags( formatCollection()->defaultFormat(),
- 0, TQString::null, c->anchorHref() );
- formatChar = c;
- } else if ( ( formatChar->format()->key() != c->format()->key() ) ||
- (c->anchorHref() != formatChar->anchorHref() ) ) {
- s += c->format()->makeFormatChangeTags( formatCollection()->defaultFormat(),
- formatChar->format() , formatChar->anchorHref(), c->anchorHref() );
- formatChar = c;
- }
- if ( c->c == '<' )
- s += "&lt;";
- else if ( c->c == '>' )
- s += "&gt;";
- else if ( c->c =='&' )
- s += "&amp;";
- else if ( c->c =='\"' )
- s += "&quot;";
-#ifndef TQT_NO_TEXTCUSTOMITEM
- else if ( c->isCustom() )
- s += c->customItem()->richText();
-#endif
- else if ( c->c == '\n' || c->c == TQChar_linesep )
- s += "<br />"; // space on purpose for compatibility with Netscape, Lynx & Co.
- else
- s += c->c;
- }
- if ( doEnd && richTextExportEnd->index() == i )
- s += "<!--EndFragment-->";
- if ( formatChar )
- s += formatChar->format()->makeFormatEndTags( formatCollection()->defaultFormat(), formatChar->anchorHref() );
- return s;
-}
-
-void TQTextParagraph::addCommand( TQTextCommand *cmd )
-{
- if ( !hasdoc )
- pseudoDocument()->commandHistory->addCommand( cmd );
- else
- document()->commands()->addCommand( cmd );
-}
-
-TQTextCursor *TQTextParagraph::undo( TQTextCursor *c )
-{
- if ( !hasdoc )
- return pseudoDocument()->commandHistory->undo( c );
- return document()->commands()->undo( c );
-}
-
-TQTextCursor *TQTextParagraph::redo( TQTextCursor *c )
-{
- if ( !hasdoc )
- return pseudoDocument()->commandHistory->redo( c );
- return document()->commands()->redo( c );
-}
-
-int TQTextParagraph::topMargin() const
-{
- int m = 0;
- if ( rtext ) {
- m = isListItem() ? (document()->li_tm/TQMAX(1,listDepth()*listDepth())) :
- ( listDepth() ? 0 : document()->par_tm );
- if ( listDepth() == 1 &&( !prev() || prev()->listDepth() < listDepth() ) )
- m = TQMAX( m, document()->list_tm );
- }
- m += utm;
- return scale( m, TQTextFormat::painter() );
-}
-
-int TQTextParagraph::bottomMargin() const
-{
- int m = 0;
- if ( rtext ) {
- m = isListItem() ? (document()->li_bm/TQMAX(1,listDepth()*listDepth())) :
- ( listDepth() ? 0 : document()->par_bm );
- if ( listDepth() == 1 &&( !next() || next()->listDepth() < listDepth() ) )
- m = TQMAX( m, document()->list_bm );
- }
- m += ubm;
- return scale( m, TQTextFormat::painter() );
-}
-
-int TQTextParagraph::leftMargin() const
-{
- int m = ulm;
- if ( listDepth() && !string()->isRightToLeft() )
- m += listDepth() * document()->list_lm;
- return scale( m, TQTextFormat::painter() );
-}
-
-int TQTextParagraph::firstLineMargin() const
-{
- int m = uflm;
- return scale( m, TQTextFormat::painter() );
-}
-
-int TQTextParagraph::rightMargin() const
-{
- int m = urm;
- if ( listDepth() && string()->isRightToLeft() )
- m += listDepth() * document()->list_lm;
- return scale( m, TQTextFormat::painter() );
-}
-
-int TQTextParagraph::lineSpacing() const
-{
- int l = ulinespacing;
- l = scale( l, TQTextFormat::painter() );
- return l;
-}
-
-void TQTextParagraph::copyParagData( TQTextParagraph *parag )
-{
- rtext = parag->rtext;
- lstyle = parag->lstyle;
- ldepth = parag->ldepth;
- litem = parag->litem;
- align = parag->align;
- utm = parag->utm;
- ubm = parag->ubm;
- urm = parag->urm;
- ulm = parag->ulm;
- uflm = parag->uflm;
- ulinespacing = parag->ulinespacing;
- TQColor *c = parag->backgroundColor();
- if ( c )
- setBackgroundColor( *c );
- str->setDirection( parag->str->direction() );
-}
-
-void TQTextParagraph::show()
-{
- if ( visible || !hasdoc )
- return;
- visible = TRUE;
-}
-
-void TQTextParagraph::hide()
-{
- if ( !visible || !hasdoc )
- return;
- visible = FALSE;
-}
-
-void TQTextParagraph::setDirection( TQChar::Direction d )
-{
- if ( str && str->direction() != d ) {
- str->setDirection( d );
- tqinvalidate( 0 );
- }
-}
-
-TQChar::Direction TQTextParagraph::direction() const
-{
- return (str ? str->direction() : TQChar::DirON );
-}
-
-void TQTextParagraph::setChanged( bool b, bool recursive )
-{
- changed = b;
- if ( recursive ) {
- if ( document() && document()->parentParagraph() )
- document()->parentParagraph()->setChanged( b, recursive );
- }
-}
-
-// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-
-TQTextPreProcessor::TQTextPreProcessor()
-{
-}
-
-// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-TQTextFormatter::TQTextFormatter()
- : thisminw(0), thiswused(0), wrapEnabled( TRUE ), wrapColumn( -1 ), biw( FALSE )
-{
-}
-
-TQTextLineStart *TQTextFormatter::formatLine( TQTextParagraph *parag, TQTextString *string, TQTextLineStart *line,
- TQTextStringChar *startChar, TQTextStringChar *lastChar, int align, int space )
-{
- if ( lastChar < startChar )
- return new TQTextLineStart;
-#ifndef TQT_NO_COMPLEXTEXT
- if( string->isBidi() )
- return bidiReorderLine( parag, string, line, startChar, lastChar, align, space );
-#endif
- int start = (startChar - &string->at(0));
- int last = (lastChar - &string->at(0) );
-
- // ignore white space at the end of the line.
- TQTextStringChar *ch = lastChar;
- while ( ch > startChar && ch->whiteSpace ) {
- space += ch->format()->width( ' ' );
- --ch;
- }
-
- if (space < 0)
- space = 0;
-
- // do tqalignment Auto == Left in this case
- if ( align & TQt::AlignHCenter || align & TQt::AlignRight ) {
- if ( align & TQt::AlignHCenter )
- space /= 2;
- for ( int j = start; j <= last; ++j )
- string->at( j ).x += space;
- } else if ( align & TQt::AlignJustify ) {
- int numSpaces = 0;
- // End at "last-1", the last space ends up with a width of 0
- for ( int j = last-1; j >= start; --j ) {
- // Start at last tab, if any.
- TQTextStringChar &ch = string->at( j );
- if ( ch.c == '\t' ) {
- start = j+1;
- break;
- }
- if(ch.whiteSpace)
- numSpaces++;
- }
- int toAdd = 0;
- for ( int k = start + 1; k <= last; ++k ) {
- TQTextStringChar &ch = string->at( k );
- if( numSpaces && ch.whiteSpace ) {
- int s = space / numSpaces;
- toAdd += s;
- space -= s;
- numSpaces--;
- }
- string->at( k ).x += toAdd;
- }
- }
-
- if ( last >= 0 && last < string->length() )
- line->w = string->at( last ).x + string->width( last );
- else
- line->w = 0;
-
- return new TQTextLineStart;
-}
-
-#ifndef TQT_NO_COMPLEXTEXT
-
-#ifdef BIDI_DEBUG
-#include <iostream>
-#endif
-
-// collects one line of the paragraph and transforms it to visual order
-TQTextLineStart *TQTextFormatter::bidiReorderLine( TQTextParagraph * /*parag*/, TQTextString *text, TQTextLineStart *line,
- TQTextStringChar *startChar, TQTextStringChar *lastChar, int align, int space )
-{
- // ignore white space at the end of the line.
- int endSpaces = 0;
- while ( lastChar > startChar && lastChar->whiteSpace ) {
- space += lastChar->format()->width( ' ' );
- --lastChar;
- ++endSpaces;
- }
-
- int start = (startChar - &text->at(0));
- int last = (lastChar - &text->at(0) );
-
- int length = lastChar - startChar + 1;
-
-
- int x = startChar->x;
-
- unsigned char _levels[256];
- int _visual[256];
-
- unsigned char *levels = _levels;
- int *visual = _visual;
-
- if ( length > 255 ) {
- levels = (unsigned char *)malloc( length*sizeof( unsigned char ) );
- visual = (int *)malloc( length*sizeof( int ) );
- }
-
- //qDebug("bidiReorderLine: length=%d (%d-%d)", length, start, last );
-
- TQTextStringChar *ch = startChar;
- unsigned char *l = levels;
- while ( ch <= lastChar ) {
- //qDebug( " level: %d", ch->bidiLevel );
- *(l++) = (ch++)->bidiLevel;
- }
-
- TQTextEngine::bidiReorder( length, levels, visual );
-
- // now construct the reordered string out of the runs...
-
- int numSpaces = 0;
- // set the correct tqalignment. This is a bit messy....
- if( align == TQt::AlignAuto ) {
- // align according to directionality of the paragraph...
- if ( text->isRightToLeft() )
- align = TQt::AlignRight;
- }
-
- // This is not really correct, but as we can't make the scrollbar move to the left of the origin,
- // this ensures all text can be scrolled to and read.
- if (space < 0)
- space = 0;
-
- if ( align & TQt::AlignHCenter )
- x += space/2;
- else if ( align & TQt::AlignRight )
- x += space;
- else if ( align & TQt::AlignJustify ) {
- // End at "last-1", the last space ends up with a width of 0
- for ( int j = last-1; j >= start; --j ) {
- // Start at last tab, if any.
- TQTextStringChar &ch = text->at( j );
- if ( ch.c == '\t' ) {
- start = j+1;
- break;
- }
- if(ch.whiteSpace)
- numSpaces++;
- }
- }
-
- int toAdd = 0;
- int xorig = x;
- TQTextStringChar *lc = startChar + visual[0];
- for ( int i = 0; i < length; i++ ) {
- TQTextStringChar *ch = startChar + visual[i];
- if (numSpaces && ch->whiteSpace) {
- int s = space / numSpaces;
- toAdd += s;
- space -= s;
- numSpaces--;
- }
-
- if (lc->format() != ch->format() && !ch->c.isSpace()
- && lc->format()->font().italic() && !ch->format()->font().italic()) {
- int rb = lc->format()->fontMetrics().rightBearing(lc->c);
- if (rb < 0)
- x -= rb;
- }
-
- ch->x = x + toAdd;
- ch->rightToLeft = ch->bidiLevel % 2;
- //qDebug("visual: %d (%x) placed at %d rightToLeft=%d", visual[i], ch->c.tqunicode(), x +toAdd, ch->rightToLeft );
- int ww = 0;
- if ( ch->c.tqunicode() >= 32 || ch->c == '\t' || ch->c == '\n' || ch->isCustom() ) {
- ww = text->width( start+visual[i] );
- } else {
- ww = ch->format()->width( ' ' );
- }
- x += ww;
- lc = ch;
- }
- x += toAdd;
-
- while ( endSpaces-- ) {
- ++lastChar;
- int sw = lastChar->format()->width( ' ' );
- if ( text->isRightToLeft() ) {
- xorig -= sw;
- lastChar->x = xorig;
- ch->rightToLeft = TRUE;
- } else {
- lastChar->x = x;
- x += sw;
- ch->rightToLeft = FALSE;
- }
- }
-
- line->w = x;
-
- if ( length > 255 ) {
- free( levels );
- free( visual );
- }
-
- return new TQTextLineStart;
-}
-#endif
-
-
-void TQTextFormatter::insertLineStart( TQTextParagraph *parag, int index, TQTextLineStart *ls )
-{
- QMap<int, TQTextLineStart*>::Iterator it;
- if ( ( it = parag->lineStartList().find( index ) ) == parag->lineStartList().end() ) {
- parag->lineStartList().insert( index, ls );
- } else {
- delete *it;
- parag->lineStartList().remove( it );
- parag->lineStartList().insert( index, ls );
- }
-}
-
-
-/* Standard pagebreak algorithm using TQTextFlow::adjustFlow. Returns
- the shift of the paragraphs bottom line.
- */
-int TQTextFormatter::formatVertically( TQTextDocument* doc, TQTextParagraph* parag )
-{
- int oldHeight = parag->rect().height();
- QMap<int, TQTextLineStart*>& lineStarts = parag->lineStartList();
- QMap<int, TQTextLineStart*>::Iterator it = lineStarts.begin();
- int h = parag->prev() ? TQMAX(parag->prev()->bottomMargin(),parag->topMargin() ) / 2: 0;
- for ( ; it != lineStarts.end() ; ++it ) {
- TQTextLineStart * ls = it.data();
- ls->y = h;
- TQTextStringChar *c = &parag->string()->at(it.key());
-#ifndef TQT_NO_TEXTCUSTOMITEM
- if ( c && c->customItem() && c->customItem()->ownLine() ) {
- int h = c->customItem()->height;
- c->customItem()->pageBreak( parag->rect().y() + ls->y + ls->baseLine - h, doc->flow() );
- int delta = c->customItem()->height - h;
- ls->h += delta;
- if ( delta )
- parag->setMovedDown( TRUE );
- } else
-#endif
- {
-
- int shift = doc->flow()->adjustFlow( parag->rect().y() + ls->y, ls->w, ls->h );
- ls->y += shift;
- if ( shift )
- parag->setMovedDown( TRUE );
- }
- h = ls->y + ls->h;
- }
- int m = parag->bottomMargin();
- if ( !parag->next() )
- m = 0;
- else
- m = TQMAX(m, parag->next()->topMargin() ) / 2;
- h += m;
- parag->setHeight( h );
- return h - oldHeight;
-}
-
-// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-TQTextFormatterBreakInWords::TQTextFormatterBreakInWords()
-{
-}
-
-#define SPACE(s) s
-
-int TQTextFormatterBreakInWords::format( TQTextDocument *doc,TQTextParagraph *parag,
- int start, const QMap<int, TQTextLineStart*> & )
-{
- // make sure bidi information is correct.
- (void )parag->string()->isBidi();
-
- TQTextStringChar *c = 0;
- TQTextStringChar *firstChar = 0;
- int left = doc ? parag->leftMargin() + doc->leftMargin() : 0;
- int x = left + ( doc ? parag->firstLineMargin() : 0 );
- int dw = parag->documentVisibleWidth() - ( doc ? doc->rightMargin() : 0 );
- int y = parag->prev() ? TQMAX(parag->prev()->bottomMargin(),parag->topMargin()) / 2: 0;
- int h = y;
- int len = parag->length();
- if ( doc )
- x = doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), x, 4 );
- int rm = parag->rightMargin();
- int w = dw - ( doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 4 ) : 0 );
- bool fullWidth = TRUE;
- int minw = 0;
- int wused = 0;
- bool wrapEnabled = isWrapEnabled( parag );
-
- start = 0; //######### what is the point with start?! (Matthias)
- if ( start == 0 )
- c = &parag->string()->at( 0 );
-
- int i = start;
- TQTextLineStart *lineStart = new TQTextLineStart( y, y, 0 );
- insertLineStart( parag, 0, lineStart );
-
- TQPainter *painter = TQTextFormat::painter();
-
- int col = 0;
- int ww = 0;
- TQChar lastChr;
- for ( ; i < len; ++i, ++col ) {
- if ( c )
- lastChr = c->c;
- c = &parag->string()->at( i );
- // ### the lines below should not be needed
- if ( painter )
- c->format()->setPainter( painter );
- if ( i > 0 ) {
- c->lineStart = 0;
- } else {
- c->lineStart = 1;
- firstChar = c;
- }
- if ( c->c.tqunicode() >= 32 || c->isCustom() ) {
- ww = parag->string()->width( i );
- } else if ( c->c == '\t' ) {
- int nx = parag->nextTab( i, x - left ) + left;
- if ( nx < x )
- ww = w - x;
- else
- ww = nx - x;
- } else {
- ww = c->format()->width( ' ' );
- }
-
-#ifndef TQT_NO_TEXTCUSTOMITEM
- if ( c->isCustom() && c->customItem()->ownLine() ) {
- x = doc ? doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), left, 4 ) : left;
- w = dw - ( doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 4 ) : 0 );
- c->customItem()->resize( w - x );
- w = dw;
- y += h;
- h = c->height();
- lineStart = new TQTextLineStart( y, h, h );
- insertLineStart( parag, i, lineStart );
- c->lineStart = 1;
- firstChar = c;
- x = 0xffffff;
- continue;
- }
-#endif
-
- if ( wrapEnabled &&
- ( ((wrapAtColumn() == -1) && (x + ww > w)) ||
- ((wrapAtColumn() != -1) && (col >= wrapAtColumn())) ) ) {
- x = doc ? parag->document()->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), left, 4 ) : left;
- w = dw;
- y += h;
- h = c->height();
- lineStart = formatLine( parag, parag->string(), lineStart, firstChar, c-1 );
- lineStart->y = y;
- insertLineStart( parag, i, lineStart );
- lineStart->baseLine = c->ascent();
- lineStart->h = c->height();
- c->lineStart = 1;
- firstChar = c;
- col = 0;
- if ( wrapAtColumn() != -1 )
- minw = TQMAX( minw, w );
- } else if ( lineStart ) {
- lineStart->baseLine = TQMAX( lineStart->baseLine, c->ascent() );
- h = TQMAX( h, c->height() );
- lineStart->h = h;
- }
-
- c->x = x;
- x += ww;
- wused = TQMAX( wused, x );
- }
-
- int m = parag->bottomMargin();
- if ( !parag->next() )
- m = 0;
- else
- m = TQMAX(m, parag->next()->topMargin() ) / 2;
- parag->setFullWidth( fullWidth );
- y += h + m;
- if ( doc )
- minw += doc->rightMargin();
- if ( !wrapEnabled )
- minw = TQMAX(minw, wused);
-
- thisminw = minw;
- thiswused = wused;
- return y;
-}
-
-// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-TQTextFormatterBreakWords::TQTextFormatterBreakWords()
-{
-}
-
-#define DO_FLOW( lineStart ) do{ if ( doc && doc->isPageBreakEnabled() ) { \
- int yflow = lineStart->y + parag->rect().y();\
- int shift = doc->flow()->adjustFlow( yflow, dw, lineStart->h ); \
- lineStart->y += shift;\
- y += shift;\
- }}while(FALSE)
-
-int TQTextFormatterBreakWords::format( TQTextDocument *doc, TQTextParagraph *parag,
- int start, const QMap<int, TQTextLineStart*> & )
-{
- // make sure bidi information is correct.
- (void )parag->string()->isBidi();
-
- TQTextStringChar *c = 0;
- TQTextStringChar *firstChar = 0;
- TQTextString *string = parag->string();
- int left = doc ? parag->leftMargin() + doc->leftMargin() : 0;
- int x = left + ( doc ? parag->firstLineMargin() : 0 );
- int y = parag->prev() ? TQMAX(parag->prev()->bottomMargin(),parag->topMargin()) / 2: 0;
- int h = y;
- int len = parag->length();
- if ( doc )
- x = doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), x, 0 );
- int dw = parag->documentVisibleWidth() - ( doc ? ( left != x ? 0 : doc->rightMargin() ) : 0 );
-
- int curLeft = x;
- int rm = parag->rightMargin();
- int rdiff = doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 0 ) : 0;
- int w = dw - rdiff;
- bool fullWidth = TRUE;
- int marg = left + rdiff;
- int minw = 0;
- int wused = 0;
- int tminw = marg;
- int linespacing = doc ? parag->lineSpacing() : 0;
- bool wrapEnabled = isWrapEnabled( parag );
-
- start = 0;
-
- int i = start;
- TQTextLineStart *lineStart = new TQTextLineStart( y, y, 0 );
- insertLineStart( parag, 0, lineStart );
- int lastBreak = -1;
- int tmpBaseLine = 0, tmph = 0;
- bool lastWasNonInlineCustom = FALSE;
-
- int align = parag->tqalignment();
- if ( align == TQt::AlignAuto && doc && doc->tqalignment() != TQt::AlignAuto )
- align = doc->tqalignment();
-
- align &= TQt::AlignHorizontal_Mask;
-
- // ### hack. The last char in the paragraph is always invisible,
- // ### and somehow sometimes has a wrong format. It changes
- // ### between // layouting and printing. This corrects some
- // ### layouting errors in BiDi mode due to this.
- if ( len > 1 ) {
- c = &parag->string()->at(len - 1);
- if (!c->isAnchor()) {
- if (c->format())
- c->format()->removeRef();
- c->setFormat( string->at( len - 2 ).format() );
- if (c->format())
- c->format()->addRef();
- }
- }
-
- c = &parag->string()->at( 0 );
-
- TQPainter *painter = TQTextFormat::painter();
- int col = 0;
- int ww = 0;
- TQChar lastChr = c->c;
- TQTextFormat *lastFormat = c->format();
- for ( ; i < len; ++i, ++col ) {
- if ( i ) {
- c = &parag->string()->at(i-1);
- lastChr = c->c;
- lastFormat = c->format();
- }
- bool lastWasOwnLineCustomItem = lastBreak == -2;
- bool hadBreakableChar = lastBreak != -1;
- bool lastWasHardBreak = lastChr == TQChar_linesep;
-
- // ### next line should not be needed
- if ( painter )
- c->format()->setPainter( painter );
- c = &string->at( i );
-
- if (lastFormat != c->format() && !c->c.isSpace()
- && lastFormat->font().italic() && !c->format()->font().italic()) {
- int rb = lastFormat->fontMetrics().rightBearing(lastChr);
- if (rb < 0)
- x -= rb;
- }
-
- if ( ((i > 0) && (x > curLeft || ww == 0)) || lastWasNonInlineCustom ) {
- c->lineStart = 0;
- } else {
- c->lineStart = 1;
- firstChar = c;
- }
-
- // ignore non spacing marks for column count.
- if (col != 0 && ::category(c->c) == TQChar::Mark_NonSpacing)
- --col;
-
-#ifndef TQT_NO_TEXTCUSTOMITEM
- lastWasNonInlineCustom = ( c->isCustom() && c->customItem()->placement() != TQTextCustomItem::PlaceInline );
-#endif
-
- if ( c->c.tqunicode() >= 32 || c->isCustom() ) {
- ww = string->width( i );
- } else if ( c->c == '\t' ) {
- if ( align == TQt::AlignRight || align == TQt::AlignCenter ) {
- // we can not (yet) do tabs
- ww = c->format()->width(' ' );
- } else {
- int tabx = lastWasHardBreak ? (left + ( doc ? parag->firstLineMargin() : 0 )) : x;
- int nx = parag->nextTab( i, tabx - left ) + left;
- if ( nx < tabx ) // strrrange...
- ww = 0;
- else
- ww = nx - tabx;
- }
- } else {
- ww = c->format()->width( ' ' );
- }
-
-#ifndef TQT_NO_TEXTCUSTOMITEM
- TQTextCustomItem* ci = c->customItem();
- if ( c->isCustom() && ci->ownLine() ) {
- TQTextLineStart *lineStart2 = formatLine( parag, string, lineStart, firstChar, c-1, align, SPACE(w - x - ww) );
- x = doc ? doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), left, 4 ) : left;
- w = dw - ( doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 4 ) : 0 );
- ci->resize(w - x);
- if ( ci->width < w - x ) {
- if ( align & TQt::AlignHCenter )
- x = ( w - ci->width ) / 2;
- else if ( align & TQt::AlignRight ) {
- x = w - ci->width;
- }
- }
- c->x = x;
- curLeft = x;
- if ( i == 0 || !isBreakable(string, i-1) ||
- string->at( i - 1 ).lineStart == 0 ) {
- y += TQMAX( h, TQMAX( tmph, linespacing ) );
- tmph = c->height();
- h = tmph;
- lineStart = lineStart2;
- lineStart->y = y;
- insertLineStart( parag, i, lineStart );
- c->lineStart = 1;
- firstChar = c;
- } else {
- tmph = c->height();
- h = tmph;
- delete lineStart2;
- }
- lineStart->h = h;
- lineStart->baseLine = h;
- tmpBaseLine = lineStart->baseLine;
- lastBreak = -2;
- x = w;
- minw = TQMAX( minw, tminw );
-
- int tw = ci->minimumWidth() + ( doc ? doc->leftMargin() : 0 );
- if ( tw < TQWIDGETSIZE_MAX )
- tminw = tw;
- else
- tminw = marg;
- wused = TQMAX( wused, ci->width );
- continue;
- } else if ( c->isCustom() && ci->placement() != TQTextCustomItem::PlaceInline ) {
- int tw = ci->minimumWidth();
- if ( tw < TQWIDGETSIZE_MAX )
- minw = TQMAX( minw, tw );
- }
-#endif
- // we break if
- // 1. the last character was a hard break (TQChar_linesep) or
- // 2. the last charater was a own-line custom item (eg. table or ruler) or
- // 3. wrapping was enabled, it was not a space and following
- // condition is true: We either had a breakable character
- // previously or we ar allowed to break in words and - either
- // we break at w pixels and the current char would exceed that
- // or - we break at a column and the current character would
- // exceed that.
- if ( lastWasHardBreak || lastWasOwnLineCustomItem ||
- ( wrapEnabled &&
- ( (!c->c.isSpace() && (hadBreakableChar || allowBreakInWords()) &&
- ( (wrapAtColumn() == -1 && x + ww > w) ||
- (wrapAtColumn() != -1 && col >= wrapAtColumn()) ) ) )
- )
- ) {
- if ( wrapAtColumn() != -1 )
- minw = TQMAX( minw, x + ww );
- // if a break was forced (no breakable char, hard break or own line custom item), break immediately....
- if ( !hadBreakableChar || lastWasHardBreak || lastWasOwnLineCustomItem ) {
- if ( lineStart ) {
- lineStart->baseLine = TQMAX( lineStart->baseLine, tmpBaseLine );
- h = TQMAX( h, tmph );
- lineStart->h = h;
- DO_FLOW( lineStart );
- }
- lineStart = formatLine( parag, string, lineStart, firstChar, c-1, align, SPACE(w - x) );
- x = doc ? doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), left, 4 ) : left;
- w = dw - ( doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 4 ) : 0 );
- if ( !doc && c->c == '\t' ) { // qt_format_text tab handling
- int nx = parag->nextTab( i, x - left ) + left;
- if ( nx < x )
- ww = w - x;
- else
- ww = nx - x;
- }
- curLeft = x;
- y += TQMAX( h, linespacing );
- tmph = c->height();
- h = 0;
- lineStart->y = y;
- insertLineStart( parag, i, lineStart );
- lineStart->baseLine = c->ascent();
- lineStart->h = c->height();
- c->lineStart = 1;
- firstChar = c;
- tmpBaseLine = lineStart->baseLine;
- lastBreak = -1;
- col = 0;
- if ( allowBreakInWords() || lastWasHardBreak ) {
- minw = TQMAX(minw, tminw);
- tminw = marg + ww;
- }
- } else { // ... otherwise if we had a breakable char, break there
- DO_FLOW( lineStart );
- c->x = x;
- i = lastBreak;
- lineStart = formatLine( parag, string, lineStart, firstChar, parag->at( lastBreak ),align, SPACE(w - string->at( i+1 ).x) );
- x = doc ? doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), left, 4 ) : left;
- w = dw - ( doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 4 ) : 0 );
- if ( !doc && c->c == '\t' ) { // qt_format_text tab handling
- int nx = parag->nextTab( i, x - left ) + left;
- if ( nx < x )
- ww = w - x;
- else
- ww = nx - x;
- }
- curLeft = x;
- y += TQMAX( h, linespacing );
- tmph = c->height();
- h = tmph;
- lineStart->y = y;
- insertLineStart( parag, i + 1, lineStart );
- lineStart->baseLine = c->ascent();
- lineStart->h = c->height();
- c->lineStart = 1;
- firstChar = c;
- tmpBaseLine = lineStart->baseLine;
- lastBreak = -1;
- col = 0;
- minw = TQMAX(minw, tminw);
- tminw = marg;
- continue;
- }
- } else if (lineStart && isBreakable(string, i)) {
- if ( len <= 2 || i < len - 1 ) {
- tmpBaseLine = TQMAX( tmpBaseLine, c->ascent() );
- tmph = TQMAX( tmph, c->height() );
- }
- minw = TQMAX( minw, tminw );
-
- tminw = marg + ww;
- lineStart->baseLine = TQMAX( lineStart->baseLine, tmpBaseLine );
- h = TQMAX( h, tmph );
- lineStart->h = h;
- if ( i < len - 2 || c->c != ' ' )
- lastBreak = i;
- } else {
- tminw += ww;
- int cascent = c->ascent();
- int cheight = c->height();
- int belowBaseLine = TQMAX( tmph - tmpBaseLine, cheight-cascent );
- tmpBaseLine = TQMAX( tmpBaseLine, cascent );
- tmph = tmpBaseLine + belowBaseLine;
- }
-
- c->x = x;
- x += ww;
- wused = TQMAX( wused, x );
- }
-
- if ( lineStart ) {
- lineStart->baseLine = TQMAX( lineStart->baseLine, tmpBaseLine );
- h = TQMAX( h, tmph );
- lineStart->h = h;
- // last line in a paragraph is not justified
- if ( align == TQt::AlignJustify )
- align = TQt::AlignAuto;
- DO_FLOW( lineStart );
- lineStart = formatLine( parag, string, lineStart, firstChar, c, align, SPACE(w - x) );
- delete lineStart;
- }
-
- minw = TQMAX( minw, tminw );
- if ( doc )
- minw += doc->rightMargin();
-
- int m = parag->bottomMargin();
- if ( !parag->next() )
- m = 0;
- else
- m = TQMAX(m, parag->next()->topMargin() ) / 2;
- parag->setFullWidth( fullWidth );
- y += TQMAX( h, linespacing ) + m;
-
- wused += rm;
- if ( !wrapEnabled || wrapAtColumn() != -1 )
- minw = TQMAX(minw, wused);
-
- // This is the case where we are breaking wherever we darn well please
- // in cases like that, the minw should not be the length of the entire
- // word, because we necessarily want to show the word on the whole line.
- // example: word wrap in iconview
- if ( allowBreakInWords() && minw > wused )
- minw = wused;
-
- thisminw = minw;
- thiswused = wused;
- return y;
-}
-
-// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-TQTextIndent::TQTextIndent()
-{
-}
-
-// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-TQTextFormatCollection::TQTextFormatCollection()
- : cKey( 307 ), painttqdevice( 0 )
-{
- defFormat = new TQTextFormat( TQApplication::font(),
- TQApplication::palette().color( TQPalette::Active, TQColorGroup::Text ) );
- lastFormat = cres = 0;
- cflags = -1;
- cKey.setAutoDelete( TRUE );
- cachedFormat = 0;
-}
-
-TQTextFormatCollection::~TQTextFormatCollection()
-{
- delete defFormat;
-}
-
-void TQTextFormatCollection::setPaintDevice( TQPaintDevice *pd )
-{
- painttqdevice = pd;
-
-#if defined(TQ_WS_X11)
- int scr = ( painttqdevice ) ? painttqdevice->x11Screen() : TQPaintDevice::x11AppScreen();
-
- defFormat->fn.tqt_x11SetScreen( scr );
- defFormat->update();
-
- TQDictIterator<TQTextFormat> it( cKey );
- TQTextFormat *format;
- while ( ( format = it.current() ) != 0 ) {
- ++it;
- format->fn.tqt_x11SetScreen( scr );
- format->update();
- }
-#endif // TQ_WS_X11
-}
-
-TQTextFormat *TQTextFormatCollection::format( TQTextFormat *f )
-{
- if ( f->parent() == this || f == defFormat ) {
- lastFormat = f;
- lastFormat->addRef();
- return lastFormat;
- }
-
- if ( f == lastFormat || ( lastFormat && f->key() == lastFormat->key() ) ) {
- lastFormat->addRef();
- return lastFormat;
- }
-
- TQTextFormat *fm = cKey.find( f->key() );
- if ( fm ) {
- lastFormat = fm;
- lastFormat->addRef();
- return lastFormat;
- }
-
- if ( f->key() == defFormat->key() )
- return defFormat;
-
- lastFormat = createFormat( *f );
- lastFormat->collection = this;
- cKey.insert( lastFormat->key(), lastFormat );
- return lastFormat;
-}
-
-TQTextFormat *TQTextFormatCollection::format( TQTextFormat *of, TQTextFormat *nf, int flags )
-{
- if ( cres && kof == of->key() && knf == nf->key() && cflags == flags ) {
- cres->addRef();
- return cres;
- }
-
- cres = createFormat( *of );
- kof = of->key();
- knf = nf->key();
- cflags = flags;
- if ( flags & TQTextFormat::Bold )
- cres->fn.setBold( nf->fn.bold() );
- if ( flags & TQTextFormat::Italic )
- cres->fn.setItalic( nf->fn.italic() );
- if ( flags & TQTextFormat::Underline )
- cres->fn.setUnderline( nf->fn.underline() );
- if ( flags & TQTextFormat::StrikeOut )
- cres->fn.setStrikeOut( nf->fn.strikeOut() );
- if ( flags & TQTextFormat::Family )
- cres->fn.setFamily( nf->fn.family() );
- if ( flags & TQTextFormat::Size ) {
- if ( of->usePixelSizes )
- cres->fn.setPixelSize( nf->fn.pixelSize() );
- else
- cres->fn.setPointSize( nf->fn.pointSize() );
- }
- if ( flags & TQTextFormat::Color )
- cres->col = nf->col;
- if ( flags & TQTextFormat::Misspelled )
- cres->missp = nf->missp;
- if ( flags & TQTextFormat::VAlign )
- cres->ha = nf->ha;
- cres->update();
-
- TQTextFormat *fm = cKey.find( cres->key() );
- if ( !fm ) {
- cres->collection = this;
- cKey.insert( cres->key(), cres );
- } else {
- delete cres;
- cres = fm;
- cres->addRef();
- }
-
- return cres;
-}
-
-TQTextFormat *TQTextFormatCollection::format( const TQFont &f, const TQColor &c )
-{
- if ( cachedFormat && cfont == f && ccol == c ) {
- cachedFormat->addRef();
- return cachedFormat;
- }
-
- TQString key = TQTextFormat::getKey( f, c, FALSE, TQTextFormat::AlignNormal );
- cachedFormat = cKey.find( key );
- cfont = f;
- ccol = c;
-
- if ( cachedFormat ) {
- cachedFormat->addRef();
- return cachedFormat;
- }
-
- if ( key == defFormat->key() )
- return defFormat;
-
- cachedFormat = createFormat( f, c );
- cachedFormat->collection = this;
- cKey.insert( cachedFormat->key(), cachedFormat );
- if ( cachedFormat->key() != key )
- qWarning("ASSERT: keys for format not identical: '%s '%s'", cachedFormat->key().latin1(), key.latin1() );
- return cachedFormat;
-}
-
-void TQTextFormatCollection::remove( TQTextFormat *f )
-{
- if ( lastFormat == f )
- lastFormat = 0;
- if ( cres == f )
- cres = 0;
- if ( cachedFormat == f )
- cachedFormat = 0;
- if (cKey.find(f->key()) == f)
- cKey.remove( f->key() );
-}
-
-#define UPDATE( up, lo, rest ) \
- if ( font.lo##rest() != defFormat->fn.lo##rest() && fm->fn.lo##rest() == defFormat->fn.lo##rest() ) \
- fm->fn.set##up##rest( font.lo##rest() )
-
-void TQTextFormatCollection::updateDefaultFormat( const TQFont &font, const TQColor &color, TQStyleSheet *sheet )
-{
- TQDictIterator<TQTextFormat> it( cKey );
- TQTextFormat *fm;
- bool usePixels = font.pointSize() == -1;
- bool changeSize = usePixels ? font.pixelSize() != defFormat->fn.pixelSize() :
- font.pointSize() != defFormat->fn.pointSize();
- int base = usePixels ? font.pixelSize() : font.pointSize();
- while ( ( fm = it.current() ) ) {
- ++it;
- UPDATE( F, f, amily );
- UPDATE( W, w, eight );
- UPDATE( B, b, old );
- UPDATE( I, i, talic );
- UPDATE( U, u, nderline );
- if ( changeSize ) {
- fm->stdSize = base;
- fm->usePixelSizes = usePixels;
- if ( usePixels )
- fm->fn.setPixelSize( fm->stdSize );
- else
- fm->fn.setPointSize( fm->stdSize );
- sheet->scaleFont( fm->fn, fm->logicalFontSize );
- }
- if ( color.isValid() && color != defFormat->col && fm->col == defFormat->col )
- fm->col = color;
- fm->update();
- }
-
- defFormat->fn = font;
- defFormat->col = color;
- defFormat->update();
- defFormat->stdSize = base;
- defFormat->usePixelSizes = usePixels;
-
- updateKeys();
-}
-
-// the keys in cKey have changed, rebuild the hashtable
-void TQTextFormatCollection::updateKeys()
-{
- if ( cKey.isEmpty() )
- return;
- cKey.setAutoDelete( FALSE );
- TQTextFormat** formats = new TQTextFormat*[ cKey.count() + 1 ];
- TQTextFormat **f = formats;
- TQDictIterator<TQTextFormat> it( cKey );
- while ( ( *f = it.current() ) ) {
- ++it;
- ++f;
- }
- cKey.clear();
- for ( f = formats; *f; f++ )
- cKey.insert( (*f)->key(), *f );
- cKey.setAutoDelete( TRUE );
- delete [] formats;
-}
-
-
-
-// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-void TQTextFormat::setBold( bool b )
-{
- if ( b == fn.bold() )
- return;
- fn.setBold( b );
- update();
-}
-
-void TQTextFormat::setMisspelled( bool b )
-{
- if ( b == (bool)missp )
- return;
- missp = b;
- update();
-}
-
-void TQTextFormat::setVAlign( VerticalAlignment a )
-{
- if ( a == ha )
- return;
- ha = a;
- update();
-}
-
-void TQTextFormat::setItalic( bool b )
-{
- if ( b == fn.italic() )
- return;
- fn.setItalic( b );
- update();
-}
-
-void TQTextFormat::setUnderline( bool b )
-{
- if ( b == fn.underline() )
- return;
- fn.setUnderline( b );
- update();
-}
-
-void TQTextFormat::setStrikeOut( bool b )
-{
- if ( b == fn.strikeOut() )
- return;
- fn.setStrikeOut( b );
- update();
-}
-
-void TQTextFormat::setFamily( const TQString &f )
-{
- if ( f == fn.family() )
- return;
- fn.setFamily( f );
- update();
-}
-
-void TQTextFormat::setPointSize( int s )
-{
- if ( s == fn.pointSize() )
- return;
- fn.setPointSize( s );
- usePixelSizes = FALSE;
- update();
-}
-
-void TQTextFormat::setFont( const TQFont &f )
-{
- if ( f == fn && !k.isEmpty() )
- return;
- fn = f;
- update();
-}
-
-void TQTextFormat::setColor( const TQColor &c )
-{
- if ( c == col )
- return;
- col = c;
- update();
-}
-
-TQString TQTextFormat::makeFormatChangeTags( TQTextFormat* defaultFormat, TQTextFormat *f,
- const TQString& oldAnchorHref, const TQString& anchorHref ) const
-{
- TQString tag;
- if ( f )
- tag += f->makeFormatEndTags( defaultFormat, oldAnchorHref );
-
- if ( !anchorHref.isEmpty() )
- tag += "<a href=\"" + anchorHref + "\">";
-
- if ( font() != defaultFormat->font()
- || vAlign() != defaultFormat->vAlign()
- || color().rgb() != defaultFormat->color().rgb() ) {
- TQString s;
- if ( font().family() != defaultFormat->font().family() )
- s += TQString(!!s?";":"") + "font-family:" + fn.family();
- if ( font().italic() && font().italic() != defaultFormat->font().italic() )
- s += TQString(!!s?";":"") + "font-style:" + (font().italic() ? "italic" : "normal");
- if ( font().pointSize() != defaultFormat->font().pointSize() )
- s += TQString(!!s?";":"") + "font-size:" + TQString::number( fn.pointSize() ) + "pt";
- if ( font().weight() != defaultFormat->font().weight() )
- s += TQString(!!s?";":"") + "font-weight:" + TQString::number( fn.weight() * 8 );
- TQString textDecoration;
- bool none = FALSE;
- if ( font().underline() != defaultFormat->font().underline() ) {
- if (font().underline())
- textDecoration = "underline";
- else
- none = TRUE;
- }
- if ( font().overline() != defaultFormat->font().overline() ) {
- if (font().overline())
- textDecoration += " overline";
- else
- none = TRUE;
- }
- if ( font().strikeOut() != defaultFormat->font().strikeOut() ) {
- if (font().strikeOut())
- textDecoration += " line-through";
- else
- none = TRUE;
- }
- if (none && textDecoration.isEmpty())
- textDecoration = "none";
- if (!textDecoration.isEmpty())
- s += TQString(!!s?";":"") + "text-decoration:" + textDecoration;
- if ( vAlign() != defaultFormat->vAlign() ) {
- s += TQString(!!s?";":"") + "vertical-align:";
- if ( vAlign() == TQTextFormat::AlignSuperScript )
- s += "super";
- else if ( vAlign() == TQTextFormat::AlignSubScript )
- s += "sub";
- else
- s += "normal";
- }
- if ( color().rgb() != defaultFormat->color().rgb() )
- s += TQString(!!s?";":"") + "color:" + col.name();
- if ( !s.isEmpty() )
- tag += "<span style=\"" + s + "\">";
- }
-
- return tag;
-}
-
-TQString TQTextFormat::makeFormatEndTags( TQTextFormat* defaultFormat, const TQString& anchorHref ) const
-{
- TQString tag;
- if ( font().family() != defaultFormat->font().family()
- || font().pointSize() != defaultFormat->font().pointSize()
- || font().weight() != defaultFormat->font().weight()
- || font().italic() != defaultFormat->font().italic()
- || font().underline() != defaultFormat->font().underline()
- || font().strikeOut() != defaultFormat->font().strikeOut()
- || vAlign() != defaultFormat->vAlign()
- || color().rgb() != defaultFormat->color().rgb() )
- tag += "</span>";
- if ( !anchorHref.isEmpty() )
- tag += "</a>";
- return tag;
-}
-
-TQTextFormat TQTextFormat::makeTextFormat( const TQStyleSheetItem *style, const QMap<TQString,TQString>& attr, double scaleFontsFactor ) const
-{
- TQTextFormat format(*this);
- if (!style )
- return format;
-
- if ( !style->isAnchor() && style->color().isValid() ) {
- // the style is not an anchor and defines a color.
- // It might be used inside an anchor and it should
- // override the link color.
- format.linkColor = FALSE;
- }
- switch ( style->verticalAlignment() ) {
- case TQStyleSheetItem::VAlignBaseline:
- format.setVAlign( TQTextFormat::AlignNormal );
- break;
- case TQStyleSheetItem::VAlignSuper:
- format.setVAlign( TQTextFormat::AlignSuperScript );
- break;
- case TQStyleSheetItem::VAlignSub:
- format.setVAlign( TQTextFormat::AlignSubScript );
- break;
- }
-
- if ( style->fontWeight() != TQStyleSheetItem::Undefined )
- format.fn.setWeight( style->fontWeight() );
- if ( style->fontSize() != TQStyleSheetItem::Undefined ) {
- format.fn.setPointSize( style->fontSize() );
- } else if ( style->logicalFontSize() != TQStyleSheetItem::Undefined ) {
- format.logicalFontSize = style->logicalFontSize();
- if ( format.usePixelSizes )
- format.fn.setPixelSize( format.stdSize );
- else
- format.fn.setPointSize( format.stdSize );
- style->styleSheet()->scaleFont( format.fn, format.logicalFontSize );
- } else if ( style->logicalFontSizeStep() ) {
- format.logicalFontSize += style->logicalFontSizeStep();
- if ( format.usePixelSizes )
- format.fn.setPixelSize( format.stdSize );
- else
- format.fn.setPointSize( format.stdSize );
- style->styleSheet()->scaleFont( format.fn, format.logicalFontSize );
- }
- if ( !style->fontFamily().isEmpty() )
- format.fn.setFamily( style->fontFamily() );
- if ( style->color().isValid() )
- format.col = style->color();
- if ( style->definesFontItalic() )
- format.fn.setItalic( style->fontItalic() );
- if ( style->definesFontUnderline() )
- format.fn.setUnderline( style->fontUnderline() );
- if ( style->definesFontStrikeOut() )
- format.fn.setStrikeOut( style->fontStrikeOut() );
-
-
- if ( style->name() == "font") {
- if ( attr.contains("color") ) {
- TQString s = attr["color"];
- if ( !s.isEmpty() ) {
- format.col.setNamedColor( s );
- format.linkColor = FALSE;
- }
- }
- if ( attr.contains("face") ) {
- TQString a = attr["face"];
- TQString family = a.section( ',', 0, 0 );
- if ( !!family )
- format.fn.setFamily( family );
- }
- if ( attr.contains("size") ) {
- TQString a = attr["size"];
- int n = a.toInt();
- if ( a[0] == '+' || a[0] == '-' )
- n += 3;
- format.logicalFontSize = n;
- if ( format.usePixelSizes )
- format.fn.setPixelSize( format.stdSize );
- else
- format.fn.setPointSize( format.stdSize );
- style->styleSheet()->scaleFont( format.fn, format.logicalFontSize );
- }
- }
- if ( attr.contains("style" ) ) {
- TQString a = attr["style"];
- for ( int s = 0; s < a.contains(';')+1; s++ ) {
- TQString style = a.section( ';', s, s );
- if ( style.startsWith("font-size:" ) && style.endsWith("pt") ) {
- format.logicalFontSize = 0;
- int size = int( scaleFontsFactor * style.mid( 10, style.length() - 12 ).toDouble() );
- format.setPointSize( size );
- } else if ( style.startsWith("font-style:" ) ) {
- TQString s = TQT_TQSTRING(style.mid( 11 )).stripWhiteSpace();
- if ( s == "normal" )
- format.fn.setItalic( FALSE );
- else if ( s == "italic" || s == "oblique" )
- format.fn.setItalic( TRUE );
- } else if ( style.startsWith("font-weight:" ) ) {
- TQString s = style.mid( 12 );
- bool ok = TRUE;
- int n = s.toInt( &ok );
- if ( ok )
- format.fn.setWeight( n/8 );
- } else if ( style.startsWith("font-family:" ) ) {
- TQString family = style.mid(12).section(',',0,0);
- family.replace( '\"', ' ' );
- family.replace( '\'', ' ' );
- family = family.stripWhiteSpace();
- format.fn.setFamily( family );
- } else if ( style.startsWith("text-decoration:" ) ) {
- TQString s = style.mid( 16 );
- format.fn.setOverline( s.find("overline") != -1 );
- format.fn.setStrikeOut( s.find("line-through") != -1 );
- format.fn.setUnderline( s.find("underline") != -1 );
- } else if ( style.startsWith("vertical-align:" ) ) {
- TQString s = TQT_TQSTRING(style.mid( 15 )).stripWhiteSpace();
- if ( s == "sub" )
- format.setVAlign( TQTextFormat::AlignSubScript );
- else if ( s == "super" )
- format.setVAlign( TQTextFormat::AlignSuperScript );
- else
- format.setVAlign( TQTextFormat::AlignNormal );
- } else if ( style.startsWith("color:" ) ) {
- format.col.setNamedColor( style.mid(6) );
- format.linkColor = FALSE;
- }
- }
- }
-
- format.update();
- return format;
-}
-
-#ifndef TQT_NO_TEXTCUSTOMITEM
-
-struct TQPixmapInt
-{
- TQPixmapInt() : ref( 0 ) {}
- TQPixmap pm;
- int ref;
- TQ_DUMMY_COMPARISON_OPERATOR(TQPixmapInt)
-};
-
-static QMap<TQString, TQPixmapInt> *pixmap_map = 0;
-
-TQTextImage::TQTextImage( TQTextDocument *p, const QMap<TQString, TQString> &attr, const TQString& context,
- TQMimeSourceFactory &factory )
- : TQTextCustomItem( p )
-{
- width = height = 0;
- if ( attr.contains("width") )
- width = attr["width"].toInt();
- if ( attr.contains("height") )
- height = attr["height"].toInt();
-
- reg = 0;
- TQString imageName = attr["src"];
-
- if (!imageName)
- imageName = attr["source"];
-
- if ( !imageName.isEmpty() ) {
- imgId = TQString( "%1,%2,%3,%4" ).arg( imageName ).arg( width ).arg( height ).arg( (ulong)&factory );
- if ( !pixmap_map )
- pixmap_map = new QMap<TQString, TQPixmapInt>;
- if ( pixmap_map->contains( imgId ) ) {
- TQPixmapInt& pmi = pixmap_map->operator[](imgId);
- pm = pmi.pm;
- pmi.ref++;
- width = pm.width();
- height = pm.height();
- } else {
- TQImage img;
- const TQMimeSource* m =
- factory.data( imageName, context );
- if ( !m ) {
- qWarning("TQTextImage: no mimesource for %s", imageName.latin1() );
- }
- else {
- if ( !TQImageDrag::decode( m, img ) ) {
- qWarning("TQTextImage: cannot decode %s", imageName.latin1() );
- }
- }
-
- if ( !img.isNull() ) {
- if ( width == 0 ) {
- width = img.width();
- if ( height != 0 ) {
- width = img.width() * height / img.height();
- }
- }
- if ( height == 0 ) {
- height = img.height();
- if ( width != img.width() ) {
- height = img.height() * width / img.width();
- }
- }
- if ( img.width() != width || img.height() != height ){
-#ifndef TQT_NO_IMAGE_SMOOTHSCALE
- img = img.smoothScale(width, height);
-#endif
- width = img.width();
- height = img.height();
- }
- pm.convertFromImage( img );
- }
- if ( !pm.isNull() ) {
- TQPixmapInt& pmi = pixmap_map->operator[](imgId);
- pmi.pm = pm;
- pmi.ref++;
- }
- }
- if ( pm.mask() ) {
- TQRegion mask( *pm.mask() );
- TQRegion all( 0, 0, pm.width(), pm.height() );
- reg = new TQRegion( all.subtract( mask ) );
- }
- }
-
- if ( pm.isNull() && (width*height)==0 )
- width = height = 50;
-
- place = PlaceInline;
- if ( attr["align"] == "left" )
- place = PlaceLeft;
- else if ( attr["align"] == "right" )
- place = PlaceRight;
-
- tmpwidth = width;
- tmpheight = height;
-
- attributes = attr;
-}
-
-TQTextImage::~TQTextImage()
-{
- if ( pixmap_map && pixmap_map->contains( imgId ) ) {
- TQPixmapInt& pmi = pixmap_map->operator[](imgId);
- pmi.ref--;
- if ( !pmi.ref ) {
- pixmap_map->remove( imgId );
- if ( pixmap_map->isEmpty() ) {
- delete pixmap_map;
- pixmap_map = 0;
- }
- }
- }
- delete reg;
-}
-
-TQString TQTextImage::richText() const
-{
- TQString s;
- s += "<img ";
- QMap<TQString, TQString>::ConstIterator it = attributes.begin();
- for ( ; it != attributes.end(); ++it ) {
- s += it.key() + "=";
- if ( (*it).find( ' ' ) != -1 )
- s += "\"" + *it + "\"" + " ";
- else
- s += *it + " ";
- }
- s += ">";
- return s;
-}
-
-void TQTextImage::adjustToPainter( TQPainter* p )
-{
- width = scale( tmpwidth, p );
- height = scale( tmpheight, p );
-}
-
-#if !defined(TQ_WS_X11)
-#include <tqbitmap.h>
-#include <tqcleanuphandler.h>
-static TQPixmap *qrt_selection = 0;
-static TQSingleCleanupHandler<TQPixmap> qrt_cleanup_pixmap;
-static void qrt_createSelectionPixmap( const TQColorGroup &cg )
-{
- qrt_selection = new TQPixmap( 2, 2 );
- qrt_cleanup_pixmap.set( &qrt_selection );
- qrt_selection->fill( TQt::color0 );
- TQBitmap m( 2, 2 );
- m.fill( TQt::color1 );
- TQPainter p( &m );
- p.setPen( TQt::color0 );
- for ( int j = 0; j < 2; ++j ) {
- p.drawPoint( j % 2, j );
- }
- p.end();
- qrt_selection->setMask( m );
- qrt_selection->fill( cg.highlight() );
-}
-#endif
-
-void TQTextImage::draw( TQPainter* p, int x, int y, int cx, int cy, int cw, int ch, const TQColorGroup& cg, bool selected )
-{
- if ( placement() != PlaceInline ) {
- x = xpos;
- y = ypos;
- }
-
- if ( pm.isNull() ) {
- p->fillRect( x , y, width, height, cg.dark() );
- return;
- }
-
- if ( is_printer( p ) ) {
- p->drawPixmap( TQRect( x, y, width, height ), pm );
- return;
- }
-
- if ( placement() != PlaceInline && !TQRect( xpos, ypos, width, height ).intersects( TQRect( cx, cy, cw, ch ) ) )
- return;
-
- if ( placement() == PlaceInline )
- p->drawPixmap( x , y, pm );
- else
- p->drawPixmap( cx , cy, pm, cx - x, cy - y, cw, ch );
-
- if ( selected && placement() == PlaceInline && is_printer( p ) ) {
-#if defined(TQ_WS_X11)
- p->fillRect( TQRect( TQPoint( x, y ), pm.size() ), TQBrush( cg.highlight(), Qt::Dense4Pattern) );
-#else // in WIN32 Dense4Pattern doesn't work correctly (transparency problem), so work around it
- if ( !qrt_selection )
- qrt_createSelectionPixmap( cg );
- p->drawTiledPixmap( x, y, pm.width(), pm.height(), *qrt_selection );
-#endif
- }
-}
-
-void TQTextHorizontalLine::adjustToPainter( TQPainter* p )
-{
- height = scale( tmpheight, p );
-}
-
-
-TQTextHorizontalLine::TQTextHorizontalLine( TQTextDocument *p, const QMap<TQString, TQString> &attr,
- const TQString &,
- TQMimeSourceFactory & )
- : TQTextCustomItem( p )
-{
- height = tmpheight = 8;
- if ( attr.find( "color" ) != attr.end() )
- color = TQColor( *attr.find( "color" ) );
- shade = attr.find( "noshade" ) == attr.end();
-}
-
-TQTextHorizontalLine::~TQTextHorizontalLine()
-{
-}
-
-TQString TQTextHorizontalLine::richText() const
-{
- return "<hr>";
-}
-
-void TQTextHorizontalLine::draw( TQPainter* p, int x, int y, int , int , int , int , const TQColorGroup& cg, bool selected )
-{
- TQRect r( x, y, width, height);
- if ( is_printer( p ) || !shade ) {
- TQPen oldPen = p->pen();
- if ( !color.isValid() )
- p->setPen( TQPen( cg.text(), is_printer( p ) ? height/8 : TQMAX( 2, height/4 ) ) );
- else
- p->setPen( TQPen( color, is_printer( p ) ? height/8 : TQMAX( 2, height/4 ) ) );
- p->drawLine( r.left()-1, y + height / 2, r.right() + 1, y + height / 2 );
- p->setPen( oldPen );
- } else {
- TQColorGroup g( cg );
- if ( color.isValid() )
- g.setColor( TQColorGroup::Dark, color );
- if ( selected )
- p->fillRect( r, g.highlight() );
- qDrawShadeLine( p, r.left() - 1, y + height / 2, r.right() + 1, y + height / 2, g, TRUE, height / 8 );
- }
-}
-#endif //TQT_NO_TEXTCUSTOMITEM
-
-/*****************************************************************/
-// Small set of utility functions to make the parser a bit simpler
-//
-
-bool TQTextDocument::hasPrefix(const TQChar* doc, int length, int pos, TQChar c)
-{
- if ( pos + 1 > length )
- return FALSE;
- return doc[ pos ].lower() == c.lower();
-}
-
-bool TQTextDocument::hasPrefix( const TQChar* doc, int length, int pos, const TQString& s )
-{
- if ( pos + (int) s.length() > length )
- return FALSE;
- for ( int i = 0; i < (int)s.length(); i++ ) {
- if ( doc[ pos + i ].lower() != s[ i ].lower() )
- return FALSE;
- }
- return TRUE;
-}
-
-#ifndef TQT_NO_TEXTCUSTOMITEM
-static bool qt_is_cell_in_use( TQPtrList<TQTextTableCell>& cells, int row, int col )
-{
- for ( TQTextTableCell* c = cells.first(); c; c = cells.next() ) {
- if ( row >= c->row() && row < c->row() + c->rowspan()
- && col >= c->column() && col < c->column() + c->colspan() )
- return TRUE;
- }
- return FALSE;
-}
-
-TQTextCustomItem* TQTextDocument::parseTable( const QMap<TQString, TQString> &attr, const TQTextFormat &fmt,
- const TQChar* doc, int length, int& pos, TQTextParagraph *curpar )
-{
-
- TQTextTable* table = new TQTextTable( this, attr );
- int row = -1;
- int col = -1;
-
- TQString rowbgcolor;
- TQString rowalign;
- TQString tablebgcolor = attr["bgcolor"];
-
- TQPtrList<TQTextTableCell> multicells;
-
- TQString tagname;
- (void) eatSpace(doc, length, pos);
- while ( pos < length) {
- if (hasPrefix(doc, length, pos, TQChar('<')) ){
- if (hasPrefix(doc, length, pos+1, TQChar('/'))) {
- tagname = parseCloseTag( doc, length, pos );
- if ( tagname == "table" ) {
- return table;
- }
- } else {
- QMap<TQString, TQString> attr2;
- bool emptyTag = FALSE;
- tagname = parseOpenTag( doc, length, pos, attr2, emptyTag );
- if ( tagname == "tr" ) {
- rowbgcolor = attr2["bgcolor"];
- rowalign = attr2["align"];
- row++;
- col = -1;
- }
- else if ( tagname == "td" || tagname == "th" ) {
- col++;
- while ( qt_is_cell_in_use( multicells, row, col ) ) {
- col++;
- }
-
- if ( row >= 0 && col >= 0 ) {
- const TQStyleSheetItem* s = sheet_->item(tagname);
- if ( !attr2.contains("bgcolor") ) {
- if (!rowbgcolor.isEmpty() )
- attr2["bgcolor"] = rowbgcolor;
- else if (!tablebgcolor.isEmpty() )
- attr2["bgcolor"] = tablebgcolor;
- }
- if ( !attr2.contains("align") ) {
- if (!rowalign.isEmpty() )
- attr2["align"] = rowalign;
- }
-
- // extract the cell contents
- int end = pos;
- while ( end < length
- && !hasPrefix( doc, length, end, "</td")
- && !hasPrefix( doc, length, end, "<td")
- && !hasPrefix( doc, length, end, "</th")
- && !hasPrefix( doc, length, end, "<th")
- && !hasPrefix( doc, length, end, "<td")
- && !hasPrefix( doc, length, end, "</tr")
- && !hasPrefix( doc, length, end, "<tr")
- && !hasPrefix( doc, length, end, "</table") ) {
- if ( hasPrefix( doc, length, end, "<table" ) ) { // nested table
- int nested = 1;
- ++end;
- while ( end < length && nested != 0 ) {
- if ( hasPrefix( doc, length, end, "</table" ) )
- nested--;
- if ( hasPrefix( doc, length, end, "<table" ) )
- nested++;
- end++;
- }
- }
- end++;
- }
- TQTextTableCell* cell = new TQTextTableCell( table, row, col,
- attr2, s, fmt.makeTextFormat( s, attr2, scaleFontsFactor ),
- contxt, *factory_, sheet_,
- TQConstString( doc + pos, end - pos ).string() );
- cell->richText()->parentPar = curpar;
- if ( cell->colspan() > 1 || cell->rowspan() > 1 )
- multicells.append( cell );
- col += cell->colspan()-1;
- pos = end;
- }
- }
- }
-
- } else {
- ++pos;
- }
- }
- return table;
-}
-#endif // TQT_NO_TEXTCUSTOMITEM
-
-bool TQTextDocument::eatSpace(const TQChar* doc, int length, int& pos, bool includeNbsp )
-{
- int old_pos = pos;
- while (pos < length && doc[pos].isSpace() && ( includeNbsp || (doc[pos] != TQChar::nbsp ) ) )
- pos++;
- return old_pos < pos;
-}
-
-bool TQTextDocument::eat(const TQChar* doc, int length, int& pos, TQChar c)
-{
- bool ok = pos < length && doc[pos] == c;
- if ( ok )
- pos++;
- return ok;
-}
-/*****************************************************************/
-
-struct Entity {
- const char * name;
- TQ_UINT16 code;
-};
-
-static const Entity entitylist [] = {
- { "AElig", 0x00c6 },
- { "Aacute", 0x00c1 },
- { "Acirc", 0x00c2 },
- { "Agrave", 0x00c0 },
- { "Alpha", 0x0391 },
- { "AMP", 38 },
- { "Aring", 0x00c5 },
- { "Atilde", 0x00c3 },
- { "Auml", 0x00c4 },
- { "Beta", 0x0392 },
- { "Ccedil", 0x00c7 },
- { "Chi", 0x03a7 },
- { "Dagger", 0x2021 },
- { "Delta", 0x0394 },
- { "ETH", 0x00d0 },
- { "Eacute", 0x00c9 },
- { "Ecirc", 0x00ca },
- { "Egrave", 0x00c8 },
- { "Epsilon", 0x0395 },
- { "Eta", 0x0397 },
- { "Euml", 0x00cb },
- { "Gamma", 0x0393 },
- { "GT", 62 },
- { "Iacute", 0x00cd },
- { "Icirc", 0x00ce },
- { "Igrave", 0x00cc },
- { "Iota", 0x0399 },
- { "Iuml", 0x00cf },
- { "Kappa", 0x039a },
- { "Lambda", 0x039b },
- { "LT", 60 },
- { "Mu", 0x039c },
- { "Ntilde", 0x00d1 },
- { "Nu", 0x039d },
- { "OElig", 0x0152 },
- { "Oacute", 0x00d3 },
- { "Ocirc", 0x00d4 },
- { "Ograve", 0x00d2 },
- { "Omega", 0x03a9 },
- { "Omicron", 0x039f },
- { "Oslash", 0x00d8 },
- { "Otilde", 0x00d5 },
- { "Ouml", 0x00d6 },
- { "Phi", 0x03a6 },
- { "Pi", 0x03a0 },
- { "Prime", 0x2033 },
- { "Psi", 0x03a8 },
- { "TQUOT", 34 },
- { "Rho", 0x03a1 },
- { "Scaron", 0x0160 },
- { "Sigma", 0x03a3 },
- { "THORN", 0x00de },
- { "Tau", 0x03a4 },
- { "Theta", 0x0398 },
- { "Uacute", 0x00da },
- { "Ucirc", 0x00db },
- { "Ugrave", 0x00d9 },
- { "Upsilon", 0x03a5 },
- { "Uuml", 0x00dc },
- { "Xi", 0x039e },
- { "Yacute", 0x00dd },
- { "Yuml", 0x0178 },
- { "Zeta", 0x0396 },
- { "aacute", 0x00e1 },
- { "acirc", 0x00e2 },
- { "acute", 0x00b4 },
- { "aelig", 0x00e6 },
- { "agrave", 0x00e0 },
- { "alefsym", 0x2135 },
- { "alpha", 0x03b1 },
- { "amp", 38 },
- { "and", 0x22a5 },
- { "ang", 0x2220 },
- { "apos", 0x0027 },
- { "aring", 0x00e5 },
- { "asymp", 0x2248 },
- { "atilde", 0x00e3 },
- { "auml", 0x00e4 },
- { "bdquo", 0x201e },
- { "beta", 0x03b2 },
- { "brvbar", 0x00a6 },
- { "bull", 0x2022 },
- { "cap", 0x2229 },
- { "ccedil", 0x00e7 },
- { "cedil", 0x00b8 },
- { "cent", 0x00a2 },
- { "chi", 0x03c7 },
- { "circ", 0x02c6 },
- { "clubs", 0x2663 },
- { "cong", 0x2245 },
- { "copy", 0x00a9 },
- { "crarr", 0x21b5 },
- { "cup", 0x222a },
- { "curren", 0x00a4 },
- { "dArr", 0x21d3 },
- { "dagger", 0x2020 },
- { "darr", 0x2193 },
- { "deg", 0x00b0 },
- { "delta", 0x03b4 },
- { "diams", 0x2666 },
- { "divide", 0x00f7 },
- { "eacute", 0x00e9 },
- { "ecirc", 0x00ea },
- { "egrave", 0x00e8 },
- { "empty", 0x2205 },
- { "emsp", 0x2003 },
- { "ensp", 0x2002 },
- { "epsilon", 0x03b5 },
- { "equiv", 0x2261 },
- { "eta", 0x03b7 },
- { "eth", 0x00f0 },
- { "euml", 0x00eb },
- { "euro", 0x20ac },
- { "exist", 0x2203 },
- { "fnof", 0x0192 },
- { "forall", 0x2200 },
- { "frac12", 0x00bd },
- { "frac14", 0x00bc },
- { "frac34", 0x00be },
- { "frasl", 0x2044 },
- { "gamma", 0x03b3 },
- { "ge", 0x2265 },
- { "gt", 62 },
- { "hArr", 0x21d4 },
- { "harr", 0x2194 },
- { "hearts", 0x2665 },
- { "hellip", 0x2026 },
- { "iacute", 0x00ed },
- { "icirc", 0x00ee },
- { "iexcl", 0x00a1 },
- { "igrave", 0x00ec },
- { "image", 0x2111 },
- { "infin", 0x221e },
- { "int", 0x222b },
- { "iota", 0x03b9 },
- { "iquest", 0x00bf },
- { "isin", 0x2208 },
- { "iuml", 0x00ef },
- { "kappa", 0x03ba },
- { "lArr", 0x21d0 },
- { "lambda", 0x03bb },
- { "lang", 0x2329 },
- { "laquo", 0x00ab },
- { "larr", 0x2190 },
- { "lceil", 0x2308 },
- { "ldquo", 0x201c },
- { "le", 0x2264 },
- { "lfloor", 0x230a },
- { "lowast", 0x2217 },
- { "loz", 0x25ca },
- { "lrm", 0x200e },
- { "lsaquo", 0x2039 },
- { "lsquo", 0x2018 },
- { "lt", 60 },
- { "macr", 0x00af },
- { "mdash", 0x2014 },
- { "micro", 0x00b5 },
- { "middot", 0x00b7 },
- { "minus", 0x2212 },
- { "mu", 0x03bc },
- { "nabla", 0x2207 },
- { "nbsp", 0x00a0 },
- { "ndash", 0x2013 },
- { "ne", 0x2260 },
- { "ni", 0x220b },
- { "not", 0x00ac },
- { "notin", 0x2209 },
- { "nsub", 0x2284 },
- { "ntilde", 0x00f1 },
- { "nu", 0x03bd },
- { "oacute", 0x00f3 },
- { "ocirc", 0x00f4 },
- { "oelig", 0x0153 },
- { "ograve", 0x00f2 },
- { "oline", 0x203e },
- { "omega", 0x03c9 },
- { "omicron", 0x03bf },
- { "oplus", 0x2295 },
- { "or", 0x22a6 },
- { "ordf", 0x00aa },
- { "ordm", 0x00ba },
- { "oslash", 0x00f8 },
- { "otilde", 0x00f5 },
- { "otimes", 0x2297 },
- { "ouml", 0x00f6 },
- { "para", 0x00b6 },
- { "part", 0x2202 },
- { "percnt", 0x0025 },
- { "permil", 0x2030 },
- { "perp", 0x22a5 },
- { "phi", 0x03c6 },
- { "pi", 0x03c0 },
- { "piv", 0x03d6 },
- { "plusmn", 0x00b1 },
- { "pound", 0x00a3 },
- { "prime", 0x2032 },
- { "prod", 0x220f },
- { "prop", 0x221d },
- { "psi", 0x03c8 },
- { "quot", 34 },
- { "rArr", 0x21d2 },
- { "radic", 0x221a },
- { "rang", 0x232a },
- { "raquo", 0x00bb },
- { "rarr", 0x2192 },
- { "rceil", 0x2309 },
- { "rdquo", 0x201d },
- { "real", 0x211c },
- { "reg", 0x00ae },
- { "rfloor", 0x230b },
- { "rho", 0x03c1 },
- { "rlm", 0x200f },
- { "rsaquo", 0x203a },
- { "rsquo", 0x2019 },
- { "sbquo", 0x201a },
- { "scaron", 0x0161 },
- { "sdot", 0x22c5 },
- { "sect", 0x00a7 },
- { "shy", 0x00ad },
- { "sigma", 0x03c3 },
- { "sigmaf", 0x03c2 },
- { "sim", 0x223c },
- { "spades", 0x2660 },
- { "sub", 0x2282 },
- { "sube", 0x2286 },
- { "sum", 0x2211 },
- { "sup1", 0x00b9 },
- { "sup2", 0x00b2 },
- { "sup3", 0x00b3 },
- { "sup", 0x2283 },
- { "supe", 0x2287 },
- { "szlig", 0x00df },
- { "tau", 0x03c4 },
- { "there4", 0x2234 },
- { "theta", 0x03b8 },
- { "thetasym", 0x03d1 },
- { "thinsp", 0x2009 },
- { "thorn", 0x00fe },
- { "tilde", 0x02dc },
- { "times", 0x00d7 },
- { "trade", 0x2122 },
- { "uArr", 0x21d1 },
- { "uacute", 0x00fa },
- { "uarr", 0x2191 },
- { "ucirc", 0x00fb },
- { "ugrave", 0x00f9 },
- { "uml", 0x00a8 },
- { "upsih", 0x03d2 },
- { "upsilon", 0x03c5 },
- { "uuml", 0x00fc },
- { "weierp", 0x2118 },
- { "xi", 0x03be },
- { "yacute", 0x00fd },
- { "yen", 0x00a5 },
- { "yuml", 0x00ff },
- { "zeta", 0x03b6 },
- { "zwj", 0x200d },
- { "zwnj", 0x200c },
- { "", 0x0000 }
-};
-
-
-
-
-
-static QMap<TQString, TQChar> *html_map = 0;
-static void qt_cleanup_html_map()
-{
- delete html_map;
- html_map = 0;
-}
-
-static QMap<TQString, TQChar> *htmlMap()
-{
- if ( !html_map ) {
- html_map = new QMap<TQString, TQChar>;
- qAddPostRoutine( qt_cleanup_html_map );
-
- const Entity *ent = entitylist;
- while( ent->code ) {
- html_map->insert( ent->name, TQChar(ent->code) );
- ent++;
- }
- }
- return html_map;
-}
-
-TQChar TQTextDocument::parseHTMLSpecialChar(const TQChar* doc, int length, int& pos)
-{
- TQString s;
- pos++;
- int recoverpos = pos;
- while ( pos < length && doc[pos] != ';' && !doc[pos].isSpace() && pos < recoverpos + 8 ) {
- s += doc[pos];
- pos++;
- }
- if (doc[pos] != ';' && !doc[pos].isSpace() ) {
- pos = recoverpos;
- return '&';
- }
- pos++;
-
- if ( s.length() > 1 && s[0] == '#') {
- int off = 1;
- int base = 10;
- if (s[1] == 'x') {
- off = 2;
- base = 16;
- }
- bool ok;
- int num = s.mid(off).toInt(&ok, base);
- if ( num == 151 ) // ### hack for designer manual
- return '-';
- if (ok)
- return num;
- } else {
- QMap<TQString, TQChar>::Iterator it = htmlMap()->find(s);
- if ( it != htmlMap()->end() ) {
- return *it;
- }
- }
-
- pos = recoverpos;
- return '&';
-}
-
-TQString TQTextDocument::parseWord(const TQChar* doc, int length, int& pos, bool lower)
-{
- TQString s;
-
- if (doc[pos] == '"') {
- pos++;
- while ( pos < length && doc[pos] != '"' ) {
- if ( doc[pos] == '&' ) {
- s += parseHTMLSpecialChar( doc, length, pos );
- } else {
- s += doc[pos];
- pos++;
- }
- }
- eat(doc, length, pos, '"');
- } else if (doc[pos] == '\'') {
- pos++;
- while ( pos < length && doc[pos] != '\'' ) {
- s += doc[pos];
- pos++;
- }
- eat(doc, length, pos, '\'');
- } else {
- static TQString term = TQString::tqfromLatin1("/>");
- while ( pos < length
- && doc[pos] != '>'
- && !hasPrefix(doc, length, pos, term)
- && doc[pos] != '<'
- && doc[pos] != '='
- && !doc[pos].isSpace() )
- {
- if ( doc[pos] == '&' ) {
- s += parseHTMLSpecialChar( doc, length, pos );
- } else {
- s += doc[pos];
- pos++;
- }
- }
- if (lower)
- s = s.lower();
- }
- return s;
-}
-
-TQChar TQTextDocument::parseChar(const TQChar* doc, int length, int& pos, TQStyleSheetItem::WhiteSpaceMode wsm )
-{
- if ( pos >= length )
- return TQChar::null;
-
- TQChar c = doc[pos++];
-
- if (c == '<' )
- return TQChar::null;
-
- if ( c.isSpace() && c != TQChar::nbsp ) {
- if ( wsm == TQStyleSheetItem::WhiteSpacePre ) {
- if ( c == '\n' )
- return TQChar_linesep;
- else
- return c;
- } else { // non-pre mode: collapse whitespace except nbsp
- while ( pos< length &&
- doc[pos].isSpace() && doc[pos] != TQChar::nbsp )
- pos++;
- return ' ';
- }
- }
- else if ( c == '&' )
- return parseHTMLSpecialChar( doc, length, --pos );
- else
- return c;
-}
-
-TQString TQTextDocument::parseOpenTag(const TQChar* doc, int length, int& pos,
- QMap<TQString, TQString> &attr, bool& emptyTag)
-{
- emptyTag = FALSE;
- pos++;
- if ( hasPrefix(doc, length, pos, '!') ) {
- if ( hasPrefix( doc, length, pos+1, "--")) {
- pos += 3;
- // eat comments
- TQString pref = TQString::tqfromLatin1("-->");
- while ( !hasPrefix(doc, length, pos, pref ) && pos < length )
- pos++;
- if ( hasPrefix(doc, length, pos, pref ) ) {
- pos += 3;
- eatSpace(doc, length, pos, TRUE);
- }
- emptyTag = TRUE;
- return TQString::null;
- }
- else {
- // eat strange internal tags
- while ( !hasPrefix(doc, length, pos, '>') && pos < length )
- pos++;
- if ( hasPrefix(doc, length, pos, '>') ) {
- pos++;
- eatSpace(doc, length, pos, TRUE);
- }
- return TQString::null;
- }
- }
-
- TQString tag = parseWord(doc, length, pos );
- eatSpace(doc, length, pos, TRUE);
- static TQString term = TQString::tqfromLatin1("/>");
- static TQString s_TRUE = TQString::tqfromLatin1("TRUE");
-
- while (doc[pos] != '>' && ! (emptyTag = hasPrefix(doc, length, pos, term) )) {
- TQString key = parseWord(doc, length, pos );
- eatSpace(doc, length, pos, TRUE);
- if ( key.isEmpty()) {
- // error recovery
- while ( pos < length && doc[pos] != '>' )
- pos++;
- break;
- }
- TQString value;
- if (hasPrefix(doc, length, pos, '=') ){
- pos++;
- eatSpace(doc, length, pos);
- value = parseWord(doc, length, pos, FALSE);
- }
- else
- value = s_TRUE;
- attr.insert(key.lower(), value );
- eatSpace(doc, length, pos, TRUE);
- }
-
- if (emptyTag) {
- eat(doc, length, pos, '/');
- eat(doc, length, pos, '>');
- }
- else
- eat(doc, length, pos, '>');
-
- return tag;
-}
-
-TQString TQTextDocument::parseCloseTag( const TQChar* doc, int length, int& pos )
-{
- pos++;
- pos++;
- TQString tag = parseWord(doc, length, pos );
- eatSpace(doc, length, pos, TRUE);
- eat(doc, length, pos, '>');
- return tag;
-}
-
-TQTextFlow::TQTextFlow()
-{
- w = pagesize = 0;
-}
-
-TQTextFlow::~TQTextFlow()
-{
- clear();
-}
-
-void TQTextFlow::clear()
-{
-#ifndef TQT_NO_TEXTCUSTOMITEM
- leftItems.setAutoDelete( TRUE );
- rightItems.setAutoDelete( TRUE );
- leftItems.clear();
- rightItems.clear();
- leftItems.setAutoDelete( FALSE );
- rightItems.setAutoDelete( FALSE );
-#endif
-}
-
-void TQTextFlow::setWidth( int width )
-{
- w = width;
-}
-
-int TQTextFlow::adjustLMargin( int yp, int, int margin, int space )
-{
-#ifndef TQT_NO_TEXTCUSTOMITEM
- for ( TQTextCustomItem* item = leftItems.first(); item; item = leftItems.next() ) {
- if ( item->ypos == -1 )
- continue;
- if ( yp >= item->ypos && yp < item->ypos + item->height )
- margin = TQMAX( margin, item->xpos + item->width + space );
- }
-#endif
- return margin;
-}
-
-int TQTextFlow::adjustRMargin( int yp, int, int margin, int space )
-{
-#ifndef TQT_NO_TEXTCUSTOMITEM
- for ( TQTextCustomItem* item = rightItems.first(); item; item = rightItems.next() ) {
- if ( item->ypos == -1 )
- continue;
- if ( yp >= item->ypos && yp < item->ypos + item->height )
- margin = TQMAX( margin, w - item->xpos - space );
- }
-#endif
- return margin;
-}
-
-
-int TQTextFlow::adjustFlow( int y, int /*w*/, int h )
-{
- if ( pagesize > 0 ) { // check pages
- int yinpage = y % pagesize;
- if ( yinpage <= border_tolerance )
- return border_tolerance - yinpage;
- else
- if ( yinpage + h > pagesize - border_tolerance )
- return ( pagesize - yinpage ) + border_tolerance;
- }
- return 0;
-}
-
-#ifndef TQT_NO_TEXTCUSTOMITEM
-void TQTextFlow::unregisterFloatingItem( TQTextCustomItem* item )
-{
- leftItems.removeRef( item );
- rightItems.removeRef( item );
-}
-
-void TQTextFlow::registerFloatingItem( TQTextCustomItem* item )
-{
- if ( item->placement() == TQTextCustomItem::PlaceRight ) {
- if ( !rightItems.contains( item ) )
- rightItems.append( item );
- } else if ( item->placement() == TQTextCustomItem::PlaceLeft &&
- !leftItems.contains( item ) ) {
- leftItems.append( item );
- }
-}
-#endif // TQT_NO_TEXTCUSTOMITEM
-
-TQRect TQTextFlow::boundingRect() const
-{
- TQRect br;
-#ifndef TQT_NO_TEXTCUSTOMITEM
- TQPtrListIterator<TQTextCustomItem> l( leftItems );
- while( l.current() ) {
- br = br.unite( l.current()->tqgeometry() );
- ++l;
- }
- TQPtrListIterator<TQTextCustomItem> r( rightItems );
- while( r.current() ) {
- br = br.unite( r.current()->tqgeometry() );
- ++r;
- }
-#endif
- return br;
-}
-
-
-void TQTextFlow::drawFloatingItems( TQPainter* p, int cx, int cy, int cw, int ch, const TQColorGroup& cg, bool selected )
-{
-#ifndef TQT_NO_TEXTCUSTOMITEM
- TQTextCustomItem *item;
- for ( item = leftItems.first(); item; item = leftItems.next() ) {
- if ( item->xpos == -1 || item->ypos == -1 )
- continue;
- item->draw( p, item->xpos, item->ypos, cx, cy, cw, ch, cg, selected );
- }
-
- for ( item = rightItems.first(); item; item = rightItems.next() ) {
- if ( item->xpos == -1 || item->ypos == -1 )
- continue;
- item->draw( p, item->xpos, item->ypos, cx, cy, cw, ch, cg, selected );
- }
-#endif
-}
-
-// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-#ifndef TQT_NO_TEXTCUSTOMITEM
-void TQTextCustomItem::pageBreak( int /*y*/ , TQTextFlow* /*flow*/ )
-{
-}
-#endif
-
-#ifndef TQT_NO_TEXTCUSTOMITEM
-TQTextTable::TQTextTable( TQTextDocument *p, const QMap<TQString, TQString> & attr )
- : TQTextCustomItem( p )
-{
- cells.setAutoDelete( FALSE );
- cellspacing = 2;
- if ( attr.contains("cellspacing") )
- cellspacing = attr["cellspacing"].toInt();
- cellpadding = 1;
- if ( attr.contains("cellpadding") )
- cellpadding = attr["cellpadding"].toInt();
- border = innerborder = 0;
- if ( attr.contains("border" ) ) {
- TQString s( attr["border"] );
- if ( s == "TRUE" )
- border = 1;
- else
- border = attr["border"].toInt();
- }
- us_b = border;
-
- innerborder = us_ib = border ? 1 : 0;
-
- if ( border )
- cellspacing += 2;
-
- us_ib = innerborder;
- us_cs = cellspacing;
- us_cp = cellpadding;
- outerborder = cellspacing + border;
- us_ob = outerborder;
- tqlayout = new TQGridLayout( 1, 1, cellspacing );
-
- fixwidth = 0;
- stretch = 0;
- if ( attr.contains("width") ) {
- bool b;
- TQString s( attr["width"] );
- int w = s.toInt( &b );
- if ( b ) {
- fixwidth = w;
- } else {
- s = s.stripWhiteSpace();
- if ( s.length() > 1 && s[ (int)s.length()-1 ] == '%' )
- stretch = s.left( s.length()-1).toInt();
- }
- }
- us_fixwidth = fixwidth;
-
- place = PlaceInline;
- if ( attr["align"] == "left" )
- place = PlaceLeft;
- else if ( attr["align"] == "right" )
- place = PlaceRight;
- cachewidth = 0;
- attributes = attr;
- pageBreakFor = -1;
-}
-
-TQTextTable::~TQTextTable()
-{
- delete tqlayout;
-}
-
-TQString TQTextTable::richText() const
-{
- TQString s;
- s = "<table ";
- QMap<TQString, TQString>::ConstIterator it = attributes.begin();
- for ( ; it != attributes.end(); ++it )
- s += it.key() + "=" + *it + " ";
- s += ">\n";
-
- int lastRow = -1;
- bool needEnd = FALSE;
- TQPtrListIterator<TQTextTableCell> it2( cells );
- while ( it2.current() ) {
- TQTextTableCell *cell = it2.current();
- ++it2;
- if ( lastRow != cell->row() ) {
- if ( lastRow != -1 )
- s += "</tr>\n";
- s += "<tr>";
- lastRow = cell->row();
- needEnd = TRUE;
- }
- s += "<td";
- it = cell->attributes.begin();
- for ( ; it != cell->attributes.end(); ++it )
- s += " " + it.key() + "=" + *it;
- s += ">";
- s += cell->richText()->richText();
- s += "</td>";
- }
- if ( needEnd )
- s += "</tr>\n";
- s += "</table>\n";
- return s;
-}
-
-void TQTextTable::setParagraph(TQTextParagraph *p)
-{
- for ( TQTextTableCell* cell = cells.first(); cell; cell = cells.next() )
- cell->richText()->parentPar = p;
- TQTextCustomItem::setParagraph(p);
-}
-
-void TQTextTable::adjustToPainter( TQPainter* p )
-{
- cellspacing = scale( us_cs, p );
- cellpadding = scale( us_cp, p );
- border = scale( us_b , p );
- innerborder = scale( us_ib, p );
- outerborder = scale( us_ob ,p );
- fixwidth = scale( us_fixwidth, p);
- width = 0;
- cachewidth = 0;
- for ( TQTextTableCell* cell = cells.first(); cell; cell = cells.next() )
- cell->adjustToPainter( p );
-}
-
-void TQTextTable::adjustCells( int y , int shift )
-{
- TQPtrListIterator<TQTextTableCell> it( cells );
- TQTextTableCell* cell;
- bool enlarge = FALSE;
- while ( ( cell = it.current() ) ) {
- ++it;
- TQRect r = cell->tqgeometry();
- if ( y <= r.top() ) {
- r.moveBy(0, shift );
- cell->setGeometry( r );
- enlarge = TRUE;
- } else if ( y <= r.bottom() ) {
- r.rBottom() += shift;
- cell->setGeometry( r );
- enlarge = TRUE;
- }
- }
- if ( enlarge )
- height += shift;
-}
-
-void TQTextTable::pageBreak( int yt, TQTextFlow* flow )
-{
- if ( flow->pageSize() <= 0 )
- return;
- if ( tqlayout && pageBreakFor > 0 && pageBreakFor != yt ) {
- tqlayout->tqinvalidate();
- int h = tqlayout->heightForWidth( width-2*outerborder );
- tqlayout->setGeometry( TQRect(0, 0, width-2*outerborder, h) );
- height = tqlayout->tqgeometry().height()+2*outerborder;
- }
- pageBreakFor = yt;
- TQPtrListIterator<TQTextTableCell> it( cells );
- TQTextTableCell* cell;
- while ( ( cell = it.current() ) ) {
- ++it;
- int y = yt + outerborder + cell->tqgeometry().y();
- int shift = flow->adjustFlow( y - cellspacing, width, cell->richText()->height() + 2*cellspacing );
- adjustCells( y - outerborder - yt, shift );
- }
-}
-
-
-void TQTextTable::draw(TQPainter* p, int x, int y, int cx, int cy, int cw, int ch, const TQColorGroup& cg, bool selected )
-{
- if ( placement() != PlaceInline ) {
- x = xpos;
- y = ypos;
- }
-
- for (TQTextTableCell* cell = cells.first(); cell; cell = cells.next() ) {
- if ( (cx < 0 && cy) < 0 ||
- TQRect( cx, cy, cw, ch ).intersects( TQRect( x + outerborder + cell->tqgeometry().x(),
- y + outerborder + cell->tqgeometry().y(),
- cell->tqgeometry().width(), cell->tqgeometry().height() ) ) ) {
- cell->draw( p, x+outerborder, y+outerborder, cx, cy, cw, ch, cg, selected );
- if ( border ) {
- TQRect r( x+outerborder+cell->tqgeometry().x() - innerborder,
- y+outerborder+cell->tqgeometry().y() - innerborder,
- cell->tqgeometry().width() + 2 * innerborder,
- cell->tqgeometry().height() + 2 * innerborder );
- if ( is_printer( p ) ) {
- TQPen oldPen = p->pen();
- TQRect r2 = r;
- r2.addCoords( innerborder/2, innerborder/2, -innerborder/2, -innerborder/2 );
- p->setPen( TQPen( cg.text(), innerborder ) );
- p->drawRect( r2 );
- p->setPen( oldPen );
- } else {
- int s = TQMAX( cellspacing-2*innerborder, 0);
- if ( s ) {
- p->fillRect( r.left()-s, r.top(), s+1, r.height(), cg.button() );
- p->fillRect( r.right(), r.top(), s+1, r.height(), cg.button() );
- p->fillRect( r.left()-s, r.top()-s, r.width()+2*s, s, cg.button() );
- p->fillRect( r.left()-s, r.bottom(), r.width()+2*s, s, cg.button() );
- }
- qDrawShadePanel( p, r, cg, TRUE, innerborder );
- }
- }
- }
- }
- if ( border ) {
- TQRect r ( x, y, width, height );
- if ( is_printer( p ) ) {
- TQRect r2 = r;
- r2.addCoords( border/2, border/2, -border/2, -border/2 );
- TQPen oldPen = p->pen();
- p->setPen( TQPen( cg.text(), border ) );
- p->drawRect( r2 );
- p->setPen( oldPen );
- } else {
- int s = border+TQMAX( cellspacing-2*innerborder, 0);
- if ( s ) {
- p->fillRect( r.left(), r.top(), s, r.height(), cg.button() );
- p->fillRect( r.right()-s, r.top(), s, r.height(), cg.button() );
- p->fillRect( r.left(), r.top(), r.width(), s, cg.button() );
- p->fillRect( r.left(), r.bottom()-s, r.width(), s, cg.button() );
- }
- qDrawShadePanel( p, r, cg, FALSE, border );
- }
- }
-
-}
-
-int TQTextTable::minimumWidth() const
-{
- return fixwidth ? fixwidth : ((tqlayout ? tqlayout->tqminimumSize().width() : 0) + 2 * outerborder);
-}
-
-void TQTextTable::resize( int nwidth )
-{
- if ( fixwidth && cachewidth != 0 )
- return;
- if ( nwidth == cachewidth )
- return;
-
-
- cachewidth = nwidth;
- int w = nwidth;
-
- format( w );
-
- if ( stretch )
- nwidth = nwidth * stretch / 100;
-
- width = nwidth;
- tqlayout->tqinvalidate();
- int shw = tqlayout->tqsizeHint().width() + 2*outerborder;
- int mw = tqlayout->tqminimumSize().width() + 2*outerborder;
- if ( stretch )
- width = TQMAX( mw, nwidth );
- else
- width = TQMAX( mw, TQMIN( nwidth, shw ) );
-
- if ( fixwidth )
- width = fixwidth;
-
- tqlayout->tqinvalidate();
- mw = tqlayout->tqminimumSize().width() + 2*outerborder;
- width = TQMAX( width, mw );
-
- int h = tqlayout->heightForWidth( width-2*outerborder );
- tqlayout->setGeometry( TQRect(0, 0, width-2*outerborder, h) );
- height = tqlayout->tqgeometry().height()+2*outerborder;
-}
-
-void TQTextTable::format( int w )
-{
- for ( int i = 0; i < (int)cells.count(); ++i ) {
- TQTextTableCell *cell = cells.at( i );
- TQRect r = cell->tqgeometry();
- r.setWidth( w - 2*outerborder );
- cell->setGeometry( r );
- }
-}
-
-void TQTextTable::addCell( TQTextTableCell* cell )
-{
- cells.append( cell );
- tqlayout->addMultiCell( cell, cell->row(), cell->row() + cell->rowspan()-1,
- cell->column(), cell->column() + cell->colspan()-1 );
-}
-
-bool TQTextTable::enter( TQTextCursor *c, TQTextDocument *&doc, TQTextParagraph *&parag, int &idx, int &ox, int &oy, bool atEnd )
-{
- currCell.remove( c );
- if ( !atEnd )
- return next( c, doc, parag, idx, ox, oy );
- currCell.insert( c, cells.count() );
- return prev( c, doc, parag, idx, ox, oy );
-}
-
-bool TQTextTable::enterAt( TQTextCursor *c, TQTextDocument *&doc, TQTextParagraph *&parag, int &idx, int &ox, int &oy, const TQPoint &pos )
-{
- currCell.remove( c );
- int lastCell = -1;
- int lastY = -1;
- int i;
- for ( i = 0; i < (int)cells.count(); ++i ) {
- TQTextTableCell *cell = cells.at( i );
- if ( !cell )
- continue;
- TQRect r( cell->tqgeometry().x(),
- cell->tqgeometry().y(),
- cell->tqgeometry().width() + 2 * innerborder + 2 * outerborder,
- cell->tqgeometry().height() + 2 * innerborder + 2 * outerborder );
-
- if ( r.left() <= pos.x() && r.right() >= pos.x() ) {
- if ( cell->tqgeometry().y() > lastY ) {
- lastCell = i;
- lastY = cell->tqgeometry().y();
- }
- if ( r.top() <= pos.y() && r.bottom() >= pos.y() ) {
- currCell.insert( c, i );
- break;
- }
- }
- }
- if ( i == (int) cells.count() )
- return FALSE; // no cell found
-
- if ( currCell.find( c ) == currCell.end() ) {
- if ( lastY != -1 )
- currCell.insert( c, lastCell );
- else
- return FALSE;
- }
-
- TQTextTableCell *cell = cells.at( *currCell.find( c ) );
- if ( !cell )
- return FALSE;
- doc = cell->richText();
- parag = doc->firstParagraph();
- idx = 0;
- ox += cell->tqgeometry().x() + cell->horizontalAlignmentOffset() + outerborder + parent->x();
- oy += cell->tqgeometry().y() + cell->verticalAlignmentOffset() + outerborder;
- return TRUE;
-}
-
-bool TQTextTable::next( TQTextCursor *c, TQTextDocument *&doc, TQTextParagraph *&parag, int &idx, int &ox, int &oy )
-{
- int cc = -1;
- if ( currCell.find( c ) != currCell.end() )
- cc = *currCell.find( c );
- if ( cc > (int)cells.count() - 1 || cc < 0 )
- cc = -1;
- currCell.remove( c );
- currCell.insert( c, ++cc );
- if ( cc >= (int)cells.count() ) {
- currCell.insert( c, 0 );
- TQTextCustomItem::next( c, doc, parag, idx, ox, oy );
- TQTextTableCell *cell = cells.first();
- if ( !cell )
- return FALSE;
- doc = cell->richText();
- idx = -1;
- return TRUE;
- }
-
- if ( currCell.find( c ) == currCell.end() )
- return FALSE;
- TQTextTableCell *cell = cells.at( *currCell.find( c ) );
- if ( !cell )
- return FALSE;
- doc = cell->richText();
- parag = doc->firstParagraph();
- idx = 0;
- ox += cell->tqgeometry().x() + cell->horizontalAlignmentOffset() + outerborder + parent->x();
- oy += cell->tqgeometry().y() + cell->verticalAlignmentOffset() + outerborder;
- return TRUE;
-}
-
-bool TQTextTable::prev( TQTextCursor *c, TQTextDocument *&doc, TQTextParagraph *&parag, int &idx, int &ox, int &oy )
-{
- int cc = -1;
- if ( currCell.find( c ) != currCell.end() )
- cc = *currCell.find( c );
- if ( cc > (int)cells.count() - 1 || cc < 0 )
- cc = cells.count();
- currCell.remove( c );
- currCell.insert( c, --cc );
- if ( cc < 0 ) {
- currCell.insert( c, 0 );
- TQTextCustomItem::prev( c, doc, parag, idx, ox, oy );
- TQTextTableCell *cell = cells.first();
- if ( !cell )
- return FALSE;
- doc = cell->richText();
- idx = -1;
- return TRUE;
- }
-
- if ( currCell.find( c ) == currCell.end() )
- return FALSE;
- TQTextTableCell *cell = cells.at( *currCell.find( c ) );
- if ( !cell )
- return FALSE;
- doc = cell->richText();
- parag = doc->lastParagraph();
- idx = parag->length() - 1;
- ox += cell->tqgeometry().x() + cell->horizontalAlignmentOffset() + outerborder + parent->x();
- oy += cell->tqgeometry().y() + cell->verticalAlignmentOffset() + outerborder;
- return TRUE;
-}
-
-bool TQTextTable::down( TQTextCursor *c, TQTextDocument *&doc, TQTextParagraph *&parag, int &idx, int &ox, int &oy )
-{
- if ( currCell.find( c ) == currCell.end() )
- return FALSE;
- TQTextTableCell *cell = cells.at( *currCell.find( c ) );
- if ( cell->row_ == tqlayout->numRows() - 1 ) {
- currCell.insert( c, 0 );
- TQTextCustomItem::down( c, doc, parag, idx, ox, oy );
- TQTextTableCell *cell = cells.first();
- if ( !cell )
- return FALSE;
- doc = cell->richText();
- idx = -1;
- return TRUE;
- }
-
- int oldRow = cell->row_;
- int oldCol = cell->col_;
- if ( currCell.find( c ) == currCell.end() )
- return FALSE;
- int cc = *currCell.find( c );
- for ( int i = cc; i < (int)cells.count(); ++i ) {
- cell = cells.at( i );
- if ( cell->row_ > oldRow && cell->col_ == oldCol ) {
- currCell.insert( c, i );
- break;
- }
- }
- doc = cell->richText();
- if ( !cell )
- return FALSE;
- parag = doc->firstParagraph();
- idx = 0;
- ox += cell->tqgeometry().x() + cell->horizontalAlignmentOffset() + outerborder + parent->x();
- oy += cell->tqgeometry().y() + cell->verticalAlignmentOffset() + outerborder;
- return TRUE;
-}
-
-bool TQTextTable::up( TQTextCursor *c, TQTextDocument *&doc, TQTextParagraph *&parag, int &idx, int &ox, int &oy )
-{
- if ( currCell.find( c ) == currCell.end() )
- return FALSE;
- TQTextTableCell *cell = cells.at( *currCell.find( c ) );
- if ( cell->row_ == 0 ) {
- currCell.insert( c, 0 );
- TQTextCustomItem::up( c, doc, parag, idx, ox, oy );
- TQTextTableCell *cell = cells.first();
- if ( !cell )
- return FALSE;
- doc = cell->richText();
- idx = -1;
- return TRUE;
- }
-
- int oldRow = cell->row_;
- int oldCol = cell->col_;
- if ( currCell.find( c ) == currCell.end() )
- return FALSE;
- int cc = *currCell.find( c );
- for ( int i = cc; i >= 0; --i ) {
- cell = cells.at( i );
- if ( cell->row_ < oldRow && cell->col_ == oldCol ) {
- currCell.insert( c, i );
- break;
- }
- }
- doc = cell->richText();
- if ( !cell )
- return FALSE;
- parag = doc->lastParagraph();
- idx = parag->length() - 1;
- ox += cell->tqgeometry().x() + cell->horizontalAlignmentOffset() + outerborder + parent->x();
- oy += cell->tqgeometry().y() + cell->verticalAlignmentOffset() + outerborder;
- return TRUE;
-}
-
-TQTextTableCell::TQTextTableCell( TQTextTable* table,
- int row, int column,
- const QMap<TQString, TQString> &attr,
- const TQStyleSheetItem* /*style*/, // ### use them
- const TQTextFormat& fmt, const TQString& context,
- TQMimeSourceFactory &factory, TQStyleSheet *sheet,
- const TQString& doc)
-{
- cached_width = -1;
- cached_sizehint = -1;
-
- maxw = TQWIDGETSIZE_MAX;
- minw = 0;
-
- parent = table;
- row_ = row;
- col_ = column;
- stretch_ = 0;
- richtext = new TQTextDocument( table->parent );
- richtext->formatCollection()->setPaintDevice( table->parent->formatCollection()->paintDevice() );
- richtext->bodyText = fmt.color();
- richtext->setTableCell( this );
- TQString a = *attr.find( "align" );
- if ( !a.isEmpty() ) {
- a = a.lower();
- if ( a == "left" )
- richtext->tqsetAlignment( TQt::AlignLeft );
- else if ( a == "center" )
- richtext->tqsetAlignment( TQt::AlignHCenter );
- else if ( a == "right" )
- richtext->tqsetAlignment( TQt::AlignRight );
- }
- align = 0;
- TQString va = *attr.find( "valign" );
- if ( !va.isEmpty() ) {
- va = va.lower();
- if ( va == "top" )
- align |= TQt::AlignTop;
- else if ( va == "center" || va == "middle" )
- align |= TQt::AlignVCenter;
- else if ( va == "bottom" )
- align |= TQt::AlignBottom;
- }
- richtext->setFormatter( table->parent->formatter() );
- richtext->setUseFormatCollection( table->parent->useFormatCollection() );
- richtext->setMimeSourceFactory( &factory );
- richtext->setStyleSheet( sheet );
- richtext->setRichText( doc, context, &fmt );
- rowspan_ = 1;
- colspan_ = 1;
- if ( attr.contains("colspan") )
- colspan_ = attr["colspan"].toInt();
- if ( attr.contains("rowspan") )
- rowspan_ = attr["rowspan"].toInt();
-
- background = 0;
- if ( attr.contains("bgcolor") ) {
- background = new TQBrush(TQColor( attr["bgcolor"] ));
- }
-
-
- hasFixedWidth = FALSE;
- if ( attr.contains("width") ) {
- bool b;
- TQString s( attr["width"] );
- int w = s.toInt( &b );
- if ( b ) {
- maxw = w;
- minw = maxw;
- hasFixedWidth = TRUE;
- } else {
- s = s.stripWhiteSpace();
- if ( s.length() > 1 && s[ (int)s.length()-1 ] == '%' )
- stretch_ = s.left( s.length()-1).toInt();
- }
- }
-
- attributes = attr;
-
- parent->addCell( this );
-}
-
-TQTextTableCell::~TQTextTableCell()
-{
- delete background;
- background = 0;
- delete richtext;
- richtext = 0;
-}
-
-TQSize TQTextTableCell::tqsizeHint() const
-{
- int extra = 2 * ( parent->innerborder + parent->cellpadding + border_tolerance);
- int used = richtext->widthUsed() + extra;
-
- if (stretch_ ) {
- int w = parent->width * stretch_ / 100 - 2*parent->cellspacing - 2*parent->cellpadding;
- return TQSize( TQMIN( w, maxw ), 0 ).expandedTo( tqminimumSize() );
- }
-
- return TQSize( used, 0 ).expandedTo( tqminimumSize() );
-}
-
-TQSize TQTextTableCell::tqminimumSize() const
-{
- int extra = 2 * ( parent->innerborder + parent->cellpadding + border_tolerance);
- return TQSize( TQMAX( richtext->minimumWidth() + extra, minw), 0 );
-}
-
-TQSize TQTextTableCell::tqmaximumSize() const
-{
- return TQSize( maxw, TQWIDGETSIZE_MAX );
-}
-
-TQ_SPExpandData TQTextTableCell::expandingDirections() const
-{
- return (TQ_SPExpandData)TQSizePolicy::BothDirections;
-}
-
-bool TQTextTableCell::isEmpty() const
-{
- return FALSE;
-}
-void TQTextTableCell::setGeometry( const TQRect& r )
-{
- int extra = 2 * ( parent->innerborder + parent->cellpadding );
- if ( r.width() != cached_width )
- richtext->doLayout( TQTextFormat::painter(), r.width() - extra );
- cached_width = r.width();
- geom = r;
-}
-
-TQRect TQTextTableCell::tqgeometry() const
-{
- return geom;
-}
-
-bool TQTextTableCell::hasHeightForWidth() const
-{
- return TRUE;
-}
-
-int TQTextTableCell::heightForWidth( int w ) const
-{
- int extra = 2 * ( parent->innerborder + parent->cellpadding );
- w = TQMAX( minw, w );
-
- if ( cached_width != w ) {
- TQTextTableCell* that = (TQTextTableCell*) this;
- that->richtext->doLayout( TQTextFormat::painter(), w - extra );
- that->cached_width = w;
- }
- return richtext->height() + extra;
-}
-
-void TQTextTableCell::adjustToPainter( TQPainter* p )
-{
- TQTextParagraph *parag = richtext->firstParagraph();
- while ( parag ) {
- parag->adjustToPainter( p );
- parag = parag->next();
- }
-}
-
-int TQTextTableCell::horizontalAlignmentOffset() const
-{
- return parent->cellpadding;
-}
-
-int TQTextTableCell::verticalAlignmentOffset() const
-{
- if ( (align & TQt::AlignVCenter ) == TQt::AlignVCenter )
- return ( geom.height() - richtext->height() ) / 2;
- else if ( ( align & TQt::AlignBottom ) == TQt::AlignBottom )
- return geom.height() - parent->cellpadding - richtext->height() ;
- return parent->cellpadding;
-}
-
-void TQTextTableCell::draw( TQPainter* p, int x, int y, int cx, int cy, int cw, int ch, const TQColorGroup& cg, bool )
-{
- if ( cached_width != geom.width() ) {
- int extra = 2 * ( parent->innerborder + parent->cellpadding );
- richtext->doLayout( p, geom.width() - extra );
- cached_width = geom.width();
- }
- TQColorGroup g( cg );
- if ( background )
- g.setBrush( TQColorGroup::Base, *background );
- else if ( richtext->paper() )
- g.setBrush( TQColorGroup::Base, *richtext->paper() );
-
- p->save();
- p->translate( x + geom.x(), y + geom.y() );
- if ( background )
- p->fillRect( 0, 0, geom.width(), geom.height(), *background );
- else if ( richtext->paper() )
- p->fillRect( 0, 0, geom.width(), geom.height(), *richtext->paper() );
-
- p->translate( horizontalAlignmentOffset(), verticalAlignmentOffset() );
-
- TQRegion r;
- if ( cx >= 0 && cy >= 0 )
- richtext->draw( p, cx - ( x + horizontalAlignmentOffset() + geom.x() ),
- cy - ( y + geom.y() + verticalAlignmentOffset() ),
- cw, ch, g, FALSE, FALSE, 0 );
- else
- richtext->draw( p, -1, -1, -1, -1, g, FALSE, FALSE, 0 );
-
- p->restore();
-}
-#endif
-
-#endif //TQT_NO_RICHTEXT
-
-#endif // USE_QT4