File indexing completed on 2024-05-19 04:24:59
0001 /* This file is part of the KDE project 0002 * SPDX-FileCopyrightText: 2006, 2010 Thomas Zander <zander@kde.org> 0003 * SPDX-FileCopyrightText: 2011 Jan Hambrecht <jaham@gmx.net> 0004 * 0005 * SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #include <QDebug> 0009 0010 #include <QAction> 0011 0012 #include "KoToolBase.h" 0013 #include "KoToolBase_p.h" 0014 #include "KoToolFactoryBase.h" 0015 #include "KoCanvasBase.h" 0016 #include "KoPointerEvent.h" 0017 #include "KoDocumentResourceManager.h" 0018 #include "KoCanvasResourceProvider.h" 0019 #include "KoViewConverter.h" 0020 #include "KoShapeController.h" 0021 #include "KoShapeControllerBase.h" 0022 #include "KoToolSelection.h" 0023 #include "KoCanvasController.h" 0024 #include "KoToolProxy.h" 0025 #include <kis_icon_utils.h> 0026 0027 #include <klocalizedstring.h> 0028 #include <kactioncollection.h> 0029 #include <QWidget> 0030 #include <QFile> 0031 #include <QDomDocument> 0032 #include <QDomElement> 0033 #include <QApplication> 0034 0035 KoToolBase::KoToolBase(KoCanvasBase *canvas) 0036 : d_ptr(new KoToolBasePrivate(this, canvas)) 0037 { 0038 Q_D(KoToolBase); 0039 d->connectSignals(); 0040 } 0041 0042 KoToolBase::KoToolBase(KoToolBasePrivate &dd) 0043 : d_ptr(&dd) 0044 { 0045 Q_D(KoToolBase); 0046 d->connectSignals(); 0047 } 0048 0049 KoToolBase::~KoToolBase() 0050 { 0051 delete d_ptr; 0052 } 0053 0054 0055 bool KoToolBase::isActivated() const 0056 { 0057 Q_D(const KoToolBase); 0058 return d->isActivated; 0059 } 0060 0061 KoPointerEvent *KoToolBase::lastDeliveredPointerEvent() const 0062 { 0063 Q_D(const KoToolBase); 0064 0065 if (!d->canvas) return 0; 0066 if (!d->canvas->toolProxy()) return 0; 0067 0068 return d->canvas->toolProxy()->lastDeliveredPointerEvent(); 0069 } 0070 0071 void KoToolBase::activate(const QSet<KoShape *> &shapes) 0072 { 0073 Q_UNUSED(shapes); 0074 0075 Q_D(KoToolBase); 0076 d->isActivated = true; 0077 } 0078 0079 void KoToolBase::deactivate() 0080 { 0081 Q_D(KoToolBase); 0082 d->isActivated = false; 0083 } 0084 0085 void KoToolBase::canvasResourceChanged(int key, const QVariant & res) 0086 { 0087 Q_UNUSED(key); 0088 Q_UNUSED(res); 0089 } 0090 0091 void KoToolBase::documentResourceChanged(int key, const QVariant &res) 0092 { 0093 Q_UNUSED(key); 0094 Q_UNUSED(res); 0095 } 0096 0097 bool KoToolBase::wantsAutoScroll() const 0098 { 0099 return true; 0100 } 0101 0102 void KoToolBase::mouseDoubleClickEvent(KoPointerEvent *event) 0103 { 0104 event->ignore(); 0105 } 0106 0107 void KoToolBase::mouseTripleClickEvent(KoPointerEvent *event) 0108 { 0109 event->ignore(); 0110 } 0111 0112 void KoToolBase::keyPressEvent(QKeyEvent *e) 0113 { 0114 e->ignore(); 0115 } 0116 0117 void KoToolBase::keyReleaseEvent(QKeyEvent *e) 0118 { 0119 e->ignore(); 0120 } 0121 0122 0123 void KoToolBase::explicitUserStrokeEndRequest() 0124 { 0125 } 0126 0127 QVariant KoToolBase::inputMethodQuery(Qt::InputMethodQuery query) const 0128 { 0129 Q_D(const KoToolBase); 0130 if (d->canvas->canvasWidget() == 0) 0131 return QVariant(); 0132 0133 switch (query) { 0134 case Qt::ImEnabled: 0135 return isInTextMode(); 0136 case Qt::ImCursorRectangle: 0137 return QRect(d->canvas->canvasWidget()->width() / 2, 0, 1, d->canvas->canvasWidget()->height()); 0138 case Qt::ImFont: 0139 return d->canvas->canvasWidget()->font(); 0140 default: 0141 return QVariant(); 0142 } 0143 } 0144 0145 void KoToolBase::inputMethodEvent(QInputMethodEvent * event) 0146 { 0147 if (! event->commitString().isEmpty()) { 0148 QKeyEvent ke(QEvent::KeyPress, -1, QFlags<Qt::KeyboardModifier>(), event->commitString()); 0149 keyPressEvent(&ke); 0150 } 0151 event->accept(); 0152 } 0153 0154 void KoToolBase::focusInEvent(QFocusEvent *event) 0155 { 0156 event->ignore(); 0157 } 0158 0159 void KoToolBase::focusOutEvent(QFocusEvent *event) 0160 { 0161 event->ignore(); 0162 } 0163 0164 void KoToolBase::customPressEvent(KoPointerEvent * event) 0165 { 0166 event->ignore(); 0167 } 0168 0169 void KoToolBase::customReleaseEvent(KoPointerEvent * event) 0170 { 0171 event->ignore(); 0172 } 0173 0174 void KoToolBase::customMoveEvent(KoPointerEvent * event) 0175 { 0176 event->ignore(); 0177 } 0178 0179 void KoToolBase::useCursor(const QCursor &cursor) 0180 { 0181 Q_D(KoToolBase); 0182 d->currentCursor = cursor; 0183 emit cursorChanged(d->currentCursor); 0184 } 0185 0186 QList<QPointer<QWidget> > KoToolBase::optionWidgets() 0187 { 0188 Q_D(KoToolBase); 0189 if (!d->optionWidgetsCreated) { 0190 d->optionWidgets = createOptionWidgets(); 0191 d->optionWidgetsCreated = true; 0192 } 0193 return d->optionWidgets; 0194 } 0195 0196 QAction *KoToolBase::action(const QString &name) const 0197 { 0198 Q_D(const KoToolBase); 0199 if (d->canvas && d->canvas->canvasController() && d->canvas->canvasController()) { 0200 return d->canvas->canvasController()->actionCollection()->action(name); 0201 } 0202 return 0; 0203 } 0204 0205 QWidget * KoToolBase::createOptionWidget() 0206 { 0207 return 0; 0208 } 0209 0210 QList<QPointer<QWidget> > KoToolBase::createOptionWidgets() 0211 { 0212 QList<QPointer<QWidget> > ow; 0213 if (QWidget *widget = createOptionWidget()) { 0214 if (widget->objectName().isEmpty()) { 0215 widget->setObjectName(toolId()); 0216 } 0217 ow.append(widget); 0218 } 0219 return ow; 0220 } 0221 0222 void KoToolBase::setFactory(KoToolFactoryBase *factory) 0223 { 0224 Q_D(KoToolBase); 0225 d->factory = factory; 0226 } 0227 0228 KoToolFactoryBase* KoToolBase::factory() const 0229 { 0230 Q_D(const KoToolBase); 0231 return d->factory; 0232 } 0233 0234 QString KoToolBase::toolId() const 0235 { 0236 Q_D(const KoToolBase); 0237 return d->factory ? d->factory->id() : 0; 0238 } 0239 0240 QCursor KoToolBase::cursor() const 0241 { 0242 Q_D(const KoToolBase); 0243 return d->currentCursor; 0244 } 0245 0246 void KoToolBase::deleteSelection() 0247 { 0248 } 0249 0250 void KoToolBase::cut() 0251 { 0252 copy(); 0253 deleteSelection(); 0254 } 0255 0256 KoCanvasBase * KoToolBase::canvas() const 0257 { 0258 Q_D(const KoToolBase); 0259 return d->canvas; 0260 } 0261 0262 void KoToolBase::setStatusText(const QString &statusText) 0263 { 0264 emit statusTextChanged(statusText); 0265 } 0266 0267 int KoToolBase::handleRadius() const 0268 { 0269 Q_D(const KoToolBase); 0270 if (d->canvas 0271 && d->canvas->resourceManager() 0272 ) 0273 { 0274 return d->canvas->resourceManager()->handleRadius(); 0275 } 0276 else { 0277 return 3; 0278 } 0279 } 0280 0281 qreal KoToolBase::handleDocRadius() const 0282 { 0283 Q_D(const KoToolBase); 0284 const KoViewConverter * converter = d->canvas->viewConverter(); 0285 const QPointF doc = converter->viewToDocument(QPointF(handleRadius(), handleRadius())); 0286 return qMax(doc.x(), doc.y()); 0287 } 0288 0289 int KoToolBase::decorationThickness() const 0290 { 0291 Q_D(const KoToolBase); 0292 if (d->canvas 0293 && d->canvas->resourceManager() 0294 ) 0295 { 0296 return d->canvas->resourceManager()->decorationThickness(); 0297 } 0298 else { 0299 return 1; 0300 } 0301 } 0302 0303 int KoToolBase::grabSensitivity() const 0304 { 0305 Q_D(const KoToolBase); 0306 if(d->canvas->shapeController()->resourceManager()) 0307 { 0308 return d->canvas->shapeController()->resourceManager()->grabSensitivity(); 0309 } else { 0310 return 3; 0311 } 0312 } 0313 0314 QRectF KoToolBase::handleGrabRect(const QPointF &position) const 0315 { 0316 Q_D(const KoToolBase); 0317 const KoViewConverter * converter = d->canvas->viewConverter(); 0318 uint handleSize = 2*grabSensitivity(); 0319 QRectF r = converter->viewToDocument(QRectF(0, 0, handleSize, handleSize)); 0320 r.moveCenter(position); 0321 return r; 0322 } 0323 0324 QRectF KoToolBase::handlePaintRect(const QPointF &position) const 0325 { 0326 Q_D(const KoToolBase); 0327 const KoViewConverter * converter = d->canvas->viewConverter(); 0328 uint handleSize = 2*handleRadius(); 0329 QRectF r = converter->viewToDocument(QRectF(0, 0, handleSize, handleSize)); 0330 r.moveCenter(position); 0331 return r; 0332 } 0333 0334 void KoToolBase::setTextMode(bool value) 0335 { 0336 Q_D(KoToolBase); 0337 d->isInTextMode = value; 0338 qApp->inputMethod()->update(Qt::ImEnabled); 0339 emit textModeChanged(d->isInTextMode); 0340 } 0341 0342 bool KoToolBase::paste() 0343 { 0344 return false; 0345 } 0346 0347 bool KoToolBase::selectAll() 0348 { 0349 return false; 0350 } 0351 0352 void KoToolBase::deselect() 0353 { 0354 } 0355 0356 void KoToolBase::copy() const 0357 { 0358 } 0359 0360 void KoToolBase::dragMoveEvent(QDragMoveEvent *event, const QPointF &point) 0361 { 0362 Q_UNUSED(event); 0363 Q_UNUSED(point); 0364 } 0365 0366 void KoToolBase::dragLeaveEvent(QDragLeaveEvent *event) 0367 { 0368 Q_UNUSED(event); 0369 } 0370 0371 void KoToolBase::dropEvent(QDropEvent *event, const QPointF &point) 0372 { 0373 Q_UNUSED(event); 0374 Q_UNUSED(point); 0375 } 0376 0377 bool KoToolBase::hasSelection() 0378 { 0379 KoToolSelection *sel = selection(); 0380 return (sel && sel->hasSelection()); 0381 } 0382 0383 KoToolSelection *KoToolBase::selection() 0384 { 0385 return 0; 0386 } 0387 0388 void KoToolBase::repaintDecorations() 0389 { 0390 Q_D(KoToolBase); 0391 0392 QRectF dirtyRect = d->lastDecorationsRect; 0393 d->lastDecorationsRect = decorationsRect(); 0394 dirtyRect |= d->lastDecorationsRect; 0395 0396 if (!dirtyRect.isEmpty()) { 0397 canvas()->updateCanvas(dirtyRect); 0398 } 0399 } 0400 0401 QRectF KoToolBase::decorationsRect() const 0402 { 0403 return QRectF(); 0404 } 0405 0406 bool KoToolBase::isInTextMode() const 0407 { 0408 Q_D(const KoToolBase); 0409 return d->isInTextMode; 0410 } 0411 0412 void KoToolBase::requestUndoDuringStroke() 0413 { 0414 /** 0415 * Default implementation just cancels the stroke 0416 */ 0417 requestStrokeCancellation(); 0418 } 0419 0420 0421 void KoToolBase::requestRedoDuringStroke() 0422 { 0423 } 0424 0425 void KoToolBase::requestStrokeCancellation() 0426 { 0427 } 0428 0429 void KoToolBase::requestStrokeEnd() 0430 { 0431 } 0432 0433 bool KoToolBase::maskSyntheticEvents() const 0434 { 0435 Q_D(const KoToolBase); 0436 return d->maskSyntheticEvents; 0437 } 0438 0439 void KoToolBase::setMaskSyntheticEvents(bool value) 0440 { 0441 Q_D(KoToolBase); 0442 d->maskSyntheticEvents = value; 0443 } 0444 0445 void KoToolBase::updateOptionsWidgetIcons() 0446 { 0447 Q_D(KoToolBase); 0448 if (d->optionWidgetsCreated) { 0449 QObjectList objects; 0450 Q_FOREACH (QPointer<QWidget> widget, d->optionWidgets) { 0451 objects.append(widget); 0452 } 0453 while (!objects.isEmpty()) { 0454 QObject* object = objects.takeFirst(); 0455 objects.append(object->children()); 0456 KisIconUtils::updateIconCommon(object); 0457 } 0458 } 0459 }