"Fossies" - the Fresh Open Source Software Archive

Member "digikam-6.3.0/core/utilities/advancedrename/advancedrenamewidget.cpp" (4 Sep 2019, 14222 Bytes) of package /linux/misc/digikam-6.3.0.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "advancedrenamewidget.cpp" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 6.2.0_vs_6.3.0.

    1 /* ============================================================
    2  *
    3  * This file is a part of digiKam project
    4  * https://www.digikam.org
    5  *
    6  * Date        : 2009-05-22
    7  * Description : a control widget for the AdvancedRename utility
    8  *
    9  * Copyright (C) 2009-2012 by Andi Clemens <andi dot clemens at gmail dot com>
   10  *
   11  * This program is free software; you can redistribute it
   12  * and/or modify it under the terms of the GNU General
   13  * Public License as published by the Free Software Foundation;
   14  * either version 2, or (at your option)
   15  * any later version.
   16  *
   17  * This program is distributed in the hope that it will be useful,
   18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   20  * GNU General Public License for more details.
   21  *
   22  * ============================================================ */
   23 
   24 #include "advancedrenamewidget.h"
   25 
   26 // Qt includes
   27 
   28 #include <QAction>
   29 #include <QApplication>
   30 #include <QGridLayout>
   31 #include <QIcon>
   32 #include <QMenu>
   33 #include <QPushButton>
   34 #include <QRegExp>
   35 #include <QStyle>
   36 #include <QToolButton>
   37 
   38 // KDE includes
   39 
   40 #include <kconfiggroup.h>
   41 #include <klocalizedstring.h>
   42 #include <ksharedconfig.h>
   43 
   44 // Local includes
   45 
   46 #include "dexpanderbox.h"
   47 #include "advancedrenameinput.h"
   48 #include "defaultrenameparser.h"
   49 #include "dynamiclayout.h"
   50 #include "tooltipcreator.h"
   51 #include "tooltipdialog.h"
   52 
   53 namespace Digikam
   54 {
   55 
   56 class Q_DECL_HIDDEN AdvancedRenameWidget::Private
   57 {
   58     typedef AdvancedRenameWidget::ControlWidgets CWMask;
   59     typedef AdvancedRenameWidget::LayoutStyle    LStyle;
   60 
   61 public:
   62 
   63     explicit Private() :
   64         configExpandedStateDefault(true),
   65         tooltipToggleButton(nullptr),
   66         modifiersToolButton(nullptr),
   67         optionsButton(nullptr),
   68         modifiersButton(nullptr),
   69         btnContainer(nullptr),
   70         tooltipDialog(nullptr),
   71         renameInput(nullptr),
   72         parser(nullptr),
   73         optionsLabel(nullptr),
   74         controlWidgetsMask(AdvancedRenameWidget::DefaultControls),
   75         layoutStyle(AdvancedRenameWidget::LayoutNormal)
   76     {
   77     }
   78 
   79     static const QString configGroupName;
   80     static const QString configExpandedStateEntry;
   81 
   82     bool                 configExpandedStateDefault;
   83 
   84     QToolButton*         tooltipToggleButton;
   85     QToolButton*         modifiersToolButton;
   86 
   87     QPushButton*         optionsButton;
   88     QPushButton*         modifiersButton;
   89 
   90     QWidget*             btnContainer;
   91 
   92     TooltipDialog*       tooltipDialog;
   93     AdvancedRenameInput* renameInput;
   94     Parser*              parser;
   95     DLabelExpander*      optionsLabel;
   96 
   97     CWMask               controlWidgetsMask;
   98     LStyle               layoutStyle;
   99 };
  100 
  101 const QString AdvancedRenameWidget::Private::configGroupName(QLatin1String("AdvancedRename Widget"));
  102 const QString AdvancedRenameWidget::Private::configExpandedStateEntry(QLatin1String("Options are expanded"));
  103 
  104 // --------------------------------------------------------
  105 
  106 AdvancedRenameWidget::AdvancedRenameWidget(QWidget* const parent)
  107     : QWidget(parent),
  108       d(new Private)
  109 {
  110     setupWidgets();
  111 }
  112 
  113 AdvancedRenameWidget::~AdvancedRenameWidget()
  114 {
  115     writeSettings();
  116     delete d;
  117 }
  118 
  119 QString AdvancedRenameWidget::parseString() const
  120 {
  121     return d->renameInput->text();
  122 }
  123 
  124 void AdvancedRenameWidget::setParseString(const QString& text)
  125 {
  126     d->renameInput->setText(text);
  127 }
  128 
  129 void AdvancedRenameWidget::setParseTimerDuration(int milliseconds)
  130 {
  131     d->renameInput->setParseTimerDuration(milliseconds);
  132 }
  133 
  134 void AdvancedRenameWidget::clearParseString()
  135 {
  136     d->renameInput->slotClearText();
  137 }
  138 
  139 void AdvancedRenameWidget::clear()
  140 {
  141     d->renameInput->slotClearTextAndHistory();
  142 }
  143 
  144 QString AdvancedRenameWidget::parse(ParseSettings& settings) const
  145 {
  146     if (!d->parser)
  147     {
  148         return QString();
  149     }
  150 
  151     settings.parseString = d->renameInput->text();
  152 
  153     QString parsed;
  154     parsed = d->parser->parse(settings);
  155 
  156     return parsed;
  157 }
  158 
  159 void AdvancedRenameWidget::createToolTip()
  160 {
  161     d->tooltipDialog->clearTooltip();
  162 
  163     if (d->parser)
  164     {
  165         d->tooltipDialog->setTooltip(TooltipCreator::getInstance().tooltip(d->parser));
  166     }
  167 }
  168 
  169 void AdvancedRenameWidget::slotToolTipButtonToggled(bool checked)
  170 {
  171     Q_UNUSED(checked)
  172 
  173     if (!d->tooltipDialog->isVisible())
  174     {
  175         d->tooltipDialog->show();
  176     }
  177 
  178     d->tooltipDialog->raise();
  179 }
  180 
  181 void AdvancedRenameWidget::setLayoutStyle(LayoutStyle style)
  182 {
  183     d->layoutStyle = style;
  184     calculateLayout();
  185 }
  186 
  187 void AdvancedRenameWidget::setControlWidgets(ControlWidgets mask)
  188 {
  189     d->controlWidgetsMask = mask;
  190 
  191     // we need a parser and at least one renaming option to successfully use
  192     // this widget.
  193     bool enable       = d->parser && !(d->parser->options().isEmpty());
  194 
  195     // enable the modifier toolbutton if environment has been set up correctly
  196     bool enableModBtn = enable && !(d->parser->modifiers().isEmpty());
  197 
  198     d->renameInput->setEnabled(enable);
  199     d->tooltipToggleButton->setVisible(enable && (mask & ToolTipButton));
  200 
  201     // layout specific
  202     if (d->layoutStyle == LayoutNormal)
  203     {
  204         d->optionsLabel->setVisible(enable && (mask & TokenButtons));
  205         d->modifiersToolButton->setVisible(enableModBtn && (mask & ModifierToolButton));
  206     }
  207     else
  208     {
  209         d->optionsButton->setVisible(enableModBtn && (mask & TokenButtons));
  210         d->modifiersButton->setVisible(enableModBtn && (mask & ModifierToolButton));
  211     }
  212 }
  213 
  214 QMenu* AdvancedRenameWidget::createControlsMenu(QWidget* parent, const RulesList& rules)
  215 {
  216     QMenu* const menu = new QMenu(parent);
  217     QAction* action   = nullptr;
  218 
  219     foreach(Rule* const rule, rules)
  220     {
  221         action = rule->registerMenu(menu);
  222 
  223         if (!action)
  224         {
  225             continue;
  226         }
  227 
  228         connect(rule, SIGNAL(signalTokenTriggered(QString)),
  229                 d->renameInput, SLOT(slotAddToken(QString)));
  230     }
  231 
  232     return menu;
  233 }
  234 
  235 void AdvancedRenameWidget::registerParserControls()
  236 {
  237     if (d->parser)
  238     {
  239         setupWidgets();
  240 
  241         RulesList optionsList   = d->parser->options();
  242         RulesList modifiersList = d->parser->modifiers();
  243 
  244         if (d->layoutStyle == LayoutNormal)
  245         {
  246             // register options
  247             QPushButton* btn      = nullptr;
  248             DynamicLayout* const layout = new DynamicLayout(QApplication::style()->pixelMetric(QStyle::PM_DefaultChildMargin),
  249                                                             QApplication::style()->pixelMetric(QStyle::PM_DefaultChildMargin));
  250 
  251             foreach(Rule* const p, d->parser->options())
  252             {
  253                 btn = p->registerButton(this);
  254 
  255                 if (!btn)
  256                 {
  257                     continue;
  258                 }
  259 
  260                 // set button tooltip
  261                 btn->setToolTip(p->description());
  262 
  263                 layout->addWidget(btn);
  264 
  265                 connect(p, SIGNAL(signalTokenTriggered(QString)),
  266                         d->renameInput, SLOT(slotAddToken(QString)));
  267             }
  268 
  269             d->btnContainer->setLayout(layout);
  270             setMinimumWidth(d->btnContainer->layout()->sizeHint().width());
  271 
  272             // register modifiers
  273             QMenu* const modifiersMenu = createControlsMenu(d->modifiersToolButton, modifiersList);
  274             d->modifiersToolButton->setMenu(modifiersMenu);
  275         }
  276         else    // LayoutCompact
  277         {
  278             // register options
  279             QMenu* const optionsMenu = createControlsMenu(d->optionsButton, optionsList);
  280             d->optionsButton->setMenu(optionsMenu);
  281 
  282             // register modifiers
  283             QMenu* const modifiersMenu = createControlsMenu(d->modifiersButton, modifiersList);
  284             d->modifiersButton->setMenu(modifiersMenu);
  285         }
  286 
  287         // --------------------------------------------------------
  288 
  289         d->renameInput->setParser(d->parser);
  290         createToolTip();
  291     }
  292 }
  293 
  294 Parser* AdvancedRenameWidget::parser() const
  295 {
  296     return d->parser;
  297 }
  298 
  299 void AdvancedRenameWidget::setParser(Parser* parser)
  300 {
  301     if (!parser)
  302     {
  303         return;
  304     }
  305 
  306     d->parser = parser;
  307 
  308     calculateLayout();
  309 }
  310 
  311 void AdvancedRenameWidget::calculateLayout()
  312 {
  313     registerParserControls();
  314     setControlWidgets(d->controlWidgetsMask);
  315 }
  316 
  317 void AdvancedRenameWidget::setupWidgets()
  318 {
  319     /*
  320      * This methods needs to delete all main widgets, do not remove the delete lines!
  321      * If a new parser is set or the layout has changed, we need to call setupWidgets() again.
  322      * So any widget that is created in here needs to be removed first, to avoid memory leaks and
  323      * duplicate signal/slot connections.
  324      */
  325     delete d->tooltipDialog;
  326     delete d->renameInput;
  327     delete d->tooltipToggleButton;
  328     delete d->optionsButton;
  329     delete d->modifiersButton;
  330     delete d->btnContainer;
  331     delete d->optionsLabel;
  332     delete d->modifiersToolButton;
  333 
  334     // --------------------------------------------------------
  335 
  336     d->tooltipDialog = new TooltipDialog(this);
  337     d->tooltipDialog->resize(650, 530);
  338 
  339     d->renameInput = new AdvancedRenameInput;
  340     d->renameInput->setToolTip(i18n("<p>Enter your renaming pattern here. Use the access buttons to quickly add renaming "
  341                                     "options and modifiers. For further explanation, use the information button.</p>"));
  342 
  343     // --------------------------------------------------------
  344 
  345     d->tooltipToggleButton = new QToolButton;
  346     d->tooltipToggleButton->setIcon(QIcon::fromTheme(QLatin1String("dialog-information")));
  347     d->tooltipToggleButton->setToolTip(i18n("Show a list of all available options"));
  348 
  349     // --------------------------------------------------------
  350 
  351     QString modifiersStr     = i18n("Modifiers");
  352     QIcon   modifiersIcon    = QIcon::fromTheme(QLatin1String("document-edit"));
  353     QString modifiersTooltip = i18n("<p>Add a modifier to a renaming option. "
  354                                     "To activate this button, place the cursor behind a renaming option "
  355                                     "or an already assigned modifier.</p>");
  356 
  357     // --------------------------------------------------------
  358 
  359     delete layout();
  360     QGridLayout* const mainLayout = new QGridLayout;
  361 
  362     if (d->layoutStyle == LayoutNormal)
  363     {
  364         d->btnContainer = new QWidget(this);
  365 
  366         d->optionsLabel = new DLabelExpander(this);
  367         d->optionsLabel->setText(i18n("Renaming Options"));
  368         d->optionsLabel->setWidget(d->btnContainer);
  369         d->optionsLabel->setLineVisible(false);
  370 
  371         d->modifiersToolButton = new QToolButton;
  372         d->modifiersToolButton->setPopupMode(QToolButton::InstantPopup);
  373         d->modifiersToolButton->setText(modifiersStr);
  374         d->modifiersToolButton->setIcon(modifiersIcon);
  375         d->modifiersToolButton->setToolTip(modifiersTooltip);
  376 
  377         mainLayout->addWidget(d->renameInput,           0, 0, 1, 1);
  378         mainLayout->addWidget(d->modifiersToolButton,   0, 1, 1, 1);
  379         mainLayout->addWidget(d->tooltipToggleButton,   0, 2, 1, 1);
  380         mainLayout->addWidget(d->optionsLabel,          1, 0, 1, -1);
  381         mainLayout->setColumnStretch(0, 10);
  382     }
  383     else
  384     {
  385         d->optionsButton = new QPushButton;
  386         d->optionsButton->setText(i18n("Options"));
  387         d->optionsButton->setIcon(QIcon::fromTheme(QLatin1String("configure")));
  388         d->optionsButton->setToolTip(i18n("<p>Add renaming options to the parse string.</p>"));
  389 
  390         // --------------------------------------------------------
  391 
  392         d->modifiersButton = new QPushButton;
  393         d->modifiersButton->setText(modifiersStr);
  394         d->modifiersButton->setIcon(modifiersIcon);
  395         d->modifiersButton->setToolTip(modifiersTooltip);
  396 
  397         mainLayout->addWidget(d->renameInput,           0, 0, 1, -1);
  398         mainLayout->addWidget(d->optionsButton,         1, 0, 1, 1);
  399         mainLayout->addWidget(d->modifiersButton,       1, 1, 1, 1);
  400         mainLayout->addWidget(d->tooltipToggleButton,   1, 3, 1, 1);
  401         mainLayout->setColumnStretch(2, 10);
  402     }
  403 
  404     mainLayout->setSpacing(QApplication::style()->pixelMetric(QStyle::PM_DefaultChildMargin));
  405     mainLayout->setContentsMargins(QMargins());
  406     setLayout(mainLayout);
  407 
  408     // --------------------------------------------------------
  409 
  410     connect(d->tooltipToggleButton, SIGNAL(clicked(bool)),
  411             this, SLOT(slotToolTipButtonToggled(bool)));
  412 
  413     connect(d->renameInput, SIGNAL(signalTextChanged(QString)),
  414             this, SIGNAL(signalTextChanged(QString)));
  415 
  416     connect(d->renameInput, SIGNAL(signalTokenMarked(bool)),
  417             this, SLOT(slotTokenMarked(bool)));
  418 
  419     connect(d->renameInput, SIGNAL(signalReturnPressed()),
  420             this, SIGNAL(signalReturnPressed()));
  421 
  422     slotTokenMarked(false);
  423     readSettings();
  424 }
  425 
  426 void AdvancedRenameWidget::slotTokenMarked(bool marked)
  427 {
  428     bool enable    = marked && d->parser;
  429     bool enableMod = enable && !(d->parser->modifiers().isEmpty());
  430 
  431     if (d->layoutStyle == LayoutNormal)
  432     {
  433         d->modifiersToolButton->setEnabled(enableMod);
  434     }
  435     else
  436     {
  437         d->modifiersButton->setEnabled(enableMod);
  438     }
  439 }
  440 
  441 void AdvancedRenameWidget::focusLineEdit()
  442 {
  443     d->renameInput->slotSetFocus();
  444 }
  445 
  446 void AdvancedRenameWidget::highlightLineEdit()
  447 {
  448     d->renameInput->slotHighlightLineEdit();
  449 }
  450 
  451 void AdvancedRenameWidget::highlightLineEdit(const QString& word)
  452 {
  453     d->renameInput->slotHighlightLineEdit(word);
  454 }
  455 
  456 void AdvancedRenameWidget::readSettings()
  457 {
  458     KSharedConfig::Ptr config = KSharedConfig::openConfig();
  459     KConfigGroup group        = config->group(d->configGroupName);
  460 
  461     if (d->layoutStyle == LayoutNormal)
  462     {
  463         d->optionsLabel->setExpanded(group.readEntry(d->configExpandedStateEntry, d->configExpandedStateDefault));
  464     }
  465 }
  466 
  467 void AdvancedRenameWidget::writeSettings()
  468 {
  469     KSharedConfig::Ptr config = KSharedConfig::openConfig();
  470     KConfigGroup group        = config->group(d->configGroupName);
  471 
  472     if (d->layoutStyle == LayoutNormal)
  473     {
  474         group.writeEntry(d->configExpandedStateEntry, d->optionsLabel
  475                          ? d->optionsLabel->isExpanded()
  476                          : d->configExpandedStateDefault);
  477     }
  478 }
  479 
  480 } // namespace Digikam