Warning, file /office/calligra/libs/widgets/KoRulerController_p.h 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) 2007 Thomas Zander <zander@kde.org>
0003  *
0004  * This library is free software; you can redistribute it and/or
0005  * modify it under the terms of the GNU Library General Public
0006  * License as published by the Free Software Foundation; either
0007  * version 2 of the License, or (at your option) any later version.
0008  *
0009  * This library is distributed in the hope that it will be useful,
0010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012  * Library General Public License for more details.
0013  *
0014  * You should have received a copy of the GNU Library General Public License
0015  * along with this library; see the file COPYING.LIB.  If not, write to
0016  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0017  * Boston, MA 02110-1301, USA.
0018  */
0019 #ifndef KoRulerController_p_h
0020 #define KoRulerController_p_h
0021 
0022 #include "KoRulerController.h"
0023 #include "KoText.h"
0024 #include "styles/KoParagraphStyle.h"
0025 
0026 #include <KoCanvasResourceManager.h>
0027 #include <KoTextDocument.h>
0028 
0029 #include <WidgetsDebug.h>
0030 
0031 #include <QVariant>
0032 #include <QTextOption>
0033 #include <QTextDocument>
0034 #include <QTextBlock>
0035 #include <QTextBlockFormat>
0036 #include <QTextLayout>
0037 #include <QTextCursor>
0038 #include <QLocale>
0039 
0040 #include <KoRuler.h>
0041 
0042 #include <algorithm>
0043 
0044 static int compareTabs(KoText::Tab &tab1, KoText::Tab &tab2)
0045 {
0046     return tab1.position < tab2.position;
0047 }
0048 
0049 class Q_DECL_HIDDEN KoRulerController::Private
0050 {
0051 public:
0052     Private(KoRuler *r, KoCanvasResourceManager *crp)
0053             : ruler(r),
0054             resourceManager(crp),
0055             lastPosition(-1),
0056             originalTabIndex(-2),
0057             currentTabIndex(-2) {
0058     }
0059 
0060     void canvasResourceChanged(int key) {
0061         if (key != KoText::CurrentTextPosition && key != KoText::CurrentTextDocument
0062             && key != KoCanvasResourceManager::ActiveRange)
0063             return;
0064 
0065         QTextBlock block = currentBlock();
0066         if (! block.isValid()) {
0067             ruler->setShowIndents(false);
0068             ruler->setShowTabs(false);
0069             return;
0070         }
0071 
0072         QRectF activeRange = resourceManager->resource(KoCanvasResourceManager::ActiveRange).toRectF();
0073         ruler->setOverrideActiveRange(activeRange.left(), activeRange.right());
0074         lastPosition = block.position();
0075         currentTabIndex = -2;
0076         tabList.clear();
0077 
0078         QTextBlockFormat format = block.blockFormat();
0079         ruler->setRightToLeft(block.layout()->textOption().textDirection() == Qt::RightToLeft);
0080         ruler->setParagraphIndent(format.leftMargin());
0081         ruler->setFirstLineIndent(format.textIndent());
0082         ruler->setEndIndent(format.rightMargin());
0083         ruler->setRelativeTabs(relativeTabs());
0084 
0085         QList<KoRuler::Tab> tabs;
0086         QVariant variant = format.property(KoParagraphStyle::TabPositions);
0087         if (! variant.isNull()) {
0088             foreach(const QVariant & var, qvariant_cast<QList<QVariant> >(variant)) {
0089                 KoText::Tab textTab = var.value<KoText::Tab>();
0090                 KoRuler::Tab tab;
0091                 tab.position = textTab.position;
0092                 tab.type = textTab.type;
0093                 tabs.append(tab);
0094             }
0095         }
0096         qreal tabStopDistance = format.doubleProperty(KoParagraphStyle::TabStopDistance);
0097 /*        if (tabStopDistance <= 0) {
0098 // kotextdocumentlayout hardly reachable from here :(
0099     tabStopDistance = block.document()->documentLayout()->defaultTabSpacing();
0100         } */
0101         ruler->updateTabs(tabs, tabStopDistance);
0102 
0103         ruler->setShowIndents(true);
0104         ruler->setShowTabs(true);
0105     }
0106 
0107     void indentsChanged() {
0108         QTextBlock block = currentBlock();
0109         if (! block.isValid())
0110             return;
0111         QTextCursor cursor(block);
0112         QTextBlockFormat bf = cursor.blockFormat();
0113         bf.setLeftMargin(ruler->paragraphIndent());
0114         bf.setTextIndent(ruler->firstLineIndent());
0115         bf.setRightMargin(ruler->endIndent());
0116         cursor.setBlockFormat(bf);
0117     }
0118 
0119     void tabChanged(int originalIndex, KoRuler::Tab *tab) {
0120         QVariant docVar = resourceManager->resource(KoText::CurrentTextDocument);
0121         if (docVar.isNull())
0122             return;
0123         QTextDocument *doc = static_cast<QTextDocument*>(docVar.value<void*>());
0124         if (doc == nullptr)
0125             return;
0126         const int position = resourceManager->intResource(KoText::CurrentTextPosition);
0127         const int anchor = resourceManager->intResource(KoText::CurrentTextAnchor);
0128 
0129         QTextCursor cursor(doc);
0130         cursor.setPosition(anchor);
0131         cursor.setPosition(position, QTextCursor::KeepAnchor);
0132 
0133         if (originalTabIndex == -2 || originalTabIndex != originalIndex) {
0134             originalTabIndex = originalIndex;
0135             KoParagraphStyle style(cursor.blockFormat(), cursor.blockCharFormat());
0136             tabList = style.tabPositions();
0137             if (originalTabIndex >= 0) { // modification
0138                 currentTab = tabList[originalTabIndex];
0139                 currentTabIndex = originalTabIndex;
0140             } else if (originalTabIndex == -1 && tab) { // new tab.
0141                 currentTab = KoText::Tab();
0142                 currentTab.type = tab->type;
0143                 if (tab->type == QTextOption::DelimiterTab)
0144                     currentTab.delimiter = QLocale::system().decimalPoint(); // TODO check language of text
0145                 currentTabIndex = tabList.count();
0146                 tabList << currentTab;
0147             } else {
0148                 warnWidgets << "Unexpected input from tabChanged signal";
0149                 Q_ASSERT(false);
0150                 return;
0151             }
0152         }
0153 
0154         if (tab) {
0155             currentTab.position = tab->position;
0156             currentTab.type = tab->type;
0157             if (currentTabIndex == -2) { // add the new tab to the list, sorting in.
0158                 currentTabIndex = tabList.count();
0159                 tabList << currentTab;
0160             } else
0161                 tabList.replace(currentTabIndex, currentTab);
0162         } else if (currentTabIndex >= 0) { // lets remove it.
0163             tabList.removeAt(currentTabIndex);
0164             currentTabIndex = -2;
0165         }
0166 
0167         QTextBlockFormat bf;
0168         QVector<KoText::Tab> sortedList = tabList;
0169         std::sort(sortedList.begin(), sortedList.end(), compareTabs);
0170         QList<QVariant> list;
0171         foreach(const KoText::Tab & tab, sortedList) {
0172             QVariant v;
0173             v.setValue(tab);
0174             list.append(v);
0175         }
0176         bf.setProperty(KoParagraphStyle::TabPositions, list);
0177         cursor.mergeBlockFormat(bf);
0178     }
0179 
0180     QTextBlock currentBlock() {
0181         QVariant docVar = resourceManager->resource(KoText::CurrentTextDocument);
0182         if (docVar.isNull())
0183             return QTextBlock();
0184         QTextDocument *doc = static_cast<QTextDocument*>(docVar.value<void*>());
0185         if (doc == nullptr)
0186             return QTextBlock();
0187         return doc->findBlock(resourceManager->intResource(KoText::CurrentTextPosition));
0188     }
0189 
0190     bool relativeTabs() {
0191         QVariant docVar = resourceManager->resource(KoText::CurrentTextDocument);
0192         if (docVar.isNull())
0193             return false;
0194         QTextDocument *doc = static_cast<QTextDocument*>(docVar.value<void*>());
0195         if (doc == nullptr)
0196             return false;
0197         return KoTextDocument(doc).relativeTabs();
0198     }
0199 
0200     void tabChangeInitiated() {
0201         tabList.clear();
0202         originalTabIndex = -2;
0203     }
0204 
0205 private:
0206     KoRuler *ruler;
0207     KoCanvasResourceManager *resourceManager;
0208     int lastPosition; // the last position in the text document.
0209     QVector<KoText::Tab> tabList;
0210     KoText::Tab currentTab;
0211     int originalTabIndex, currentTabIndex;
0212 };
0213 #endif