krita

kis_tool_manager.cc

00001 /*
00002  *  Copyright (c) 2005 Boudewijn Rempt <boud@valdyas.org>
00003  *
00004  *  This program is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; either version 2 of the License, or
00007  *  (at your option) any later version.
00008  *
00009  *  This program is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *  GNU General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU General Public License
00015  *  along with this program; if not, write to the Free Software
00016  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  */
00018 #include "kopalettemanager.h"
00019 
00020 #include "kis_part_layer.h"
00021 #include "kis_tool_manager.h"
00022 #include "kis_tool_registry.h"
00023 #include "kis_tool_dummy.h"
00024 #include "kis_canvas_subject.h"
00025 #include "kis_tool_controller.h"
00026 #include "kis_view.h"
00027 #include "kis_canvas.h"
00028 #include "kis_cursor.h"
00029 #include "KoToolBox.h"
00030 #include "kis_image.h"
00031 #include "kis_layer.h"
00032 #include "kis_input_device.h"
00033 
00034 
00035 KisToolManager::KisToolManager(KisCanvasSubject * parent, KisCanvasController * controller)
00036     : m_subject(parent),
00037       m_controller(controller)
00038 {
00039     m_toolBox = 0;
00040     m_oldTool = 0;
00041     m_dummyTool = 0;
00042     m_paletteManager = 0;
00043     m_actionCollection = 0;
00044     m_tools_disabled = false;
00045     setup = false;
00046 }
00047 
00048 KisToolManager::~KisToolManager()
00049 {
00050     delete m_dummyTool;
00051 }
00052 
00053 void KisToolManager::setUp(KoToolBox * toolbox, KoPaletteManager * paletteManager, KActionCollection * actionCollection)
00054 {
00055     if (setup) {
00056         resetToolBox( toolbox );
00057         return;
00058     }
00059 
00060     m_toolBox = toolbox;
00061     m_paletteManager = paletteManager;
00062     m_actionCollection = actionCollection;
00063 
00064     // Dummy tool for when the layer is locked or invisible
00065     if (!m_dummyTool)
00066         m_dummyTool = KisToolDummyFactory().createTool(actionCollection);
00067 
00068     QValueVector<KisInputDevice> inputDevices = KisInputDevice::inputDevices();
00069 
00070     for (Q_UINT32 inputDevice = 0; inputDevice < inputDevices.count(); inputDevice++) {
00071         m_inputDeviceToolSetMap[inputDevices[inputDevice]] = KisToolRegistry::instance()->createTools(actionCollection, m_subject);
00072     }
00073 
00074     m_tools = m_inputDeviceToolSetMap[KisInputDevice::mouse()];
00075     for (vKisTool_it it = m_tools.begin(); it != m_tools.end(); ++it) {
00076         KisTool * t = *it;
00077         if (!t) continue;
00078         toolbox->registerTool( t->action(), t->toolType(), t->priority() );
00079     }
00080 
00081     toolbox->setupTools();
00082 
00083     KisTool * t = findTool("tool_brush");
00084     if (t) {
00085         t->activate();
00086         setCurrentTool(t);
00087     }
00088     setup = true;
00089         
00090 }
00091 
00092 
00093 
00094 void KisToolManager::youAintGotNoToolBox()
00095 {
00096     m_toolBox = 0;
00097     m_oldTool = currentTool();
00098 }
00099 
00100 void KisToolManager::resetToolBox(KoToolBox * toolbox)
00101 {
00102     m_toolBox = toolbox;
00103 
00104     m_tools = m_inputDeviceToolSetMap[KisInputDevice::mouse()];
00105     for (vKisTool_it it = m_tools.begin(); it != m_tools.end(); ++it) {
00106         KisTool * t = *it;
00107         if (!t) continue;
00108         m_toolBox->registerTool( t->action(), t->toolType(), t->priority() );
00109     }
00110 
00111     toolbox->setupTools();
00112 
00113 #if 0 //  Because I cannot find out how to reset the toolbox so the button is depressed, we reset the tool to brush
00114     setCurrentTool(findTool("tool_brush"));
00115 #else
00116     if (m_oldTool) {
00117          // restore the old current tool
00118          setCurrentTool(m_oldTool);
00119          m_oldTool = 0;
00120     }
00121 #endif
00122 
00123 }
00124 
00125 void KisToolManager::updateGUI()
00126 {
00127     Q_ASSERT(m_subject);
00128     if (m_subject == 0) {
00129         // "Eek, no parent!
00130         return;
00131     }
00132 
00133     if (!m_toolBox) return;
00134 
00135     KisImageSP img = m_subject->currentImg();
00136     KisLayerSP l = 0;
00137 
00138     bool enable = false;
00139 
00140 
00141     KisPartLayer * partLayer = dynamic_cast<KisPartLayer*>(l.data());
00142     
00143     if (img) {
00144         l = img->activeLayer();
00145         enable = l && !l->locked() && l->visible() && (partLayer == 0);
00146     }
00147 
00148     m_toolBox->enableTools( enable );
00149 
00150     KisTool * current = currentTool();
00151 
00152     // XXX: Fix this properly: changing the visibility of a layer causes this cause to be executed twice!
00153     if (!enable && current != m_dummyTool) {
00154         // Store the current tool
00155         m_oldTool = currentTool();
00156         // Set the dummy tool
00157         if (!m_dummyTool) {
00158             m_dummyTool = KisToolDummyFactory().createTool(m_actionCollection);
00159         }
00160         setCurrentTool(m_dummyTool);
00161         m_tools_disabled = true;
00162     }
00163     else if (enable && m_tools_disabled) {
00164         m_tools_disabled = false;
00165         if (m_oldTool) {
00166             // restore the old current tool
00167             setCurrentTool(m_oldTool);
00168             m_oldTool = 0;
00169         }
00170         else {
00171             m_oldTool = 0;
00172             KisTool * t = findTool("tool_brush");
00173             setCurrentTool(t);
00174         }
00175     }
00176 }
00177 
00178 void KisToolManager::setCurrentTool(KisTool *tool)
00179 {
00180     KisTool *oldTool = currentTool();
00181     KisCanvas * canvas = (KisCanvas*)m_controller->kiscanvas();
00182 
00183 
00184     if (oldTool)
00185     {
00186         oldTool->deactivate();
00187         oldTool->action()->setChecked( false );
00188 
00189         m_paletteManager->removeWidget(krita::TOOL_OPTION_WIDGET);
00190     }
00191 
00192     if (tool) {
00193 
00194         if (!tool->optionWidget()) {
00195             tool->createOptionWidget(0);
00196         }
00197         QWidget * w = tool->optionWidget();
00198         
00199         if (w)
00200             m_paletteManager->addWidget(w, krita::TOOL_OPTION_WIDGET, krita::CONTROL_PALETTE );
00201 
00202         m_inputDeviceToolMap[m_controller->currentInputDevice()] = tool;
00203         m_controller->setCanvasCursor(tool->cursor());
00204 
00205         canvas->enableMoveEventCompressionHint(dynamic_cast<KisToolNonPaint *>(tool) != NULL);
00206 
00207         m_subject->notifyObservers();
00208 
00209         tool->action()->setChecked( true );
00210         tool->action()->activate();
00211         m_toolBox->slotSetTool(tool->name());
00212     } else {
00213         m_inputDeviceToolMap[m_controller->currentInputDevice()] = 0;
00214         m_controller->setCanvasCursor(KisCursor::arrowCursor());
00215     }
00216 
00217 }
00218 
00219 void KisToolManager::setCurrentTool( const QString & toolName )
00220 {
00221     setCurrentTool(findTool(toolName));
00222 }
00223 
00224 KisTool * KisToolManager::currentTool() const
00225 {
00226     InputDeviceToolMap::const_iterator it = m_inputDeviceToolMap.find(m_controller->currentInputDevice());
00227 
00228     if (it != m_inputDeviceToolMap.end()) {
00229         return (*it).second;
00230     } else {
00231         return 0;
00232     }
00233 }
00234 
00235 
00236 void KisToolManager::setToolForInputDevice(KisInputDevice oldDevice, KisInputDevice newDevice)
00237 {
00238     InputDeviceToolSetMap::iterator vit = m_inputDeviceToolSetMap.find(oldDevice);
00239 
00240     if (vit != m_inputDeviceToolSetMap.end()) {
00241         vKisTool& oldTools = (*vit).second;
00242         for (vKisTool::iterator it = oldTools.begin(); it != oldTools.end(); ++it) {
00243             KisTool *tool = *it;
00244             KAction *toolAction = tool->action();
00245             toolAction->disconnect(SIGNAL(activated()), tool, SLOT(activate()));
00246         }
00247     }
00248     KisTool *oldTool = currentTool();
00249     if (oldTool)
00250     {
00251         m_paletteManager->removeWidget(krita::TOOL_OPTION_WIDGET);
00252         oldTool->deactivate();
00253     }
00254 
00255 
00256     vit = m_inputDeviceToolSetMap.find(newDevice);
00257 
00258     Q_ASSERT(vit != m_inputDeviceToolSetMap.end());
00259 
00260     vKisTool& tools = (*vit).second;
00261 
00262     for (vKisTool::iterator it = tools.begin(); it != tools.end(); ++it) {
00263         KisTool *tool = *it;
00264         KAction *toolAction = tool->action();
00265         connect(toolAction, SIGNAL(activated()), tool, SLOT(activate()));
00266     }
00267 }
00268 
00269 void KisToolManager::activateCurrentTool()
00270 {
00271     KisTool * t = currentTool();
00272     if (t && t->action()) {
00273         t->action()->activate();
00274     }
00275 }
00276 
00277 KisTool * KisToolManager::findTool(const QString &toolName, KisInputDevice inputDevice) const
00278 {
00279     if (inputDevice == KisInputDevice::unknown()) {
00280         inputDevice = m_controller->currentInputDevice();
00281     }
00282 
00283     KisTool *tool = 0;
00284 
00285     InputDeviceToolSetMap::const_iterator vit = m_inputDeviceToolSetMap.find(inputDevice);
00286 
00287     Q_ASSERT(vit != m_inputDeviceToolSetMap.end());
00288 
00289     const vKisTool& tools = (*vit).second;
00290 
00291     for (vKisTool::const_iterator it = tools.begin(); it != tools.end(); ++it) {
00292         KisTool *t = *it;
00293         if (t->name() == toolName) {
00294             tool = t;
00295             break;
00296         }
00297     }
00298 
00299     return tool;
00300 }
00301 
00302 
00303 #include "kis_tool_manager.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys