File indexing completed on 2024-05-12 15:56:51
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 0034 KoToolBase::KoToolBase(KoCanvasBase *canvas) 0035 : d_ptr(new KoToolBasePrivate(this, canvas)) 0036 { 0037 Q_D(KoToolBase); 0038 d->connectSignals(); 0039 } 0040 0041 KoToolBase::KoToolBase(KoToolBasePrivate &dd) 0042 : d_ptr(&dd) 0043 { 0044 Q_D(KoToolBase); 0045 d->connectSignals(); 0046 } 0047 0048 KoToolBase::~KoToolBase() 0049 { 0050 qDeleteAll(d_ptr->optionWidgets); 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 KoViewConverter &) const 0128 { 0129 Q_D(const KoToolBase); 0130 if (d->canvas->canvasWidget() == 0) 0131 return QVariant(); 0132 0133 switch (query) { 0134 case Qt::ImMicroFocus: 0135 return QRect(d->canvas->canvasWidget()->width() / 2, 0, 1, d->canvas->canvasWidget()->height()); 0136 case Qt::ImFont: 0137 return d->canvas->canvasWidget()->font(); 0138 default: 0139 return QVariant(); 0140 } 0141 } 0142 0143 void KoToolBase::inputMethodEvent(QInputMethodEvent * event) 0144 { 0145 if (! event->commitString().isEmpty()) { 0146 QKeyEvent ke(QEvent::KeyPress, -1, QFlags<Qt::KeyboardModifier>(), event->commitString()); 0147 keyPressEvent(&ke); 0148 } 0149 event->accept(); 0150 } 0151 0152 void KoToolBase::customPressEvent(KoPointerEvent * event) 0153 { 0154 event->ignore(); 0155 } 0156 0157 void KoToolBase::customReleaseEvent(KoPointerEvent * event) 0158 { 0159 event->ignore(); 0160 } 0161 0162 void KoToolBase::customMoveEvent(KoPointerEvent * event) 0163 { 0164 event->ignore(); 0165 } 0166 0167 void KoToolBase::useCursor(const QCursor &cursor) 0168 { 0169 Q_D(KoToolBase); 0170 d->currentCursor = cursor; 0171 emit cursorChanged(d->currentCursor); 0172 } 0173 0174 QList<QPointer<QWidget> > KoToolBase::optionWidgets() 0175 { 0176 Q_D(KoToolBase); 0177 if (!d->optionWidgetsCreated) { 0178 d->optionWidgets = createOptionWidgets(); 0179 d->optionWidgetsCreated = true; 0180 } 0181 return d->optionWidgets; 0182 } 0183 0184 QAction *KoToolBase::action(const QString &name) const 0185 { 0186 Q_D(const KoToolBase); 0187 if (d->canvas && d->canvas->canvasController() && d->canvas->canvasController()) { 0188 return d->canvas->canvasController()->actionCollection()->action(name); 0189 } 0190 return 0; 0191 } 0192 0193 QWidget * KoToolBase::createOptionWidget() 0194 { 0195 return 0; 0196 } 0197 0198 QList<QPointer<QWidget> > KoToolBase::createOptionWidgets() 0199 { 0200 QList<QPointer<QWidget> > ow; 0201 if (QWidget *widget = createOptionWidget()) { 0202 if (widget->objectName().isEmpty()) { 0203 widget->setObjectName(toolId()); 0204 } 0205 ow.append(widget); 0206 } 0207 return ow; 0208 } 0209 0210 void KoToolBase::setFactory(KoToolFactoryBase *factory) 0211 { 0212 Q_D(KoToolBase); 0213 d->factory = factory; 0214 } 0215 0216 KoToolFactoryBase* KoToolBase::factory() const 0217 { 0218 Q_D(const KoToolBase); 0219 return d->factory; 0220 } 0221 0222 QString KoToolBase::toolId() const 0223 { 0224 Q_D(const KoToolBase); 0225 return d->factory ? d->factory->id() : 0; 0226 } 0227 0228 QCursor KoToolBase::cursor() const 0229 { 0230 Q_D(const KoToolBase); 0231 return d->currentCursor; 0232 } 0233 0234 void KoToolBase::deleteSelection() 0235 { 0236 } 0237 0238 void KoToolBase::cut() 0239 { 0240 copy(); 0241 deleteSelection(); 0242 } 0243 0244 KoCanvasBase * KoToolBase::canvas() const 0245 { 0246 Q_D(const KoToolBase); 0247 return d->canvas; 0248 } 0249 0250 void KoToolBase::setStatusText(const QString &statusText) 0251 { 0252 emit statusTextChanged(statusText); 0253 } 0254 0255 int KoToolBase::handleRadius() const 0256 { 0257 Q_D(const KoToolBase); 0258 if (d->canvas 0259 && d->canvas->shapeController() 0260 && d->canvas->shapeController()->resourceManager() 0261 ) 0262 { 0263 return d->canvas->shapeController()->resourceManager()->handleRadius(); 0264 } 0265 else { 0266 return 3; 0267 } 0268 } 0269 0270 qreal KoToolBase::handleDocRadius() const 0271 { 0272 Q_D(const KoToolBase); 0273 const KoViewConverter * converter = d->canvas->viewConverter(); 0274 const QPointF doc = converter->viewToDocument(QPointF(handleRadius(), handleRadius())); 0275 return qMax(doc.x(), doc.y()); 0276 } 0277 0278 int KoToolBase::grabSensitivity() const 0279 { 0280 Q_D(const KoToolBase); 0281 if(d->canvas->shapeController()->resourceManager()) 0282 { 0283 return d->canvas->shapeController()->resourceManager()->grabSensitivity(); 0284 } else { 0285 return 3; 0286 } 0287 } 0288 0289 QRectF KoToolBase::handleGrabRect(const QPointF &position) const 0290 { 0291 Q_D(const KoToolBase); 0292 const KoViewConverter * converter = d->canvas->viewConverter(); 0293 uint handleSize = 2*grabSensitivity(); 0294 QRectF r = converter->viewToDocument(QRectF(0, 0, handleSize, handleSize)); 0295 r.moveCenter(position); 0296 return r; 0297 } 0298 0299 QRectF KoToolBase::handlePaintRect(const QPointF &position) const 0300 { 0301 Q_D(const KoToolBase); 0302 const KoViewConverter * converter = d->canvas->viewConverter(); 0303 uint handleSize = 2*handleRadius(); 0304 QRectF r = converter->viewToDocument(QRectF(0, 0, handleSize, handleSize)); 0305 r.moveCenter(position); 0306 return r; 0307 } 0308 0309 void KoToolBase::setTextMode(bool value) 0310 { 0311 Q_D(KoToolBase); 0312 d->isInTextMode=value; 0313 } 0314 0315 bool KoToolBase::paste() 0316 { 0317 return false; 0318 } 0319 0320 void KoToolBase::copy() const 0321 { 0322 } 0323 0324 void KoToolBase::dragMoveEvent(QDragMoveEvent *event, const QPointF &point) 0325 { 0326 Q_UNUSED(event); 0327 Q_UNUSED(point); 0328 } 0329 0330 void KoToolBase::dragLeaveEvent(QDragLeaveEvent *event) 0331 { 0332 Q_UNUSED(event); 0333 } 0334 0335 void KoToolBase::dropEvent(QDropEvent *event, const QPointF &point) 0336 { 0337 Q_UNUSED(event); 0338 Q_UNUSED(point); 0339 } 0340 0341 bool KoToolBase::hasSelection() 0342 { 0343 KoToolSelection *sel = selection(); 0344 return (sel && sel->hasSelection()); 0345 } 0346 0347 KoToolSelection *KoToolBase::selection() 0348 { 0349 return 0; 0350 } 0351 0352 void KoToolBase::repaintDecorations() 0353 { 0354 Q_D(KoToolBase); 0355 0356 QRectF dirtyRect = d->lastDecorationsRect; 0357 d->lastDecorationsRect = decorationsRect(); 0358 dirtyRect |= d->lastDecorationsRect; 0359 0360 if (!dirtyRect.isEmpty()) { 0361 canvas()->updateCanvas(dirtyRect); 0362 } 0363 } 0364 0365 QRectF KoToolBase::decorationsRect() const 0366 { 0367 return QRectF(); 0368 } 0369 0370 bool KoToolBase::isInTextMode() const 0371 { 0372 Q_D(const KoToolBase); 0373 return d->isInTextMode; 0374 } 0375 0376 void KoToolBase::requestUndoDuringStroke() 0377 { 0378 /** 0379 * Default implementation just cancels the stroke 0380 */ 0381 requestStrokeCancellation(); 0382 } 0383 0384 0385 void KoToolBase::requestRedoDuringStroke() 0386 { 0387 } 0388 0389 void KoToolBase::requestStrokeCancellation() 0390 { 0391 } 0392 0393 void KoToolBase::requestStrokeEnd() 0394 { 0395 } 0396 0397 bool KoToolBase::maskSyntheticEvents() const 0398 { 0399 Q_D(const KoToolBase); 0400 return d->maskSyntheticEvents; 0401 } 0402 0403 void KoToolBase::setMaskSyntheticEvents(bool value) 0404 { 0405 Q_D(KoToolBase); 0406 d->maskSyntheticEvents = value; 0407 } 0408 0409 void KoToolBase::updateOptionsWidgetIcons() 0410 { 0411 Q_D(KoToolBase); 0412 if (d->optionWidgetsCreated) { 0413 QObjectList objects; 0414 for (QPointer<QWidget> widget : d->optionWidgets) { 0415 objects.append(widget); 0416 } 0417 while (!objects.isEmpty()) { 0418 QObject* object = objects.takeFirst(); 0419 objects.append(object->children()); 0420 KisIconUtils::updateIconCommon(object); 0421 } 0422 } 0423 }