File indexing completed on 2025-01-05 03:59:45
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2010-01-10 0007 * Description : a tool bar for preview mode 0008 * 0009 * SPDX-FileCopyrightText: 2010-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 "previewtoolbar.h" 0016 0017 // Qt includes 0018 0019 #include <QButtonGroup> 0020 #include <QLayout> 0021 #include <QToolButton> 0022 #include <QAbstractButton> 0023 #include <QStandardPaths> 0024 #include <QActionGroup> 0025 #include <QMenu> 0026 0027 // KDE includes 0028 0029 #if !defined(Q_OS_DARWIN) && defined(Q_CC_GNU) 0030 # pragma GCC diagnostic push 0031 # pragma GCC diagnostic ignored "-Wdeprecated-declarations" 0032 #endif 0033 0034 #if defined(Q_CC_CLANG) 0035 # pragma clang diagnostic push 0036 # pragma clang diagnostic ignored "-Wdeprecated-declarations" 0037 #endif 0038 0039 #include <kconfiggroup.h> 0040 #include <klocalizedstring.h> 0041 #include <kactioncollection.h> 0042 0043 // Restore warnings 0044 #if !defined(Q_OS_DARWIN) && defined(Q_CC_GNU) 0045 # pragma GCC diagnostic pop 0046 #endif 0047 0048 #if defined(Q_CC_CLANG) 0049 # pragma clang diagnostic pop 0050 #endif 0051 0052 // Local includes 0053 0054 #include "editorwindow.h" 0055 0056 namespace Digikam 0057 { 0058 0059 class Q_DECL_HIDDEN PreviewToolBar::Private 0060 { 0061 public: 0062 0063 explicit Private() 0064 : previewOriginalButton(nullptr), 0065 previewBothButtonVert(nullptr), 0066 previewBothButtonHorz(nullptr), 0067 previewDuplicateBothButtonVert(nullptr), 0068 previewDupplicateBothButtonHorz(nullptr), 0069 previewtargetButton(nullptr), 0070 previewToggleMouseOverButton(nullptr), 0071 previewButtons(nullptr), 0072 actionsGroup(nullptr), 0073 actionsMenu(nullptr) 0074 { 0075 } 0076 0077 QToolButton* previewOriginalButton; 0078 QToolButton* previewBothButtonVert; 0079 QToolButton* previewBothButtonHorz; 0080 QToolButton* previewDuplicateBothButtonVert; 0081 QToolButton* previewDupplicateBothButtonHorz; 0082 QToolButton* previewtargetButton; 0083 QToolButton* previewToggleMouseOverButton; 0084 0085 QButtonGroup* previewButtons; 0086 QActionGroup* actionsGroup; 0087 0088 QMenu* actionsMenu; 0089 }; 0090 0091 PreviewToolBar::PreviewToolBar(QWidget* const parent) 0092 : QWidget(parent), 0093 d(new Private) 0094 { 0095 setAttribute(Qt::WA_DeleteOnClose); 0096 0097 QHBoxLayout* const hlay = new QHBoxLayout(this); 0098 d->previewButtons = new QButtonGroup(this); 0099 d->previewButtons->setExclusive(true); 0100 hlay->setContentsMargins(QMargins()); 0101 hlay->setSpacing(0); 0102 0103 d->previewOriginalButton = new QToolButton(this); 0104 d->previewButtons->addButton(d->previewOriginalButton, PreviewOriginalImage); 0105 hlay->addWidget(d->previewOriginalButton); 0106 d->previewOriginalButton->setIcon(QPixmap(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QLatin1String("digikam/data/original.png")))); 0107 d->previewOriginalButton->setCheckable(true); 0108 d->previewOriginalButton->setWhatsThis(i18n("If this option is enabled, the original image will be shown.")); 0109 d->previewOriginalButton->setToolTip(i18n("Preview original image")); 0110 d->previewOriginalButton->setObjectName(QLatin1String("preview-original")); 0111 0112 d->previewBothButtonVert = new QToolButton(this); 0113 d->previewButtons->addButton(d->previewBothButtonVert, PreviewBothImagesVertCont); 0114 hlay->addWidget(d->previewBothButtonVert); 0115 d->previewBothButtonVert->setIcon(QPixmap(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QLatin1String("digikam/data/bothvert.png")))); 0116 d->previewBothButtonVert->setCheckable(true); 0117 d->previewBothButtonVert->setWhatsThis(i18n("If this option is enabled, the preview area will " 0118 "split vertically. " 0119 "A contiguous area of the image will be shown, " 0120 "with one half from the original image, " 0121 "the other half from the target image.")); 0122 d->previewBothButtonVert->setToolTip(i18n("Preview vertical split with contiguous image")); 0123 d->previewBothButtonVert->setObjectName(QLatin1String("preview-both-vert")); 0124 0125 d->previewBothButtonHorz = new QToolButton(this); 0126 d->previewButtons->addButton(d->previewBothButtonHorz, PreviewBothImagesHorzCont); 0127 hlay->addWidget(d->previewBothButtonHorz); 0128 d->previewBothButtonHorz->setIcon(QPixmap(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QLatin1String("digikam/data/bothhorz.png")))); 0129 d->previewBothButtonHorz->setCheckable(true); 0130 d->previewBothButtonHorz->setWhatsThis(i18n("If this option is enabled, the preview area will " 0131 "split horizontally. " 0132 "A contiguous area of the image will be shown, " 0133 "with one half from the original image, " 0134 "the other half from the target image.")); 0135 d->previewBothButtonHorz->setToolTip(i18n("Preview horizontal split with contiguous image")); 0136 d->previewBothButtonHorz->setObjectName(QLatin1String("preview--both-horz")); 0137 0138 d->previewDuplicateBothButtonVert = new QToolButton(this); 0139 d->previewButtons->addButton(d->previewDuplicateBothButtonVert, PreviewBothImagesVert); 0140 hlay->addWidget(d->previewDuplicateBothButtonVert); 0141 d->previewDuplicateBothButtonVert->setIcon(QPixmap(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QLatin1String("digikam/data/duplicatebothvert.png")))); 0142 d->previewDuplicateBothButtonVert->setCheckable(true); 0143 d->previewDuplicateBothButtonVert->setWhatsThis(i18n("If this option is enabled, the preview area will " 0144 "split vertically. " 0145 "The same part of the original and the target image " 0146 "will be shown side by side.")); 0147 d->previewDuplicateBothButtonVert->setToolTip(i18n("Preview vertical split with same image region")); 0148 d->previewDuplicateBothButtonVert->setObjectName(QLatin1String("preview-duplicate-both-vert")); 0149 0150 d->previewDupplicateBothButtonHorz = new QToolButton(this); 0151 d->previewButtons->addButton(d->previewDupplicateBothButtonHorz, PreviewBothImagesHorz); 0152 hlay->addWidget(d->previewDupplicateBothButtonHorz); 0153 d->previewDupplicateBothButtonHorz->setIcon(QPixmap(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QLatin1String("digikam/data/duplicatebothhorz.png")))); 0154 d->previewDupplicateBothButtonHorz->setCheckable(true); 0155 d->previewDupplicateBothButtonHorz->setWhatsThis(i18n("If this option is enabled, the preview area will " 0156 "split horizontally. " 0157 "The same part of the original and the target image " 0158 "will be shown side by side.")); 0159 d->previewDupplicateBothButtonHorz->setToolTip(i18n("Preview horizontal split with same image region")); 0160 d->previewDupplicateBothButtonHorz->setObjectName(QLatin1String("preview-duplicate-both-horz")); 0161 0162 d->previewtargetButton = new QToolButton(this); 0163 d->previewButtons->addButton(d->previewtargetButton, PreviewTargetImage); 0164 hlay->addWidget(d->previewtargetButton); 0165 d->previewtargetButton->setIcon(QPixmap(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QLatin1String("digikam/data/target.png")))); 0166 d->previewtargetButton->setCheckable(true); 0167 d->previewtargetButton->setWhatsThis(i18n("If this option is enabled, the target image will be shown.")); 0168 d->previewtargetButton->setToolTip(i18n("Preview target image")); 0169 d->previewtargetButton->setObjectName(QLatin1String("preview-target")); 0170 0171 d->previewToggleMouseOverButton = new QToolButton(this); 0172 d->previewButtons->addButton(d->previewToggleMouseOverButton, PreviewToggleOnMouseOver); 0173 hlay->addWidget(d->previewToggleMouseOverButton); 0174 d->previewToggleMouseOverButton->setIcon(QPixmap(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QLatin1String("digikam/data/togglemouseover.png")))); 0175 d->previewToggleMouseOverButton->setCheckable(true); 0176 d->previewToggleMouseOverButton->setWhatsThis(i18n("If this option is enabled, the original image will " 0177 "be shown when the mouse is over image area; otherwise, " 0178 "the target image will be shown.")); 0179 d->previewToggleMouseOverButton->setToolTip(i18n("Preview on mouse-over")); 0180 d->previewToggleMouseOverButton->setObjectName(QLatin1String("preview-toggle-mouse-over")); 0181 0182 #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) 0183 0184 connect(d->previewButtons, SIGNAL(idReleased(int)), 0185 this, SLOT(slotButtonReleased(int))); 0186 0187 #else 0188 0189 connect(d->previewButtons, SIGNAL(buttonReleased(int)), 0190 this, SLOT(slotButtonReleased(int))); 0191 0192 #endif 0193 0194 } 0195 0196 PreviewToolBar::~PreviewToolBar() 0197 { 0198 delete d; 0199 } 0200 0201 void PreviewToolBar::registerMenuActionGroup(EditorWindow* const editor) 0202 { 0203 d->actionsMenu = new QMenu(i18nc("@action Select image editor preview mode", "Preview Mode"), editor); 0204 d->actionsGroup = new QActionGroup(d->actionsMenu); 0205 0206 connect(d->actionsGroup, SIGNAL(triggered(QAction*)), 0207 this, SLOT(slotActionTriggered(QAction*))); 0208 0209 Q_FOREACH (QAbstractButton* const btn, d->previewButtons->buttons()) 0210 { 0211 QAction* const ac = new QAction(btn->toolTip(), d->actionsGroup); 0212 ac->setData(QVariant(d->previewButtons->id(btn))); 0213 ac->setIcon(btn->icon()); 0214 ac->setCheckable(true); 0215 editor->actionCollection()->addAction(btn->objectName(), ac); 0216 d->actionsMenu->addAction(ac); 0217 } 0218 0219 editor->actionCollection()->addAction(QLatin1String("editorwindow_previewmode"), d->actionsMenu->menuAction()); 0220 } 0221 0222 void PreviewToolBar::slotActionTriggered(QAction* ac) 0223 { 0224 int id = ac->data().toInt(); 0225 d->previewButtons->button(id)->setChecked(true); 0226 0227 Q_EMIT signalPreviewModeChanged(id); 0228 } 0229 0230 void PreviewToolBar::slotButtonReleased(int id) 0231 { 0232 setCheckedAction(id); 0233 0234 Q_EMIT signalPreviewModeChanged(id); 0235 } 0236 0237 void PreviewToolBar::setCheckedAction(int id) 0238 { 0239 if (!d->actionsGroup) return; 0240 0241 Q_FOREACH (QAction* const ac, d->actionsGroup->actions()) 0242 { 0243 if (ac->data().toInt() == id) 0244 { // cppcheck-suppress useStlAlgorithm 0245 ac->setChecked(true); 0246 return; 0247 } 0248 } 0249 } 0250 0251 void PreviewToolBar::setPreviewModeMask(int mask) 0252 { 0253 if (mask == NoPreviewMode) 0254 { 0255 setDisabled(true); 0256 0257 if (d->actionsMenu) 0258 { 0259 d->actionsMenu->setDisabled(true); 0260 } 0261 0262 return; 0263 } 0264 0265 setDisabled(false); 0266 0267 if (d->actionsMenu) 0268 { 0269 d->actionsMenu->setDisabled(false); 0270 } 0271 0272 d->previewOriginalButton->setEnabled(mask & PreviewOriginalImage); 0273 d->previewBothButtonVert->setEnabled(mask & PreviewBothImagesHorz); 0274 d->previewBothButtonHorz->setEnabled(mask & PreviewBothImagesVert); 0275 d->previewDuplicateBothButtonVert->setEnabled(mask & PreviewBothImagesHorzCont); 0276 d->previewDupplicateBothButtonHorz->setEnabled(mask & PreviewBothImagesVertCont); 0277 d->previewtargetButton->setEnabled(mask & PreviewTargetImage); 0278 d->previewToggleMouseOverButton->setEnabled(mask & PreviewToggleOnMouseOver); 0279 0280 if (d->actionsGroup) 0281 { 0282 Q_FOREACH (QAction* const ac, d->actionsGroup->actions()) 0283 { 0284 ac->setEnabled(mask & ac->data().toInt()); 0285 } 0286 } 0287 0288 // When we switch to another mask, check if current mode is valid. 0289 0290 PreviewToolBar::PreviewMode mode = previewMode(); 0291 0292 if (d->previewButtons->button(mode)) 0293 { 0294 if (!d->previewButtons->button(mode)->isEnabled()) 0295 { 0296 QList<QAbstractButton*> btns = d->previewButtons->buttons(); 0297 0298 Q_FOREACH (QAbstractButton* const btn, btns) 0299 { 0300 if (btn && btn->isEnabled()) 0301 { // cppcheck-suppress useStlAlgorithm 0302 btn->setChecked(true); 0303 setCheckedAction(d->previewButtons->id(btn)); 0304 0305 return; 0306 } 0307 } 0308 } 0309 } 0310 } 0311 0312 void PreviewToolBar::setPreviewMode(PreviewMode mode) 0313 { 0314 if (d->previewButtons->button(mode)) 0315 { 0316 d->previewButtons->button(mode)->setChecked(true); 0317 setCheckedAction((int)mode); 0318 } 0319 } 0320 0321 PreviewToolBar::PreviewMode PreviewToolBar::previewMode() const 0322 { 0323 if (!isEnabled()) 0324 { 0325 return PreviewToolBar::NoPreviewMode; 0326 } 0327 0328 return ((PreviewMode)d->previewButtons->checkedId()); 0329 } 0330 0331 void PreviewToolBar::readSettings(KConfigGroup& group) 0332 { 0333 int mode = group.readEntry("PreviewMode", (int)PreviewBothImagesVertCont); 0334 mode = qMax((int)PreviewOriginalImage, mode); 0335 mode = qMin((int)PreviewToggleOnMouseOver, mode); 0336 setPreviewMode((PreviewMode)mode); 0337 } 0338 0339 void PreviewToolBar::writeSettings(KConfigGroup& group) 0340 { 0341 group.writeEntry("PreviewMode", (int)previewMode()); 0342 } 0343 0344 } // namespace Digikam 0345 0346 #include "moc_previewtoolbar.cpp"