Commit d65258b2 authored by Casper Boemann's avatar Casper Boemann

Enable content outside the textshape (well any shape for that matter)

Tables don't report their extent correctly yet, so they are still cut off


svn path=/branches/work/koffice-essen/; revision=1174172
parent d0dc5b47
......@@ -59,6 +59,7 @@ enum CanvasResource {
Unit, ///< The unit of this canvas
CurrentPage, ///< The current page number
ActiveStyleType, ///< the actual active style type see KoFlake::StyleType for valid values
ActiveRange, ///< The area where the rulers should show white
KarbonStart = 1000, ///< Base number for karbon specific values.
KexiStart = 2000, ///< Base number for kexi specific values.
KivioStart = 3000, ///< Base number for kivio specific values.
......
......@@ -315,7 +315,7 @@ QRectF KoShape::boundingRect() const
Q_D(const KoShape);
QSizeF mySize = size();
QTransform transform = absoluteTransformation(0);
QRectF bb(QPointF(0, 0), mySize);
QRectF bb = outlineRect();
if (d->border) {
KoInsets insets;
d->border->borderInsets(this, insets);
......@@ -328,7 +328,7 @@ QRectF KoShape::boundingRect() const
bb.adjust(-insets.left, -insets.top, insets.right, insets.bottom);
}
if (d->filterEffectStack) {
QRectF clipRect = d->filterEffectStack->clipRectForBoundingRect(QRectF(QPointF(), mySize));
QRectF clipRect = d->filterEffectStack->clipRectForBoundingRect(outlineRect());
bb |= transform.mapRect(clipRect);
}
......@@ -475,12 +475,17 @@ void KoShape::update(const QRectF &shape) const
QPainterPath KoShape::outline() const
{
Q_D(const KoShape);
QPainterPath path;
path.addRect(QRectF(QPointF(0, 0), QSizeF(qMax(d->size.width(), qreal(0.0001)), qMax(d->size.height(), qreal(0.0001)))));
path.addRect(outlineRect());
return path;
}
QRectF KoShape::outlineRect() const
{
Q_D(const KoShape);
return QRectF(QPointF(0, 0), QSizeF(qMax(d->size.width(), qreal(0.0001)), qMax(d->size.height(), qreal(0.0001))));
}
QPointF KoShape::absolutePosition(KoFlake::Position anchor) const
{
QPointF point;
......
......@@ -512,6 +512,14 @@ public:
*/
virtual QPainterPath outline() const;
/**
* returns the outline of the shape in the form of a rect.
* The outlineRect returned will always have the position() of the shape as the origin, so
* moving the shape will not alter the result. The outline is used to calculate the boundingRect.
* @returns the outline of the shape in the form of a rect.
*/
virtual QRectF outlineRect() const;
/**
* Returns the currently set border, or 0 if there is no border.
* @return the currently set border, or 0 if there is no border.
......
......@@ -66,6 +66,9 @@ public:
qreal docOffsetInShape() const {
return 0;
}
QRectF expandVisibleRect(const QRectF &rect) const {
return rect;
}
bool addLine(QTextLine &, bool) {
return false;
}
......@@ -248,6 +251,11 @@ QSizeF KoTextDocumentLayout::documentSize() const
return QSizeF(10, 10);
}
QRectF KoTextDocumentLayout::expandVisibleRect(const QRectF &rect) const
{
return m_state->expandVisibleRect(rect);
}
void KoTextDocumentLayout::draw(QPainter *painter, const QAbstractTextDocumentLayout::PaintContext &context)
{
PaintContext pc;
......
......@@ -87,6 +87,14 @@ public:
*/
virtual QSizeF documentSize() const;
/**
* Expands the give rect in the horizontal dimension,
* so that everything in the document will be visible
* Notably this can give a negative x coord
* the vertical dimensions are never touched or relied upon
*/
QRectF expandVisibleRect(const QRectF &rect) const;
/// Draws the layout on the given painter with the given context.
virtual void draw(QPainter * painter, const QAbstractTextDocumentLayout::PaintContext & context);
......@@ -159,6 +167,8 @@ public:
/// return the y offset of the document at start of shape.
virtual qreal docOffsetInShape() const = 0;
/// when a line is added, update internal vars. Inner shapes possibly intersect and split line into more parts. Set processingLine true, when current line is part of line and not last part of line. So baseline will be same for all parts of line. Return true if line does not fit in shape.
/// expand a bounding rect by excessive indents (indents outside the shape)
virtual QRectF expandVisibleRect(const QRectF &rect) const = 0;
virtual bool addLine(QTextLine &line, bool processingLine = false) = 0;
/// prepare for next paragraph; return false if there is no next parag.
virtual bool nextParag() = 0;
......
......@@ -74,6 +74,56 @@ void TestDocumentLayout::testHitTest()
QVERIFY(layout->hitTest(QPointF(20, paragOffets[1] + 20), Qt::FuzzyHit) > 109);
}
void TestDocumentLayout::testHitTestSection()
{
// init a basic document with 3 parags.
initForNewTest();
QTextCursor cursor;
QTextBlock block = doc->begin();
qreal offset = 50.0;
qreal lineHeight = 0;
int lines = 0, parag = 0;
qreal paragOffets[3];
while (1) {
if (!block.isValid()) break;
paragOffets[parag++] = offset;
QTextLayout *txtLayout = block.layout();
txtLayout->beginLayout();
while (1) {
QTextLine line = txtLayout->createLine();
if (!line.isValid()) break;
lines++;
line.setLineWidth(50);
line.setPosition(QPointF(20, offset));
offset += 20;
lineHeight = line.height();
}
txtLayout->endLayout();
block = block.next();
}
//QCOMPARE(lines, 7);
// outside text
QCOMPARE(layout->hitTest(QPointF(0, 0), Qt::FuzzyHit), 0);
QCOMPARE(layout->hitTest(QPointF(0, 0), Qt::ExactHit), -1);
QCOMPARE(layout->hitTest(QPointF(19, 49), Qt::ExactHit), -1);
QCOMPARE(layout->hitTest(QPointF(71, 0), Qt::ExactHit), -1);
QCOMPARE(layout->hitTest(QPointF(71, 51), Qt::ExactHit), -1);
// first char
QCOMPARE(layout->hitTest(QPointF(20, 51), Qt::ExactHit), 0);
QCOMPARE(layout->hitTest(QPointF(20, 50), Qt::ExactHit), 0);
// below line 1
QCOMPARE(layout->hitTest(QPointF(20, 51 + lineHeight), Qt::ExactHit), -1);
QVERIFY(layout->hitTest(QPointF(20, 51 + lineHeight), Qt::FuzzyHit) > 0); // line 2
// parag2
QCOMPARE(layout->hitTest(QPointF(20, paragOffets[1]), Qt::ExactHit), 109);
QCOMPARE(layout->hitTest(QPointF(20, paragOffets[1]), Qt::FuzzyHit), 109);
QVERIFY(layout->hitTest(QPointF(20, paragOffets[1] + 20), Qt::FuzzyHit) > 109);
}
QTEST_KDEMAIN(TestDocumentLayout, GUI)
#include <TestDocumentLayout.moc>
......@@ -24,6 +24,8 @@ private slots:
/// Test the hittest of KoTextDocumentLayout
void testHitTest();
/// Test the hittest of KoTextDocumentLayout regarding setions
void testHitTestSection();
private:
void initForNewTest();
......
This diff is collapsed.
......@@ -112,6 +112,14 @@ public slots:
*/
void setActiveRange(qreal start, qreal end);
/** Set the override active range, ie the part of the ruler that is most likely used.
* set to 0, 0 when there is no longer any active range
* The override, means that if set it takes precedence over the normal active range.
* @param start the start of the range in pt
* @param end the end of the range in pt
*/
void setOverrideActiveRange(qreal start, qreal end);
/** Set the state of the ruler so that it shows everything in right to left mode.
* @param isRightToLeft state of right to left mode. Default is false.
*/
......
......@@ -53,7 +53,8 @@ public:
}
void canvasResourceChanged(int key) {
if (key != KoText::CurrentTextPosition && key != KoText::CurrentTextDocument)
if (key != KoText::CurrentTextPosition && key != KoText::CurrentTextDocument
&& key != KoCanvasResource::ActiveRange)
return;
QTextBlock block = currentBlock();
......@@ -62,6 +63,8 @@ public:
ruler->setShowTabs(false);
return;
}
QRectF activeRange = resourceManager->resource(KoCanvasResource::ActiveRange).toRectF();
ruler->setOverrideActiveRange(activeRange.left(), activeRange.right());
ruler->setShowIndents(true);
ruler->setShowTabs(true);
if (block.position() <= lastPosition && block.position() + block.length() > lastPosition)
......
......@@ -134,6 +134,8 @@ public:
qreal rulerLength;
qreal activeRangeStart;
qreal activeRangeEnd;
qreal activeOverrideRangeStart;
qreal activeOverrideRangeEnd;
int mouseCoordinate;
int showMousePosition;
......@@ -190,6 +192,8 @@ public:
qreal doSnapping(const qreal value) const;
Selection selectionAtPosition(const QPoint & pos, int *selectOffset = 0);
int hotSpotIndex(const QPoint & pos);
qreal effectiveActiveRangeStart() const;
qreal effectiveActiveRangeEnd() const;
friend class VerticalPaintingStrategy;
friend class HorizontalPaintingStrategy;
......
......@@ -3,7 +3,7 @@
* Copyright (C) 2008 Thorsten Zachmann <zachmann@kde.org>
* Copyright (C) 2008 Girish Ramakrishnan <girish@forwardbias.in>
* Copyright (C) 2008 Roopesh Chander <roop@forwardbias.in>
* Copyright (C) 2009 KO GmbH <cbo@kogmbh.com>
* Copyright (C) 2009-2010 KO GmbH <cbo@kogmbh.com>
* Copyright (C) 2009-2010 Casper Boemann <cbo@boemann.dk>
*
* This library is free software; you can redistribute it and/or
......@@ -84,6 +84,7 @@ Layout::Layout(KoTextDocumentLayout *parent)
m_dropCapsPositionAdjust(0),
m_restartingAfterTableBreak(false),
m_restartingFirstCellAfterTableBreak(false),
m_allTimeMinimumLeft(0),
m_maxLineHeight(0)
{
m_frameStack.reserve(5); // avoid reallocs
......@@ -141,14 +142,15 @@ qreal Layout::width()
qreal Layout::x()
{
qreal result = m_newParag ? resolveTextIndent() : 0.0;
if (m_inTable) {
result += m_tableLayout.cellContentRect(m_tableCell).x();
}
result += m_isRtl ? m_format.rightMargin() : (m_format.leftMargin() + listIndent());
result += m_borderInsets.left + m_shapeBorder.left;
// if (m_block.layout()->lineCount() > 1)
if (m_dropCapsNChars == 0)
result += m_dropCapsAffectedLineWidthAdjust;
m_allTimeMinimumLeft = qMin(m_allTimeMinimumLeft, result);
if (m_inTable) {
result += m_tableLayout.cellContentRect(m_tableCell).x();
}
return result;
}
......@@ -175,6 +177,11 @@ qreal Layout::docOffsetInShape() const
return m_data->documentOffset();
}
QRectF Layout::expandVisibleRect(const QRectF &rect) const
{
return rect.adjusted(m_allTimeMinimumLeft, 0.0, 50.0, 0.0);
}
bool Layout::addLine(QTextLine &line, bool processingLine)
{
if (m_blockData && m_block.textList() && m_block.layout()->lineCount() == 1) {
......@@ -510,7 +517,7 @@ bool Layout::nextParag()
KoText::Tab koTab = tv.value<KoText::Tab>();
QTextOption::Tab tab;
// convertion here is required because Qt thinks in device units and we don't
// conversion here is required because Qt thinks in device units and we don't
tab.position = (koTab.position - tabOffset) * qt_defaultDpiY() / 72.;
tab.type = koTab.type;
tab.delimiter = koTab.delimiter;
......
/* This file is part of the KDE project
* Copyright (C) 2006-2007, 2010 Thomas Zander <zander@kde.org>
* Copyright (C) 2009-2010 KO GmbH <cbo@kogmbh.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
......@@ -60,6 +61,8 @@ public:
virtual int cursorPosition() const;
/// return the y offset of the document at start of shape.
virtual qreal docOffsetInShape() const;
/// expand a bounding rect by excessive indents (indents outside the shape)
QRectF expandVisibleRect(const QRectF &rect) const;
/// when a line is added, update internal vars. Return true if line does not fit in shape
virtual bool addLine(QTextLine &line, bool processingLine = false);
/// prepare for next paragraph; return false if there is no next parag.
......@@ -179,6 +182,8 @@ private:
QTextTableCell m_tableCell; /**< Current table cell. */
bool m_restartingAfterTableBreak; /** We are in a re-layout that was a result of a break in a table. */
bool m_restartingFirstCellAfterTableBreak; /** We are in a re-layout that was a result of a break in a table. only true first cell after */
// bookkeeping for drawing outside borders
qreal m_allTimeMinimumLeft;
qreal m_maxLineHeight;
};
......
......@@ -2,6 +2,7 @@
* Copyright (C) 2006-2010 Thomas Zander <zander@kde.org>
* Copyright (C) 2008-2010 Thorsten Zachmann <zachmann@kde.org>
* Copyright (C) 2008 Pierre Stirnweiss \pierre.stirnweiss_koffice@gadz.org>
* Copyright (C) 2010 KO GmbH <cbo@kogmbh.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
......@@ -176,9 +177,7 @@ void TextShape::paintComponent(QPainter &painter, const KoViewConverter &convert
context.viewConverter = &converter;
context.imageCollection = m_imageCollection;
QRectF rect(0, 0, size().width(), size().height());
rect.adjust(-5, 0, 5, 0);
painter.setClipRect(rect, Qt::IntersectClip);
painter.setClipRect(outlineRect(), Qt::IntersectClip);
painter.save();
painter.translate(0, -m_textShapeData->documentOffset());
lay->draw(&painter, context);
......@@ -191,12 +190,22 @@ void TextShape::paintComponent(QPainter &painter, const KoViewConverter &convert
m_paintRegion = QRegion();
}
QPointF TextShape::convertScreenPos(const QPointF &point)
QPointF TextShape::convertScreenPos(const QPointF &point) const
{
QPointF p = absoluteTransformation(0).inverted().map(point);
return p + QPointF(0.0, m_textShapeData->documentOffset());
}
QRectF TextShape::outlineRect() const
{
QRectF rect(QPointF(0,0), size());
KoTextDocumentLayout *lay = qobject_cast<KoTextDocumentLayout*>(m_textShapeData->document()->documentLayout());
if (lay) {
rect = lay->expandVisibleRect(rect);
}
return rect;
}
void TextShape::shapeChanged(ChangeType type, KoShape *shape)
{
Q_UNUSED(shape);
......@@ -230,16 +239,15 @@ void TextShape::paintDecorations(QPainter &painter, const KoViewConverter &conve
QPointF tl(0.0, 0.0);
QRectF rect(tl, size());
pen.setWidthF(onePixel.y());
painter.setPen(pen);
painter.drawLine(tl, rect.topRight());
painter.drawLine(rect.topLeft(), rect.topRight());
painter.drawLine(rect.bottomLeft(), rect.bottomRight());
pen.setWidthF(onePixel.x());
painter.setPen(pen);
painter.drawLine(rect.topRight(), rect.bottomRight());
painter.drawLine(tl, rect.bottomLeft());
painter.drawLine(rect.topLeft(), rect.bottomLeft());
painter.restore();
}
......
......@@ -2,6 +2,7 @@
* Copyright (C) 2006-2010 Thomas Zander <zander@kde.org>
* Copyright (C) 2008 Thorsten Zachmann <zachmann@kde.org>
* Copyright (C) 2008 Pierre Stirnweiss \pierre.stirnweiss_koffice@gadz.org>
* Copyright (C) 2010 KO GmbH <cbo@kogmbh.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
......@@ -22,6 +23,8 @@
#ifndef KOTEXTSHAPE_H
#define KOTEXTSHAPE_H
#include "Layout.h"
#include <KoShapeContainer.h>
#include <KoFrameShape.h>
#include <KoTextShapeData.h>
......@@ -56,7 +59,10 @@ public:
virtual void waitUntilReady(const KoViewConverter &converter, bool asynchronous) const;
/// helper method.
QPointF convertScreenPos(const QPointF &point);
QPointF convertScreenPos(const QPointF &point) const;
/// reimplemented
QRectF outlineRect() const;
/// set the image collection which is needed to draw bullet from images
void setImageCollection(KoImageCollection *collection) { m_imageCollection = collection; }
......@@ -134,7 +140,6 @@ private:
mutable QWaitCondition m_waiter;
KoPageProvider *m_pageProvider;
KoImageCollection *m_imageCollection;
QRegion m_paintRegion;
};
......
......@@ -565,7 +565,7 @@ void TextTool::paint(QPainter &painter, const KoViewConverter &converter)
QTransform shapeMatrix = ts->absoluteTransformation(&converter);
shapeMatrix.scale(zoomX, zoomY);
painter.setTransform(shapeMatrix * painter.transform());
painter.setClipRect(QRectF(QPointF(), ts->size()), Qt::IntersectClip);
painter.setClipRect(ts->outlineRect(), Qt::IntersectClip);
painter.translate(0, -data->documentOffset());
if ((data->endPosition() >= selectStart && data->position() <= selectEnd)
|| (data->position() <= selectStart && data->endPosition() >= selectEnd)) {
......@@ -620,6 +620,15 @@ void TextTool::updateSelectedShape(const QPointF &point)
}
}
setShapeData(static_cast<KoTextShapeData*>(m_textShape->userData()));
// This is how we inform the rulers of the active range
// For now we will not consider table cells, but just give the shape dimensions
QVariant v;
QRectF rect(QPoint(), m_textShape->size());
rect = m_textShape->absoluteTransformation(0).mapRect(rect);
v.setValue(rect);
canvas()->resourceManager()->setResource(KoCanvasResource::ActiveRange, v);
}
}
......@@ -1310,9 +1319,20 @@ void TextTool::activate(ToolActivation toolActivation, const QSet<KoShape*> &sha
}
if (m_textShape == 0) { // none found
emit done();
// This is how we inform the rulers of the active range
// No shape means no active range
canvas()->resourceManager()->setResource(KoCanvasResource::ActiveRange, QVariant(QRectF()));
return;
}
// This is how we inform the rulers of the active range
// For now we will not consider table cells, but just give the shape dimensions
QVariant v;
QRectF rect(QPoint(), m_textShape->size());
rect = m_textShape->absoluteTransformation(0).mapRect(rect);
v.setValue(rect);
canvas()->resourceManager()->setResource(KoCanvasResource::ActiveRange, v);
setShapeData(static_cast<KoTextShapeData*>(m_textShape->userData()));
useCursor(Qt::IBeamCursor);
......@@ -1346,6 +1366,11 @@ void TextTool::deactivate()
if (m_textShapeData) // then we got disabled without ever having done anything.
repaintCaret();
m_textShape = 0;
// This is how we inform the rulers of the active range
// No shape means no active range
canvas()->resourceManager()->setResource(KoCanvasResource::ActiveRange, QVariant(QRectF()));
if (m_textShapeData && m_textShapeData) {
TextSelection selection;
selection.document = m_textShapeData->document();
......@@ -1459,7 +1484,7 @@ QRectF TextTool::textRect(int startPosition, int endPosition) const
if (line1.textStart() + block.position() == line2.textStart() + block2.position())
return QRectF(qMin(startX, endX), line1.y(), qAbs(startX - endX), line1.height());
return QRectF(0, line1.y(), 10E6, line2.y() + line2.height() - line1.y());
return QRectF(-5E6, line1.y(), 10E6, line2.y() + line2.height() - line1.y());
}
KoToolSelection* TextTool::selection()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment