File indexing completed on 2025-01-05 03:57:53

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2021-08-27
0007  * Description : a tool bar for Showfoto folder view
0008  *
0009  * SPDX-FileCopyrightText: 2021-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 "showfotofolderviewbar.h"
0016 
0017 // Qt includes
0018 
0019 #include <QDir>
0020 #include <QApplication>
0021 #include <QSlider>
0022 #include <QLayout>
0023 #include <QLineEdit>
0024 #include <QToolButton>
0025 #include <QPixmap>
0026 #include <QActionGroup>
0027 #include <QMenu>
0028 #include <QComboBox>
0029 
0030 // KDE includes
0031 
0032 #include <klocalizedstring.h>
0033 
0034 // Local includes
0035 
0036 #include "digikam_debug.h"
0037 #include "drawdecoder.h"
0038 #include "showfotofolderviewmodel.h"
0039 #include "showfotofolderviewlist.h"
0040 #include "showfotosetup.h"
0041 
0042 namespace ShowFoto
0043 {
0044 
0045 class Q_DECL_HIDDEN ShowfotoFolderViewBar::Private
0046 {
0047 
0048 public:
0049 
0050     explicit Private()
0051       : pluginFingerPrint  (QLatin1String("DPlugin::Generic::View")),
0052         previousBtn        (nullptr),
0053         nextBtn            (nullptr),
0054         upBtn              (nullptr),
0055         homeBtn            (nullptr),
0056         iconSizeSlider     (nullptr),
0057         optionsBtn         (nullptr),
0058         optionsMenu        (nullptr),
0059         runBtn             (nullptr),
0060         runMenu            (nullptr),
0061         shortAction        (nullptr),
0062         detailedAction     (nullptr),
0063         showBookmarksAction(nullptr),
0064         moreSettingsAction (nullptr),
0065         pathEdit           (nullptr),
0066         sidebar            (nullptr),
0067         typeMimesCombo     (nullptr)
0068     {
0069     }
0070 
0071     const QString              pluginFingerPrint;           ///< Identify plugins category to host in folder-view.
0072     QToolButton*               previousBtn;
0073     QToolButton*               nextBtn;
0074     QToolButton*               upBtn;
0075     QToolButton*               homeBtn;
0076     QSlider*                   iconSizeSlider;
0077     QToolButton*               optionsBtn;
0078     QMenu*                     optionsMenu;
0079     QToolButton*               runBtn;
0080     QMenu*                     runMenu;
0081     QAction*                   shortAction;
0082     QAction*                   detailedAction;
0083     QAction*                   showBookmarksAction;
0084     QAction*                   moreSettingsAction;
0085     QComboBox*                 pathEdit;
0086     QList<QAction*>            actionsList;                 ///< used to shared actions with list-view context menu.
0087     ShowfotoFolderViewSideBar* sidebar;
0088     QComboBox*                 typeMimesCombo;
0089 };
0090 
0091 ShowfotoFolderViewBar::ShowfotoFolderViewBar(ShowfotoFolderViewSideBar* const sidebar)
0092     : DVBox(sidebar),
0093       d    (new Private)
0094 {
0095     setContentsMargins(QMargins());
0096 
0097     d->sidebar               = sidebar;
0098     DHBox* const btnBox      = new DHBox(this);
0099     QAction* btnAction       = nullptr;
0100 
0101     // ---
0102 
0103     btnAction                = new QAction(this);
0104     btnAction->setObjectName(QLatin1String("GoPrevious"));
0105     btnAction->setIcon(QIcon::fromTheme(QLatin1String("go-previous")));
0106     btnAction->setText(i18nc("@action", "Go to Previous"));
0107     btnAction->setToolTip(i18nc("@info", "Go to previous place in folder-view hierarchy"));
0108 
0109     connect(btnAction, SIGNAL(triggered(bool)),
0110             this, SIGNAL(signalGoPrevious()));
0111 
0112     d->actionsList << btnAction;
0113 
0114     d->previousBtn           = new QToolButton(btnBox);
0115     d->previousBtn->setDefaultAction(btnAction);
0116     d->previousBtn->setFocusPolicy(Qt::NoFocus);
0117 
0118     // ---
0119 
0120     btnAction                = new QAction(this);
0121     btnAction->setObjectName(QLatin1String("GoNext"));
0122     btnAction->setIcon(QIcon::fromTheme(QLatin1String("go-next")));
0123     btnAction->setText(i18nc("@action", "Go to Next"));
0124     btnAction->setToolTip(i18nc("@info", "Go to next place in folder-view hierarchy"));
0125 
0126     connect(btnAction, SIGNAL(triggered(bool)),
0127             this, SIGNAL(signalGoNext()));
0128 
0129     d->actionsList << btnAction;
0130 
0131     d->nextBtn               = new QToolButton(btnBox);
0132     d->nextBtn->setDefaultAction(btnAction);
0133     d->nextBtn->setFocusPolicy(Qt::NoFocus);
0134 
0135     // ---
0136 
0137     btnAction                = new QAction(this);
0138     btnAction->setObjectName(QLatin1String("GoUp"));
0139     btnAction->setIcon(QIcon::fromTheme(QLatin1String("go-up")));
0140     btnAction->setText(i18nc("@action", "Go Up"));
0141     btnAction->setToolTip(i18nc("@info", "Go up in folder-view hierarchy"));
0142 
0143     connect(btnAction, SIGNAL(triggered(bool)),
0144             this, SIGNAL(signalGoUp()));
0145 
0146     d->actionsList << btnAction;
0147 
0148     d->upBtn                 = new QToolButton(btnBox);
0149     d->upBtn->setDefaultAction(btnAction);
0150     d->upBtn->setFocusPolicy(Qt::NoFocus);
0151 
0152     // ---
0153 
0154     btnAction                = new QAction(this);
0155     btnAction->setObjectName(QLatin1String("GoHome"));
0156     btnAction->setIcon(QIcon::fromTheme(QLatin1String("go-home")));
0157     btnAction->setText(i18nc("@action", "Go Home"));
0158     btnAction->setToolTip(i18nc("@info", "Go to home directory"));
0159 
0160     connect(btnAction, SIGNAL(triggered(bool)),
0161             this, SIGNAL(signalGoHome()));
0162 
0163     d->actionsList << btnAction;
0164 
0165     d->homeBtn               = new QToolButton(btnBox);
0166     d->homeBtn->setDefaultAction(btnAction);
0167     d->homeBtn->setFocusPolicy(Qt::NoFocus);
0168 
0169     // ---
0170 
0171     d->iconSizeSlider        = new QSlider(Qt::Horizontal, btnBox);
0172     d->iconSizeSlider->setRange(16, ShowfotoFolderViewModel::maxIconSize());
0173     d->iconSizeSlider->setSingleStep(10);
0174     d->iconSizeSlider->setValue(32);
0175     d->iconSizeSlider->setFocusPolicy(Qt::NoFocus);
0176     btnBox->setStretchFactor(d->iconSizeSlider, 10);
0177 
0178     connect(d->iconSizeSlider, SIGNAL(valueChanged(int)),
0179             this, SLOT(slotIconSizeChanged(int)));
0180 
0181     slotIconSizeChanged(32);
0182 
0183     // ---
0184 
0185     d->optionsBtn              = new QToolButton(btnBox);
0186     d->optionsBtn->setToolTip(i18nc("@info: folder-view", "View Options"));
0187     d->optionsBtn->setIcon(QIcon::fromTheme(QLatin1String("configure")));
0188     d->optionsBtn->setPopupMode(QToolButton::InstantPopup);
0189     d->optionsBtn->setWhatsThis(i18nc("@info: folder-view", "Selection options to render folder-view."));
0190 
0191     d->optionsMenu             = new QMenu(d->optionsBtn);
0192     QActionGroup* const optGrp = new QActionGroup(this);
0193 
0194     d->shortAction             = d->optionsMenu->addAction(i18nc("@action:inmenu", "Short View"));
0195     d->shortAction->setObjectName(QLatin1String("ShortView"));
0196     d->shortAction->setIcon(QIcon::fromTheme(QLatin1String("view-list-text")));
0197     d->shortAction->setToolTip(i18nc("@info", "Switch Folder-View to Short Mode"));
0198     d->shortAction->setCheckable(true);
0199     optGrp->addAction(d->shortAction);
0200 
0201     d->actionsList << d->shortAction;
0202 
0203     d->detailedAction          = d->optionsMenu->addAction(i18nc("@action:inmenu", "Detailed View"));
0204     d->detailedAction->setObjectName(QLatin1String("DetailledView"));
0205     d->detailedAction->setIcon(QIcon::fromTheme(QLatin1String("view-list-details")));
0206     d->detailedAction->setToolTip(i18nc("@info", "Switch Folder-View to Detailed Mode"));
0207     d->detailedAction->setCheckable(true);
0208     optGrp->addAction(d->detailedAction);
0209 
0210     d->actionsList << d->detailedAction;
0211 
0212     optGrp->setExclusive(true);
0213 
0214     d->showBookmarksAction      = d->optionsMenu->addAction(i18nc("@action:inmenu", "Show Bookmarks"));
0215     d->showBookmarksAction->setObjectName(QLatin1String("ShowBookmarks"));
0216     d->showBookmarksAction->setIcon(QIcon::fromTheme(QLatin1String("bookmarks")));
0217     d->showBookmarksAction->setToolTip(i18nc("@info", "Show or Hide the Bookmarked places"));
0218     d->showBookmarksAction->setCheckable(true);
0219 
0220     d->actionsList << d->showBookmarksAction;
0221 
0222     d->moreSettingsAction       = d->optionsMenu->addAction(i18nc("@action:inmenu", "More Settings..."));
0223     d->moreSettingsAction->setObjectName(QLatin1String("MoreSettings"));
0224     d->moreSettingsAction->setIcon(QIcon::fromTheme(QLatin1String("configure")));
0225     d->moreSettingsAction->setToolTip(i18nc("@info", "Open configure dialog with more settings options"));
0226 
0227     d->actionsList << d->moreSettingsAction;
0228 
0229     d->optionsBtn->setMenu(d->optionsMenu);
0230 
0231     connect(d->optionsMenu, SIGNAL(triggered(QAction*)),
0232             this, SLOT(slotOptionsChanged(QAction*)));
0233 
0234     // ---
0235 
0236     d->runBtn                = new QToolButton(btnBox);
0237     d->runBtn->setToolTip(i18nc("@info: folder-view", "Stack Options"));
0238     d->runBtn->setIcon(QIcon::fromTheme(QLatin1String("layer-visible-on")));
0239     d->runBtn->setPopupMode(QToolButton::InstantPopup);
0240     d->runBtn->setWhatsThis(i18nc("@info: folder-view", "Stack options to handle folder-view contents."));
0241 
0242     d->runMenu               = new QMenu(d->runBtn);
0243 
0244     btnAction                = d->runMenu->addAction(i18nc("@action:inmenu", "Load Contents"));
0245     btnAction->setObjectName(QLatin1String("LoadContents"));
0246     btnAction->setIcon(QIcon::fromTheme(QLatin1String("media-playlist-normal")));
0247     btnAction->setText(i18nc("@action", "Load Contents"));
0248     btnAction->setToolTip(i18nc("@info", "Load contents to editor stack"));
0249 
0250     connect(btnAction, SIGNAL(triggered(bool)),
0251             this, SIGNAL(signalLoadContents()));
0252 
0253     d->actionsList << btnAction;
0254 
0255     btnAction                = d->runMenu->addAction(i18nc("@action:inmenu", "Append Contents"));
0256     btnAction->setObjectName(QLatin1String("AppendContents"));
0257     btnAction->setIcon(QIcon::fromTheme(QLatin1String("media-playlist-append")));
0258     btnAction->setText(i18nc("@action", "Append Contents"));
0259     btnAction->setToolTip(i18nc("@info", "Append contents to editor stack"));
0260 
0261     connect(btnAction, SIGNAL(triggered(bool)),
0262             this, SIGNAL(signalAppendContents()));
0263 
0264     d->actionsList << btnAction;
0265 
0266     d->runBtn->setMenu(d->runMenu);
0267 
0268     // ---
0269 
0270     d->pathEdit              = new QComboBox(this);
0271     d->pathEdit->setEditable(true);
0272     d->pathEdit->setDuplicatesEnabled(false);
0273     d->pathEdit->setWhatsThis(i18nc("@info", "Enter the customized folder-view path or select from history"));
0274     d->pathEdit->lineEdit()->setPlaceholderText(i18nc("@info: folder-view path edit", "Enter local path here..."));
0275     d->pathEdit->lineEdit()->setClearButtonEnabled(true);
0276 
0277     connect(d->pathEdit->lineEdit(), SIGNAL(returnPressed()),
0278             this, SLOT(slotCustomPathChanged()));
0279 
0280     connect(d->pathEdit, SIGNAL(textActivated(QString)),
0281             this, SIGNAL(signalCustomPathChanged(QString)));
0282 
0283     // ---
0284 
0285     d->typeMimesCombo = new QComboBox(this);
0286     d->typeMimesCombo->insertItem(TYPE_MIME_JPEG,  i18nc("@item: filter type mime", "JPEG images"),         QLatin1String("*.JPEG *.JPG *.JPE"));
0287     d->typeMimesCombo->insertItem(TYPE_MIME_TIFF,  i18nc("@item: filter type mime", "TIFF images"),         QLatin1String("*.TIFF *.TIF"));
0288     d->typeMimesCombo->insertItem(TYPE_MIME_PNG,   i18nc("@item: filter type mime", "PNG images"),          QLatin1String("*.PNG"));
0289     d->typeMimesCombo->insertItem(TYPE_MIME_PGF,   i18nc("@item: filter type mime", "PGF images"),          QLatin1String("*.PGF"));
0290     d->typeMimesCombo->insertItem(TYPE_MIME_HEIF,  i18nc("@item: filter type mime", "HEIF images"),         QLatin1String("*.HEIF *.HEIC"));
0291     d->typeMimesCombo->insertItem(TYPE_MIME_AVIF,  i18nc("@item: filter type mime", "AVIF images"),         QLatin1String("*.AVIF"));
0292     d->typeMimesCombo->insertItem(TYPE_MIME_JXL,   i18nc("@item: filter type mime", "JPEG-XL images"),      QLatin1String("*.JXL"));
0293     d->typeMimesCombo->insertItem(TYPE_MIME_WEBP,  i18nc("@item: filter type mime", "WEBP images"),         QLatin1String("*.WEBP"));
0294     d->typeMimesCombo->insertItem(TYPE_MIME_DNG,   i18nc("@item: filter type mime", "DNG images"),          QLatin1String("*.DNG"));
0295     d->typeMimesCombo->insertItem(TYPE_MIME_RAW,   i18nc("@item: filter type mime", "RAW images"),          DRawDecoder::rawFiles());
0296 
0297     QString filter;
0298     QString patterns;
0299     (void)supportedImageMimeTypes(QIODevice::WriteOnly, filter);
0300     patterns = filter.toLower();
0301     patterns.append(QLatin1Char(' '));
0302     patterns.append(filter.toUpper());
0303 
0304     d->typeMimesCombo->insertItem(TYPE_MIME_NORAW, i18nc("@item: filter type mime", "No RAW images"),       patterns);
0305 
0306     (void)supportedImageMimeTypes(QIODevice::ReadOnly, filter);
0307     patterns  = filter.toLower();
0308     patterns.append(QLatin1Char(' '));
0309     patterns.append(filter.toUpper());
0310 
0311     d->typeMimesCombo->insertItem( TYPE_MIME_ALL,  i18nc("@item: filter type mime", "All supported files"), patterns);
0312 
0313     connect(d->typeMimesCombo, SIGNAL(activated(int)),
0314             this, SLOT(slotTypeMimesChanged(int)));
0315 }
0316 
0317 ShowfotoFolderViewBar::~ShowfotoFolderViewBar()
0318 {
0319     delete d;
0320 }
0321 
0322 void ShowfotoFolderViewBar::slotTypeMimesChanged(int index)
0323 {
0324     Q_EMIT signalTypeMimesChanged(d->typeMimesCombo->itemData(index).toString());
0325 }
0326 
0327 QAction* ShowfotoFolderViewBar::toolBarAction(const QString& name) const
0328 {
0329     Q_FOREACH (QAction* const act, d->actionsList)
0330     {
0331         if (act && (act->objectName() == name))
0332         {
0333             return act;
0334         }
0335     }
0336 
0337     return nullptr;
0338 }
0339 
0340 QList<QAction*> ShowfotoFolderViewBar::pluginActions() const
0341 {
0342     QList<QAction*> lst;
0343 
0344     Q_FOREACH (QAction* const act, d->actionsList)
0345     {
0346         if (act && (act->data() == d->pluginFingerPrint))
0347         {
0348             lst << act;
0349         }
0350     }
0351 
0352     return lst;
0353 }
0354 
0355 void ShowfotoFolderViewBar::setFolderViewTypeMime(int mime)
0356 {
0357     d->typeMimesCombo->setCurrentIndex(mime);
0358     slotTypeMimesChanged(d->typeMimesCombo->currentIndex());
0359 }
0360 
0361 int ShowfotoFolderViewBar::folderViewTypeMime() const
0362 {
0363     return d->typeMimesCombo->currentIndex();
0364 }
0365 
0366 void ShowfotoFolderViewBar::setFolderViewMode(int mode)
0367 {
0368     if (mode == ShowfotoFolderViewList::ShortView)
0369     {
0370         d->shortAction->setChecked(true);
0371     }
0372     else
0373     {
0374         d->detailedAction->setChecked(true);
0375     }
0376 }
0377 
0378 int ShowfotoFolderViewBar::folderViewMode() const
0379 {
0380     if (d->shortAction->isChecked())
0381     {
0382         return ShowfotoFolderViewList::ShortView;
0383     }
0384 
0385     return ShowfotoFolderViewList::DetailledView;
0386 }
0387 
0388 void ShowfotoFolderViewBar::setBookmarksVisible(bool b)
0389 {
0390     d->showBookmarksAction->setChecked(b);
0391     Q_EMIT signalShowBookmarks(b);
0392 }
0393 
0394 bool ShowfotoFolderViewBar::bookmarksVisible() const
0395 {
0396     return (d->showBookmarksAction->isChecked());
0397 }
0398 
0399 void ShowfotoFolderViewBar::setCurrentPath(const QString& path)
0400 {
0401     d->pathEdit->lineEdit()->setText(path);
0402 
0403     if (d->pathEdit->findText(path) == -1)
0404     {
0405         d->pathEdit->addItem(path);
0406     }
0407 
0408     QDir dir(path);
0409     d->upBtn->setEnabled(dir.cdUp());
0410 }
0411 
0412 QString ShowfotoFolderViewBar::currentPath() const
0413 {
0414     return d->pathEdit->lineEdit()->text();
0415 }
0416 
0417 void ShowfotoFolderViewBar::setIconSize(int size)
0418 {
0419     d->iconSizeSlider->setValue(size);
0420 }
0421 
0422 int ShowfotoFolderViewBar::iconSize() const
0423 {
0424     return d->iconSizeSlider->value();
0425 }
0426 
0427 void ShowfotoFolderViewBar::slotCustomPathChanged()
0428 {
0429     QString path = d->pathEdit->lineEdit()->text();
0430 
0431     if (d->pathEdit->findText(path) == -1)
0432     {
0433         d->pathEdit->addItem(path);
0434     }
0435 
0436     Q_EMIT signalCustomPathChanged(path);
0437 }
0438 
0439 void ShowfotoFolderViewBar::slotPreviousEnabled(bool b)
0440 {
0441     d->previousBtn->setEnabled(b);
0442 }
0443 
0444 void ShowfotoFolderViewBar::slotNextEnabled(bool b)
0445 {
0446     d->nextBtn->setEnabled(b);
0447 }
0448 
0449 void ShowfotoFolderViewBar::slotIconSizeChanged(int size)
0450 {
0451     d->iconSizeSlider->setToolTip(i18nc("@info", "Icon Size: %1", size));
0452 
0453     Q_EMIT signalIconSizeChanged(size);
0454 }
0455 
0456 void ShowfotoFolderViewBar::slotOptionsChanged(QAction* action)
0457 {
0458     if      (action == d->shortAction)
0459     {
0460         Q_EMIT signalViewModeChanged(ShowfotoFolderViewList::ShortView);
0461 
0462         return;
0463     }
0464     else if (action == d->detailedAction)
0465     {
0466         Q_EMIT signalViewModeChanged(ShowfotoFolderViewList::DetailledView);
0467 
0468         return;
0469     }
0470     else if (action == d->showBookmarksAction)
0471     {
0472         Q_EMIT signalShowBookmarks(d->showBookmarksAction->isChecked());
0473 
0474         return;
0475     }
0476     else if (action == d->moreSettingsAction)
0477     {
0478         Q_EMIT signalSetup();
0479 
0480         return;
0481     }
0482 }
0483 
0484 void ShowfotoFolderViewBar::registerPluginActions(const QList<DPluginAction*>& actions)
0485 {
0486     if (!actions.isEmpty())
0487     {
0488         d->runMenu->addSeparator();
0489 
0490         connect(d->runMenu, SIGNAL(triggered(QAction*)),
0491                 this, SIGNAL(signalPluginActionTriggered(QAction*)));
0492 
0493         Q_FOREACH (QAction* const dpact, actions)
0494         {
0495             QAction* const act = d->runMenu->addAction(dpact->text());
0496             act->setObjectName(dpact->objectName());
0497             act->setIcon(dpact->icon());
0498             act->setToolTip(dpact->toolTip());
0499             act->setData(d->pluginFingerPrint);
0500 
0501             d->actionsList << act;
0502 
0503             d->runMenu->addAction(act);
0504         }
0505     }
0506 }
0507 
0508 } // namespace ShowFoto
0509 
0510 #include "moc_showfotofolderviewbar.cpp"