File indexing completed on 2024-04-28 04:51:37

0001 /*
0002     SPDX-FileCopyrightText: 2023 Jean-Baptiste Mardelle <jb@kdenlive.org>
0003 
0004 SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005 */
0006 
0007 #include "managesubtitles.h"
0008 #include "bin/model/subtitlemodel.hpp"
0009 #include "core.h"
0010 #include "dialogs/importsubtitle.h"
0011 #include "doc/kdenlivedoc.h"
0012 #include "kdenlive_debug.h"
0013 #include "klocalizedstring.h"
0014 #include "mainwindow.h"
0015 #include "timeline2/view/timelinecontroller.h"
0016 #include <KMessageBox>
0017 #include <QFontDatabase>
0018 #include <QMenu>
0019 
0020 ManageSubtitles::ManageSubtitles(std::shared_ptr<SubtitleModel> model, TimelineController *controller, int currentIx, QWidget *parent)
0021     : QDialog(parent)
0022     , m_model(model)
0023     , m_controller(controller)
0024 {
0025     setFont(QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont));
0026     setupUi(this);
0027     setAttribute(Qt::WA_DeleteOnClose);
0028     setWindowTitle(i18nc("@title:window", "Manage Subtitles"));
0029     subtitlesList->hideColumn(1);
0030     messageWidget->hide();
0031     parseList(currentIx);
0032     connect(subtitlesList, &QTreeWidget::itemChanged, this, &ManageSubtitles::updateSubtitle);
0033     connect(subtitlesList, &QTreeWidget::currentItemChanged, this, [this](QTreeWidgetItem *current, QTreeWidgetItem *) {
0034         int ix = subtitlesList->indexOfTopLevelItem(current);
0035         if (ix > -1) {
0036             m_controller->subtitlesMenuActivated(ix);
0037         }
0038     });
0039     connect(button_new, &QPushButton::clicked, this, [this]() { addSubtitle(); });
0040     connect(button_duplicate, &QPushButton::clicked, this, &ManageSubtitles::duplicateSubtitle);
0041     connect(button_delete, &QPushButton::clicked, this, &ManageSubtitles::deleteSubtitle);
0042     // Import/Export menu
0043     QMenu *menu = new QMenu(this);
0044     QAction *importSub = new QAction(QIcon::fromTheme(QStringLiteral("document-import")), i18nc("@action:inmenu", "Import Subtitle"), this);
0045     QAction *exportSub = new QAction(QIcon::fromTheme(QStringLiteral("document-export")), i18nc("@action:inmenu", "Export Subtitle"), this);
0046     menu->addAction(importSub);
0047     menu->addAction(exportSub);
0048     connect(importSub, &QAction::triggered, this, &ManageSubtitles::importSubtitle);
0049     connect(exportSub, &QAction::triggered, pCore->window(), &MainWindow::slotExportSubtitle);
0050     button_menu->setMenu(menu);
0051 }
0052 
0053 ManageSubtitles::~ManageSubtitles()
0054 {
0055     QSignalBlocker bk(subtitlesList);
0056     delete subtitlesList;
0057 }
0058 
0059 void ManageSubtitles::parseList(int ix)
0060 {
0061     QSignalBlocker bk(subtitlesList);
0062     subtitlesList->clear();
0063     QMap<std::pair<int, QString>, QString> currentSubs = m_model->getSubtitlesList();
0064     QMapIterator<std::pair<int, QString>, QString> i(currentSubs);
0065     while (i.hasNext()) {
0066         i.next();
0067         QStringList texts = {i.key().second, QString(), i.value()};
0068         QTreeWidgetItem *item = new QTreeWidgetItem(subtitlesList, {i.key().second, i.value()});
0069         item->setData(0, Qt::UserRole, i.key().first);
0070         new QTreeWidgetItem(item, {i.value()});
0071         item->setFlags(item->flags() | Qt::ItemIsEditable);
0072         if (ix > -1 && ix == i.key().first) {
0073             subtitlesList->setCurrentItem(item);
0074         }
0075     }
0076     button_delete->setEnabled(subtitlesList->topLevelItemCount() > 1);
0077 }
0078 
0079 void ManageSubtitles::updateSubtitle(QTreeWidgetItem *item, int column)
0080 {
0081     if (column == 0) {
0082         // An item was renamed
0083         m_model->updateModelName(item->data(0, Qt::UserRole).toInt(), item->text(0));
0084         m_controller->subtitlesListChanged();
0085         m_controller->refreshSubtitlesComboIndex();
0086     }
0087 }
0088 
0089 void ManageSubtitles::addSubtitle(const QString name)
0090 {
0091     m_model->createNewSubtitle(name);
0092     m_controller->subtitlesListChanged();
0093     parseList();
0094     // Makes last item active
0095     subtitlesList->setCurrentItem(subtitlesList->topLevelItem(subtitlesList->topLevelItemCount() - 1));
0096 }
0097 
0098 void ManageSubtitles::duplicateSubtitle()
0099 {
0100     m_model->createNewSubtitle(QString(), subtitlesList->currentItem()->data(0, Qt::UserRole).toInt());
0101     m_controller->subtitlesListChanged();
0102     parseList();
0103     // Makes last item active
0104     subtitlesList->setCurrentItem(subtitlesList->topLevelItem(subtitlesList->topLevelItemCount() - 1));
0105 }
0106 
0107 void ManageSubtitles::deleteSubtitle()
0108 {
0109     const QString name = subtitlesList->currentItem()->text(0);
0110     const QString path = subtitlesList->currentItem()->text(1);
0111     if (KMessageBox::warningContinueCancel(
0112             this, i18n("This will delete all subtitle entries in <b>%1</b>,<br/>as well as the subtitle file: %2 ", name, path)) != KMessageBox::Continue) {
0113         return;
0114     }
0115     qDebug() << ":::: DELETING SUBTITLE WIT TREE INDEX: " << subtitlesList->indexOfTopLevelItem(subtitlesList->currentItem());
0116     int ix = subtitlesList->indexOfTopLevelItem(subtitlesList->currentItem());
0117     // Makes last item active
0118     int nextId = -1;
0119     int id = subtitlesList->currentItem()->data(0, Qt::UserRole).toInt();
0120     if (ix == 0) {
0121         nextId = subtitlesList->topLevelItem(1)->data(0, Qt::UserRole).toInt();
0122     } else {
0123         nextId = subtitlesList->topLevelItem(ix - 1)->data(0, Qt::UserRole).toInt();
0124     }
0125     if (m_model->deleteSubtitle(id)) {
0126         m_controller->subtitlesListChanged();
0127         parseList(nextId);
0128         int ix = subtitlesList->indexOfTopLevelItem(subtitlesList->currentItem());
0129         if (ix > -1) {
0130             m_controller->subtitlesMenuActivated(ix);
0131         }
0132     } else {
0133         subtitlesList->setCurrentItem(subtitlesList->topLevelItem(qMax(0, ix)));
0134     }
0135 }
0136 
0137 void ManageSubtitles::importSubtitle()
0138 {
0139     QScopedPointer<ImportSubtitle> d(new ImportSubtitle(QString(), this));
0140     d->create_track->setChecked(true);
0141     if (d->exec() == QDialog::Accepted && !d->subtitle_url->url().isEmpty()) {
0142         if (d->create_track->isChecked()) {
0143             // Create a new subtitle entry
0144             addSubtitle(d->track_name->text());
0145         }
0146         int offset = 0, startFramerate = 30.00, targetFramerate = 30.00;
0147         if (d->cursor_pos->isChecked()) {
0148             offset = pCore->getMonitorPosition();
0149         }
0150         if (d->transform_framerate_check_box->isChecked()) {
0151             startFramerate = d->caption_original_framerate->value();
0152             targetFramerate = d->caption_target_framerate->value();
0153         }
0154         m_model->importSubtitle(d->subtitle_url->url().toLocalFile(), offset, true, startFramerate, targetFramerate, d->codecs_list->currentText().toUtf8());
0155     }
0156 }