00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "advancedrenamewidget.moc"
00025
00026
00027
00028 #include <QAction>
00029 #include <QGridLayout>
00030 #include <QMenu>
00031 #include <QPushButton>
00032 #include <QRegExp>
00033 #include <QToolButton>
00034
00035
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
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
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> %3 </b></font></td>" \
00196 "<td> %4 </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
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
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
00347
00348
00349
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
00388
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
00453 QString pattern = d->renameInput->text();
00454 group.writeEntry(d->configExpandedStateEntry, d->optionsLabel
00455 ? d->optionsLabel->isExpanded()
00456 : d->configExpandedStateDefault);
00457 }
00458
00459 }