Warning, file /office/calligra/libs/text/KoTextDocument.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /* This file is part of the KDE project
0002  * Copyright (C) 2008 Girish Ramakrishnan <girish@forwardbias.in>
0003  * Copyright (C) 2009 Thomas Zander <zander@kde.org>
0004  * Copyright (C) 2008 Pierre Stirnweiss \pierre.stirnweiss_calligra@gadz.org>
0005  * Copyright (C) 2011-2012 C. Boemann <cbo@boemann.dk>
0006  * Copyright (C) 2014-2015 Denis Kuplyakov <dener.kup@gmail.com>
0007  *
0008  * This library is free software; you can redistribute it and/or
0009  * modify it under the terms of the GNU Library General Public
0010  * License as published by the Free Software Foundation; either
0011  * version 2 of the License, or (at your option) any later version.
0012  *
0013  * This library is distributed in the hope that it will be useful,
0014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0016  * Library General Public License for more details.
0017  *
0018  * You should have received a copy of the GNU Library General Public License
0019  * along with this library; see the file COPYING.LIB.  If not, write to
0020  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0021  * Boston, MA 02110-1301, USA.
0022  */
0023 
0024 #include "KoTextDocument.h"
0025 
0026 #include <QTextCursor>
0027 #include <QVariant>
0028 #include <QVariantList>
0029 
0030 #include "TextDebug.h"
0031 #include <KoTextDebug.h>
0032 
0033 #include <kundo2stack.h>
0034 
0035 #include "KoText.h"
0036 #include "KoTextEditor.h"
0037 #include "styles/KoStyleManager.h"
0038 #include "OdfTextTrackStyles.h"
0039 #include "KoTextRangeManager.h"
0040 #include "KoInlineTextObjectManager.h"
0041 #include "KoList.h"
0042 #include "KoOdfLineNumberingConfiguration.h"
0043 #include "changetracker/KoChangeTracker.h"
0044 #include <KoShapeController.h>
0045 #include <KoSectionModel.h>
0046 
0047 Q_DECLARE_METATYPE(QAbstractTextDocumentLayout::Selection)
0048 Q_DECLARE_METATYPE(QTextFrame*)
0049 Q_DECLARE_METATYPE(QTextCharFormat)
0050 Q_DECLARE_METATYPE(QTextBlockFormat)
0051 
0052 const QUrl KoTextDocument::StyleManagerURL = QUrl("kotext://stylemanager");
0053 const QUrl KoTextDocument::ListsURL = QUrl("kotext://lists");
0054 const QUrl KoTextDocument::InlineObjectTextManagerURL = QUrl("kotext://inlineObjectTextManager");
0055 const QUrl KoTextDocument::TextRangeManagerURL = QUrl("kotext://textRangeManager");
0056 const QUrl KoTextDocument::UndoStackURL = QUrl("kotext://undoStack");
0057 const QUrl KoTextDocument::ChangeTrackerURL = QUrl("kotext://changetracker");
0058 const QUrl KoTextDocument::TextEditorURL = QUrl("kotext://textEditor");
0059 const QUrl KoTextDocument::LineNumberingConfigurationURL = QUrl("kotext://linenumberingconfiguration");
0060 const QUrl KoTextDocument::RelativeTabsURL = QUrl("kotext://relativetabs");
0061 const QUrl KoTextDocument::HeadingListURL = QUrl("kotext://headingList");
0062 const QUrl KoTextDocument::SelectionsURL = QUrl("kotext://selections");
0063 const QUrl KoTextDocument::LayoutTextPageUrl = QUrl("kotext://layoutTextPage");
0064 const QUrl KoTextDocument::ParaTableSpacingAtStartUrl = QUrl("kotext://spacingAtStart");
0065 const QUrl KoTextDocument::IndexGeneratorManagerUrl = QUrl("kotext://indexGeneratorManager");
0066 const QUrl KoTextDocument::FrameCharFormatUrl = QUrl("kotext://frameCharFormat");
0067 const QUrl KoTextDocument::FrameBlockFormatUrl = QUrl("kotext://frameBlockFormat");
0068 const QUrl KoTextDocument::ShapeControllerUrl = QUrl("kotext://shapeController");
0069 const QUrl KoTextDocument::SectionModelUrl = QUrl("ktext://sectionModel");
0070 
0071 KoTextDocument::KoTextDocument(QTextDocument *document)
0072     : m_document(document)
0073 {
0074     Q_ASSERT(m_document);
0075 }
0076 
0077 KoTextDocument::KoTextDocument(const QTextDocument *document)
0078     : m_document(const_cast<QTextDocument *>(document))
0079 {
0080     Q_ASSERT(m_document);
0081 }
0082 
0083 KoTextDocument::KoTextDocument(QPointer<QTextDocument> document)
0084     : m_document(document.data())
0085 {
0086     Q_ASSERT(m_document);
0087 }
0088 
0089 KoTextDocument::~KoTextDocument()
0090 {
0091 }
0092 
0093 QTextDocument *KoTextDocument::document() const
0094 {
0095     return m_document;
0096 }
0097 
0098 void KoTextDocument::setTextEditor (KoTextEditor* textEditor)
0099 {
0100     Q_ASSERT(textEditor->document() == m_document);
0101 
0102     QVariant v;
0103     v.setValue(textEditor);
0104     m_document->addResource(KoTextDocument::TextEditor, TextEditorURL, v);
0105 }
0106 
0107 KoTextEditor* KoTextDocument::textEditor() const
0108 {
0109     QVariant resource = m_document->resource(KoTextDocument::TextEditor, TextEditorURL);
0110     return resource.value<KoTextEditor *>();
0111 }
0112 
0113 void KoTextDocument::setStyleManager(KoStyleManager *sm)
0114 {
0115     QVariant v;
0116     v.setValue(sm);
0117     m_document->addResource(KoTextDocument::StyleManager, StyleManagerURL, v);
0118     if (sm) {
0119         OdfTextTrackStyles *cf = OdfTextTrackStyles::instance(sm);
0120         cf->registerDocument(m_document);
0121     }
0122 }
0123 
0124 void KoTextDocument::setInlineTextObjectManager(KoInlineTextObjectManager *manager)
0125 {
0126     QVariant v;
0127     v.setValue(manager);
0128     m_document->addResource(KoTextDocument::InlineTextManager, InlineObjectTextManagerURL, v);
0129 }
0130 
0131 void KoTextDocument::setTextRangeManager(KoTextRangeManager *manager)
0132 {
0133     QVariant v;
0134     v.setValue(manager);
0135     m_document->addResource(KoTextDocument::TextRangeManager, TextRangeManagerURL, v);
0136 }
0137 
0138 KoStyleManager *KoTextDocument::styleManager() const
0139 {
0140     QVariant resource = m_document->resource(KoTextDocument::StyleManager, StyleManagerURL);
0141     return resource.value<KoStyleManager *>();
0142 }
0143 
0144 void KoTextDocument::setChangeTracker(KoChangeTracker *changeTracker)
0145 {
0146     QVariant v;
0147     v.setValue(changeTracker);
0148     m_document->addResource(KoTextDocument::ChangeTrackerResource, ChangeTrackerURL, v);
0149 }
0150 
0151 KoChangeTracker *KoTextDocument::changeTracker() const
0152 {
0153     QVariant resource = m_document->resource(KoTextDocument::ChangeTrackerResource, ChangeTrackerURL);
0154     if (resource.isValid()) {
0155         return resource.value<KoChangeTracker *>();
0156     }
0157     else {
0158         return 0;
0159     }
0160 }
0161 
0162 void KoTextDocument::setShapeController(KoShapeController *controller)
0163 {
0164     QVariant v;
0165     v.setValue(controller);
0166     m_document->addResource(KoTextDocument::ShapeController, ShapeControllerUrl, v);
0167 }
0168 
0169 KoShapeController *KoTextDocument::shapeController() const
0170 {
0171     QVariant resource = m_document->resource(KoTextDocument::ShapeController, ShapeControllerUrl);
0172     if (resource.isValid()) {
0173         return resource.value<KoShapeController *>();
0174     }
0175     else {
0176         return 0;
0177     }
0178 }
0179 
0180 void KoTextDocument::setLineNumberingConfiguration(KoOdfLineNumberingConfiguration *lineNumberingConfiguration)
0181 {
0182     lineNumberingConfiguration->setParent(m_document);
0183     QVariant v;
0184     v.setValue(lineNumberingConfiguration);
0185     m_document->addResource(KoTextDocument::LineNumberingConfiguration, LineNumberingConfigurationURL, v);
0186 }
0187 
0188 KoOdfLineNumberingConfiguration *KoTextDocument::lineNumberingConfiguration() const
0189 {
0190     return m_document->resource(KoTextDocument::LineNumberingConfiguration, LineNumberingConfigurationURL)
0191             .value<KoOdfLineNumberingConfiguration*>();
0192 }
0193 
0194 void KoTextDocument::setHeadingList(KoList *headingList)
0195 {
0196     QVariant v;
0197     v.setValue(headingList);
0198     m_document->addResource(KoTextDocument::HeadingList, HeadingListURL, v);
0199 }
0200 
0201 KoList *KoTextDocument::headingList() const
0202 {
0203     QVariant resource = m_document->resource(KoTextDocument::HeadingList, HeadingListURL);
0204     return resource.value<KoList *>();
0205 }
0206 
0207 void KoTextDocument::setUndoStack(KUndo2Stack *undoStack)
0208 {
0209     QVariant v;
0210     v.setValue<void*>(undoStack);
0211     m_document->addResource(KoTextDocument::UndoStack, UndoStackURL, v);
0212 }
0213 
0214 KUndo2Stack *KoTextDocument::undoStack() const
0215 {
0216     QVariant resource = m_document->resource(KoTextDocument::UndoStack, UndoStackURL);
0217     return static_cast<KUndo2Stack*>(resource.value<void*>());
0218 }
0219 
0220 void KoTextDocument::setLists(const QList<KoList *> &lists)
0221 {
0222     QVariant v;
0223     v.setValue(lists);
0224     m_document->addResource(KoTextDocument::Lists, ListsURL, v);
0225 }
0226 
0227 QList<KoList *> KoTextDocument::lists() const
0228 {
0229     QVariant resource = m_document->resource(KoTextDocument::Lists, ListsURL);
0230     return resource.value<QList<KoList *> >();
0231 }
0232 
0233 void KoTextDocument::addList(KoList *list)
0234 {
0235     Q_ASSERT(list);
0236     list->setParent(m_document);
0237     QList<KoList *> l = lists();
0238     if (l.contains(list))
0239         return;
0240     l.append(list);
0241     setLists(l);
0242 }
0243 
0244 void KoTextDocument::removeList(KoList *list)
0245 {
0246     QList<KoList *> l = lists();
0247     if (l.contains(list)) {
0248         l.removeAll(list);
0249         setLists(l);
0250     }
0251 }
0252 
0253 KoList *KoTextDocument::list(const QTextBlock &block) const
0254 {
0255     QTextList *textList = block.textList();
0256     if (!textList)
0257         return 0;
0258     return list(textList);
0259 }
0260 
0261 KoList *KoTextDocument::list(QTextList *textList) const
0262 {
0263     if (!textList) {
0264         return 0;
0265     }
0266     // FIXME: this is horrible.
0267     foreach(KoList *l, lists()) {
0268         if (l->textLists().contains(textList))
0269             return l;
0270     }
0271     return 0;
0272 }
0273 
0274 KoList *KoTextDocument::list(KoListStyle::ListIdType listId) const
0275 {
0276     foreach(KoList *l, lists()) {
0277         if (l->textListIds().contains(listId))
0278             return l;
0279     }
0280     return 0;
0281 }
0282 
0283 void KoTextDocument::clearText()
0284 {
0285     QTextCursor cursor(m_document);
0286     cursor.select(QTextCursor::Document);
0287     cursor.removeSelectedText();
0288 }
0289 
0290 QVector< QAbstractTextDocumentLayout::Selection > KoTextDocument::selections() const
0291 {
0292     QVariant resource = m_document->resource(KoTextDocument::Selections, SelectionsURL);
0293     QVariantList variants = resource.toList();
0294 
0295     QVector<QAbstractTextDocumentLayout::Selection> selections;
0296     foreach(const QVariant &variant, variants) {
0297         selections.append(variant.value<QAbstractTextDocumentLayout::Selection>());
0298     }
0299 
0300     return selections;
0301 }
0302 
0303 void KoTextDocument::setSelections(const QVector< QAbstractTextDocumentLayout::Selection >& selections)
0304 {
0305     QVariantList variants;
0306     foreach(const QAbstractTextDocumentLayout::Selection &selection, selections) {
0307         variants.append(QVariant::fromValue<QAbstractTextDocumentLayout::Selection>(selection));
0308     }
0309 
0310     m_document->addResource(KoTextDocument::Selections, SelectionsURL, variants);
0311 }
0312 
0313 KoInlineTextObjectManager *KoTextDocument::inlineTextObjectManager() const
0314 {
0315     QVariant resource = m_document->resource(KoTextDocument::InlineTextManager,
0316             InlineObjectTextManagerURL);
0317     return resource.value<KoInlineTextObjectManager *>();
0318 }
0319 
0320 KoTextRangeManager *KoTextDocument::textRangeManager() const
0321 {
0322     QVariant resource = m_document->resource(KoTextDocument::TextRangeManager,
0323             TextRangeManagerURL);
0324     return resource.value<KoTextRangeManager *>();
0325 }
0326 
0327 QTextFrame *KoTextDocument::auxillaryFrame()
0328 {
0329     QTextCursor cursor(m_document->rootFrame()->lastCursorPosition());
0330     cursor.movePosition(QTextCursor::PreviousCharacter);
0331     QTextFrame *frame = cursor.currentFrame();
0332 
0333     if (frame->format().intProperty(KoText::SubFrameType) != KoText::AuxillaryFrameType) {
0334         cursor = m_document->rootFrame()->lastCursorPosition();
0335 
0336         QTextFrameFormat format;
0337         format.setProperty(KoText::SubFrameType, KoText::AuxillaryFrameType);
0338 
0339         frame = cursor.insertFrame(format);
0340     }
0341     return frame;
0342 }
0343 
0344 void KoTextDocument::setRelativeTabs(bool relative)
0345 {
0346     QVariant v(relative);
0347     m_document->addResource(KoTextDocument::RelativeTabs, RelativeTabsURL, v);
0348 }
0349 
0350 bool KoTextDocument::relativeTabs() const
0351 {
0352     QVariant resource = m_document->resource(KoTextDocument::RelativeTabs, RelativeTabsURL);
0353     if (resource.isValid())
0354         return resource.toBool();
0355     else
0356         return true;
0357 }
0358 
0359 void KoTextDocument::setParaTableSpacingAtStart(bool spacingAtStart)
0360 {
0361     QVariant v(spacingAtStart);
0362     m_document->addResource(KoTextDocument::ParaTableSpacingAtStart, ParaTableSpacingAtStartUrl, v);
0363 }
0364 
0365 bool KoTextDocument::paraTableSpacingAtStart() const
0366 {
0367     QVariant resource = m_document->resource(KoTextDocument::ParaTableSpacingAtStart, ParaTableSpacingAtStartUrl);
0368     if (resource.isValid())
0369         return resource.toBool();
0370     else
0371         return false;
0372 }
0373 
0374 QTextCharFormat KoTextDocument::frameCharFormat() const
0375 {
0376     QVariant resource = m_document->resource(KoTextDocument::FrameCharFormat, FrameCharFormatUrl);
0377     if (resource.isValid())
0378         return resource.value<QTextCharFormat>();
0379     else
0380         return QTextCharFormat();
0381 }
0382 
0383 void KoTextDocument::setFrameCharFormat(const QTextCharFormat &format)
0384 {
0385     m_document->addResource(KoTextDocument::FrameCharFormat, FrameCharFormatUrl, QVariant::fromValue(format));
0386 }
0387 
0388 QTextBlockFormat KoTextDocument::frameBlockFormat() const
0389 {
0390     QVariant resource = m_document->resource(KoTextDocument::FrameBlockFormat, FrameBlockFormatUrl);
0391     if (resource.isValid())
0392         return resource.value<QTextBlockFormat>();
0393     else
0394         return QTextBlockFormat();
0395 }
0396 
0397 void KoTextDocument::setFrameBlockFormat(const QTextBlockFormat &format)
0398 {
0399     m_document->addResource(KoTextDocument::FrameBlockFormat, FrameBlockFormatUrl, QVariant::fromValue(format));
0400 }
0401 
0402 KoSectionModel* KoTextDocument::sectionModel()
0403 {
0404     QVariant resource = m_document->resource(KoTextDocument::SectionModel, SectionModelUrl);
0405     if (!resource.isValid()) {
0406         setSectionModel(new KoSectionModel(document())); // Using create on demand strategy
0407     }
0408     return m_document->resource(KoTextDocument::SectionModel, SectionModelUrl).value<KoSectionModel *>();
0409 }
0410 
0411 void KoTextDocument::setSectionModel(KoSectionModel *model)
0412 {
0413     QVariant v;
0414     v.setValue(model);
0415     m_document->addResource(KoTextDocument::SectionModel, SectionModelUrl, v);
0416 }