File indexing completed on 2024-05-26 04:26:41
0001 /* This file is part of the KDE project 0002 0003 SPDX-FileCopyrightText: 2006-2007, 2010 Thomas Zander <zander@kde.org> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #include "KoInteractionTool.h" 0009 #include "KoInteractionTool_p.h" 0010 #include "KoToolBase_p.h" 0011 #include "KoPointerEvent.h" 0012 #include "KoCanvasBase.h" 0013 0014 #include "kis_global.h" 0015 #include "kis_assert.h" 0016 0017 0018 KoInteractionTool::KoInteractionTool(KoCanvasBase *canvas) 0019 : KoToolBase(*(new KoInteractionToolPrivate(this, canvas))) 0020 { 0021 } 0022 0023 KoInteractionTool::~KoInteractionTool() 0024 { 0025 } 0026 0027 void KoInteractionTool::paint(QPainter &painter, const KoViewConverter &converter) 0028 { 0029 Q_D(KoInteractionTool); 0030 0031 if (d->currentStrategy) { 0032 d->currentStrategy->paint(painter, converter); 0033 } else { 0034 Q_FOREACH (KoInteractionStrategyFactorySP factory, d->interactionFactories) { 0035 // skip the rest of rendering if the factory asks for it 0036 if (factory->paintOnHover(painter, converter)) break; 0037 } 0038 } 0039 } 0040 0041 void KoInteractionTool::mousePressEvent(KoPointerEvent *event) 0042 { 0043 Q_D(KoInteractionTool); 0044 if (d->currentStrategy) { // possible if the user presses an extra mouse button 0045 cancelCurrentStrategy(); 0046 return; 0047 } 0048 d->currentStrategy = createStrategyBase(event); 0049 if (d->currentStrategy == 0) 0050 event->ignore(); 0051 } 0052 0053 void KoInteractionTool::mouseMoveEvent(KoPointerEvent *event) 0054 { 0055 Q_D(KoInteractionTool); 0056 d->lastPoint = event->point; 0057 0058 if (d->currentStrategy) { 0059 d->currentStrategy->handleMouseMove(d->lastPoint, event->modifiers()); 0060 } else { 0061 Q_FOREACH (KoInteractionStrategyFactorySP factory, d->interactionFactories) { 0062 // skip the rest of rendering if the factory asks for it 0063 if (factory->hoverEvent(event)) return; 0064 } 0065 0066 event->ignore(); 0067 } 0068 } 0069 0070 void KoInteractionTool::mouseReleaseEvent(KoPointerEvent *event) 0071 { 0072 Q_D(KoInteractionTool); 0073 if (d->currentStrategy) { 0074 d->currentStrategy->finishInteraction(event->modifiers()); 0075 KUndo2Command *command = d->currentStrategy->createCommand(); 0076 if (command) 0077 d->canvas->addCommand(command); 0078 delete d->currentStrategy; 0079 d->currentStrategy = 0; 0080 repaintDecorations(); 0081 } else 0082 event->ignore(); 0083 } 0084 0085 void KoInteractionTool::keyPressEvent(QKeyEvent *event) 0086 { 0087 Q_D(KoInteractionTool); 0088 event->ignore(); 0089 if (d->currentStrategy && 0090 (event->key() == Qt::Key_Control || 0091 event->key() == Qt::Key_Alt || event->key() == Qt::Key_Shift || 0092 event->key() == Qt::Key_Meta)) { 0093 d->currentStrategy->handleMouseMove(d->lastPoint, event->modifiers()); 0094 event->accept(); 0095 } 0096 } 0097 0098 void KoInteractionTool::keyReleaseEvent(QKeyEvent *event) 0099 { 0100 Q_D(KoInteractionTool); 0101 0102 if (!d->currentStrategy) { 0103 KoToolBase::keyReleaseEvent(event); 0104 return; 0105 } 0106 0107 if (event->key() == Qt::Key_Escape) { 0108 cancelCurrentStrategy(); 0109 event->accept(); 0110 } else if (event->key() == Qt::Key_Control || 0111 event->key() == Qt::Key_Alt || event->key() == Qt::Key_Shift || 0112 event->key() == Qt::Key_Meta) { 0113 d->currentStrategy->handleMouseMove(d->lastPoint, event->modifiers()); 0114 } 0115 } 0116 0117 KoInteractionStrategy *KoInteractionTool::currentStrategy() 0118 { 0119 Q_D(KoInteractionTool); 0120 return d->currentStrategy; 0121 } 0122 0123 void KoInteractionTool::cancelCurrentStrategy() 0124 { 0125 Q_D(KoInteractionTool); 0126 if (d->currentStrategy) { 0127 d->currentStrategy->cancelInteraction(); 0128 delete d->currentStrategy; 0129 d->currentStrategy = 0; 0130 } 0131 } 0132 0133 KoInteractionStrategy *KoInteractionTool::createStrategyBase(KoPointerEvent *event) 0134 { 0135 Q_D(KoInteractionTool); 0136 0137 Q_FOREACH (KoInteractionStrategyFactorySP factory, d->interactionFactories) { 0138 KoInteractionStrategy *strategy = factory->createStrategy(event); 0139 if (strategy) { 0140 return strategy; 0141 } 0142 } 0143 0144 return createStrategy(event); 0145 } 0146 0147 void KoInteractionTool::addInteractionFactory(KoInteractionStrategyFactory *factory) 0148 { 0149 Q_D(KoInteractionTool); 0150 0151 Q_FOREACH (auto f, d->interactionFactories) { 0152 KIS_SAFE_ASSERT_RECOVER_RETURN(f->id() != factory->id()); 0153 } 0154 0155 d->interactionFactories.append(toQShared(factory)); 0156 std::sort(d->interactionFactories.begin(), 0157 d->interactionFactories.end(), 0158 KoInteractionStrategyFactory::compareLess); 0159 } 0160 0161 void KoInteractionTool::removeInteractionFactory(const QString &id) 0162 { 0163 Q_D(KoInteractionTool); 0164 QList<KoInteractionStrategyFactorySP>::iterator it = 0165 d->interactionFactories.begin(); 0166 0167 while (it != d->interactionFactories.end()) { 0168 if ((*it)->id() == id) { 0169 it = d->interactionFactories.erase(it); 0170 } else { 0171 ++it; 0172 } 0173 } 0174 } 0175 0176 bool KoInteractionTool::hasInteractionFactory(const QString &id) 0177 { 0178 Q_D(KoInteractionTool); 0179 0180 Q_FOREACH (auto f, d->interactionFactories) { 0181 if (f->id() == id) { 0182 return true; 0183 } 0184 } 0185 0186 return false; 0187 } 0188 0189 bool KoInteractionTool::tryUseCustomCursor() 0190 { 0191 Q_D(KoInteractionTool); 0192 0193 Q_FOREACH (auto f, d->interactionFactories) { 0194 if (f->tryUseCustomCursor()) { 0195 return true; 0196 } 0197 } 0198 0199 return false; 0200 } 0201 0202 KoInteractionTool::KoInteractionTool(KoInteractionToolPrivate &dd) 0203 : KoToolBase(dd) 0204 { 0205 }