00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "KoToolManager.h"
00025 #include "KoToolManager_p.h"
00026 #include "KoToolRegistry.h"
00027 #include "KoToolProxy.h"
00028 #include "KoSelection.h"
00029 #include "tools/KoCreatePathToolFactory.h"
00030 #include "tools/KoCreateShapesToolFactory.h"
00031 #include "tools/KoCreateShapesTool.h"
00032 #include "tools/KoPathToolFactory.h"
00033 #include "KoCanvasController.h"
00034 #include "KoShape.h"
00035 #include "KoShapeLayer.h"
00036 #include "KoShapeRegistry.h"
00037 #include "KoShapeManager.h"
00038 #include "KoCanvasBase.h"
00039 #include "KoDeviceRegistry.h"
00040 #include "KoDeviceEvent.h"
00041 #include "KoPointerEvent.h"
00042 #include "tools/KoZoomTool.h"
00043 #include "tools/KoZoomToolFactory.h"
00044 #include "tools/KoPanTool.h"
00045 #include "tools/KoPanToolFactory.h"
00046 #include "tools/KoGuidesTool.h"
00047
00048
00049 #include <QWidget>
00050 #include <QEvent>
00051 #include <QWheelEvent>
00052 #include <QMouseEvent>
00053 #include <QPaintEvent>
00054 #include <QTabletEvent>
00055 #include <QKeyEvent>
00056 #include <QGridLayout>
00057 #include <QDockWidget>
00058 #include <QStringList>
00059 #include <QAbstractButton>
00060 #include <QApplication>
00061 #include <QTimer>
00062 #include <kactioncollection.h>
00063 #include <kdebug.h>
00064 #include <kglobal.h>
00065 #include <kaction.h>
00066 #include <QStack>
00067 #include <QLabel>
00068
00069 class CanvasData
00070 {
00071 public:
00072 CanvasData(KoCanvasController *cc, const KoInputDevice &id)
00073 : activeTool(0),
00074 canvas(cc),
00075 inputDevice(id),
00076 dummyToolWidget(0),
00077 dummyToolLabel(0) {
00078 }
00079
00080 KoTool *activeTool;
00081 QString activeToolId;
00082 QString activationShapeId;
00083 QHash<QString, KoTool*> allTools;
00084 QStack<QString> stack;
00085 KoCanvasController *const canvas;
00086 const KoInputDevice inputDevice;
00087 QWidget *dummyToolWidget;
00088 QLabel *dummyToolLabel;
00089 };
00090
00091 class KoToolManager::Private
00092 {
00093 public:
00094 Private() : canvasData(0), layerEnabled(true) {
00095 tabletEventTimer.setSingleShot(true);
00096 }
00097 ~Private() {
00098 qDeleteAll(tools);
00099 }
00100
00101 QList<ToolHelper*> tools;
00102
00103 QHash<KoTool*, int> uniqueToolIds;
00104 QHash<KoCanvasController*, QList<CanvasData*> > canvasses;
00105 QHash<KoCanvasBase*, KoToolProxy*> proxies;
00106
00107 CanvasData *canvasData;
00108
00109 KoInputDevice inputDevice;
00110 QTimer tabletEventTimer;
00111
00112
00113 bool layerEnabled;
00114
00115
00116 CanvasData *createCanvasData(KoCanvasController *controller, KoInputDevice device) {
00117 QHash<QString, KoTool*> origHash;
00118 if (canvasses.contains(controller))
00119 origHash = canvasses.value(controller).first()->allTools;
00120
00121 QHash<QString, KoTool*> toolsHash;
00122 foreach(ToolHelper *tool, tools) {
00123 if (tool->inputDeviceAgnostic() && origHash.contains(tool->id())) {
00124
00125 toolsHash.insert(tool->id(), origHash.value(tool->id()));
00126 continue;
00127 }
00128 if (! tool->canCreateTool(controller->canvas())) {
00129 kDebug(30006) << "Skipping the creation of tool" << tool->id();
00130 continue;
00131 }
00132 kDebug(30006) << "Creating tool" << tool->id() << ". Activated on:" << tool->activationShapeId() << ", prio:" << tool->priority();
00133 KoTool *tl = tool->createTool(controller->canvas());
00134 Q_ASSERT(tl);
00135 uniqueToolIds.insert(tl, tool->uniqueId());
00136 toolsHash.insert(tool->id(), tl);
00137 tl->setObjectName(tool->id());
00138 foreach(KAction *action, tl->actions())
00139 action->setEnabled(false);
00140 KoZoomTool *zoomTool = dynamic_cast<KoZoomTool*>(tl);
00141 if (zoomTool)
00142 zoomTool->setCanvasController(controller);
00143 KoPanTool *panTool = dynamic_cast<KoPanTool*>(tl);
00144 if (panTool)
00145 panTool->setCanvasController(controller);
00146 }
00147 KoCreateShapesTool *createTool = dynamic_cast<KoCreateShapesTool*>(toolsHash.value(KoCreateShapesTool_ID));
00148 Q_ASSERT(createTool);
00149 QString id = KoShapeRegistry::instance()->keys()[0];
00150 createTool->setShapeId(id);
00151
00152 CanvasData *cd = new CanvasData(controller, device);
00153 cd->allTools = toolsHash;
00154 return cd;
00155 }
00156
00157 bool toolCanBeUsed( const QString &activationShapeId)
00158 {
00159 if (layerEnabled)
00160 return true;
00161 if (activationShapeId.endsWith(QLatin1String( "/always")))
00162 return true;
00163 return false;
00164 }
00165 };
00166
00167
00168 KoToolManager::KoToolManager()
00169 : QObject(),
00170 d(new Private())
00171 {
00172 connect(QApplication::instance(), SIGNAL(focusChanged(QWidget*, QWidget*)),
00173 this, SLOT(movedFocus(QWidget*, QWidget*)));
00174 }
00175
00176 KoToolManager::~KoToolManager()
00177 {
00178 delete d;
00179 }
00180
00181 void KoToolManager::setup()
00182 {
00183 if (d->tools.size() > 0)
00184 return;
00185
00186 d->tools.append(new ToolHelper(new KoCreatePathToolFactory(this)));
00187 d->tools.append(new ToolHelper(new KoCreateShapesToolFactory(this)));
00188 d->tools.append(new ToolHelper(new KoPathToolFactory(this)));
00189 d->tools.append(new ToolHelper(new KoZoomToolFactory(this)));
00190 d->tools.append(new ToolHelper(new KoPanToolFactory(this)));
00191
00192 KoShapeRegistry::instance();
00193 KoToolRegistry *registry = KoToolRegistry::instance();
00194 foreach(const QString & id, registry->keys()) {
00195 ToolHelper *t = new ToolHelper(registry->value(id));
00196 d->tools.append(t);
00197 }
00198
00199
00200 foreach(ToolHelper *tool, d->tools)
00201 connect(tool, SIGNAL(toolActivated(ToolHelper*)), this, SLOT(toolActivated(ToolHelper*)));
00202
00203
00204 KoDeviceRegistry::instance();
00205 }
00206
00207 QList<KoToolManager::Button> KoToolManager::createToolList(KoCanvasBase *canvas) const
00208 {
00209 QList<KoToolManager::Button> answer;
00210 foreach(ToolHelper *tool, d->tools) {
00211 if (tool->id() == KoCreateShapesTool_ID)
00212 continue;
00213 if (tool->id() == KoGuidesTool_ID)
00214 continue;
00215 if (! tool->canCreateTool(canvas))
00216 continue;
00217 Button button;
00218 button.button = tool->createButton();
00219 button.section = tool->toolType();
00220 button.priority = tool->priority();
00221 button.buttonGroupId = tool->uniqueId();
00222 button.visibilityCode = tool->activationShapeId();
00223 answer.append(button);
00224 }
00225 return answer;
00226 }
00227
00228 void KoToolManager::requestToolActivation(KoCanvasController * controller)
00229 {
00230 if (d->canvasses.contains(controller)) {
00231 QString activeToolId = d->canvasses.value(controller).first()->activeToolId;
00232 foreach(ToolHelper * th, d->tools) {
00233 if (th->id() == activeToolId) {
00234 toolActivated(th);
00235 break;
00236 }
00237 }
00238 }
00239 }
00240
00241 KoInputDevice KoToolManager::currentInputDevice() const
00242 {
00243 return d->inputDevice;
00244 }
00245
00246 void KoToolManager::registerTools(KActionCollection *ac, KoCanvasController *controller)
00247 {
00248 Q_ASSERT(controller);
00249 Q_ASSERT(ac);
00250
00251 setup();
00252
00253 if (! d->canvasses.contains(controller)) {
00254 kWarning(30006) << "registerTools called on a canvasController that has not been registered (yet)!";
00255 return;
00256 }
00257 CanvasData *cd = d->canvasses.value(controller).first();
00258 foreach(KoTool *tool, cd->allTools) {
00259 QHash<QString, KAction*> actions = tool->actions();
00260 QHash<QString, KAction*>::const_iterator it(actions.constBegin());
00261 for (; it != actions.constEnd(); ++it) {
00262 ac->addAction(it.key(), it.value());
00263 }
00264 }
00265 }
00266
00267 void KoToolManager::addController(KoCanvasController *controller)
00268 {
00269 Q_ASSERT(controller);
00270 if (d->canvasses.keys().contains(controller))
00271 return;
00272 setup();
00273 attachCanvas(controller);
00274 connect(controller, SIGNAL(canvasRemoved(KoCanvasController*)), this, SLOT(detachCanvas(KoCanvasController*)));
00275 connect(controller, SIGNAL(canvasSet(KoCanvasController*)), this, SLOT(attachCanvas(KoCanvasController*)));
00276 }
00277
00278 void KoToolManager::removeCanvasController(KoCanvasController *controller)
00279 {
00280 Q_ASSERT(controller);
00281 detachCanvas(controller);
00282 disconnect(controller, SIGNAL(canvasRemoved(KoCanvasController*)), this, SLOT(detachCanvas(KoCanvasController*)));
00283 disconnect(controller, SIGNAL(canvasSet(KoCanvasController*)), this, SLOT(attachCanvas(KoCanvasController*)));
00284 }
00285
00286 void KoToolManager::toolActivated(ToolHelper *tool)
00287 {
00288 Q_ASSERT(tool);
00289 if (!d->toolCanBeUsed(tool->activationShapeId()))
00290 return;
00291
00292 Q_ASSERT(d->canvasData);
00293 if (!d->canvasData) return;
00294 KoTool *t = d->canvasData->allTools.value(tool->id());
00295 Q_ASSERT(t);
00296
00297 d->canvasData->activeToolId = tool->id();
00298 d->canvasData->activationShapeId = tool->activationShapeId();
00299
00300 switchTool(t, false);
00301 }
00302
00303 void KoToolManager::switchTool(const QString &id, bool temporary)
00304 {
00305 Q_ASSERT(d->canvasData);
00306 if (!d->canvasData) return;
00307
00308 if (d->canvasData->activeTool && temporary)
00309 d->canvasData->stack.push(d->canvasData->activeToolId);
00310 d->canvasData->activeToolId = id;
00311 KoTool *tool = d->canvasData->allTools.value(id);
00312 if (! tool) {
00313 kWarning(30006) << "KoToolManager::switchTool() " << (temporary ? "temporary" : "") << " got request to unknown tool: '" << id << "'";
00314 return;
00315 }
00316
00317 foreach(ToolHelper *th, d->tools) {
00318 if (th->id() == id) {
00319 if(!d->toolCanBeUsed(th->activationShapeId()) ) return;
00320 d->canvasData->activationShapeId = th->activationShapeId();
00321 break;
00322 }
00323 }
00324
00325 switchTool(tool, temporary);
00326 }
00327
00328 void KoToolManager::switchTool(KoTool *tool, bool temporary)
00329 {
00330 Q_ASSERT(tool);
00331 if (d->canvasData == 0)
00332 return;
00333
00334 if (d->canvasData->activeTool == tool && tool->toolId() != KoInteractionTool_ID)
00335 return;
00336
00337 bool newActiveTool = d->canvasData->activeTool != 0;
00338
00339 if (newActiveTool) {
00340 d->canvasData->activeTool->repaintDecorations();
00341
00342 QList<CanvasData*> items = d->canvasses[d->canvasData->canvas];
00343 foreach(CanvasData *cd, items) {
00344 if (cd == d->canvasData) continue;
00345 if (cd->activeTool == d->canvasData->activeTool) {
00346 newActiveTool = false;
00347 break;
00348 }
00349 }
00350 }
00351
00352 if (newActiveTool) {
00353 foreach(KAction *action, d->canvasData->activeTool->actions())
00354 action->setEnabled(false);
00355
00356
00357 d->canvasData->activeTool->deactivate();
00358 disconnect(d->canvasData->activeTool, SIGNAL(cursorChanged(const QCursor&)),
00359 this, SLOT(updateCursor(const QCursor&)));
00360 disconnect(d->canvasData->activeTool, SIGNAL(activateTool(const QString &)),
00361 this, SLOT(switchToolRequested(const QString &)));
00362 disconnect(d->canvasData->activeTool, SIGNAL(activateTemporary(const QString &)),
00363 this, SLOT(switchToolTemporaryRequested(const QString &)));
00364 disconnect(d->canvasData->activeTool, SIGNAL(done()), this, SLOT(switchBackRequested()));
00365 disconnect(d->canvasData->activeTool, SIGNAL(statusTextChanged(const QString &)),
00366 this, SIGNAL(changedStatusText(const QString &)));
00367 }
00368
00369 d->canvasData->activeTool = tool;
00370
00371 connect(d->canvasData->activeTool, SIGNAL(cursorChanged(const QCursor &)),
00372 this, SLOT(updateCursor(const QCursor &)));
00373 connect(d->canvasData->activeTool, SIGNAL(activateTool(const QString &)),
00374 this, SLOT(switchToolRequested(const QString &)));
00375 connect(d->canvasData->activeTool, SIGNAL(activateTemporary(const QString &)),
00376 this, SLOT(switchToolTemporaryRequested(const QString &)));
00377 connect(d->canvasData->activeTool, SIGNAL(done()), this, SLOT(switchBackRequested()));
00378 connect(d->canvasData->activeTool, SIGNAL(statusTextChanged(const QString &)),
00379 this, SIGNAL(changedStatusText(const QString &)));
00380
00381
00382 emit changedStatusText(QString());
00383
00384
00385 d->canvasData->canvas->canvas()->canvasWidget()->setCursor(Qt::ForbiddenCursor);
00386 foreach(KAction *action, d->canvasData->activeTool->actions()) {
00387 action->setEnabled(true);
00388 d->canvasData->canvas->addAction(action);
00389 }
00390
00391 postSwitchTool(temporary);
00392 }
00393
00394 void KoToolManager::postSwitchTool(bool temporary)
00395 {
00396 #ifndef NDEBUG
00397 int canvasCount = 1;
00398 foreach(QList<CanvasData*> list, d->canvasses) {
00399 bool first = true;
00400 foreach(CanvasData *data, list) {
00401 if (first)
00402 kDebug(30006) << "Canvas" << canvasCount++;
00403 kDebug(30006) << " +- Tool:" << data->activeToolId << (data == d->canvasData ? " *" : "");
00404 first = false;
00405 }
00406 }
00407 #endif
00408 Q_ASSERT(d->canvasData);
00409 if (!d->canvasData) return;
00410
00411 if (d->canvasData->canvas->canvas()) {
00412 KoCanvasBase *canvas = d->canvasData->canvas->canvas();
00413
00414 KoToolProxy *tp = d->proxies.value(canvas);
00415 if (tp)
00416 tp->setActiveTool(d->canvasData->activeTool);
00417 d->canvasData->activeTool->activate(temporary);
00418 canvas->updateInputMethodInfo();
00419 } else {
00420 d->canvasData->activeTool->activate(temporary);
00421 }
00422
00423 QMap<QString, QWidget *> optionWidgetMap = d->canvasData->activeTool->optionWidgets();
00424 if (optionWidgetMap.empty()) {
00425 QWidget *toolWidget;
00426 QString name;
00427 foreach(ToolHelper *tool, d->tools) {
00428 if (tool->id() == d->canvasData->activeTool->toolId()) {
00429 name = tool->name();
00430 break;
00431 }
00432 }
00433 toolWidget = d->canvasData->dummyToolWidget;
00434 if (toolWidget == 0) {
00435 toolWidget = new QWidget();
00436 toolWidget->setObjectName( "DummyToolWidget" );
00437 QVBoxLayout *layout = new QVBoxLayout(toolWidget);
00438 layout->setMargin(3);
00439 d->canvasData->dummyToolLabel = new QLabel(toolWidget);
00440 layout->addWidget(d->canvasData->dummyToolLabel);
00441 layout->addItem(new QSpacerItem(1, 1, QSizePolicy::Minimum, QSizePolicy::Expanding));
00442 toolWidget->setLayout(layout);
00443 d->canvasData->dummyToolWidget = toolWidget;
00444 }
00445 d->canvasData->dummyToolLabel->setText(i18n("Active tool: %1", name));
00446 optionWidgetMap.insert(i18n("Tool Options"), toolWidget);
00447 }
00448
00449
00450 foreach(KAction *action, d->canvasData->activeTool->actions()) {
00451 action->setEnabled(true);
00452 }
00453
00454 d->canvasData->canvas->setToolOptionWidgets(optionWidgetMap);
00455 emit changedTool(d->canvasData->canvas, d->uniqueToolIds.value(d->canvasData->activeTool));
00456 }
00457
00458
00459 void KoToolManager::attachCanvas(KoCanvasController *controller)
00460 {
00461 Q_ASSERT(controller);
00462 CanvasData *cd = d->createCanvasData(controller, KoInputDevice::mouse());
00463
00464 if (d->canvasData == 0) {
00465 QApplication::instance()->installEventFilter(this);
00466 }
00467 d->canvasData = cd;
00468 d->inputDevice = cd->inputDevice;
00469 QList<CanvasData*> canvasses;
00470 canvasses.append(cd);
00471 d->canvasses[controller] = canvasses;
00472
00473 KoToolProxy *tp = d->proxies[controller->canvas()];
00474 if (tp)
00475 tp->setCanvasController(controller);
00476
00477 if (cd->activeTool == 0) {
00478
00479 int highestPriority = INT_MAX;
00480 ToolHelper * helper = 0;
00481 foreach(ToolHelper * th, d->tools) {
00482 if (th->toolType() == KoToolFactory::mainToolType()) {
00483 if (th->priority() < highestPriority) {
00484 highestPriority = qMin(highestPriority, th->priority());
00485 helper = th;
00486 }
00487 }
00488 }
00489 if (helper)
00490 toolActivated(helper);
00491 }
00492
00493 Connector *connector = new Connector(controller->canvas()->shapeManager());
00494 connect(connector, SIGNAL(selectionChanged(QList<KoShape*>)), this,
00495 SLOT(selectionChanged(QList<KoShape*>)));
00496 connect(controller->canvas()->shapeManager()->selection(),
00497 SIGNAL(currentLayerChanged(const KoShapeLayer*)),
00498 this, SLOT(currentLayerChanged(const KoShapeLayer*)));
00499
00500 d->canvasData->canvas->activate();
00501
00502 emit changedCanvas(d->canvasData ? d->canvasData->canvas->canvas() : 0);
00503 }
00504
00505 void KoToolManager::movedFocus(QWidget *from, QWidget *to)
00506 {
00507 Q_UNUSED(from);
00508 if (to == 0 || (d->canvasData && to == d->canvasData->canvas))
00509 return;
00510
00511 KoCanvasController *newCanvas = 0;
00512
00513 foreach(KoCanvasController* canvas, d->canvasses.keys()) {
00514 if (canvas == to || canvas->canvas()->canvasWidget() == to) {
00515 newCanvas = canvas;
00516 break;
00517 }
00518 }
00519
00520 if (newCanvas == 0)
00521 return;
00522 if (d->canvasData && newCanvas == d->canvasData->canvas)
00523 return;
00524
00525 if (! d->canvasses.contains(newCanvas))
00526 return;
00527 foreach(CanvasData *data, d->canvasses.value(newCanvas)) {
00528 if (data->inputDevice == d->inputDevice) {
00529 if (d->canvasData) {
00530 d->canvasData->canvas->canvas()->canvasWidget()->setCursor(Qt::ArrowCursor);
00531 if (d->canvasData->activeTool) {
00532 d->canvasData->activeTool->deactivate();
00533 KoToolProxy *proxy = d->proxies.value(d->canvasData->canvas->canvas());
00534 Q_ASSERT(proxy);
00535 proxy->setActiveTool(0);
00536 }
00537 }
00538
00539 d->canvasData = data;
00540 d->canvasData->canvas->canvas()->canvasWidget()->setCursor(d->canvasData->activeTool->cursor());
00541 d->canvasData->canvas->activate();
00542 postSwitchTool(false);
00543 emit changedCanvas(d->canvasData ? d->canvasData->canvas->canvas() : 0);
00544 return;
00545 }
00546 }
00547
00548 d->canvasData = d->canvasses.value(newCanvas).first();
00549 d->inputDevice = d->canvasData->inputDevice;
00550 d->canvasData->canvas->activate();
00551 emit changedCanvas(d->canvasData ? d->canvasData->canvas->canvas() : 0);
00552 }
00553
00554 void KoToolManager::detachCanvas(KoCanvasController *controller)
00555 {
00556 Q_ASSERT(controller);
00557
00558 if (d->canvasData && d->canvasData->canvas == controller) {
00559 KoCanvasController *newCanvas = 0;
00560
00561 foreach(KoCanvasController* canvas, d->canvasses.keys()) {
00562 if (canvas != controller) {
00563
00564 newCanvas = canvas;
00565 break;
00566 }
00567 }
00568 if (newCanvas) {
00569
00570 d->canvasData = d->canvasses.value(newCanvas).first();
00571 d->inputDevice = d->canvasData->inputDevice;
00572 d->canvasData->canvas->activate();
00573 } else {
00574
00575 d->canvasData = 0;
00576
00577 QApplication::instance()->removeEventFilter(this);
00578 }
00579 }
00580
00581 QList<KoTool *> tools;
00582 foreach(CanvasData *cd, d->canvasses.value(controller)) {
00583 foreach(KoTool *tool, cd->allTools)
00584 if (! tools.contains(tool))
00585 tools.append(tool);
00586 delete cd;
00587 }
00588 foreach(KoTool *tool, tools) {
00589 d->uniqueToolIds.remove(tool);
00590 delete tool;
00591 }
00592 d->canvasses.remove(controller);
00593 emit changedCanvas(d->canvasData ? d->canvasData->canvas->canvas() : 0);
00594 }
00595
00596 void KoToolManager::updateCursor(const QCursor &cursor)
00597 {
00598 Q_ASSERT(d->canvasData);
00599 Q_ASSERT(d->canvasData->canvas);
00600 Q_ASSERT(d->canvasData->canvas->canvas());
00601 d->canvasData->canvas->canvas()->canvasWidget()->setCursor(cursor);
00602 }
00603
00604 void KoToolManager::switchToolRequested(const QString & id)
00605 {
00606 Q_ASSERT(d->canvasData);
00607 if (!d->canvasData) return;
00608
00609 while (!d->canvasData->stack.isEmpty())
00610 d->canvasData->stack.pop();
00611 switchTool(id, false);
00612 }
00613
00614 void KoToolManager::switchToolTemporaryRequested(const QString &id)
00615 {
00616 switchTool(id, true);
00617 }
00618
00619 void KoToolManager::switchBackRequested()
00620 {
00621 Q_ASSERT(d->canvasData);
00622 if (!d->canvasData) return;
00623
00624 if (d->canvasData->stack.isEmpty()) {
00625
00626 switchTool(KoInteractionTool_ID, false);
00627 return;
00628 }
00629 switchTool(d->canvasData->stack.pop(), false);
00630 }
00631
00632 KoCreateShapesTool * KoToolManager::shapeCreatorTool(KoCanvasBase *canvas) const
00633 {
00634 Q_ASSERT(canvas);
00635 foreach(KoCanvasController *controller, d->canvasses.keys()) {
00636 if (controller->canvas() == canvas) {
00637 KoCreateShapesTool *createTool = dynamic_cast<KoCreateShapesTool*>
00638 (d->canvasData->allTools.value(KoCreateShapesTool_ID));
00639 Q_ASSERT(createTool );
00640 return createTool;
00641 }
00642 }
00643 Q_ASSERT(0);
00644 return 0;
00645 }
00646
00647 KoGuidesTool * KoToolManager::guidesTool(KoCanvasBase * canvas) const
00648 {
00649 Q_ASSERT(canvas);
00650 foreach(KoCanvasController *controller, d->canvasses.keys()) {
00651 if (controller->canvas() == canvas) {
00652 KoGuidesTool * guidesTool = dynamic_cast<KoGuidesTool*>
00653 (d->canvasData->allTools.value(KoGuidesTool_ID));
00654 Q_ASSERT(guidesTool );
00655 return guidesTool;
00656 }
00657 }
00658 Q_ASSERT(0);
00659 return 0;
00660 }
00661
00662 void KoToolManager::selectionChanged(QList<KoShape*> shapes)
00663 {
00664 QList<QString> types;
00665 foreach(KoShape *shape, shapes) {
00666 if (! types.contains(shape->shapeId())) {
00667 types.append(shape->shapeId());
00668 }
00669 }
00670
00671
00672
00673
00674
00675 if (!(d->canvasData->activationShapeId.isNull() && shapes.size() > 0)
00676 && d->canvasData->activationShapeId != "flake/always"
00677 && d->canvasData->activationShapeId != "flake/edit"
00678 && ! types.contains(d->canvasData->activationShapeId)) {
00679 switchTool(KoInteractionTool_ID, false);
00680 }
00681
00682 emit toolCodesSelected(d->canvasData->canvas, types);
00683 }
00684
00685 void KoToolManager::currentLayerChanged(const KoShapeLayer *layer)
00686 {
00687 kDebug(30006) << "layer changed to" << layer;
00688
00689 emit currentLayerChanged(d->canvasData->canvas, layer);
00690 d->layerEnabled = layer == 0 || (layer->isEditable() && layer->isVisible());
00691
00692 kDebug(30006 ) << "and the layer enabled is" << (d->layerEnabled ? "true" : "false");
00693
00694 KoToolProxy *proxy = d->proxies.value(d->canvasData->canvas->canvas());
00695 kDebug(30006) << " and the proxy is" << proxy;
00696 if (proxy) {
00697 kDebug( 30006 ) << " set " << d->canvasData->activeTool << (d->layerEnabled ? "enabled" : "disabled");
00698 proxy->setActiveTool(d->toolCanBeUsed(d->canvasData->activationShapeId) ? d->canvasData->activeTool : 0);
00699 }
00700 }
00701
00702 KoCanvasController *KoToolManager::activeCanvasController() const
00703 {
00704 if (! d->canvasData) return 0;
00705 return d->canvasData->canvas;
00706 }
00707
00708 void KoToolManager::switchToolByShortcut(QKeyEvent *event)
00709 {
00710 QKeySequence item(event->key() | ((Qt::ControlModifier | Qt::AltModifier) & event->modifiers()));
00711
00712 foreach(ToolHelper *th, d->tools) {
00713 if (th->shortcut().contains(item)) {
00714 event->accept();
00715 switchTool(th->id(), false);
00716 return;
00717 }
00718 }
00719 if (event->key() == Qt::Key_Space && event->modifiers() == 0) {
00720 switchTool(KoPanTool_ID, true);
00721 }
00722 }
00723
00724 QString KoToolManager::preferredToolForSelection(const QList<KoShape*> &shapes)
00725 {
00726 QList<QString> types;
00727 foreach(KoShape *shape, shapes)
00728 if (! types.contains(shape->shapeId()))
00729 types.append(shape->shapeId());
00730
00731 QString toolType = KoInteractionTool_ID;
00732 int prio = INT_MAX;
00733 foreach(ToolHelper *helper, d->tools) {
00734 if (helper->priority() >= prio)
00735 continue;
00736 if (helper->toolType() == KoToolFactory::mainToolType())
00737 continue;
00738 if (types.contains(helper->activationShapeId())) {
00739 toolType = helper->id();
00740 prio = helper->priority();
00741 }
00742 }
00743 return toolType;
00744 }
00745
00746 #define MSECS_TO_IGNORE_SWITCH_TO_MOUSE_AFTER_TABLET_EVENT_RECEIVED 100
00747
00748 void KoToolManager::switchInputDevice(const KoInputDevice &device)
00749 {
00750 Q_ASSERT(d->canvasData);
00751 if (!d->canvasData) return;
00752 if (!device.isMouse()) {
00753 d->tabletEventTimer.start(MSECS_TO_IGNORE_SWITCH_TO_MOUSE_AFTER_TABLET_EVENT_RECEIVED);
00754 }
00755 if (d->inputDevice == device) return;
00756 if (device.isMouse() && d->tabletEventTimer.isActive()) {
00757
00758
00759
00760
00761 return;
00762 }
00763 d->inputDevice = device;
00764 QList<CanvasData*> items = d->canvasses[d->canvasData->canvas];
00765
00766
00767 foreach(CanvasData *cd, items) {
00768 foreach(KoTool* tool, cd->allTools) {
00769 foreach(KAction* action, tool->actions()) {
00770 action->setEnabled(false);
00771 }
00772 }
00773 }
00774
00775
00776 foreach(CanvasData *cd, items) {
00777
00778 if (cd->inputDevice == device) {
00779 d->canvasData = cd;
00780 if (cd->activeTool == 0)
00781 switchTool(KoInteractionTool_ID, false);
00782 else {
00783 postSwitchTool(false);
00784 d->canvasData->canvas->canvas()->canvasWidget()->setCursor(d->canvasData->activeTool->cursor());
00785 }
00786 d->canvasData->canvas->activate();
00787 emit inputDeviceChanged(device);
00788 emit changedCanvas(d->canvasData ? d->canvasData->canvas->canvas() : 0);
00789 return;
00790 }
00791 }
00792
00793
00794 CanvasData *cd = d->createCanvasData(d->canvasData->canvas, device);
00795
00796 QString oldTool = d->canvasData->activeToolId;
00797
00798 d->canvasData = cd;
00799 items.append(cd);
00800 d->canvasses[d->canvasData->canvas] = items;
00801
00802 switchToolRequested(oldTool);
00803 emit inputDeviceChanged(device);
00804 d->canvasData->canvas->activate();
00805 emit changedCanvas(d->canvasData ? d->canvasData->canvas->canvas() : 0);
00806 }
00807
00808 bool KoToolManager::eventFilter(QObject *object, QEvent *event)
00809 {
00810 switch (event->type()) {
00811 case QEvent::TabletMove:
00812 case QEvent::TabletPress:
00813 case QEvent::TabletRelease:
00814 case QEvent::TabletEnterProximity:
00815 case QEvent::TabletLeaveProximity: {
00816 QTabletEvent *tabletEvent = static_cast<QTabletEvent *>(event);
00817
00818 KoInputDevice id(tabletEvent->device(), tabletEvent->pointerType(), tabletEvent->uniqueId());
00819 switchInputDevice(id);
00820 break;
00821 }
00822 case QEvent::MouseButtonPress:
00823 case QEvent::MouseMove:
00824 case QEvent::MouseButtonRelease:
00825 switchInputDevice(KoInputDevice::mouse());
00826 break;
00827 default:
00828 break;
00829 }
00830
00831 return QObject::eventFilter(object, event);
00832 }
00833
00834 void KoToolManager::registerToolProxy(KoToolProxy *proxy, KoCanvasBase *canvas)
00835 {
00836 d->proxies.insert(canvas, proxy);
00837 foreach(KoCanvasController *controller, d->canvasses.keys()) {
00838 if (controller->canvas() == canvas) {
00839 proxy->setCanvasController(controller);
00840 break;
00841 }
00842 }
00843 }
00844
00845 void KoToolManager::injectDeviceEvent(KoDeviceEvent * event)
00846 {
00847 if (d->canvasData && d->canvasData->canvas->canvas()) {
00848 if (static_cast<KoDeviceEvent::Type>(event->type()) == KoDeviceEvent::ButtonPressed)
00849 d->canvasData->activeTool->customPressEvent(event->pointerEvent());
00850 else if (static_cast<KoDeviceEvent::Type>(event->type()) == KoDeviceEvent::ButtonReleased)
00851 d->canvasData->activeTool->customReleaseEvent(event->pointerEvent());
00852 else if (static_cast<KoDeviceEvent::Type>(event->type()) == KoDeviceEvent::PositionChanged)
00853 d->canvasData->activeTool->customMoveEvent(event->pointerEvent());
00854 }
00855 }
00856
00857 KoToolManager* KoToolManager::instance()
00858 {
00859 K_GLOBAL_STATIC(KoToolManager, s_instance)
00860 return s_instance;
00861 }
00862
00863 QString KoToolManager::activeToolId() const
00864 {
00865 if (!d->canvasData) return QString();
00866 return d->canvasData->activeToolId;
00867 }
00868
00869 #include "KoToolManager.moc"