Warning, file /office/calligra/libs/flake/KoToolProxy.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  * Copyright (C) 2006-2007 Thomas Zander <zander@kde.org>
0003  * Copyright (c) 2006-2011 Boudewijn Rempt <boud@valdyas.org>
0004  *
0005  * This library is free software; you can redistribute it and/or
0006  * modify it under the terms of the GNU Library General Public
0007  * License as published by the Free Software Foundation; either
0008  * version 2 of the License, or (at your option) any later version.
0009  *
0010  * This library is distributed in the hope that it will be useful,
0011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0013  * Library General Public License for more details.
0014  *
0015  * You should have received a copy of the GNU Library General Public License
0016  * along with this library; see the file COPYING.LIB.  If not, write to
0017  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0018  * Boston, MA 02110-1301, USA.
0019  */
0020 #include "KoToolProxy.h"
0021 #include "KoToolProxy_p.h"
0022 
0023 #include "KoToolBase.h"
0024 #include "KoPointerEvent.h"
0025 #include "KoInputDevice.h"
0026 #include "KoToolManager_p.h"
0027 #include "KoToolSelection.h"
0028 #include "KoCanvasBase.h"
0029 #include "KoCanvasController.h"
0030 #include "KoShapeManager.h"
0031 #include "KoSelection.h"
0032 #include "KoShapeLayer.h"
0033 #include "KoShapePaste.h"
0034 #include "KoShapeRegistry.h"
0035 #include "KoShapeController.h"
0036 #include "KoOdf.h"
0037 #include "FlakeDebug.h"
0038 
0039 #include <kundo2command.h>
0040 #include <KoProperties.h>
0041 #include <KoNetAccess.h>
0042 
0043 #include <klocalizedstring.h>
0044 #include <kmessagebox.h>
0045 
0046 #include <QUrl>
0047 #include <QTimer>
0048 #include <QApplication>
0049 #include <QTouchEvent>
0050 #include <QClipboard>
0051 
0052 
0053 KoToolProxyPrivate::KoToolProxyPrivate(KoToolProxy *p)
0054     : activeTool(0),
0055     tabletPressed(false),
0056     hasSelection(false),
0057     controller(0),
0058     parent(p)
0059 {
0060     scrollTimer.setInterval(100);
0061     mouseLeaveWorkaround = false;
0062     multiClickCount = 0;
0063 }
0064 
0065 void KoToolProxyPrivate::timeout() // Auto scroll the canvas
0066 {
0067     Q_ASSERT(controller);
0068 
0069     QPoint offset = QPoint(controller->canvasOffsetX(), controller->canvasOffsetY());
0070     QPoint origin = controller->canvas()->documentOrigin();
0071     QPoint viewPoint = widgetScrollPoint - origin - offset;
0072 
0073     QRectF mouseArea(viewPoint, QSizeF(10, 10));
0074     mouseArea.setTopLeft(mouseArea.center());
0075 
0076     controller->ensureVisible(mouseArea, true);
0077 
0078     QPoint newOffset = QPoint(controller->canvasOffsetX(), controller->canvasOffsetY());
0079 
0080     QPoint moved = offset - newOffset;
0081     if (moved.isNull())
0082         return;
0083 
0084     widgetScrollPoint += moved;
0085 
0086     QPointF documentPoint = parent->widgetToDocument(widgetScrollPoint);
0087     QMouseEvent event(QEvent::MouseMove, widgetScrollPoint, Qt::LeftButton, Qt::LeftButton, 0);
0088     KoPointerEvent ev(&event, documentPoint);
0089     activeTool->mouseMoveEvent(&ev);
0090 }
0091 
0092 void KoToolProxyPrivate::checkAutoScroll(const KoPointerEvent &event)
0093 {
0094     if (controller == 0) return;
0095     if (!activeTool) return;
0096     if (!activeTool->wantsAutoScroll()) return;
0097     if (!event.isAccepted()) return;
0098     if (event.buttons() != Qt::LeftButton) return;
0099 
0100     widgetScrollPoint = event.pos();
0101 
0102     if (! scrollTimer.isActive())
0103         scrollTimer.start();
0104 }
0105 
0106 void KoToolProxyPrivate::selectionChanged(bool newSelection)
0107 {
0108     if (hasSelection == newSelection)
0109         return;
0110     hasSelection = newSelection;
0111     emit parent->selectionChanged(hasSelection);
0112 }
0113 
0114 bool KoToolProxyPrivate::isActiveLayerEditable()
0115 {
0116     if (!activeTool)
0117         return false;
0118 
0119     KoShapeManager * shapeManager = activeTool->canvas()->shapeManager();
0120     KoShapeLayer * activeLayer = shapeManager->selection()->activeLayer();
0121     if (activeLayer && !activeLayer->isEditable())
0122         return false;
0123     return true;
0124 }
0125 
0126 KoToolProxy::KoToolProxy(KoCanvasBase *canvas, QObject *parent)
0127         : QObject(parent),
0128         d(new KoToolProxyPrivate(this))
0129 {
0130     KoToolManager::instance()->priv()->registerToolProxy(this, canvas);
0131 
0132     connect(&d->scrollTimer, SIGNAL(timeout()), this, SLOT(timeout()));
0133 }
0134 
0135 KoToolProxy::~KoToolProxy()
0136 {
0137     delete d;
0138 }
0139 
0140 void KoToolProxy::paint(QPainter &painter, const KoViewConverter &converter)
0141 {
0142     if (d->activeTool) d->activeTool->paint(painter, converter);
0143 }
0144 
0145 void KoToolProxy::repaintDecorations()
0146 {
0147     if (d->activeTool) d->activeTool->repaintDecorations();
0148 }
0149 
0150 
0151 QPointF KoToolProxy::widgetToDocument(const QPointF &widgetPoint) const
0152 {
0153     QPoint offset = QPoint(d->controller->canvasOffsetX(), d->controller->canvasOffsetY());
0154     QPoint origin = d->controller->canvas()->documentOrigin();
0155     QPoint viewPoint = widgetPoint.toPoint() - origin - offset;
0156 
0157     return d->controller->canvas()->viewConverter()->viewToDocument(viewPoint);
0158 }
0159 
0160 KoCanvasBase* KoToolProxy::canvas() const
0161 {
0162     return d->controller->canvas();
0163 }
0164 
0165 void KoToolProxy::touchEvent(QTouchEvent *event)
0166 {
0167     QPointF point;
0168     QVector<KoTouchPoint> touchPoints;
0169 
0170     bool isPrimary = true;
0171     foreach(QTouchEvent::TouchPoint p, event->touchPoints()) {
0172         QPointF docPoint = widgetToDocument(p.screenPos());
0173         if (isPrimary) {
0174             point = docPoint;
0175             isPrimary = false;
0176         }
0177         KoTouchPoint touchPoint;
0178         touchPoint.touchPoint = p;
0179         touchPoint.point = point;
0180         touchPoint.lastPoint = widgetToDocument(p.lastNormalizedPos());
0181         touchPoints << touchPoint;
0182     }
0183 
0184     KoPointerEvent ev(event, point, touchPoints);
0185 
0186     KoInputDevice id;
0187     KoToolManager::instance()->priv()->switchInputDevice(id);
0188 
0189     switch (event->type()) {
0190     case QEvent::TouchBegin:
0191         ev.setTabletButton(Qt::LeftButton);
0192         if (d->activeTool) {
0193             if( d->activeTool->wantsTouch() )
0194                 d->activeTool->touchEvent(event);
0195             else
0196                 d->activeTool->mousePressEvent(&ev);
0197         }
0198         break;
0199     case QEvent::TouchUpdate:
0200         ev.setTabletButton(Qt::LeftButton);
0201         if (d->activeTool) {
0202             if( d->activeTool->wantsTouch() )
0203                 d->activeTool->touchEvent(event);
0204             else
0205                 d->activeTool->mouseMoveEvent(&ev);
0206         }
0207         break;
0208     case QEvent::TouchEnd:
0209         ev.setTabletButton(Qt::LeftButton);
0210         if (d->activeTool) {
0211             if( d->activeTool->wantsTouch() )
0212                 d->activeTool->touchEvent(event);
0213             else
0214                 d->activeTool->mouseReleaseEvent(&ev);
0215         }
0216         break;
0217     default:
0218         ; // ingore the rest
0219     }
0220     d->mouseLeaveWorkaround = true;
0221 
0222 }
0223 
0224 void KoToolProxy::tabletEvent(QTabletEvent *event, const QPointF &point)
0225 {
0226     // don't process tablet events for stylus middle and right mouse button
0227     // they will be re-send as mouse events with the correct button. there is no possibility to get the button from the QTabletEvent.
0228     if(qFuzzyIsNull(event->pressure()) && d->tabletPressed==false && event->type()!=QEvent::TabletMove) {
0229         //debugFlake<<"don't accept tablet event: "<< point;
0230         return;
0231     }
0232     else {
0233         // Accept the tablet events as they are useless to parent widgets and they will
0234         // get re-send as mouseevents if we don't accept them.
0235         //debugFlake<<"accept tablet event: "<< point;
0236         event->accept();
0237     }
0238 
0239     KoInputDevice id(event->device(), event->pointerType(), event->uniqueId());
0240     KoToolManager::instance()->priv()->switchInputDevice(id);
0241 
0242     KoPointerEvent ev(event, point);
0243     switch (event->type()) {
0244     case QEvent::TabletPress:
0245         ev.setTabletButton(Qt::LeftButton);
0246         if (!d->tabletPressed && d->activeTool)
0247             d->activeTool->mousePressEvent(&ev);
0248         d->tabletPressed = true;
0249         break;
0250     case QEvent::TabletRelease:
0251         ev.setTabletButton(Qt::LeftButton);
0252         d->tabletPressed = false;
0253         d->scrollTimer.stop();
0254         if (d->activeTool)
0255             d->activeTool->mouseReleaseEvent(&ev);
0256         break;
0257     case QEvent::TabletMove:
0258         if (d->tabletPressed)
0259             ev.setTabletButton(Qt::LeftButton);
0260         if (d->activeTool)
0261             d->activeTool->mouseMoveEvent(&ev);
0262         d->checkAutoScroll(ev);
0263     default:
0264         ; // ignore the rest.
0265     }
0266 
0267     d->mouseLeaveWorkaround = true;
0268 }
0269 
0270 void KoToolProxy::mousePressEvent(KoPointerEvent *ev)
0271 {
0272     d->mouseLeaveWorkaround = false;
0273     KoInputDevice id;
0274     KoToolManager::instance()->priv()->switchInputDevice(id);
0275     d->mouseDownPoint = ev->pos();
0276 
0277     if (d->tabletPressed) // refuse to send a press unless there was a release first.
0278         return;
0279 
0280     QPointF globalPoint = ev->globalPos();
0281     if (d->multiClickGlobalPoint != globalPoint) {
0282         if (qAbs(globalPoint.x() - d->multiClickGlobalPoint.x()) > 5||
0283             qAbs(globalPoint.y() - d->multiClickGlobalPoint.y()) > 5) {
0284             d->multiClickCount = 0;
0285         }
0286         d->multiClickGlobalPoint = globalPoint;
0287     }
0288 
0289     if (d->multiClickCount && d->multiClickTimeStamp.elapsed() < QApplication::doubleClickInterval() && d->multiClickButton == ev->button()) {
0290         // One more multiclick;
0291         d->multiClickCount++;
0292     } else {
0293         d->multiClickTimeStamp.start();
0294         d->multiClickCount = 1;
0295         d->multiClickButton = ev->button();
0296     }
0297 
0298     if (d->activeTool) {
0299         switch (d->multiClickCount) {
0300         case 0:
0301         case 1:
0302             d->activeTool->mousePressEvent(ev);
0303             break;
0304         case 2:
0305             d->activeTool->mouseDoubleClickEvent(ev);
0306             break;
0307         case 3:
0308         default:
0309             d->activeTool->mouseTripleClickEvent(ev);
0310             break;
0311         }
0312     } else {
0313         d->multiClickCount = 0;
0314         ev->ignore();
0315     }
0316 }
0317 
0318 void KoToolProxy::mousePressEvent(QMouseEvent *event, const QPointF &point)
0319 {
0320     KoPointerEvent ev(event, point);
0321     mousePressEvent(&ev);
0322 }
0323 
0324 void KoToolProxy::mouseDoubleClickEvent(QMouseEvent *event, const QPointF &point)
0325 {
0326     KoPointerEvent ev(event, point);
0327     mouseDoubleClickEvent(&ev);
0328 }
0329 
0330 void KoToolProxy::mouseDoubleClickEvent(KoPointerEvent *event)
0331 {
0332      // let us handle it as any other mousepress (where we then detect multi clicks
0333     mousePressEvent(event);
0334     if (!event->isAccepted() && d->activeTool)
0335         d->activeTool->canvas()->shapeManager()->suggestChangeTool(event);
0336 }
0337 
0338 void KoToolProxy::mouseMoveEvent(QMouseEvent *event, const QPointF &point)
0339 {
0340     if (d->mouseLeaveWorkaround) {
0341         d->mouseLeaveWorkaround = false;
0342         return;
0343     }
0344     KoInputDevice id;
0345     KoToolManager::instance()->priv()->switchInputDevice(id);
0346     if (d->activeTool == 0) {
0347         event->ignore();
0348         return;
0349     }
0350 
0351     KoPointerEvent ev(event, point);
0352     d->activeTool->mouseMoveEvent(&ev);
0353 
0354     d->checkAutoScroll(ev);
0355 }
0356 
0357 void KoToolProxy::mouseMoveEvent(KoPointerEvent *event)
0358 {
0359     if (d->mouseLeaveWorkaround) {
0360         d->mouseLeaveWorkaround = false;
0361         return;
0362     }
0363     KoInputDevice id;
0364     KoToolManager::instance()->priv()->switchInputDevice(id);
0365     if (d->activeTool == 0) {
0366         event->ignore();
0367         return;
0368     }
0369 
0370     d->activeTool->mouseMoveEvent(event);
0371 
0372     d->checkAutoScroll(*event);
0373 }
0374 
0375 void KoToolProxy::mouseReleaseEvent(QMouseEvent *event, const QPointF &point)
0376 {
0377     d->mouseLeaveWorkaround = false;
0378     KoInputDevice id;
0379     KoToolManager::instance()->priv()->switchInputDevice(id);
0380     d->scrollTimer.stop();
0381 
0382     KoPointerEvent ev(event, point);
0383     if (d->activeTool) {
0384         d->activeTool->mouseReleaseEvent(&ev);
0385 
0386         if (! event->isAccepted() && event->button() == Qt::LeftButton && event->modifiers() == 0
0387                 && qAbs(d->mouseDownPoint.x() - event->x()) < 5
0388                 && qAbs(d->mouseDownPoint.y() - event->y()) < 5) {
0389             // we potentially will change the selection
0390             Q_ASSERT(d->activeTool->canvas());
0391             KoShapeManager *manager = d->activeTool->canvas()->shapeManager();
0392             Q_ASSERT(manager);
0393             // only change the selection if that will not lead to losing a complex selection
0394             if (manager->selection()->count() <= 1) {
0395                 KoShape *shape = manager->shapeAt(point);
0396                 if (shape && !manager->selection()->isSelected(shape)) { // make the clicked shape the active one
0397                     manager->selection()->deselectAll();
0398                     manager->selection()->select(shape);
0399                     QList<KoShape*> shapes;
0400                     shapes << shape;
0401                     QString tool = KoToolManager::instance()->preferredToolForSelection(shapes);
0402                     KoToolManager::instance()->switchToolRequested(tool);
0403                 }
0404             }
0405         }
0406     } else {
0407         event->ignore();
0408     }
0409 }
0410 
0411 void KoToolProxy::mouseReleaseEvent(KoPointerEvent* event)
0412 {
0413     d->mouseLeaveWorkaround = false;
0414     KoInputDevice id;
0415     KoToolManager::instance()->priv()->switchInputDevice(id);
0416     d->scrollTimer.stop();
0417 
0418     if (d->activeTool) {
0419         d->activeTool->mouseReleaseEvent(event);
0420 
0421         if (!event->isAccepted() && event->button() == Qt::LeftButton && event->modifiers() == 0
0422                 && qAbs(d->mouseDownPoint.x() - event->x()) < 5
0423                 && qAbs(d->mouseDownPoint.y() - event->y()) < 5) {
0424             // we potentially will change the selection
0425             Q_ASSERT(d->activeTool->canvas());
0426             KoShapeManager *manager = d->activeTool->canvas()->shapeManager();
0427             Q_ASSERT(manager);
0428             // only change the selection if that will not lead to losing a complex selection
0429             if (manager->selection()->count() <= 1) {
0430                 KoShape *shape = manager->shapeAt(event->point);
0431                 if (shape && !manager->selection()->isSelected(shape)) { // make the clicked shape the active one
0432                     manager->selection()->deselectAll();
0433                     manager->selection()->select(shape);
0434                     QList<KoShape*> shapes;
0435                     shapes << shape;
0436                     QString tool = KoToolManager::instance()->preferredToolForSelection(shapes);
0437                     KoToolManager::instance()->switchToolRequested(tool);
0438                 }
0439             }
0440         }
0441     } else {
0442         event->ignore();
0443     }
0444 }
0445 
0446 void KoToolProxy::shortcutOverrideEvent(QKeyEvent *event)
0447 {
0448     if (d->activeTool)
0449         d->activeTool->shortcutOverrideEvent(event);
0450     else
0451         event->ignore();
0452 }
0453 
0454 void KoToolProxy::keyPressEvent(QKeyEvent *event)
0455 {
0456     if (d->activeTool)
0457         d->activeTool->keyPressEvent(event);
0458     else
0459         event->ignore();
0460 }
0461 
0462 void KoToolProxy::keyReleaseEvent(QKeyEvent *event)
0463 {
0464     if (d->activeTool)
0465         d->activeTool->keyReleaseEvent(event);
0466     else
0467         event->ignore();
0468 }
0469 
0470 void KoToolProxy::wheelEvent(QWheelEvent *event, const QPointF &point)
0471 {
0472     KoPointerEvent ev(event, point);
0473     if (d->activeTool)
0474         d->activeTool->wheelEvent(&ev);
0475     else
0476         event->ignore();
0477 }
0478 
0479 void KoToolProxy::wheelEvent(KoPointerEvent *event)
0480 {
0481     if (d->activeTool)
0482         d->activeTool->wheelEvent(event);
0483     else
0484         event->ignore();
0485 }
0486 
0487 QVariant KoToolProxy::inputMethodQuery(Qt::InputMethodQuery query, const KoViewConverter &converter) const
0488 {
0489     if (d->activeTool)
0490         return d->activeTool->inputMethodQuery(query, converter);
0491     return QVariant();
0492 }
0493 
0494 void KoToolProxy::inputMethodEvent(QInputMethodEvent *event)
0495 {
0496     if (d->activeTool) d->activeTool->inputMethodEvent(event);
0497 }
0498 
0499 void KoToolProxy::setActiveTool(KoToolBase *tool)
0500 {
0501     if (d->activeTool)
0502         disconnect(d->activeTool, SIGNAL(selectionChanged(bool)), this, SLOT(selectionChanged(bool)));
0503     d->activeTool = tool;
0504     if (tool) {
0505         connect(d->activeTool, SIGNAL(selectionChanged(bool)), this, SLOT(selectionChanged(bool)));
0506         d->selectionChanged(hasSelection());
0507         emit toolChanged(tool->toolId());
0508     }
0509 }
0510 
0511 void KoToolProxyPrivate::setCanvasController(KoCanvasController *c)
0512 {
0513     controller = c;
0514 }
0515 
0516 QHash<QString, QAction *> KoToolProxy::actions() const
0517 {
0518     return d->activeTool ? d->activeTool->actions() : QHash<QString, QAction *>();
0519 }
0520 
0521 bool KoToolProxy::hasSelection() const
0522 {
0523     return d->activeTool ? d->activeTool->hasSelection() : false;
0524 }
0525 
0526 void KoToolProxy::cut()
0527 {
0528     // TODO maybe move checking the active layer to KoPasteController ?
0529     if (d->activeTool && d->isActiveLayerEditable())
0530         d->activeTool->cut();
0531 }
0532 
0533 void KoToolProxy::copy() const
0534 {
0535     if (d->activeTool)
0536         d->activeTool->copy();
0537 }
0538 
0539 bool KoToolProxy::paste()
0540 {
0541     bool success = false;
0542     KoCanvasBase *canvas = d->controller->canvas();
0543 
0544     // TODO maybe move checking the active layer to KoPasteController ?
0545     if (d->activeTool && d->isActiveLayerEditable())
0546         success = d->activeTool->paste();
0547 
0548     if (!success) {
0549         const QMimeData *data = QApplication::clipboard()->mimeData();
0550 
0551         if (data->hasFormat(KoOdf::mimeType(KoOdf::Text))) {
0552             KoShapeManager *shapeManager = canvas->shapeManager();
0553             KoShapePaste paste(canvas, shapeManager->selection()->activeLayer());
0554             success = paste.paste(KoOdf::Text, data);
0555             if (success) {
0556                 shapeManager->selection()->deselectAll();
0557                 foreach(KoShape *shape, paste.pastedShapes()) {
0558                     shapeManager->selection()->select(shape);
0559                 }
0560             }
0561         }
0562     }
0563 
0564     if (!success) {
0565         const QMimeData *data = QApplication::clipboard()->mimeData();
0566 
0567         QVector<QImage> imageList;
0568 
0569         QImage image = QApplication::clipboard()->image();
0570 
0571         if (!image.isNull()) {
0572             imageList << image;
0573         } else if (data->hasUrls()) {
0574             QList<QUrl> urls = QApplication::clipboard()->mimeData()->urls();
0575             foreach (const QUrl &url, urls) {
0576                 QImage image;
0577                 // make sure we download the files before inserting them
0578                 if (!url.isLocalFile()) {
0579                     QString tmpFile;
0580                     if (KIO::NetAccess::download(url, tmpFile, canvas->canvasWidget())) {
0581                         image.load(tmpFile);
0582                         KIO::NetAccess::removeTempFile(tmpFile);
0583                     } else {
0584                         KMessageBox::error(canvas->canvasWidget(), KIO::NetAccess::lastErrorString());
0585                     }
0586                 }
0587                 else {
0588                     image.load(url.toLocalFile());
0589                 }
0590                 if (!image.isNull()) {
0591                     imageList << image;
0592                 }
0593             }
0594         }
0595 
0596         KoShapeFactoryBase *factory = KoShapeRegistry::instance()->value("PictureShape");
0597         QWidget *canvasWidget = canvas->canvasWidget();
0598         const KoViewConverter *converter = canvas->viewConverter();
0599         if (imageList.length() > 0 && factory && canvasWidget) {
0600             KUndo2Command *cmd = new KUndo2Command(kundo2_i18n("Paste Image"));
0601             foreach(const QImage &image, imageList) {
0602                 if (!image.isNull()) {
0603                     QPointF p = converter->viewToDocument(canvasWidget->mapFromGlobal(QCursor::pos()) + canvas->canvasController()->documentOffset()- canvasWidget->pos());
0604                     KoProperties params;
0605                     params.setProperty("qimage", image);
0606 
0607                     KoShape *shape = factory->createShape(&params, canvas->shapeController()->resourceManager());
0608                     shape->setPosition(p);
0609 
0610                     // add shape to the document
0611                     canvas->shapeController()->addShapeDirect(shape, cmd);
0612 
0613                     success = true;
0614                 }
0615             }
0616             canvas->addCommand(cmd);
0617         }
0618     }
0619     return success;
0620 }
0621 
0622 void KoToolProxy::dragMoveEvent(QDragMoveEvent *event, const QPointF &point)
0623 {
0624     if (d->activeTool)
0625         d->activeTool->dragMoveEvent(event, point);
0626 }
0627 
0628 void KoToolProxy::dragLeaveEvent(QDragLeaveEvent *event)
0629 {
0630     if (d->activeTool)
0631         d->activeTool->dragLeaveEvent(event);
0632 }
0633 
0634 void KoToolProxy::dropEvent(QDropEvent *event, const QPointF &point)
0635 {
0636     if (d->activeTool)
0637         d->activeTool->dropEvent(event, point);
0638 }
0639 
0640 QStringList KoToolProxy::supportedPasteMimeTypes() const
0641 {
0642     if (d->activeTool)
0643         return d->activeTool->supportedPasteMimeTypes();
0644 
0645     return QStringList();
0646 }
0647 
0648 QList<QAction*> KoToolProxy::popupActionList() const
0649 {
0650     if (d->activeTool)
0651         return d->activeTool->popupActionList();
0652     return QList<QAction*>();
0653 }
0654 
0655 void KoToolProxy::deleteSelection()
0656 {
0657     if (d->activeTool)
0658         return d->activeTool->deleteSelection();
0659 }
0660 
0661 void KoToolProxy::processEvent(QEvent *e)
0662 {
0663     if (e->type()==QEvent::ShortcutOverride) {
0664         QKeyEvent *kev = static_cast<QKeyEvent *>(e);
0665         if (d->activeTool
0666                 && d->activeTool->isInTextMode()
0667                 && (kev->modifiers()==Qt::NoModifier ||
0668                     kev->modifiers()==Qt::ShiftModifier)) {
0669             e->accept();
0670         }
0671         shortcutOverrideEvent(kev);
0672     }
0673 }
0674 
0675 KoToolProxyPrivate *KoToolProxy::priv()
0676 {
0677     return d;
0678 }
0679 
0680 //have to include this because of Q_PRIVATE_SLOT
0681 #include "moc_KoToolProxy.cpp"