Warning, file /office/calligra/libs/textlayout/KoTextLayoutNoteArea.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 Brijesh Patel <brijesh3105@gmail.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 "KoTextLayoutNoteArea.h" 0021 0022 #include "FrameIterator.h" 0023 #include "KoStyleManager.h" 0024 #include "KoParagraphStyle.h" 0025 #include "KoTextLayoutObstruction.h" 0026 #include "KoPointedAt.h" 0027 #include <KoOdfNumberDefinition.h> 0028 #include <KoInlineNote.h> 0029 #include <KoTextDocument.h> 0030 0031 #include <QPainter> 0032 0033 #define OVERLAPPREVENTION 1000 0034 0035 class Q_DECL_HIDDEN KoTextLayoutNoteArea::Private 0036 { 0037 public: 0038 Private() 0039 { 0040 } 0041 KoInlineNote *note; 0042 QTextLayout *textLayout; 0043 QTextLayout *postLayout; 0044 qreal labelIndent; 0045 bool isContinuedArea; 0046 qreal labelWidth; 0047 qreal labelHeight; 0048 qreal labelYOffset; 0049 }; 0050 0051 KoTextLayoutNoteArea::KoTextLayoutNoteArea(KoInlineNote *note, KoTextLayoutArea *parent, KoTextDocumentLayout *documentLayout) 0052 : KoTextLayoutArea(parent, documentLayout) 0053 , d(new Private) 0054 { 0055 Q_ASSERT(note); 0056 Q_ASSERT(parent); 0057 0058 d->note = note; 0059 d->isContinuedArea = false; 0060 d->postLayout = 0; 0061 } 0062 0063 KoTextLayoutNoteArea::~KoTextLayoutNoteArea() 0064 { 0065 delete d; 0066 } 0067 0068 void KoTextLayoutNoteArea::paint(QPainter *painter, const KoTextDocumentLayout::PaintContext &context) 0069 { 0070 painter->save(); 0071 if (d->isContinuedArea) { 0072 painter->translate(0, -OVERLAPPREVENTION); 0073 } 0074 0075 KoTextLayoutArea::paint(painter, context); 0076 if (d->postLayout) { 0077 d->postLayout->draw(painter, QPointF(left() + d->labelIndent, top() + d->labelYOffset)); 0078 } 0079 d->textLayout->draw(painter, QPointF(left() + d->labelIndent, top() + d->labelYOffset)); 0080 painter->restore(); 0081 } 0082 0083 bool KoTextLayoutNoteArea::layout(FrameIterator *cursor) 0084 { 0085 KoOdfNotesConfiguration *notesConfig = 0; 0086 if (d->note->type() == KoInlineNote::Footnote) { 0087 notesConfig = KoTextDocument(d->note->textFrame()->document()).styleManager()->notesConfiguration(KoOdfNotesConfiguration::Footnote); 0088 } else if (d->note->type() == KoInlineNote::Endnote) { 0089 notesConfig = KoTextDocument(d->note->textFrame()->document()).styleManager()->notesConfiguration(KoOdfNotesConfiguration::Endnote); 0090 } 0091 0092 QString label; 0093 if (d->isContinuedArea) { 0094 if (! notesConfig->footnoteContinuationBackward().isEmpty()) { 0095 label = notesConfig->footnoteContinuationBackward() + " " + d->note->label(); 0096 } 0097 setReferenceRect(left(), right(), top() + OVERLAPPREVENTION 0098 , maximumAllowedBottom() + OVERLAPPREVENTION); 0099 } else { 0100 label = d->note->label(); 0101 } 0102 label.prepend(notesConfig->numberFormat().prefix()); 0103 label.append(notesConfig->numberFormat().suffix()); 0104 QPaintDevice *pd = documentLayout()->paintDevice(); 0105 QTextBlock block = cursor->it.currentBlock(); 0106 QTextCharFormat format = block.charFormat(); 0107 KoCharacterStyle *style = static_cast<KoCharacterStyle *>(notesConfig->citationTextStyle()); 0108 if (style) { 0109 style->applyStyle(format); 0110 } 0111 QFont font(format.font(), pd); 0112 d->textLayout = new QTextLayout(label, font, pd); 0113 QList<QTextLayout::FormatRange> layouts; 0114 QTextLayout::FormatRange range; 0115 range.start = 0; 0116 range.length = label.length(); 0117 range.format = format; 0118 layouts.append(range); 0119 d->textLayout->setAdditionalFormats(layouts); 0120 0121 QTextOption option(Qt::AlignLeft | Qt::AlignAbsolute); 0122 d->textLayout->setTextOption(option); 0123 d->textLayout->beginLayout(); 0124 QTextLine line = d->textLayout->createLine(); 0125 d->textLayout->endLayout(); 0126 0127 KoParagraphStyle pStyle(block.blockFormat(), QTextCharFormat()); 0128 d->labelIndent = textIndent(d->note->textFrame()->begin().currentBlock(), 0, pStyle); 0129 if (line.naturalTextWidth() > -d->labelIndent) { 0130 KoTextLayoutArea::setExtraTextIndent(line.naturalTextWidth()); 0131 } else { 0132 KoTextLayoutArea::setExtraTextIndent(-d->labelIndent); 0133 } 0134 d->labelIndent += pStyle.leftMargin(); 0135 d->labelWidth = line.naturalTextWidth(); 0136 d->labelHeight = line.naturalTextRect().bottom() - line.naturalTextRect().top(); 0137 d->labelYOffset = -line.ascent(); 0138 0139 bool contNotNeeded = KoTextLayoutArea::layout(cursor); 0140 0141 QTextLine blockLayoutLine = block.layout()->lineAt(0); 0142 0143 if (blockLayoutLine.isValid()) { 0144 d->labelYOffset += blockLayoutLine.ascent(); 0145 } 0146 0147 if (!contNotNeeded) { 0148 QString contNote = notesConfig->footnoteContinuationForward(); 0149 font.setBold(true); 0150 d->postLayout = new QTextLayout(contNote, font, pd); 0151 QList<QTextLayout::FormatRange> contTextLayouts; 0152 QTextLayout::FormatRange contTextRange; 0153 contTextRange.start = 0; 0154 contTextRange.length = contNote.length(); 0155 contTextRange.format = block.charFormat();; 0156 contTextLayouts.append(contTextRange); 0157 d->postLayout->setAdditionalFormats(contTextLayouts); 0158 0159 QTextOption contTextOption(Qt::AlignLeft | Qt::AlignAbsolute); 0160 //option.setTextDirection(); 0161 d->postLayout->setTextOption(contTextOption); 0162 d->postLayout->beginLayout(); 0163 QTextLine contTextLine = d->postLayout->createLine(); 0164 d->postLayout->endLayout(); 0165 contTextLine.setPosition(QPointF(right() - contTextLine.naturalTextWidth(), bottom() - contTextLine.height())); 0166 0167 documentLayout()->setContinuationObstruction(new 0168 KoTextLayoutObstruction(contTextLine.naturalTextRect(), false)); 0169 } 0170 return contNotNeeded; 0171 } 0172 0173 void KoTextLayoutNoteArea::setAsContinuedArea(bool isContinuedArea) 0174 { 0175 d->isContinuedArea = isContinuedArea; 0176 } 0177 0178 KoPointedAt KoTextLayoutNoteArea::hitTest(const QPointF &p, Qt::HitTestAccuracy accuracy) const 0179 { 0180 KoPointedAt pointedAt; 0181 pointedAt.noteReference = -1; 0182 QPointF tmpP(p.x(), p.y() + (d->isContinuedArea ? OVERLAPPREVENTION : 0)); 0183 0184 pointedAt = KoTextLayoutArea::hitTest(tmpP, accuracy); 0185 0186 if (tmpP.x() > left() && tmpP.x() < d->labelWidth && tmpP.y() < top() + d->labelYOffset + d->labelHeight) 0187 { 0188 pointedAt.noteReference = d->note->getPosInDocument(); 0189 pointedAt.position = tmpP.x(); 0190 } 0191 0192 return pointedAt; 0193 } 0194 0195 QRectF KoTextLayoutNoteArea::selectionBoundingBox(QTextCursor &cursor) const 0196 { 0197 return KoTextLayoutArea::selectionBoundingBox(cursor).translated(0 0198 , d->isContinuedArea ? -OVERLAPPREVENTION : 0); 0199 0200 }