Warning, file /office/calligra/libs/flake/KoShapeController.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  *
0003  * Copyright (C) 2006-2007, 2010 Thomas Zander <zander@kde.org>
0004  * Copyright (C) 2006-2008 Thorsten Zachmann <zachmann@kde.org>
0005  * Copyright (C) 2011 Jan Hambrecht <jaham@gmx.net>
0006  *
0007  * This library is free software; you can redistribute it and/or
0008  * modify it under the terms of the GNU Library General Public
0009  * License as published by the Free Software Foundation; either
0010  * version 2 of the License, or (at your option) any later version.
0011  *
0012  * This library is distributed in the hope that it will be useful,
0013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0015  * Library General Public License for more details.
0016  *
0017  * You should have received a copy of the GNU Library General Public License
0018  * along with this library; see the file COPYING.LIB.  If not, write to
0019  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0020  * Boston, MA 02110-1301, USA.
0021  */
0022 
0023 #include "KoShapeController.h"
0024 #include "KoShapeBasedDocumentBase.h"
0025 #include "KoShapeRegistry.h"
0026 #include "KoDocumentResourceManager.h"
0027 #include "KoShapeManager.h"
0028 #include "KoShapeLayer.h"
0029 #include "KoSelection.h"
0030 #include "commands/KoShapeCreateCommand.h"
0031 #include "commands/KoShapeDeleteCommand.h"
0032 #include "commands/KoShapeConnectionChangeCommand.h"
0033 #include "KoCanvasBase.h"
0034 #include "KoShapeConfigWidgetBase.h"
0035 #include "KoShapeConfigFactoryBase.h"
0036 #include "KoShapeFactoryBase.h"
0037 #include "KoShape.h"
0038 #include "KoConnectionShape.h"
0039 #include <KoUnit.h>
0040 
0041 #include <QObject>
0042 
0043 #include <kpagedialog.h>
0044 #include <klocalizedstring.h>
0045 
0046 #include <algorithm>
0047 
0048 class KoShapeController::Private
0049 {
0050 public:
0051     Private()
0052         : canvas(0),
0053           shapeBasedDocument(0)
0054     {
0055     }
0056 
0057     KoCanvasBase *canvas;
0058     KoShapeBasedDocumentBase *shapeBasedDocument;
0059 
0060     KUndo2Command* addShape(KoShape *shape, bool showDialog, KUndo2Command *parent) {
0061 
0062         if (canvas) {
0063             if (showDialog) {
0064                 KoShapeFactoryBase *factory = KoShapeRegistry::instance()->value(shape->shapeId());
0065                 Q_ASSERT(factory);
0066                 int z = 0;
0067                 foreach(KoShape *sh, canvas->shapeManager()->shapes())
0068                     z = qMax(z, sh->zIndex());
0069                 shape->setZIndex(z + 1);
0070 
0071                 // show config dialog.
0072                 KPageDialog *dialog = new KPageDialog(canvas->canvasWidget());
0073                 dialog->setWindowTitle(i18n("%1 Options", factory->name()));
0074 
0075                 int pageCount = 0;
0076                 QList<KoShapeConfigFactoryBase*> panels = factory->panelFactories();
0077                 std::sort(panels.begin(), panels.end(), KoShapeConfigFactoryBase::compare);
0078                 QList<KoShapeConfigWidgetBase*> widgets;
0079                 foreach(KoShapeConfigFactoryBase *panelFactory, panels) {
0080                     if (! panelFactory->showForShapeId(shape->shapeId()))
0081                         continue;
0082                     KoShapeConfigWidgetBase *widget = panelFactory->createConfigWidget(shape);
0083                     if (widget == 0)
0084                         continue;
0085                     if (! widget->showOnShapeCreate()) {
0086                         delete widget;
0087                         continue;
0088                     }
0089                     widget->connect(widget, SIGNAL(accept()), dialog, SLOT(accept()));
0090                     widgets.append(widget);
0091                     widget->setResourceManager(canvas->resourceManager());
0092                     widget->setUnit(canvas->unit());
0093                     dialog->addPage(widget, panelFactory->name());
0094                     pageCount ++;
0095                 }
0096                 foreach(KoShapeConfigWidgetBase* panel, factory->createShapeOptionPanels()) {
0097                     if (! panel->showOnShapeCreate())
0098                         continue;
0099                     panel->open(shape);
0100                     panel->connect(panel, SIGNAL(accept()), dialog, SLOT(accept()));
0101                     widgets.append(panel);
0102                     panel->setResourceManager(canvas->resourceManager());
0103                     panel->setUnit(canvas->unit());
0104                     QString title = panel->windowTitle().isEmpty() ? panel->objectName() : panel->windowTitle();
0105                     dialog->addPage(panel, title);
0106                     pageCount ++;
0107                 }
0108 
0109                 if (pageCount > 0) {
0110                     if (pageCount > 1)
0111                         dialog->setFaceType(KPageDialog::Tabbed);
0112                     if (dialog->exec() != KPageDialog::Accepted) {
0113                         delete dialog;
0114                         return 0;
0115                     }
0116                     foreach(KoShapeConfigWidgetBase *widget, widgets)
0117                         widget->save();
0118                 }
0119                 delete dialog;
0120             }
0121 
0122             // set the active layer as parent if there is not yet a parent.
0123             if (!shape->parent()) {
0124                 shape->setParent(canvas->shapeManager()->selection()->activeLayer());
0125             }
0126         }
0127         return new KoShapeCreateCommand(shapeBasedDocument, shape, parent);
0128     }
0129 
0130     void handleAttachedConnections(KoShape *shape, KUndo2Command *parentCmd) {
0131         foreach (KoShape *dependee, shape->dependees()) {
0132             KoConnectionShape *connection = dynamic_cast<KoConnectionShape*>(dependee);
0133             if (connection) {
0134                 if (shape == connection->firstShape()) {
0135                     new KoShapeConnectionChangeCommand(connection, KoConnectionShape::StartHandle,
0136                                                        shape, connection->firstConnectionId(), 0, -1, parentCmd);
0137                 } else if (shape == connection->secondShape()) {
0138                     new KoShapeConnectionChangeCommand(connection, KoConnectionShape::EndHandle,
0139                                                        shape, connection->secondConnectionId(), 0, -1, parentCmd);
0140                 }
0141             }
0142         }
0143     }
0144 };
0145 
0146 KoShapeController::KoShapeController(KoCanvasBase *canvas, KoShapeBasedDocumentBase *shapeBasedDocument)
0147     : d(new Private())
0148 {
0149     d->canvas = canvas;
0150     d->shapeBasedDocument = shapeBasedDocument;
0151     if (shapeBasedDocument) {
0152         shapeBasedDocument->resourceManager()->setShapeController(this);
0153     }
0154 }
0155 
0156 KoShapeController::~KoShapeController()
0157 {
0158     delete d;
0159 }
0160 
0161 KUndo2Command* KoShapeController::addShape(KoShape *shape, KUndo2Command *parent)
0162 {
0163     return d->addShape(shape, true, parent);
0164 }
0165 
0166 KUndo2Command* KoShapeController::addShapeDirect(KoShape *shape, KUndo2Command *parent)
0167 {
0168     return d->addShape(shape, false, parent);
0169 }
0170 
0171 KUndo2Command* KoShapeController::removeShape(KoShape *shape, KUndo2Command *parent)
0172 {
0173     KUndo2Command *cmd = new KoShapeDeleteCommand(d->shapeBasedDocument, shape, parent);
0174     QList<KoShape*> shapes;
0175     shapes.append(shape);
0176     d->shapeBasedDocument->shapesRemoved(shapes, cmd);
0177     // detach shape from any attached connection shapes
0178     d->handleAttachedConnections(shape, cmd);
0179     return cmd;
0180 }
0181 
0182 KUndo2Command* KoShapeController::removeShapes(const QList<KoShape*> &shapes, KUndo2Command *parent)
0183 {
0184     KUndo2Command *cmd = new KoShapeDeleteCommand(d->shapeBasedDocument, shapes, parent);
0185     d->shapeBasedDocument->shapesRemoved(shapes, cmd);
0186     foreach (KoShape *shape, shapes) {
0187         d->handleAttachedConnections(shape, cmd);
0188     }
0189     return cmd;
0190 }
0191 
0192 void KoShapeController::setShapeControllerBase(KoShapeBasedDocumentBase *shapeBasedDocument)
0193 {
0194     d->shapeBasedDocument = shapeBasedDocument;
0195 }
0196 
0197 KoDocumentResourceManager *KoShapeController::resourceManager() const
0198 {
0199     if (!d->shapeBasedDocument)
0200         return 0;
0201     return d->shapeBasedDocument->resourceManager();
0202 }
0203 
0204 KoShapeBasedDocumentBase *KoShapeController::documentBase() const
0205 {
0206     return d->shapeBasedDocument;
0207 }