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 }