Index: src/ExportManager.cpp =================================================================== --- src/ExportManager.cpp +++ src/ExportManager.cpp @@ -175,6 +175,24 @@ QString title; + SpectacleConfig *cfgManager = SpectacleConfig::instance(); + QString sequentialFileNumber = cfgManager->nextSequentialFileNumber(); + int paddedNumLength; + QRegularExpression seqRE; + seqRE.setPattern(QLatin1String("%\\d*d")); + QRegularExpressionMatch match; + if (baseName.indexOf(seqRE, 0, &match) > -1) { + paddedNumLength = match.captured().mid(1, match.captured().length() - 2).toInt(); + } else { + paddedNumLength = 0; + } + if (sequentialFileNumber.toInt() >= 999999) { + cfgManager->setNextSequentialFileNumber(QString::number(1)); + } else { + cfgManager->setNextSequentialFileNumber(QString::number(sequentialFileNumber.toInt() + 1)); + } + + if (mGrabMode == ImageGrabber::GrabMode::ActiveWindow || mGrabMode == ImageGrabber::GrabMode::TransientWithParent || mGrabMode == ImageGrabber::GrabMode::WindowUnderCursor) { @@ -194,7 +212,9 @@ .replace(QLatin1String("%H"), timestamp.toString(QStringLiteral("hh"))) .replace(QLatin1String("%m"), timestamp.toString(QStringLiteral("mm"))) .replace(QLatin1String("%S"), timestamp.toString(QStringLiteral("ss"))) - .replace(QLatin1String("%T"), title); + .replace(QLatin1String("%T"), title) + .replace(seqRE, sequentialFileNumber.rightJustified(paddedNumLength, QLatin1Char('0'), false)); + // Remove leading and trailing '/' while (result.startsWith(QLatin1Char('/'))) { Index: src/Gui/SettingsDialog/SaveOptionsPage.h =================================================================== --- src/Gui/SettingsDialog/SaveOptionsPage.h +++ src/Gui/SettingsDialog/SaveOptionsPage.h @@ -52,6 +52,8 @@ KUrlRequester *mUrlRequester; QComboBox *mSaveImageFormat; QCheckBox *mCopyPathToClipboard; + QLineEdit *mNextSequentialNumber; + QCheckBox *mRestartSequentialNumberingOnRelaunch; }; Index: src/Gui/SettingsDialog/SaveOptionsPage.cpp =================================================================== --- src/Gui/SettingsDialog/SaveOptionsPage.cpp +++ src/Gui/SettingsDialog/SaveOptionsPage.cpp @@ -28,14 +28,16 @@ #include #include #include +#include #include #include #include +#include SaveOptionsPage::SaveOptionsPage(QWidget *parent) : SettingsPage(parent) { - // set up the layout. start with the directory + // set up the layout. start with the directory groupbox QGroupBox *dirGroup = new QGroupBox(i18n("Default Save Location"), this); QVBoxLayout *dirLayout = new QVBoxLayout; @@ -57,7 +59,7 @@ connect(mCopyPathToClipboard, &QCheckBox::toggled, this, &SaveOptionsPage::markDirty); dirLayout->addWidget(mCopyPathToClipboard, 1); - // filename chooser text field + // filename chooser groupbox QGroupBox *fmtGroup = new QGroupBox(i18n("Default Save Filename")); QVBoxLayout *fmtLayout = new QVBoxLayout; @@ -109,7 +111,8 @@ "%H: Hour
" "%m: Minute
" "%S: Second
" - "%T: Window title" + "%T: Window title
" + "%[N]d: Sequential numbering (optionally include a number N to pad to that many digits)" "" "

To save to a sub-folder, use slashes to describe the desired path, e.g.:

" @@ -125,6 +128,25 @@ fmtHelpText->setTextFormat(Qt::RichText); fmtHelpText->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); fmtLayout->addWidget(fmtHelpText); + + // Sequential Numbering Settings + + QHBoxLayout *nextSequentialNumberLayout = new QHBoxLayout; + + nextSequentialNumberLayout->addWidget(new QLabel(i18n("Next sequential number:"), this)); + mNextSequentialNumber = new QLineEdit; + QIntValidator *intValidator = new QIntValidator(1, 999999, this); + mNextSequentialNumber->setValidator(intValidator); + connect(mNextSequentialNumber, &QLineEdit::textEdited, this, &SaveOptionsPage::markDirty); + + mRestartSequentialNumberingOnRelaunch = new QCheckBox(i18n("Restart numbering with relaunch"), this); + connect(mRestartSequentialNumberingOnRelaunch, &QCheckBox::toggled, this, &SaveOptionsPage::markDirty); + dirLayout->addWidget(mRestartSequentialNumberingOnRelaunch, 1); + + nextSequentialNumberLayout->addWidget(mNextSequentialNumber); + nextSequentialNumberLayout->addWidget(mRestartSequentialNumberingOnRelaunch); + + fmtLayout->addLayout(nextSequentialNumberLayout); // read in the data @@ -158,6 +180,8 @@ cfgManager->setAutoSaveFilenameFormat(mSaveNameFormat->text()); cfgManager->setSaveImageFormat(mSaveImageFormat->currentText().toLower()); cfgManager->setCopySaveLocationToClipboard(mCopyPathToClipboard->checkState() == Qt::Checked); + cfgManager->setNextSequentialFileNumber(mNextSequentialNumber->text()); + cfgManager->setRestartSequentialNumberingOnRelaunch(mRestartSequentialNumberingOnRelaunch->checkState() == Qt::Checked); // done @@ -175,6 +199,8 @@ mSaveNameFormat->setText(cfgManager->autoSaveFilenameFormat()); mUrlRequester->setUrl(QUrl::fromUserInput(cfgManager->autoSaveLocation())); mCopyPathToClipboard->setChecked(cfgManager->copySaveLocationToClipboard()); + mNextSequentialNumber->setText(cfgManager->nextSequentialFileNumber()); + mRestartSequentialNumberingOnRelaunch->setChecked(cfgManager->restartSequentialNumberingOnRelaunch()); // read in the save image format and calculate its index Index: src/SpectacleConfig.h =================================================================== --- src/SpectacleConfig.h +++ src/SpectacleConfig.h @@ -108,6 +108,12 @@ QString saveImageFormat() const; void setSaveImageFormat(const QString &saveFmt); + QString nextSequentialFileNumber() const; + void setNextSequentialFileNumber(QString num); + + bool restartSequentialNumberingOnRelaunch() const; + void setRestartSequentialNumberingOnRelaunch(bool enabled); + private: KSharedConfigPtr mConfig; Index: src/SpectacleConfig.cpp =================================================================== --- src/SpectacleConfig.cpp +++ src/SpectacleConfig.cpp @@ -277,3 +277,29 @@ mGeneralConfig.writeEntry(QStringLiteral("default-save-image-format"), saveFmt); mGeneralConfig.sync(); } + +// next sequential file number + +QString SpectacleConfig::nextSequentialFileNumber() const +{ + return mGeneralConfig.readEntry(QStringLiteral("next-sequential-file-number")); +} + +void SpectacleConfig::setNextSequentialFileNumber(QString nextNum) +{ + mGeneralConfig.writeEntry(QStringLiteral("next-sequential-file-number"), nextNum); +} + +// restart sequential numbering on restart + +bool SpectacleConfig::restartSequentialNumberingOnRelaunch() const +{ + return mGeneralConfig.readEntry(QStringLiteral("restartSequentialNumberingOnRestart"), false); +} + +void SpectacleConfig::setRestartSequentialNumberingOnRelaunch(bool enabled) +{ + mGeneralConfig.writeEntry(QStringLiteral("restartSequentialNumberingOnRestart"), enabled); + mGeneralConfig.sync(); +} + Index: src/SpectacleCore.cpp =================================================================== --- src/SpectacleCore.cpp +++ src/SpectacleCore.cpp @@ -18,6 +18,7 @@ */ #include "SpectacleCore.h" +#include "SpectacleConfig.h" #include "Config.h" #include "PlatformBackends/DummyImageGrabber.h" @@ -309,5 +310,11 @@ isGuiInited = true; QMetaObject::invokeMethod(mImageGrabber, "doImageGrab", Qt::QueuedConnection); + + SpectacleConfig *cfgManager = SpectacleConfig::instance(); + if (cfgManager->restartSequentialNumberingOnRelaunch()) { + cfgManager->setNextSequentialFileNumber(QStringLiteral("1")); + } + } }