Warning, file /office/calligra/braindump/src/Layout.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 * Copyright (c) 2009 Cyrille Berger <cberger@cberger.net> 0003 * 0004 * This library is free software; you can redistribute it and/or 0005 * modify it under the terms of the GNU Lesser General Public 0006 * License as published by the Free Software Foundation; 0007 * either version 2, or (at your option) any later version of the License. 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 * Lesser General Public License for more details. 0013 * 0014 * You should have received a copy of the GNU Lesser General Public License 0015 * along with this library; see the file COPYING. 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 "Layout.h" 0021 0022 #include <QEvent> 0023 #include <QPainter> 0024 #include <QCoreApplication> 0025 0026 #include <KoShape.h> 0027 #include <KoViewConverter.h> 0028 #include <KoXmlReader.h> 0029 #include <KoShapeLoadingContext.h> 0030 #include <KoShapeSavingContext.h> 0031 0032 #include <Utils.h> 0033 0034 struct Layout::Private : public KoShape { 0035 Private() : eventSent(false) {} 0036 Layout* self; 0037 QList<KoShape*> shapes; 0038 QString id; 0039 bool eventSent; 0040 void removeDependees(); 0041 void triggerRelayout(); 0042 protected: 0043 virtual void shapeChanged(ChangeType type, KoShape * shape); 0044 private: 0045 // Fake 0046 virtual void paint(QPainter &painter, const KoViewConverter &converter, KoShapePaintingContext &) { 0047 Q_UNUSED(painter); 0048 Q_UNUSED(converter); 0049 qFatal("Shouldn't be called"); 0050 } 0051 virtual bool loadOdf(const KoXmlElement & element, KoShapeLoadingContext &context) { 0052 Q_UNUSED(element); 0053 Q_UNUSED(context); 0054 qFatal("Shouldn't be called"); 0055 return false; 0056 } 0057 virtual void saveOdf(KoShapeSavingContext & context) const { 0058 Q_UNUSED(context); 0059 qFatal("Shouldn't be called"); 0060 } 0061 0062 }; 0063 0064 static int event_type_delayed_relayout = QEvent::registerEventType(); 0065 0066 void Layout::Private::removeDependees() 0067 { 0068 foreach(KoShape * shape, shapes) { 0069 shape->removeDependee(this); 0070 } 0071 } 0072 0073 void Layout::Private::shapeChanged(ChangeType type, KoShape * shape) 0074 { 0075 switch(type) { 0076 case PositionChanged: 0077 case RotationChanged: 0078 case ScaleChanged: 0079 case ShearChanged: 0080 case SizeChanged: 0081 case GenericMatrixChange: 0082 self->shapeGeometryChanged(shape); 0083 triggerRelayout(); 0084 break; 0085 default: 0086 break; 0087 } 0088 } 0089 0090 void Layout::Private::triggerRelayout() 0091 { 0092 if(!eventSent) { 0093 QCoreApplication::postEvent(self, new QEvent(QEvent::Type(event_type_delayed_relayout))); 0094 eventSent = true; 0095 } 0096 } 0097 0098 0099 Layout::Layout(const QString& _id) : d(new Private) 0100 { 0101 d->self = this; 0102 d->id = _id; 0103 } 0104 0105 Layout::~Layout() 0106 { 0107 d->removeDependees(); 0108 delete d; 0109 } 0110 0111 const QString& Layout::id() const 0112 { 0113 return d->id; 0114 } 0115 0116 void Layout::replaceLayout(Layout* layout) 0117 { 0118 layout->d->removeDependees(); // Avoid both layout to fight for the shapes position 0119 addShapes(layout->d->shapes); 0120 d->triggerRelayout(); 0121 } 0122 0123 void Layout::addShapes(QList<KoShape*> _shapes) 0124 { 0125 foreach(KoShape * shape, _shapes) { 0126 Q_ASSERT(!d->shapes.contains(shape)); 0127 d->shapes.push_back(shape); 0128 } 0129 shapesAdded(_shapes); 0130 foreach(KoShape * shape, _shapes) { 0131 shape->addDependee(d); 0132 } 0133 d->triggerRelayout(); 0134 } 0135 0136 void Layout::addShape(KoShape* _shape) 0137 { 0138 Q_ASSERT(!d->shapes.contains(_shape)); 0139 d->shapes.push_back(_shape); 0140 shapeAdded(_shape); 0141 _shape->addDependee(d); 0142 d->triggerRelayout(); 0143 } 0144 0145 void Layout::removeShape(KoShape* _shape) 0146 { 0147 _shape->removeDependee(d); 0148 d->shapes.removeAll(_shape); 0149 shapeRemoved(_shape); 0150 d->triggerRelayout(); 0151 } 0152 0153 void Layout::shapesAdded(QList<KoShape*> _shapes) 0154 { 0155 foreach(KoShape * shape, _shapes) { 0156 shapeAdded(shape); 0157 } 0158 } 0159 0160 0161 QRectF Layout::boundingBox() const 0162 { 0163 QRectF b; 0164 Utils::containerBoundRec(shapes(), b); 0165 return b; 0166 } 0167 0168 const QList<KoShape*>& Layout::shapes() const 0169 { 0170 return d->shapes; 0171 } 0172 0173 bool Layout::event(QEvent * e) 0174 { 0175 if(e->type() == event_type_delayed_relayout) { 0176 Q_ASSERT(d->eventSent); 0177 e->accept(); 0178 relayout(); 0179 d->eventSent = false; 0180 return true; 0181 } else { 0182 return QObject::event(e); 0183 } 0184 }