File indexing completed on 2025-03-09 03:57:07

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2009-08-08
0007  * Description : an option to add a sequence number to the parser
0008  *
0009  * SPDX-FileCopyrightText: 2009-2012 by Andi Clemens <andi dot clemens at gmail dot com>
0010  *
0011  * SPDX-License-Identifier: GPL-2.0-or-later
0012  *
0013  * ============================================================ */
0014 
0015 #include "sequencenumberoption.h"
0016 
0017 // Qt includes
0018 
0019 #include <QLabel>
0020 #include <QPointer>
0021 #include <QGroupBox>
0022 #include <QGridLayout>
0023 #include <QRegularExpression>
0024 
0025 // KDE includes
0026 
0027 #include <klocalizedstring.h>
0028 
0029 // Local includes
0030 
0031 #include "digikam_debug.h"
0032 #include "ui_sequencenumberoptiondialogwidget.h"
0033 
0034 namespace Digikam
0035 {
0036 
0037 SequenceNumberDialog::SequenceNumberDialog(Rule* const parent)
0038     : RuleDialog(parent),
0039       ui(new Ui::SequenceNumberOptionDialogWidget())
0040 {
0041     QWidget* const mainWidget = new QWidget(this);
0042     ui->setupUi(mainWidget);
0043     setSettingsWidget(mainWidget);
0044     ui->digits->setFocus();
0045 }
0046 
0047 SequenceNumberDialog::~SequenceNumberDialog()
0048 {
0049     delete ui;
0050 }
0051 
0052 // --------------------------------------------------------
0053 
0054 SequenceNumberOption::SequenceNumberOption()
0055     : Option(i18nc("Sequence Number", "Number..."),
0056              i18n("Add a sequence number"),
0057              QLatin1String("accessories-calculator"))
0058 {
0059     addToken(QLatin1String("#"),                                 i18n("Sequence number"));
0060     addToken(QLatin1String("#[||options||]"),                    i18n("Sequence number (||options||: "
0061                                                                       "||c|| = file counter aware, "
0062                                                                       "||e|| = extension aware, "
0063                                                                       "||f|| = folder aware, "
0064                                                                       "||r|| = random aware, "
0065                                                                       "||ce|| = counter and extension aware, "
0066                                                                       "||re|| = random and extension aware)"));
0067     addToken(QLatin1String("#[||options||,||start||]"),          i18n("Sequence number (custom start) "
0068                                                                       "||options||: ||e||, ||f||"));
0069     addToken(QLatin1String("#[||options||,||step||]"),           i18n("Sequence number (custom step) "
0070                                                                       "||options||: ||c||"));
0071     addToken(QLatin1String("#[||options||,||start||,||step||]"), i18n("Sequence number (custom start + step) "
0072                                                                       "||options||: ||e||, ||f||"));
0073 
0074     QRegularExpression reg(QLatin1String("(#+)(\\[(([cefr]?|ce?|re?)?,?)?((-?\\d+)(,(-?\\d+))?)?\\])?"));
0075     setRegExp(reg);
0076 }
0077 
0078 SequenceNumberOption::~SequenceNumberOption()
0079 {
0080 }
0081 
0082 void SequenceNumberOption::slotTokenTriggered(const QString& token)
0083 {
0084     Q_UNUSED(token)
0085 
0086     QPointer<SequenceNumberDialog> dlg = new SequenceNumberDialog(this);
0087 
0088     QString result;
0089 
0090     if (dlg->exec() == QDialog::Accepted)
0091     {
0092         int digits          = dlg->ui->digits->value();
0093         int start           = dlg->ui->start->value();
0094         int step            = dlg->ui->step->value();
0095         bool extensionAware = (dlg->ui->extensionAware->isChecked()    ||
0096                                dlg->ui->randomAndExtAware->isChecked() ||
0097                                dlg->ui->counterAndExtAware->isChecked());
0098         bool counterAware   = (dlg->ui->counterAware->isChecked()      ||
0099                                dlg->ui->counterAndExtAware->isChecked());
0100         bool folderAware    = dlg->ui->folderAware->isChecked();
0101         bool randomAware    = (dlg->ui->randomAware->isChecked()      ||
0102                                dlg->ui->randomAndExtAware->isChecked());
0103 
0104         result = QString::fromUtf8("%1").arg(QLatin1String("#"), digits, QLatin1Char('#'));
0105 
0106         if ((start > 1) || (step > 1) || extensionAware || folderAware || counterAware || randomAware)
0107         {
0108             result.append(QLatin1Char('['));
0109 
0110             if (folderAware)
0111             {
0112                 result.append(QLatin1Char('f'));
0113             }
0114 
0115             if (counterAware)
0116             {
0117                 result.append(QLatin1Char('c'));
0118             }
0119 
0120             if (randomAware)
0121             {
0122                 result.append(QLatin1Char('r'));
0123             }
0124 
0125             if (extensionAware)
0126             {
0127                 result.append(QLatin1Char('e'));
0128             }
0129 
0130             if (!randomAware && !counterAware &&
0131                 ((start  > 1) || ((start == 1) && (step > 1))))
0132             {
0133                 if (extensionAware || folderAware)
0134                 {
0135                     result.append(QLatin1Char(','));
0136                 }
0137 
0138                 result.append(QString::number(start));
0139             }
0140 
0141             if (!randomAware && (step > 1))
0142             {
0143                 result.append(QString::fromUtf8(",%1").arg(step));
0144             }
0145 
0146             result.append(QLatin1Char(']'));
0147         }
0148     }
0149 
0150     delete dlg;
0151 
0152     Q_EMIT signalTokenTriggered(result);
0153 }
0154 
0155 QString SequenceNumberOption::parseOperation(ParseSettings& settings, const QRegularExpressionMatch& match)
0156 {
0157     QString result;
0158     QString random;
0159     int slength         = 0;
0160     int start           = 0;
0161     int step            = 0;
0162     int number          = 0;
0163     int index           = 0;
0164 
0165     bool extensionAware = false;
0166     bool counterAware   = false;
0167     bool folderAware    = false;
0168     bool randomAware    = false;
0169 
0170     if (settings.manager)
0171     {
0172         extensionAware = !match.captured(3).isEmpty() && match.captured(3).contains(QLatin1Char('e'));
0173         counterAware   = !match.captured(3).isEmpty() && match.captured(3).contains(QLatin1Char('c'));
0174         folderAware    = !match.captured(3).isEmpty() && match.captured(3).contains(QLatin1Char('f'));
0175         randomAware    = !match.captured(3).isEmpty() && match.captured(3).contains(QLatin1Char('r'));
0176 
0177         index          = settings.manager->indexOfFile(settings.fileUrl.toLocalFile());
0178 
0179         if (extensionAware)
0180         {
0181             index = settings.manager->indexOfFileGroup(settings.fileUrl.toLocalFile());
0182         }
0183 
0184         if (counterAware)
0185         {
0186             if (extensionAware)
0187             {
0188                 index = settings.manager->indexOfFileGroup(settings.fileUrl.toLocalFile());
0189             }
0190             else
0191             {
0192                 index = settings.manager->indexOfFolder(settings.fileUrl.toLocalFile());
0193             }
0194 
0195             start = settings.manager->indexOfFileCounter(settings.fileUrl.toLocalFile());
0196         }
0197 
0198         if (folderAware)
0199         {
0200             index = settings.manager->indexOfFolder(settings.fileUrl.toLocalFile());
0201         }
0202 
0203         if (randomAware)
0204         {
0205             if (extensionAware)
0206             {
0207                 index = settings.manager->indexOfFileGroup(settings.fileUrl.toLocalFile());
0208             }
0209 
0210             random = settings.manager->randomStringOfIndex(index - 1);
0211         }
0212     }
0213 
0214     // --------------------------------------------------------
0215 
0216     slength = match.captured(1).length();
0217 
0218     if (!counterAware)
0219     {
0220         start = match.captured(6).isEmpty() ? settings.startIndex : match.captured(6).toInt();
0221         step  = match.captured(8).isEmpty() ? 1 : match.captured(8).toInt();
0222     }
0223     else
0224     {
0225         step  = match.captured(5).isEmpty() ? 1 : match.captured(5).toInt();
0226     }
0227 
0228     if (step < 1)
0229     {
0230         step = 1;
0231     }
0232 
0233     if      (start < 1)
0234     {
0235         start = settings.startIndex;
0236     }
0237     else if (counterAware)
0238     {
0239         start += step;
0240     }
0241 
0242     if (randomAware && !random.isEmpty())
0243     {
0244          result = random.left(slength);
0245     }
0246     else
0247     {
0248         number  = start + ((index - 1) * step);
0249         result  = QString::fromUtf8("%1").arg(number, slength, 10, QLatin1Char('0'));
0250     }
0251 
0252     return result;
0253 }
0254 
0255 } // namespace Digikam
0256 
0257 #include "moc_sequencenumberoption.cpp"