• Skip to content
  • Skip to link menu
KDE 4.4 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

digikam

advancedrenamewidget.cpp

Go to the documentation of this file.
00001 /* ============================================================
00002  *
00003  * This file is a part of digiKam project
00004  * http://www.digikam.org
00005  *
00006  * Date        : 2009-05-22
00007  * Description : a control widget for the AdvancedRename utility
00008  *
00009  * Copyright (C) 2009 by Andi Clemens <andi dot clemens at gmx dot net>
00010  *
00011  * This program is free software; you can redistribute it
00012  * and/or modify it under the terms of the GNU General
00013  * Public License as published by the Free Software Foundation;
00014  * either version 2, or (at your option)
00015  * any later version.
00016  *
00017  * This program is distributed in the hope that it will be useful,
00018  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00019  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020  * GNU General Public License for more details.
00021  *
00022  * ============================================================ */
00023 
00024 #include "advancedrenamewidget.moc"
00025 
00026 // Qt includes
00027 
00028 #include <QAction>
00029 #include <QGridLayout>
00030 #include <QMenu>
00031 #include <QPushButton>
00032 #include <QRegExp>
00033 #include <QToolButton>
00034 
00035 // KDE includes
00036 
00037 #include <kconfig.h>
00038 #include <kconfiggroup.h>
00039 #include <kdialog.h>
00040 #include <kicon.h>
00041 #include <kiconloader.h>
00042 #include <klocale.h>
00043 
00044 // Local includes
00045 
00046 #include "advancedrenameinput.h"
00047 #include "dcursortracker.h"
00048 #include "defaultrenameparser.h"
00049 #include "dynamiclayout.h"
00050 #include "rexpanderbox.h"
00051 #include "themeengine.h"
00052 
00053 namespace Digikam
00054 {
00055 
00056 class AdvancedRenameWidgetPriv
00057 {
00058     typedef AdvancedRenameWidget::ControlWidgets CWMask;
00059 
00060 public:
00061 
00062     AdvancedRenameWidgetPriv() :
00063         configGroupName("AdvancedRename Widget"),
00064         configExpandedStateEntry("Options are expanded"),
00065         configExpandedStateDefault(true),
00066 
00067         tooltipToggleButton(0),
00068         tokenToolButton(0),
00069         modifierToolButton(0),
00070         btnContainer(0),
00071         tooltipTrackerAlignment(Qt::AlignLeft),
00072         tooltipTracker(0),
00073         renameInput(0),
00074         parser(0),
00075         optionsLabel(0),
00076         controlWidgetsMask(AdvancedRenameWidget::DefaultControls)
00077     {}
00078 
00079     const QString        configGroupName;
00080     const QString        configExpandedStateEntry;
00081     bool                 configExpandedStateDefault;
00082 
00083     QToolButton*         tooltipToggleButton;
00084     QToolButton*         tokenToolButton;
00085     QToolButton*         modifierToolButton;
00086 
00087     QWidget*             btnContainer;
00088 
00089     Qt::Alignment        tooltipTrackerAlignment;
00090 
00091     DTipTracker*         tooltipTracker;
00092     AdvancedRenameInput* renameInput;
00093     Parser*              parser;
00094     RLabelExpander*      optionsLabel;
00095 
00096     CWMask               controlWidgetsMask;
00097 };
00098 
00099 AdvancedRenameWidget::AdvancedRenameWidget(QWidget* parent)
00100                  : QWidget(parent), d(new AdvancedRenameWidgetPriv)
00101 {
00102     setupWidgets();
00103     setParser(new DefaultRenameParser());
00104 }
00105 
00106 AdvancedRenameWidget::~AdvancedRenameWidget()
00107 {
00108     writeSettings();
00109 
00110     // we need to delete it manually, because it has no parent
00111     delete d->tooltipTracker;
00112 
00113     delete d->parser;
00114     delete d;
00115 }
00116 
00117 QString AdvancedRenameWidget::text() const
00118 {
00119     return d->renameInput->text();
00120 }
00121 
00122 void AdvancedRenameWidget::setText(const QString& text)
00123 {
00124     d->renameInput->setText(text);
00125 }
00126 
00127 void AdvancedRenameWidget::clearText()
00128 {
00129     d->renameInput->clearText();
00130 }
00131 
00132 void AdvancedRenameWidget::setTooltipAlignment(Qt::Alignment alignment)
00133 {
00134     d->tooltipTrackerAlignment = alignment;
00135     d->tooltipTracker->setTrackerAlignment(alignment);
00136 }
00137 
00138 void AdvancedRenameWidget::clear()
00139 {
00140     d->renameInput->clearTextAndHistory();
00141 }
00142 
00143 void AdvancedRenameWidget::slotHideToolTipTracker()
00144 {
00145     d->tooltipToggleButton->setChecked(false);
00146     slotToolTipButtonToggled(false);
00147 }
00148 
00149 QString AdvancedRenameWidget::parse(ParseInformation& info) const
00150 {
00151     if (!d->parser)
00152     {
00153         return QString();
00154     }
00155 
00156     QString parseString = d->renameInput->text();
00157 
00158     QString parsed;
00159     parsed = d->parser->parse(parseString, info);
00160 
00161     return parsed;
00162 }
00163 
00164 void AdvancedRenameWidget::createToolTip()
00165 {
00166     QRegExp optionsRegExp("\\|(.*)\\|");
00167     optionsRegExp.setMinimal(true);
00168 
00169 
00170 #define MARK_OPTIONS(str)                                                                      \
00171         str.replace(optionsRegExp, QString("<i><font color=\"%1\">\\1</font></i>")             \
00172            .arg(ThemeEngine::instance()->textSpecialRegColor().name()))
00173 
00174 #define TOOLTIP_HEADER(str)                                                                    \
00175     do                                                                                         \
00176     {                                                                                          \
00177         tooltip += QString("<tr bgcolor=\"%1\"><td colspan=\"2\">"                             \
00178                            "<nobr><font color=\"%2\"><center><b>")                             \
00179                            .arg(ThemeEngine::instance()->baseColor().name())                   \
00180                            .arg(ThemeEngine::instance()->textRegColor().name());               \
00181         tooltip += QString(str);                                                               \
00182         tooltip += QString("</b></center></font></nobr></td></tr>");                           \
00183     } while (0)                                                                                \
00184 
00185 
00186 #define TOOLTIP_ENTRIES(type, data)                                                            \
00187     do                                                                                         \
00188     {                                                                                          \
00189         foreach (type* t, data)                                                                \
00190         {                                                                                      \
00191             foreach (Token* token, t->tokens())                                                \
00192             {                                                                                  \
00193                 tooltip += QString("<tr>"                                                      \
00194                                    "<td bgcolor=\"%1\">"                                       \
00195                                        "<font color=\"%2\"><b>&nbsp;%3&nbsp;</b></font></td>"  \
00196                                    "<td>&nbsp;%4&nbsp;</td></tr>")                             \
00197                                    .arg(ThemeEngine::instance()->baseColor().name())           \
00198                                    .arg(ThemeEngine::instance()->textRegColor().name())        \
00199                                    .arg(MARK_OPTIONS(token->id()))                             \
00200                                    .arg(MARK_OPTIONS(token->description()));                   \
00201             }                                                                                  \
00202         }                                                                                      \
00203     } while (0)
00204 
00205     // --------------------------------------------------------
00206 
00207     if (!d->parser)
00208     {
00209         d->tooltipTracker->setText(QString());
00210     }
00211     else
00212     {
00213         QString tooltip;
00214         tooltip += QString("<qt><table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">");
00215 
00216         // --------------------------------------------------------
00217 
00218         TOOLTIP_HEADER(i18n("Renaming Options"));
00219         TOOLTIP_ENTRIES(Option, d->parser->options());
00220 
00221         tooltip += QString("<tr></tr>");
00222 
00223         TOOLTIP_HEADER(i18n("Modifiers"));
00224         TOOLTIP_ENTRIES(Modifier, d->parser->modifiers());
00225 
00226         // --------------------------------------------------------
00227 
00228         tooltip += QString("</table></qt>");
00229         tooltip += i18n("<p>Modifiers can be applied to every renaming option. <br/>"
00230                         "They are applied in the order you assign them. It is possible to chain modifiers.</p>");
00231 
00232         d->tooltipTracker->setText(tooltip);
00233     }
00234 
00235     // --------------------------------------------------------
00236 
00237 #undef TOOLTIP_HEADER
00238 #undef TOOLTIP_ENTRIES
00239 #undef MARK_OPTIONS
00240 }
00241 
00242 void AdvancedRenameWidget::slotToolTipButtonToggled(bool checked)
00243 {
00244     d->tooltipTracker->setVisible(checked);
00245     slotUpdateTrackerPos();
00246 }
00247 
00248 void AdvancedRenameWidget::slotUpdateTrackerPos()
00249 {
00250     d->tooltipTracker->refresh();
00251 }
00252 
00253 void AdvancedRenameWidget::setControlWidgets(ControlWidgets mask)
00254 {
00255     bool enable       = d->parser && !(d->parser->options().isEmpty());
00256     bool enableModBtn = enable && !(d->parser->modifiers().isEmpty());
00257 
00258     d->renameInput->setEnabled(enable);
00259     d->optionsLabel->setVisible(enable && (mask & TokenButtons));
00260     d->tokenToolButton->setVisible(enable && (mask & TokenToolButton));
00261     d->modifierToolButton->setVisible(enableModBtn && (mask & ModifierToolButton));
00262     d->tooltipToggleButton->setVisible(enable && (mask & ToolTipButton));
00263 
00264     d->controlWidgetsMask = mask;
00265 }
00266 
00267 void AdvancedRenameWidget::registerParserControls()
00268 {
00269    if (d->parser)
00270    {
00271        setupWidgets();
00272 
00273        QMenu* tokenToolBtnMenu    = new QMenu(d->tokenToolButton);
00274        QMenu* modifierToolBtnMenu = new QMenu(d->modifierToolButton);
00275        QPushButton* btn           = 0;
00276        QAction* action            = 0;
00277        DynamicLayout* layout      = new DynamicLayout(KDialog::marginHint(), KDialog::marginHint());
00278 
00279        foreach (Option* option, d->parser->options())
00280        {
00281            btn    = option->registerButton(this);
00282            action = option->registerMenu(tokenToolBtnMenu);
00283 
00284            if (!btn || !action)
00285            {
00286                continue;
00287            }
00288 
00289            // set button tooltip
00290            btn->setToolTip(option->description());
00291 
00292            layout->addWidget(btn);
00293 
00294            connect(option, SIGNAL(signalTokenTriggered(const QString&)),
00295                    d->renameInput, SLOT(slotAddToken(const QString&)));
00296        }
00297 
00298        // --------------------------------------------------------
00299 
00300        // register modifiers
00301        foreach (Modifier* modifier, d->parser->modifiers())
00302        {
00303            action = modifier->registerMenu(modifierToolBtnMenu);
00304            if (!action)
00305            {
00306                continue;
00307            }
00308 
00309            connect(modifier, SIGNAL(signalTokenTriggered(const QString&)),
00310                    d->renameInput, SLOT(slotAddToken(const QString&)));
00311        }
00312 
00313        // --------------------------------------------------------
00314 
00315        d->btnContainer->setLayout(layout);
00316        setMinimumWidth(d->btnContainer->layout()->sizeHint().width());
00317 
00318        d->tokenToolButton->setMenu(tokenToolBtnMenu);
00319        d->modifierToolButton->setMenu(modifierToolBtnMenu);
00320 
00321        d->renameInput->setParser(d->parser);
00322        createToolTip();
00323    }
00324 }
00325 
00326 void AdvancedRenameWidget::setParser(Parser* parser)
00327 {
00328     if (!parser)
00329     {
00330         return;
00331     }
00332 
00333     if (d->parser)
00334     {
00335         delete d->parser;
00336     }
00337     d->parser = parser;
00338 
00339     registerParserControls();
00340     setControlWidgets(d->controlWidgetsMask);
00341 }
00342 
00343 void AdvancedRenameWidget::setupWidgets()
00344 {
00345     /*
00346      * This methods needs to delete all main widgets, do not remove the delete lines!
00347      * If a new parser is set or the layout has changed, we need to call setupWidgets() again.
00348      * So any widget that is created in here needs to be removed first, to avoid memory leaks and
00349      * duplicate signal/slot connections.
00350      */
00351     delete d->renameInput;
00352     d->renameInput = new AdvancedRenameInput;
00353 
00354     delete d->tooltipToggleButton;
00355     d->tooltipToggleButton = new QToolButton;
00356     d->tooltipToggleButton->setCheckable(true);
00357     d->tooltipToggleButton->setIcon(SmallIcon("dialog-information"));
00358     d->tooltipToggleButton->setToolTip(i18n("Show help"));
00359 
00360     // --------------------------------------------------------
00361 
00362     delete d->btnContainer;
00363     d->btnContainer = new QWidget(this);
00364 
00365     delete d->optionsLabel;
00366     d->optionsLabel = new RLabelExpander(this);
00367     d->optionsLabel->setText(i18n("Renaming Options"));
00368     d->optionsLabel->setWidget(d->btnContainer);
00369     d->optionsLabel->setLineVisible(false);
00370 
00371     // --------------------------------------------------------
00372 
00373     delete d->tokenToolButton;
00374     d->tokenToolButton = new QToolButton;
00375     d->tokenToolButton->setPopupMode(QToolButton::InstantPopup);
00376     d->tokenToolButton->setIcon(SmallIcon("list-add"));
00377     d->tokenToolButton->setToolTip(i18n("Quickly add a renaming option"));
00378 
00379     delete d->modifierToolButton;
00380     d->modifierToolButton = new QToolButton;
00381     d->modifierToolButton->setPopupMode(QToolButton::InstantPopup);
00382     d->modifierToolButton->setIcon(SmallIcon("document-edit"));
00383     d->modifierToolButton->setToolTip(i18n("Quickly add a modifier to a renaming option"));
00384 
00385     // --------------------------------------------------------
00386 
00387     // Although we delete every other widget in here, DON'T delete this one!
00388     // It has a parent now and will be deleted automatically.
00389     d->tooltipTracker = new DTipTracker(QString(), d->renameInput, Qt::AlignLeft);
00390     d->tooltipTracker->setTextFormat(Qt::RichText);
00391     d->tooltipTracker->setEnable(false);
00392     d->tooltipTracker->setKeepOpen(true);
00393     d->tooltipTracker->setOpenExternalLinks(true);
00394     setTooltipAlignment(d->tooltipTrackerAlignment);
00395 
00396     // --------------------------------------------------------
00397 
00398     delete layout();
00399     QGridLayout* mainLayout = new QGridLayout;
00400     mainLayout->addWidget(d->renameInput,         0, 0, 1, 1);
00401     mainLayout->addWidget(d->tooltipToggleButton, 0, 1, 1, 1);
00402     mainLayout->addWidget(d->tokenToolButton,     0, 2, 1, 1);
00403     mainLayout->addWidget(d->modifierToolButton,  0, 3, 1, 1);
00404     mainLayout->addWidget(d->optionsLabel,        1, 0, 1,-1);
00405     mainLayout->setColumnStretch(0, 10);
00406     mainLayout->setMargin(0);
00407     mainLayout->setSpacing(KDialog::marginHint());
00408     setLayout(mainLayout);
00409 
00410     // --------------------------------------------------------
00411 
00412     connect(d->tooltipToggleButton, SIGNAL(toggled(bool)),
00413             this, SLOT(slotToolTipButtonToggled(bool)));
00414 
00415     connect(d->renameInput, SIGNAL(signalTextChanged(const QString&)),
00416             this, SIGNAL(signalTextChanged(const QString&)));
00417 
00418     connect(d->renameInput, SIGNAL(signalTokenMarked(bool)),
00419             this, SLOT(slotTokenMarked(bool)));
00420 
00421     connect(d->renameInput, SIGNAL(signalReturnPressed()),
00422             this, SIGNAL(signalReturnPressed()));
00423 
00424     slotTokenMarked(false);
00425     readSettings();
00426 }
00427 
00428 void AdvancedRenameWidget::slotTokenMarked(bool marked)
00429 {
00430     bool enable    = marked && d->parser;
00431     bool enableMod = enable && !(d->parser->modifiers().isEmpty());
00432     d->modifierToolButton->setEnabled(enableMod);
00433 }
00434 
00435 void AdvancedRenameWidget::focusLineEdit()
00436 {
00437     d->renameInput->setFocus();
00438 }
00439 
00440 void AdvancedRenameWidget::readSettings()
00441 {
00442     KSharedConfig::Ptr config = KGlobal::config();
00443     KConfigGroup group        = config->group(d->configGroupName);
00444     d->optionsLabel->setExpanded(group.readEntry(d->configExpandedStateEntry, d->configExpandedStateDefault));
00445 }
00446 
00447 void AdvancedRenameWidget::writeSettings()
00448 {
00449     KSharedConfig::Ptr config = KGlobal::config();
00450     KConfigGroup group        = config->group(d->configGroupName);
00451 
00452     // remove duplicate entries and save pattern history, omit empty strings
00453     QString pattern = d->renameInput->text();
00454     group.writeEntry(d->configExpandedStateEntry, d->optionsLabel
00455                                                   ? d->optionsLabel->isExpanded()
00456                                                   : d->configExpandedStateDefault);
00457 }
00458 
00459 }  // namespace Digikam

digikam

Skip menu "digikam"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members

API Reference

Skip menu "API Reference"
  • digikam
Generated for API Reference by doxygen 1.5.9-20090814
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal