diff --git a/ChangeLog b/ChangeLog index c350bd9c0..efc223578 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2015-10-04 Moritz Bunkus + + * MKVToolNix GUI: chapter editor enhancement: Added another + variable to the chapter name templates called which is + replaced by the chapter's start timestamp. An optional format can + be specified, e.g. resulting in something + like 01:35:27.734. This can be used in the 'generate sub-chapters' + or the 'renumber sub-chapters' functionality. Implements #1445. + 2015-10-03 Moritz Bunkus * MKVToolNix GUI: merge tool bug fix: If there's currently no diff --git a/src/mkvtoolnix-gui/chapter_editor/generate_sub_chapters_parameters_dialog.cpp b/src/mkvtoolnix-gui/chapter_editor/generate_sub_chapters_parameters_dialog.cpp index 3bff14683..88d079b80 100644 --- a/src/mkvtoolnix-gui/chapter_editor/generate_sub_chapters_parameters_dialog.cpp +++ b/src/mkvtoolnix-gui/chapter_editor/generate_sub_chapters_parameters_dialog.cpp @@ -10,6 +10,7 @@ #include "common/strings/formatting.h" #include "common/strings/parsing.h" #include "mkvtoolnix-gui/chapter_editor/generate_sub_chapters_parameters_dialog.h" +#include "mkvtoolnix-gui/chapter_editor/tool.h" #include "mkvtoolnix-gui/forms/chapter_editor/generate_sub_chapters_parameters_dialog.h" #include "mkvtoolnix-gui/main_window/main_window.h" #include "mkvtoolnix-gui/util/settings.h" @@ -59,12 +60,7 @@ GenerateSubChaptersParametersDialog::setupUi(int firstChapterNumber, void GenerateSubChaptersParametersDialog::retranslateUi() { Util::setToolTip(m_ui->leStartTimecode, QY("The format is either the form 'HH:MM:SS.nnnnnnnnn' or a number followed by one of the units 's', 'ms' or 'us'.")); - Util::setToolTip(m_ui->leNameTemplate, - Q("

%1 %2

%3 %4

") - .arg(QY("This template will be used for new chapter entries.")) - .arg(QY("The string '' will be replaced by the chapter number.").toHtmlEscaped()) - .arg(QY("You can specify a minimum number of places for the chapter number with '', e.g. ''.").toHtmlEscaped()) - .arg(QY("The resulting number will be padded with leading zeroes if the number of places is less than specified."))); + Util::setToolTip(m_ui->leNameTemplate, Tool::chapterNameTemplateToolTip()); } int diff --git a/src/mkvtoolnix-gui/chapter_editor/renumber_sub_chapters_parameters_dialog.cpp b/src/mkvtoolnix-gui/chapter_editor/renumber_sub_chapters_parameters_dialog.cpp index e912b95e4..20b8b0269 100644 --- a/src/mkvtoolnix-gui/chapter_editor/renumber_sub_chapters_parameters_dialog.cpp +++ b/src/mkvtoolnix-gui/chapter_editor/renumber_sub_chapters_parameters_dialog.cpp @@ -10,6 +10,7 @@ #include "common/strings/formatting.h" #include "common/strings/parsing.h" #include "mkvtoolnix-gui/chapter_editor/renumber_sub_chapters_parameters_dialog.h" +#include "mkvtoolnix-gui/chapter_editor/tool.h" #include "mkvtoolnix-gui/forms/chapter_editor/renumber_sub_chapters_parameters_dialog.h" #include "mkvtoolnix-gui/main_window/main_window.h" #include "mkvtoolnix-gui/util/settings.h" @@ -50,12 +51,7 @@ RenumberSubChaptersParametersDialog::setupUi(int firstChapterNumber, m_ui->cbLanguageOfNamesToReplace->setCurrentIndex(0); - Util::setToolTip(m_ui->leNameTemplate, - Q("

%1 %2

%3 %4

") - .arg(QY("This template will be used for new chapter entries.")) - .arg(QY("The string '' will be replaced by the chapter number.").toHtmlEscaped()) - .arg(QY("You can specify a minimum number of places for the chapter number with '', e.g. ''.").toHtmlEscaped()) - .arg(QY("The resulting number will be padded with leading zeroes if the number of places is less than specified."))); + Util::setToolTip(m_ui->leNameTemplate, Tool::chapterNameTemplateToolTip()); m_ui->cbFirstEntryToRenumber->setFocus(); diff --git a/src/mkvtoolnix-gui/chapter_editor/tab.cpp b/src/mkvtoolnix-gui/chapter_editor/tab.cpp index 3d90d7dc8..7f1b3ba3a 100644 --- a/src/mkvtoolnix-gui/chapter_editor/tab.cpp +++ b/src/mkvtoolnix-gui/chapter_editor/tab.cpp @@ -349,7 +349,7 @@ Tab::timecodesToChapters(std::vector const &timecodes) for (auto const &timecode : timecodes) { auto nameTemplate = QString{ cfg.m_chapterNameTemplate }; - auto name = formatChapterName(nameTemplate, ++idx); + auto name = formatChapterName(nameTemplate, ++idx, timecode); auto atom = mtx::construct::cons(new KaxChapterTimeStart, timecode.to_ns(), mtx::construct::cons(new KaxChapterString, name, new KaxChapterLanguage, to_utf8(cfg.m_defaultChapterLanguage))); @@ -962,7 +962,7 @@ Tab::createEmptyChapter(int64_t startTime, auto &cfg = Util::Settings::get(); auto chapter = std::make_shared(); auto &display = GetChild(*chapter); - auto name = formatChapterName(nameTemplate ? *nameTemplate : cfg.m_chapterNameTemplate, chapterNumber); + auto name = formatChapterName(nameTemplate ? *nameTemplate : cfg.m_chapterNameTemplate, chapterNumber, timecode_c::ns(startTime)); GetChild(*chapter).SetValue(0); GetChild(*chapter).SetValue(startTime); @@ -1212,13 +1212,15 @@ Tab::duplicateElement() { QString Tab::formatChapterName(QString const &nameTemplate, - int chapterNumber) + int chapterNumber, + timecode_c const &startTimecode) const { - auto name = QString{ nameTemplate }; - auto re = QRegularExpression{Q("")}; + auto name = QString{ nameTemplate }; + auto numberRe = QRegularExpression{Q("")}; + auto timecodeRe = QRegularExpression{Q("]+))?>")}; while (true) { - auto matches = re.match(name); + auto matches = numberRe.match(name); if (!matches.hasMatch()) break; @@ -1228,6 +1230,15 @@ Tab::formatChapterName(QString const &nameTemplate, name.replace(matches.capturedStart(), matches.capturedLength(), strNumber); } + while (true) { + auto matches = timecodeRe.match(name); + if (!matches.hasMatch()) + break; + + auto format = matches.capturedLength(1) ? matches.captured(1) : Q("%H:%M:%S"); + name.replace(matches.capturedStart(), matches.capturedLength(), Q(format_timecode(startTimecode, to_utf8(format)))); + } + return name; } @@ -1300,7 +1311,8 @@ Tab::changeChapterName(QModelIndex const &parentIdx, return false; } - auto name = to_wide(formatChapterName(nameTemplate, chapterNumber)); + auto startTimecode = FindChildValue(*chapter); + auto name = to_wide(formatChapterName(nameTemplate, chapterNumber, timecode_c::ns(startTimecode))); if (RenumberSubChaptersParametersDialog::NameMatch::First == nameMatchingMode) { GetChild(GetChild(*chapter)).SetValue(name); diff --git a/src/mkvtoolnix-gui/chapter_editor/tab.h b/src/mkvtoolnix-gui/chapter_editor/tab.h index 4d4f4bb9d..110d9478d 100644 --- a/src/mkvtoolnix-gui/chapter_editor/tab.h +++ b/src/mkvtoolnix-gui/chapter_editor/tab.h @@ -165,7 +165,7 @@ protected: QString currentState() const; ChaptersPtr timecodesToChapters(std::vector const &timecodes) const; - QString formatChapterName(QString const &nameTemplate, int chapterNumber) const; + QString formatChapterName(QString const &nameTemplate, int chapterNumber, timecode_c const &startTimecode) const; bool changeChapterName(QModelIndex const &parentIdx, int row, int chapterNumber, QString const &nameTemplate, RenumberSubChaptersParametersDialog::NameMatch nameMatchingMode, QString const &languageOfNamesToReplace, bool skipHidden); diff --git a/src/mkvtoolnix-gui/chapter_editor/tool.cpp b/src/mkvtoolnix-gui/chapter_editor/tool.cpp index 02bff4caf..2c209d873 100644 --- a/src/mkvtoolnix-gui/chapter_editor/tool.cpp +++ b/src/mkvtoolnix-gui/chapter_editor/tool.cpp @@ -293,4 +293,28 @@ Tool::setupTabPositions() { ui->editors->setTabPosition(Util::Settings::get().m_tabPosition); } +QString +Tool::chapterNameTemplateToolTip() { + return Q("

%1 %2 %3

%4 %5

%6 %7 %8

  • %9
  • %10
  • %11
  • %12
  • %13
  • %14
  • %15
  • %16
") + .arg(QY("This template will be used for new chapter entries.")) + .arg(QY("The string '' will be replaced by the chapter number.").toHtmlEscaped()) + .arg(QY("The string '' will be replaced by the chapter's start timestamp.").toHtmlEscaped()) + + .arg(QY("You can specify a minimum number of places for the chapter number with '', e.g. ''.").toHtmlEscaped()) + .arg(QY("The resulting number will be padded with leading zeroes if the number of places is less than specified.")) + + .arg(QY("You can control the format used by the start timestamp with .").toHtmlEscaped()) + .arg(QY("The format defaults to %H:%M:%S if none is given.")) + .arg(QY("Valid format codes are:")) + + .arg(QY("%h – hours")) + .arg(QY("%H – hours zero-padded to two places")) + .arg(QY("%m – minutes")) + .arg(QY("%M – minutes zero-padded to two places")) + .arg(QY("%s – seconds")) + .arg(QY("%S – seconds zero-padded to two places")) + .arg(QY("%n – nanoseconds with nine places")) + .arg(QY("%<1-9>n – nanoseconds with up to nine places (e.g. three places with %3n)").toHtmlEscaped()); +} + }}} diff --git a/src/mkvtoolnix-gui/chapter_editor/tool.h b/src/mkvtoolnix-gui/chapter_editor/tool.h index 61bba7e94..66f2f8524 100644 --- a/src/mkvtoolnix-gui/chapter_editor/tool.h +++ b/src/mkvtoolnix-gui/chapter_editor/tool.h @@ -62,6 +62,9 @@ protected: virtual void dragEnterEvent(QDragEnterEvent *event) override; virtual void dropEvent(QDropEvent *event) override; + +public: + static QString chapterNameTemplateToolTip(); }; }}} diff --git a/src/mkvtoolnix-gui/main_window/preferences_dialog.cpp b/src/mkvtoolnix-gui/main_window/preferences_dialog.cpp index 830396e9e..132134ff3 100644 --- a/src/mkvtoolnix-gui/main_window/preferences_dialog.cpp +++ b/src/mkvtoolnix-gui/main_window/preferences_dialog.cpp @@ -7,6 +7,7 @@ #include "common/qt.h" #include "common/translation.h" #include "mkvtoolnix-gui/app.h" +#include "mkvtoolnix-gui/chapter_editor/tool.h" #include "mkvtoolnix-gui/forms/main_window/preferences_dialog.h" #include "mkvtoolnix-gui/main_window/preferences_dialog.h" #include "mkvtoolnix-gui/merge/additional_command_line_options_dialog.h" @@ -125,12 +126,7 @@ PreferencesDialog::setupToolTips() { .arg(QY("Normally completed jobs stay in the queue even over restarts until the user clears them out manually.")) .arg(QY("You can opt for having them removed automatically under certain conditions."))); - Util::setToolTip(ui->leCENameTemplate, - Q("

%1 %2

%3 %4

") - .arg(QY("This template will be used for new chapter entries.")) - .arg(QY("The string '' will be replaced by the chapter number.").toHtmlEscaped()) - .arg(QY("You can specify a minimum number of places for the chapter number with '', e.g. ''.").toHtmlEscaped()) - .arg(QY("The resulting number will be padded with leading zeroes if the number of places is less than specified."))); + Util::setToolTip(ui->leCENameTemplate, ChapterEditor::Tool::chapterNameTemplateToolTip()); Util::setToolTip(ui->cbCEDefaultLanguage, QY("This is the language that newly added chapter names get assigned automatically.")); Util::setToolTip(ui->cbCEDefaultCountry, QY("This is the country that newly added chapter names get assigned automatically.")); Util::setToolTip(ui->cbCEDropLastFromBlurayPlaylist,