File indexing completed on 2025-01-05 03:59:40

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2008-08-20
0007  * Description : A widget stack to embed editor view.
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 "editorstackview.h"
0016 
0017 // Local includes
0018 
0019 #include "dzoombar.h"
0020 #include "canvas.h"
0021 #include "thumbnailsize.h"
0022 #include "graphicsdimgview.h"
0023 #include "previewlayout.h"
0024 
0025 namespace Digikam
0026 {
0027 
0028 class Q_DECL_HIDDEN EditorStackView::Private
0029 {
0030 
0031 public:
0032 
0033     explicit Private()
0034       : toolView(nullptr),
0035         canvas  (nullptr)
0036     {
0037     }
0038 
0039     QWidget* toolView;
0040     Canvas*  canvas;
0041 };
0042 
0043 EditorStackView::EditorStackView(QWidget* const parent)
0044     : QStackedWidget(parent),
0045       d             (new Private)
0046 {
0047 }
0048 
0049 EditorStackView::~EditorStackView()
0050 {
0051     delete d;
0052 }
0053 
0054 void EditorStackView::setCanvas(Canvas* const canvas)
0055 {
0056     if (d->canvas)
0057     {
0058         return;
0059     }
0060 
0061     d->canvas = canvas;
0062     insertWidget(CanvasMode, d->canvas);
0063 
0064     connect(d->canvas, SIGNAL(signalZoomChanged(double)),
0065             this, SLOT(slotZoomChanged(double)));
0066 
0067     connect(d->canvas, SIGNAL(signalToggleOffFitToWindow()),
0068             this, SIGNAL(signalToggleOffFitToWindow()));
0069 }
0070 
0071 Canvas* EditorStackView::canvas() const
0072 {
0073     return d->canvas;
0074 }
0075 
0076 void EditorStackView::setToolView(QWidget* const view)
0077 {
0078     if (d->toolView)
0079     {
0080         removeWidget(d->toolView);
0081     }
0082 
0083     d->toolView = view;
0084 
0085     if (d->toolView)
0086     {
0087         insertWidget(ToolViewMode, d->toolView);
0088     }
0089 
0090     GraphicsDImgView* const preview = previewWidget();
0091 
0092     if (preview)
0093     {
0094         connect(preview->layout(), SIGNAL(zoomFactorChanged(double)),
0095                 this, SLOT(slotZoomChanged(double)));
0096 
0097         connect(preview->layout(), SIGNAL(fitToWindowToggled(bool)),
0098                 this, SLOT(slotToggleOffFitToWindow(bool)));
0099     }
0100 }
0101 
0102 QWidget* EditorStackView::toolView() const
0103 {
0104     return d->toolView;
0105 }
0106 
0107 int EditorStackView::viewMode() const
0108 {
0109     return indexOf(currentWidget());
0110 }
0111 
0112 void EditorStackView::setViewMode(int mode)
0113 {
0114     if ((mode != CanvasMode) && (mode != ToolViewMode))
0115     {
0116         return;
0117     }
0118 
0119     setCurrentIndex(mode);
0120 }
0121 
0122 void EditorStackView::increaseZoom()
0123 {
0124     if (viewMode() == CanvasMode)
0125     {
0126         d->canvas->layout()->increaseZoom();
0127     }
0128     else
0129     {
0130         GraphicsDImgView* const preview = previewWidget();
0131 
0132         if (preview)
0133         {
0134             preview->layout()->increaseZoom();
0135         }
0136     }
0137 }
0138 
0139 void EditorStackView::decreaseZoom()
0140 {
0141     if (viewMode() == CanvasMode)
0142     {
0143         d->canvas->layout()->decreaseZoom();
0144     }
0145     else
0146     {
0147         GraphicsDImgView* const preview = previewWidget();
0148 
0149         if (preview)
0150         {
0151             preview->layout()->decreaseZoom();
0152         }
0153     }
0154 }
0155 
0156 void EditorStackView::toggleFitToWindow()
0157 {
0158     // Fit to window action is common place to switch view in this mode.
0159     // User want to see the same behaviors between canvas and tool preview.
0160     // Both are toggle at the same time.
0161 
0162     d->canvas->layout()->toggleFitToWindow();
0163 
0164     GraphicsDImgView* const preview = previewWidget();
0165 
0166     if (preview)
0167     {
0168         preview->layout()->toggleFitToWindow();
0169     }
0170 }
0171 
0172 void EditorStackView::fitToSelect()
0173 {
0174     if (viewMode() == CanvasMode)
0175     {
0176         d->canvas->fitToSelect();
0177     }
0178 }
0179 
0180 void EditorStackView::zoomTo100Percent()
0181 {
0182     if (viewMode() == CanvasMode)
0183     {
0184         d->canvas->layout()->toggleFitToWindowOr100();
0185     }
0186     else
0187     {
0188         GraphicsDImgView* const preview = previewWidget();
0189 
0190         if (preview)
0191         {
0192             preview->layout()->toggleFitToWindowOr100();
0193         }
0194     }
0195 }
0196 
0197 void EditorStackView::setZoomFactor(double zoom)
0198 {
0199     if (viewMode() == CanvasMode)
0200     {
0201         d->canvas->layout()->setZoomFactor(zoom);
0202     }
0203     else
0204     {
0205         GraphicsDImgView* const preview = previewWidget();
0206 
0207         if (preview)
0208         {
0209             preview->layout()->setZoomFactor(zoom);
0210         }
0211     }
0212 }
0213 
0214 double EditorStackView::zoomMax() const
0215 {
0216     if (viewMode() == CanvasMode)
0217     {
0218         return d->canvas->layout()->maxZoomFactor();
0219     }
0220     else
0221     {
0222         GraphicsDImgView* const preview  = previewWidget();
0223 
0224         if (preview)
0225         {
0226             return preview->layout()->maxZoomFactor();
0227         }
0228         else
0229         {
0230             return (-1.0);
0231         }
0232     }
0233 }
0234 
0235 double EditorStackView::zoomMin() const
0236 {
0237     if (viewMode() == CanvasMode)
0238     {
0239         return d->canvas->layout()->minZoomFactor();
0240     }
0241     else
0242     {
0243         GraphicsDImgView* const preview  = previewWidget();
0244 
0245         if (preview)
0246         {
0247             return preview->layout()->minZoomFactor();
0248         }
0249         else
0250         {
0251             return (-1.0);
0252         }
0253     }
0254 }
0255 
0256 void EditorStackView::slotZoomSliderChanged(int size)
0257 {
0258     if ((viewMode() == ToolViewMode) && !isZoomablePreview())
0259     {
0260         return;
0261     }
0262 
0263     double z = DZoomBar::zoomFromSize(size, zoomMin(), zoomMax());
0264 
0265     if (viewMode() == CanvasMode)
0266     {
0267         d->canvas->layout()->setZoomFactorSnapped(z);
0268     }
0269     else
0270     {
0271         GraphicsDImgView* const preview = previewWidget();
0272 
0273         if (preview)
0274         {
0275             preview->layout()->setZoomFactorSnapped(z);
0276         }
0277     }
0278 }
0279 
0280 void EditorStackView::slotZoomChanged(double zoom)
0281 {
0282     bool max, min;
0283 
0284     if (viewMode() == CanvasMode)
0285     {
0286         max = d->canvas->layout()->atMaxZoom();
0287         min = d->canvas->layout()->atMinZoom();
0288 
0289         Q_EMIT signalZoomChanged(max, min, zoom);
0290     }
0291     else
0292     {
0293         GraphicsDImgView* const preview = previewWidget();
0294 
0295         if (preview)
0296         {
0297             max = preview->layout()->atMaxZoom();
0298             min = preview->layout()->atMinZoom();
0299 
0300             Q_EMIT signalZoomChanged(max, min, zoom);
0301         }
0302     }
0303 }
0304 
0305 void EditorStackView::slotToggleOffFitToWindow(bool b)
0306 {
0307     if (b)
0308     {
0309         Q_EMIT signalToggleOffFitToWindow();
0310     }
0311 }
0312 
0313 GraphicsDImgView* EditorStackView::previewWidget() const
0314 {
0315     GraphicsDImgView* const preview = dynamic_cast<GraphicsDImgView*>(d->toolView);
0316 
0317     if (preview)
0318     {
0319         return preview;
0320     }
0321 
0322     return nullptr;
0323 }
0324 
0325 bool EditorStackView::isZoomablePreview() const
0326 {
0327     return previewWidget();
0328 }
0329 
0330 } // namespace Digikam
0331 
0332 #include "moc_editorstackview.cpp"