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

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2009-09-18
0007  * Description : a modifier for displaying only a range of a token result
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 "rangemodifier.h"
0016 
0017 // Qt includes
0018 
0019 #include <QCheckBox>
0020 #include <QGridLayout>
0021 #include <QPointer>
0022 #include <QRegularExpression>
0023 
0024 // KDE includes
0025 
0026 #include <klocalizedstring.h>
0027 
0028 // Local includes
0029 
0030 #include "ui_rangemodifierdialogwidget.h"
0031 
0032 namespace Digikam
0033 {
0034 
0035 RangeDialog::RangeDialog(Rule* const parent)
0036     : RuleDialog(parent),
0037       ui        (new Ui::RangeModifierDialogWidget())
0038 {
0039     QWidget* const mainWidget = new QWidget(this);
0040     ui->setupUi(mainWidget);
0041     setSettingsWidget(mainWidget);
0042     ui->startInput->setFocus();
0043 
0044     slotToTheEndChecked(true);
0045 
0046     connect(ui->toTheEndCheckBox, SIGNAL(toggled(bool)),
0047             this, SLOT(slotToTheEndChecked(bool)));
0048 }
0049 
0050 RangeDialog::~RangeDialog()
0051 {
0052     delete ui;
0053 }
0054 
0055 void RangeDialog::slotToTheEndChecked(bool checked)
0056 {
0057     ui->stopInput->setEnabled(!checked);
0058 }
0059 
0060 // --------------------------------------------------------
0061 
0062 RangeModifier::RangeModifier()
0063     : Modifier(i18n("Range..."),
0064                i18n("Add only a specific range of a renaming option"),
0065                QLatin1String("measure"))
0066 {
0067     addToken(QLatin1String("{range:||from||,||to||}"),
0068              i18n("Extract a specific range (if '||to||' is omitted, go to the end of string)"));
0069 
0070     QRegularExpression reg(QLatin1String("\\{range(:(-?\\d+)(,((-1|\\d+))?)?)\\}"));
0071     reg.setPatternOptions(QRegularExpression::InvertedGreedinessOption);
0072     setRegExp(reg);
0073 }
0074 
0075 void RangeModifier::slotTokenTriggered(const QString& token)
0076 {
0077     Q_UNUSED(token)
0078 
0079     QString result;
0080 
0081     QPointer<RangeDialog> dlg = new RangeDialog(this);
0082 
0083     if (dlg->exec() == QDialog::Accepted)
0084     {
0085         int start = dlg->ui->startInput->value();
0086         int stop  = dlg->ui->stopInput->value();
0087 
0088         if (dlg->ui->toTheEndCheckBox->isChecked())
0089         {
0090             result = QString::fromUtf8("{range:%1,}").arg(start);
0091         }
0092         else
0093         {
0094             result = QString::fromUtf8("{range:%1,%2}").arg(start).arg(stop);
0095         }
0096     }
0097 
0098     delete dlg;
0099 
0100     Q_EMIT signalTokenTriggered(result);
0101 }
0102 
0103 QString RangeModifier::parseOperation(ParseSettings& settings, const QRegularExpressionMatch& match)
0104 {
0105     bool ok                       = false;
0106 
0107     // if the start parameter can not be extracted or is a negative value, set it to 1
0108 
0109     int start = match.captured(2).simplified().toInt(&ok);
0110 
0111     if (!ok || start < 0)
0112     {
0113         start = 1;
0114     }
0115 
0116     // If no range is defined at all ({start}), set stop = start.
0117     // If the stop parameter is omitted ({start-}), set stop = -1 (end of string)
0118 
0119     ok = false;
0120     int stop;
0121 
0122     if (!match.captured(3).isEmpty())
0123     {
0124         ok   = true;
0125         stop = (match.captured(4).isEmpty()) ? -1 : match.captured(5).simplified().toInt(&ok);
0126     }
0127     else
0128     {
0129         stop = start;
0130     }
0131 
0132     if (!ok)
0133     {
0134         stop = start;
0135     }
0136 
0137     // --------------------------------------------------------
0138 
0139     // replace the string according to the given range
0140 
0141     if (start > settings.str2Modify.count())
0142     {
0143         return QString();
0144     }
0145 
0146     if (stop > settings.str2Modify.count())
0147     {
0148         stop = -1;
0149     }
0150 
0151     --start;
0152 
0153     if (stop != -1)
0154     {
0155         --stop;
0156     }
0157 
0158     if ((start < 0) || (stop < -1))
0159     {
0160         return QString();
0161     }
0162 
0163     if (stop == -1)
0164     {
0165         stop = settings.str2Modify.count() - 1;
0166     }
0167 
0168     QString result;
0169 
0170     for (int i = start ; i <= stop ; ++i)
0171     {
0172         result.append(settings.str2Modify.at(i));
0173     }
0174 
0175     return result;
0176 }
0177 
0178 } // namespace Digikam
0179 
0180 #include "moc_rangemodifier.cpp"