Commit 237d8e02 authored by Thomas Zander's avatar Thomas Zander

Change in event forwarding of flake shape changes.

 * A container will not be notified with a 'collision detection' when a child changes anymore.
 * for all such changes the KoShapeContainerModel will be notified separately.
Using the above and some refactoring; make sure we only relayout 1 time on a change.
Make the default anchred frame be an inline character, like KOffce1 used.

svn path=/trunk/koffice/; revision=651797
parent 621ff806
......@@ -21,6 +21,7 @@
#include "KoShape.h"
#include "KoShapeContainer.h"
#include "KoShapeContainerModel.h"
#include "KoSelection.h"
#include "KoPointerEvent.h"
#include "KoInsets.h"
......@@ -42,9 +43,9 @@
#include <kdebug.h>
class KoShapePrivate {
class KoShape::Private {
public:
KoShapePrivate()
Private(KoShape *shape)
: scaleX( 1 ),
scaleY( 1 ),
angle( 0 ),
......@@ -62,15 +63,22 @@ public:
userData(0),
appData(0),
backgroundBrush(Qt::NoBrush),
border(0)
border(0),
me(shape)
{
}
~KoShapePrivate() {
~Private() {
delete userData;
delete appData;
}
void shapeChanged(ChangeType type) {
if(parent)
parent->model()->childChanged(me, type);
me->shapeChanged(type);
}
double scaleX;
double scaleY;
double angle; // degrees
......@@ -100,10 +108,11 @@ public:
QBrush backgroundBrush; ///< Stands for the background color / fill etc.
KoShapeBorderModel *border; ///< points to a border, or 0 if there is no border
QList<KoShapeConnection*> connections;
KoShape *me;
};
KoShape::KoShape()
: d(new KoShapePrivate())
: d(new Private(this))
{
recalcMatrix();
}
......@@ -227,7 +236,7 @@ void KoShape::scale( double sx, double sy )
d->scaleX = sx;
d->scaleY = sy;
recalcMatrix();
shapeChanged(ScaleChanged);
d->shapeChanged(ScaleChanged);
}
void KoShape::rotate( double angle )
......@@ -238,7 +247,7 @@ void KoShape::rotate( double angle )
while(d->angle >= 360) d->angle -= 360;
while(d->angle <= -360) d->angle += 360;
recalcMatrix();
shapeChanged(RotationChanged);
d->shapeChanged(RotationChanged);
}
void KoShape::shear( double sx, double sy )
......@@ -248,7 +257,7 @@ void KoShape::shear( double sx, double sy )
d->shearX = sx;
d->shearY = sy;
recalcMatrix();
shapeChanged(ShearChanged);
d->shapeChanged(ShearChanged);
}
void KoShape::resize( const QSizeF &newSize )
......@@ -269,7 +278,7 @@ void KoShape::resize( const QSizeF &newSize )
point.setY(point.y() * fy);
}
recalcMatrix();
shapeChanged(SizeChanged);
d->shapeChanged(SizeChanged);
}
void KoShape::setPosition( const QPointF &position )
......@@ -278,7 +287,7 @@ void KoShape::setPosition( const QPointF &position )
return;
d->pos = position;
recalcMatrix();
shapeChanged(PositionChanged);
d->shapeChanged(PositionChanged);
}
bool KoShape::hitTest( const QPointF &position ) const
......@@ -379,7 +388,7 @@ void KoShape::setParent(KoShapeContainer *parent) {
else
d->parent = 0;
recalcMatrix();
shapeChanged(ParentChanged);
d->shapeChanged(ParentChanged);
}
int KoShape::zIndex() const {
......
......@@ -46,7 +46,6 @@ class KoShapeManager;
class KoShapeUserData;
class KoViewConverter;
class KoShapeApplicationData;
class KoShapePrivate;
class KoShapeSavingContext;
class KoCanvasBase;
class KoGenStyle;
......@@ -83,6 +82,17 @@ class KoGenStyle;
class FLAKE_EXPORT KoShape
{
public:
/// Used by shapeChanged() to select which change was made
enum ChangeType {
PositionChanged, ///< used after a setPosition()
RotationChanged, ///< used after a rotate()
ScaleChanged, ///< used after a scale()
ShearChanged, ///< used after a shear()
SizeChanged, ///< used after a resize()
ParentChanged, ///< used after a setParent()
CollisionDetected ///< used when another shape moved in our boundingrect
};
/**
* @brief Constructor
*/
......@@ -595,17 +605,6 @@ protected:
*/
void notifyChanged();
/// Used by shapeChanged() to select which change was made
enum ChangeType {
PositionChanged, ///< used after a setPosition()
RotationChanged, ///< used after a rotate()
ScaleChanged, ///< used after a scale()
ShearChanged, ///< used after a shear()
SizeChanged, ///< used after a resize()
ParentChanged, ///< used after a setParent()
CollisionDetected ///< used when another shape moved in our boundingrect
};
/**
* A hook that allows inheriting classes to do something after a KoShape property changed
* This is called whenever the shape, position rotation or scale properties were altered.
......@@ -656,7 +655,9 @@ private:
void addShapeManager( KoShapeManager * manager );
void removeShapeManager( KoShapeManager * manager );
KoShapePrivate * const d;
class Private;
friend class Private;
Private * const d;
};
#endif
......@@ -75,6 +75,7 @@ public:
}
void containerChanged(KoShapeContainer *) { }
void childChanged(KoShape *, KoShape::ChangeType ) { }
private:
/**
......
......@@ -22,10 +22,11 @@
#include <flake_export.h>
#include <KoShape.h>
#include <QList>
#include <QPointF>
class KoShape;
class KoShapeContainer;
/**
......@@ -93,6 +94,8 @@ public:
virtual void containerChanged(KoShapeContainer *container) = 0;
virtual void proposeMove(KoShape *child, QPointF &move) { Q_UNUSED(child); Q_UNUSED(move); }
virtual void childChanged(KoShape *child, KoShape::ChangeType type) = 0;
};
#endif
......@@ -341,7 +341,14 @@ void KoShapeManager::updateTree()
DetectCollision() {}
void detect(KoRTree<KoShape *> &tree, KoShape *s, int prevZIndex) {
foreach(KoShape *shape, tree.intersects( s->boundingRect() )) {
if(shape == s)
bool isChild = false;
KoShapeContainer *parent = s->parent();
while(parent && !isChild) {
if(parent == shape)
isChild = true;
parent = parent->parent();
}
if(isChild)
continue;
if(s->zIndex() <= shape->zIndex() && prevZIndex <= shape->zIndex())
// Moving a shape will only make it collide with shapes below it.
......
......@@ -43,6 +43,7 @@ public:
return QList<KoShape*>(m_members);
}
void containerChanged(KoShapeContainer *) { }
void childChanged(KoShape *, KoShape::ChangeType ) { }
private: // members
QList <KoShape *> m_members;
......
......@@ -24,6 +24,7 @@
#include <KoShapeContainer.h>
#include <QTextInlineObject>
#include <QFontMetricsF>
#include <KDebug>
class KoTextAnchor::Private {
......@@ -31,8 +32,8 @@ public:
Private(KoTextAnchor *p, KoShape *s)
: parent(p),
shape(s),
horizontalAlignment(Left),
verticalAlignment(TopOfParagraph),
horizontalAlignment(HorizontalOffset),
verticalAlignment(VerticalOffset),
document(0),
position(-1),
model(0)
......@@ -112,9 +113,6 @@ void KoTextAnchor::updatePosition(const QTextDocument *document, QTextInlineObje
d->document = document;
d->position = posInDocument;
d->setContainer(dynamic_cast<KoShapeContainer*> (shapeForPosition(document, posInDocument)));
// if(d->model)
// d->model->reposition(d->shape);
}
void KoTextAnchor::resize(const QTextDocument *document, QTextInlineObject object, int posInDocument, const QTextCharFormat &format, QPaintDevice *pd) {
......@@ -123,6 +121,17 @@ void KoTextAnchor::resize(const QTextDocument *document, QTextInlineObject objec
Q_UNUSED(posInDocument);
Q_UNUSED(format);
Q_UNUSED(pd);
if(horizontalAlignment() == HorizontalOffset && verticalAlignment() == VerticalOffset) {
object.setWidth(d->shape->size().width());
object.setAscent(d->shape->size().height());
}
else {
QFontMetricsF fm(format.font());
object.setWidth(0);
object.setAscent(fm.ascent());
}
object.setDescent(0);
}
void KoTextAnchor::paint (QPainter &painter, QPaintDevice *pd, const QTextDocument *document, const QRectF &rect, QTextInlineObject object, int posInDocument, const QTextCharFormat &format) {
......
......@@ -49,6 +49,7 @@ public:
double docOffsetInShape() const { return 0; }
bool addLine(QTextLine &) { return false; }
bool nextParag() { return false; }
bool previousParag() { return false; }
double documentOffsetInShape() { return 0; }
void draw(QPainter *, const QAbstractTextDocumentLayout::PaintContext &) {}
KoStyleManager *styleManager() const { return m_styleManager; }
......
......@@ -126,6 +126,8 @@ public:
virtual bool addLine(QTextLine &line) = 0;
/// prepare for next paragraph; return false if there is no next parag.
virtual bool nextParag() = 0;
// revert layout to the previous paragraph. Return false if there is no previous paragraph.
virtual bool previousParag() = 0;
virtual double documentOffsetInShape() = 0;
/// paint the document
virtual void draw(QPainter *painter, const PaintContext & context ) = 0;
......
......@@ -20,6 +20,7 @@
#include "KoTextShapeContainerModel.h"
#include "KoTextAnchor.h"
#include "KoTextShapeData.h"
#include "KoTextDocumentLayout.h"
#include <QTextBlock>
#include <QTextLayout>
......@@ -82,10 +83,26 @@ QList<KoShape*> KoTextShapeContainerModel::iterator() const {
}
void KoTextShapeContainerModel::containerChanged(KoShapeContainer *container) {
kDebug() << "KoTextShapeContainerModel::containerChanged\n";
// TODO
// For children which are aligned to the side of the page we may need to update the position so they will stay at the same vertical position.
}
void KoTextShapeContainerModel::childChanged(KoShape *child, KoShape::ChangeType type) {
if(type == KoShape::RotationChanged || type == KoShape::ScaleChanged ||
type == KoShape::ShearChanged || type == KoShape::SizeChanged) {
KoTextShapeData *data = dynamic_cast<KoTextShapeData*> (child->parent()->userData());
Q_ASSERT(data);
data->faul();
KoTextDocumentLayout *lay= dynamic_cast<KoTextDocumentLayout*> (data->document()->documentLayout());
if(lay)
lay->interruptLayout();
data->fireResizeEvent();
}
}
void KoTextShapeContainerModel::addAnchor(KoTextAnchor *anchor) {
Relation *relation = d->children.value(anchor->shape());
Q_ASSERT(relation);
......
......@@ -45,8 +45,10 @@ public:
virtual QList<KoShape*> iterator() const;
/// reimplemented from KoShapeContainerModel
virtual void containerChanged(KoShapeContainer *container);
/// reimplemented from KoShapeContainerModel
virtual void proposeMove(KoShape *child, QPointF &move);
/// reimplemented from KoShapeContainerModel
virtual void childChanged(KoShape *child, KoShape::ChangeType type);
/// each child that is added due to being anchored in the text has an anchor; register it for rules based placement.
void addAnchor(KoTextAnchor *anchor);
......@@ -56,6 +58,7 @@ public:
/// Check the anchor rules and move the shape to the right place.
void reposition(KoShape *shape);
private:
class Private;
Private * const d;
......
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