Warning, file /office/calligra/libs/textlayout/KoTextLayoutEndNotesArea.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) 2011 C. Boemann <cbo@kogmbh.com> 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 0020 #include "KoTextLayoutEndNotesArea.h" 0021 0022 #include "KoTextLayoutNoteArea.h" 0023 #include "KoInlineTextObjectManager.h" 0024 #include "KoInlineNote.h" 0025 #include "KoPointedAt.h" 0026 #include "FrameIterator.h" 0027 #include "KoCharAreaInfo.h" 0028 0029 #include <KoTextDocument.h> 0030 0031 #include <QPainter> 0032 0033 #include <algorithm> 0034 0035 static bool beforeThan(KoInlineNote *note1, KoInlineNote *note2) 0036 { 0037 return (note1->getPosInDocument() < note2->getPosInDocument()); 0038 } 0039 0040 class Q_DECL_HIDDEN KoTextLayoutEndNotesArea::Private 0041 { 0042 public: 0043 Private() 0044 : startOfArea(0) 0045 { 0046 } 0047 QList<KoTextLayoutNoteArea *> endNoteAreas; 0048 QList<QTextFrame *> endNoteFrames; 0049 FrameIterator *startOfArea; 0050 FrameIterator *endOfArea; 0051 int endNoteAutoCount; 0052 }; 0053 0054 KoTextLayoutEndNotesArea::KoTextLayoutEndNotesArea(KoTextLayoutArea *parent, KoTextDocumentLayout *documentLayout) 0055 : KoTextLayoutArea(parent, documentLayout) 0056 , d(new Private) 0057 { 0058 d->endNoteAutoCount = 0; 0059 } 0060 0061 KoTextLayoutEndNotesArea::~KoTextLayoutEndNotesArea() 0062 { 0063 qDeleteAll(d->endNoteAreas); 0064 delete d; 0065 } 0066 0067 bool KoTextLayoutEndNotesArea::layout(FrameIterator *cursor) 0068 { 0069 qDeleteAll(d->endNoteAreas); 0070 d->endNoteAreas.clear(); 0071 d->endNoteFrames.clear(); 0072 0073 d->startOfArea = new FrameIterator(cursor); 0074 d->endOfArea = 0; 0075 int shiftDown = 15; 0076 qreal y = top() + shiftDown; 0077 setBottom(y); 0078 0079 KoInlineTextObjectManager *manager = KoTextDocument(documentLayout()->document()).inlineTextObjectManager(); 0080 QList<KoInlineNote *> list = QList<KoInlineNote *>(manager->endNotes()); 0081 std::sort(list.begin(), list.end(), beforeThan); //making a list of endnotes in the order they appear 0082 while (cursor->endNoteIndex < list.length()) 0083 { 0084 KoInlineNote *note = list[cursor->endNoteIndex]; 0085 if (note->autoNumbering()) { 0086 note->setAutoNumber(d->endNoteAutoCount++); 0087 } 0088 QTextFrame *subFrame = note->textFrame(); 0089 KoTextLayoutNoteArea *noteArea = new KoTextLayoutNoteArea(note, this, documentLayout()); 0090 d->endNoteAreas.append(noteArea); 0091 d->endNoteFrames.append(subFrame); 0092 noteArea->setReferenceRect(left(), right(), y, maximumAllowedBottom()); 0093 if (noteArea->layout(cursor->subFrameIterator(subFrame)) == false) { 0094 d->endOfArea = new FrameIterator(cursor); 0095 setBottom(noteArea->bottom()); 0096 return false; 0097 } 0098 y = noteArea->bottom(); 0099 setBottom(y); 0100 delete cursor->currentSubFrameIterator; 0101 cursor->currentSubFrameIterator = 0; 0102 cursor->endNoteIndex++; 0103 } 0104 if (cursor->endNoteIndex == 0) { 0105 setBottom(top() + shiftDown); 0106 } 0107 d->endOfArea = new FrameIterator(cursor); 0108 return true; 0109 } 0110 KoPointedAt KoTextLayoutEndNotesArea::hitTest(const QPointF &p, Qt::HitTestAccuracy accuracy) const 0111 { 0112 KoPointedAt pointedAt; 0113 int endNoteIndex = 0; 0114 while (endNoteIndex < d->endNoteAreas.length()) { 0115 // check if p is over end notes area 0116 if (p.y() > d->endNoteAreas[endNoteIndex]->top() 0117 && p.y() < d->endNoteAreas[endNoteIndex]->bottom()) { 0118 pointedAt = d->endNoteAreas[endNoteIndex]->hitTest(p, accuracy); 0119 return pointedAt; 0120 } 0121 ++endNoteIndex; 0122 } 0123 return KoPointedAt(); 0124 } 0125 0126 QVector<KoCharAreaInfo> KoTextLayoutEndNotesArea::generateCharAreaInfos() const 0127 { 0128 QVector<KoCharAreaInfo> result; 0129 0130 if (d->startOfArea == 0) {// We have not been layouted yet 0131 return result; 0132 } 0133 0134 foreach(KoTextLayoutNoteArea *area, d->endNoteAreas) { 0135 result.append(area->generateCharAreaInfos()); 0136 } 0137 0138 return result; 0139 } 0140 0141 0142 QRectF KoTextLayoutEndNotesArea::selectionBoundingBox(QTextCursor &cursor) const 0143 { 0144 QTextFrame *subFrame; 0145 int endNoteIndex = 0; 0146 while (endNoteIndex < d->endNoteFrames.length()) { 0147 subFrame = d->endNoteFrames[endNoteIndex]; 0148 if (subFrame != 0) { 0149 if (cursor.selectionStart() >= subFrame->firstPosition() && cursor.selectionEnd() <= subFrame->lastPosition()) { 0150 return d->endNoteAreas[endNoteIndex]->selectionBoundingBox(cursor); 0151 } 0152 ++endNoteIndex; 0153 } 0154 } 0155 return QRectF(); 0156 } 0157 0158 void KoTextLayoutEndNotesArea::paint(QPainter *painter, const KoTextDocumentLayout::PaintContext &context) 0159 { 0160 if (d->startOfArea == 0) // We have not been layouted yet 0161 return; 0162 0163 if (!d->endNoteAreas.isEmpty()) { 0164 int left = 2; 0165 int right = 150; 0166 int shiftDown = 10; 0167 painter->drawLine(left, top()+shiftDown, right, top()+shiftDown); 0168 } 0169 foreach(KoTextLayoutNoteArea *area, d->endNoteAreas) { 0170 area->paint(painter, context); 0171 } 0172 }