File indexing completed on 2025-01-19 03:59:13
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2008-08-20 0007 * Description : Image editor interface used by editor tools. 0008 * 0009 * SPDX-FileCopyrightText: 2008-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0010 * 0011 * SPDX-License-Identifier: GPL-2.0-or-later 0012 * 0013 * ============================================================ */ 0014 0015 #include "editortooliface.h" 0016 0017 // Qt includes 0018 0019 #include <QWidget> 0020 0021 // KDE includes 0022 0023 #include <klocalizedstring.h> 0024 0025 // Local includes 0026 0027 #include "sidebar.h" 0028 #include "canvas.h" 0029 #include "statusprogressbar.h" 0030 #include "editortool.h" 0031 #include "editortoolsettings.h" 0032 #include "editorstackview.h" 0033 #include "editorwindow.h" 0034 #include "imageguidewidget.h" 0035 #include "imageregionwidget.h" 0036 #include "previewlayout.h" 0037 #include "dcategorizedview.h" 0038 0039 namespace Digikam 0040 { 0041 0042 class Q_DECL_HIDDEN EditorToolIface::Private 0043 { 0044 0045 public: 0046 0047 explicit Private() 0048 : toolsIconView(nullptr), 0049 lastActiveTab(nullptr), 0050 tool (nullptr), 0051 editor (nullptr), 0052 splitterSize (0) 0053 { 0054 } 0055 0056 DCategorizedView* toolsIconView; 0057 QWidget* lastActiveTab; 0058 EditorTool* tool; 0059 EditorWindow* editor; 0060 0061 int splitterSize; 0062 }; 0063 0064 EditorToolIface* EditorToolIface::m_iface = nullptr; 0065 0066 EditorToolIface* EditorToolIface::editorToolIface() 0067 { 0068 return m_iface; 0069 } 0070 0071 EditorToolIface::EditorToolIface(EditorWindow* const editor) 0072 : QObject(), 0073 d (new Private) 0074 { 0075 d->editor = editor; 0076 m_iface = this; 0077 } 0078 0079 EditorToolIface::~EditorToolIface() 0080 { 0081 delete d->tool; 0082 delete d; 0083 0084 if (m_iface == this) 0085 { 0086 m_iface = nullptr; 0087 } 0088 } 0089 0090 void EditorToolIface::setToolsIconView(DCategorizedView* const view) 0091 { 0092 d->toolsIconView = view; 0093 d->editor->rightSideBar()->appendTab(d->toolsIconView, 0094 QIcon::fromTheme(QLatin1String("document-edit")), 0095 i18n("Tools")); 0096 } 0097 0098 EditorTool* EditorToolIface::currentTool() const 0099 { 0100 return d->tool; 0101 } 0102 0103 void EditorToolIface::loadTool(EditorTool* const tool) 0104 { 0105 if (d->tool) 0106 { 0107 unLoadTool(); 0108 } 0109 0110 d->tool = tool; 0111 d->lastActiveTab = d->editor->rightSideBar()->getActiveTab(); 0112 d->splitterSize = d->editor->sidebarSplitter()->size(d->editor->rightSideBar()); 0113 0114 d->editor->editorStackView()->setToolView(d->tool->toolView()); 0115 d->editor->editorStackView()->setViewMode(EditorStackView::ToolViewMode); 0116 0117 d->editor->rightSideBar()->deleteTab(d->toolsIconView); 0118 d->editor->rightSideBar()->appendTab(d->tool->toolSettings(), d->tool->toolIcon(), d->tool->toolName()); 0119 d->editor->rightSideBar()->setActiveTab(d->tool->toolSettings()); 0120 0121 int w = qMax(d->splitterSize, d->tool->toolSettings()->minimumSizeHint().width()); 0122 d->editor->sidebarSplitter()->setSize(d->editor->rightSideBar(), w); 0123 0124 d->editor->toggleActions(false); 0125 d->editor->toggleToolActions(d->tool); 0126 0127 // If editor tool has zoomable preview, switch on zoom actions. 0128 0129 d->editor->toggleZoomActions(d->editor->editorStackView()->isZoomablePreview()); 0130 0131 ImageGuideWidget* const view = dynamic_cast<ImageGuideWidget*>(d->tool->toolView()); 0132 0133 if (view) 0134 { 0135 connect(d->editor, SIGNAL(signalPreviewModeChanged(int)), 0136 view, SLOT(slotPreviewModeChanged(int))); 0137 0138 view->slotPreviewModeChanged(d->editor->previewMode()); 0139 } 0140 0141 // To set zoomable preview zoom level and position accordingly with main canvas. 0142 0143 ImageRegionWidget* const view2 = dynamic_cast<ImageRegionWidget*>(d->tool->toolView()); 0144 0145 if (view2) 0146 { 0147 connect(d->editor, SIGNAL(signalPreviewModeChanged(int)), 0148 view2, SLOT(slotPreviewModeChanged(int))); 0149 0150 connect(d->editor->editorStackView(), SIGNAL(signalZoomChanged(bool,bool,double)), 0151 view2, SLOT(slotOriginalImageRegionChangedDelayed())); 0152 0153 if (d->editor->editorStackView()->canvas()->layout()->isFitToWindow()) 0154 { 0155 view2->fitToWindow(); 0156 } 0157 else 0158 { 0159 view2->layout()->setZoomFactor(d->editor->editorStackView()->canvas()->layout()->zoomFactor()); 0160 QPoint tl = d->editor->editorStackView()->canvas()->visibleArea().topLeft(); 0161 view2->setContentsPos(tl.x(), tl.y()); 0162 } 0163 0164 view2->slotPreviewModeChanged(d->editor->previewMode()); 0165 } 0166 0167 themeChanged(); 0168 updateExposureSettings(); 0169 updateICCSettings(); 0170 setToolInfoMessage(QString()); 0171 0172 connect(d->editor, SIGNAL(signalPreviewModeChanged(int)), 0173 d->tool, SLOT(slotPreviewModeChanged())); 0174 0175 connect(d->tool, SIGNAL(okClicked()), 0176 this, SLOT(slotToolApplied())); 0177 0178 d->tool->init(); 0179 } 0180 0181 void EditorToolIface::unLoadTool() 0182 { 0183 if (!d->tool) 0184 { 0185 return; 0186 } 0187 0188 // To restore zoom level and position accordingly with zoomable preview. 0189 0190 ImageRegionWidget* const view2 = dynamic_cast<ImageRegionWidget*>(d->tool->toolView()); 0191 0192 if (view2) 0193 { 0194 if (view2->layout()->isFitToWindow()) 0195 { 0196 d->editor->editorStackView()->canvas()->fitToWindow(); 0197 } 0198 else 0199 { 0200 d->editor->editorStackView()->canvas()->layout()->setZoomFactor(view2->layout()->zoomFactor()); 0201 QPoint tl = view2->visibleArea().topLeft(); 0202 d->editor->editorStackView()->canvas()->setContentsPos(tl.x(), tl.y()); 0203 } 0204 } 0205 0206 d->editor->editorStackView()->setViewMode(EditorStackView::CanvasMode); 0207 d->editor->editorStackView()->setToolView(nullptr); 0208 d->editor->rightSideBar()->deleteTab(d->tool->toolSettings()); 0209 d->editor->rightSideBar()->appendTab(d->toolsIconView, 0210 QIcon::fromTheme(QLatin1String("document-edit")), 0211 i18n("Tools")); 0212 0213 d->editor->rightSideBar()->setActiveTab(d->lastActiveTab); 0214 0215 if (d->splitterSize > 0) 0216 { 0217 d->editor->sidebarSplitter()->setSize(d->editor->rightSideBar(), 0218 d->splitterSize); 0219 } 0220 else 0221 { 0222 d->editor->rightSideBar()->shrink(); 0223 } 0224 0225 d->editor->toggleActions(true); 0226 d->editor->toggleToolActions(); 0227 d->editor->slotUpdateItemInfo(); 0228 d->editor->setPreviewModeMask(PreviewToolBar::NoPreviewMode); 0229 0230 delete d->tool; 0231 d->tool = nullptr; 0232 0233 // Reset info label in status bar with canvas selection info. 0234 0235 d->editor->slotSelected(!d->editor->m_canvas->getSelectedArea().isNull()); 0236 d->editor->editorStackView()->canvas()->layout()->updateZoomAndSize(); 0237 } 0238 0239 void EditorToolIface::setToolInfoMessage(const QString& txt) 0240 { 0241 d->editor->setToolInfoMessage(txt); 0242 } 0243 0244 void EditorToolIface::setToolStartProgress(const QString& toolName) 0245 { 0246 d->editor->setToolStartProgress(toolName); 0247 d->editor->toggleZoomActions(!d->editor->editorStackView()->isZoomablePreview()); 0248 } 0249 0250 void EditorToolIface::setToolProgress(int progress) 0251 { 0252 d->editor->setToolProgress(progress); 0253 } 0254 0255 void EditorToolIface::setToolStopProgress() 0256 { 0257 d->editor->setToolStopProgress(); 0258 d->editor->toggleZoomActions(d->editor->editorStackView()->isZoomablePreview()); 0259 } 0260 0261 void EditorToolIface::slotToolAborted() 0262 { 0263 EditorToolThreaded* const tool = dynamic_cast<EditorToolThreaded*>(d->tool); 0264 0265 if (tool) 0266 { 0267 tool->slotAbort(); 0268 } 0269 } 0270 0271 void EditorToolIface::slotCloseTool() 0272 { 0273 EditorTool* const tool = dynamic_cast<EditorTool*>(d->tool); 0274 0275 if (tool) 0276 { 0277 tool->slotCloseTool(); 0278 } 0279 } 0280 0281 void EditorToolIface::slotApplyTool() 0282 { 0283 EditorTool* const tool = dynamic_cast<EditorTool*>(d->tool); 0284 0285 if (tool) 0286 { 0287 tool->slotApplyTool(); 0288 } 0289 } 0290 0291 void EditorToolIface::setupICC() 0292 { 0293 d->editor->slotSetupICC(); 0294 } 0295 0296 void EditorToolIface::themeChanged() 0297 { 0298 EditorTool* const tool = dynamic_cast<EditorTool*>(d->tool); 0299 0300 if (tool) 0301 { 0302 tool->setBackgroundColor(d->editor->m_bgColor); 0303 } 0304 } 0305 0306 void EditorToolIface::updateICCSettings() 0307 { 0308 EditorTool* const tool = dynamic_cast<EditorTool*>(d->tool); 0309 0310 if (tool) 0311 { 0312 tool->ICCSettingsChanged(); 0313 } 0314 } 0315 0316 void EditorToolIface::updateExposureSettings() 0317 { 0318 ExposureSettingsContainer* const expoSettings = d->editor->exposureSettings(); 0319 d->editor->editorStackView()->canvas()->setExposureSettings(expoSettings); 0320 EditorTool* const tool = dynamic_cast<EditorTool*>(d->tool); 0321 0322 if (tool) 0323 { 0324 tool->exposureSettingsChanged(); 0325 } 0326 } 0327 0328 void EditorToolIface::setPreviewModeMask(int mask) 0329 { 0330 d->editor->setPreviewModeMask(mask); 0331 } 0332 0333 void EditorToolIface::slotToolApplied() 0334 { 0335 Q_EMIT d->editor->signalToolApplied(); 0336 } 0337 0338 } // namespace Digikam 0339 0340 #include "moc_editortooliface.cpp"