]> git.sesse.net Git - kdenlive/blob - src/dvdwizardchapters.cpp
Save chapters now works in DVD Wizard
[kdenlive] / src / dvdwizardchapters.cpp
1 /***************************************************************************
2  *   Copyright (C) 2009 by Jean-Baptiste Mardelle (jb@kdenlive.org)        *
3  *                                                                         *
4  *   This program is free software; you can redistribute it and/or modify  *
5  *   it under the terms of the GNU General Public License as published by  *
6  *   the Free Software Foundation; either version 2 of the License, or     *
7  *   (at your option) any later version.                                   *
8  *                                                                         *
9  *   This program is distributed in the hope that it will be useful,       *
10  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
12  *   GNU General Public License for more details.                          *
13  *                                                                         *
14  *   You should have received a copy of the GNU General Public License     *
15  *   along with this program; if not, write to the                         *
16  *   Free Software Foundation, Inc.,                                       *
17  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA          *
18  ***************************************************************************/
19
20 #include "dvdwizardchapters.h"
21
22 #include <KDebug>
23
24 #include <QFile>
25
26 DvdWizardChapters::DvdWizardChapters(bool isPal, QWidget *parent) :
27         QWizardPage(parent),
28         m_isPal(isPal)
29
30 {
31     m_view.setupUi(this);
32     connect(m_view.vob_list, SIGNAL(currentIndexChanged(int)), this, SLOT(slotUpdateChaptersList()));
33     connect(m_view.button_add, SIGNAL(clicked()), this, SLOT(slotAddChapter()));
34     connect(m_view.button_delete, SIGNAL(clicked()), this, SLOT(slotRemoveChapter()));
35     connect(m_view.button_save, SIGNAL(clicked()), this, SLOT(slotSaveChapter()));
36     connect(m_view.chapters_list, SIGNAL(itemSelectionChanged()), this, SLOT(slotGoToChapter()));
37
38     // Build monitor for chapters
39
40     if (m_isPal) m_tc.setFormat(25);
41     else m_tc.setFormat(30, true);
42
43     m_manager = new MonitorManager(this);
44     m_manager->resetProfiles(m_tc);
45     m_monitor = new Monitor("chapter", m_manager, this);
46     m_monitor->start();
47
48     QVBoxLayout *vbox = new QVBoxLayout;
49     vbox->addWidget(m_monitor);
50     m_view.monitor_frame->setLayout(vbox);
51
52
53 }
54
55 DvdWizardChapters::~DvdWizardChapters()
56 {
57     delete m_monitor;
58     delete m_manager;
59 }
60
61 // virtual
62
63 bool DvdWizardChapters::isComplete() const
64 {
65     return true;
66 }
67
68 void DvdWizardChapters::slotUpdateChaptersList()
69 {
70     m_monitor->slotOpenFile(m_view.vob_list->currentText());
71     m_monitor->adjustRulerSize(m_view.vob_list->itemData(m_view.vob_list->currentIndex(), Qt::UserRole).toInt());
72     QStringList currentChaps = m_view.vob_list->itemData(m_view.vob_list->currentIndex(), Qt::UserRole + 1).toStringList();
73
74     // insert chapters
75     QStringList chaptersString;
76     for (int i = 0; i < currentChaps.count(); i++) {
77         chaptersString.append(Timecode::getStringTimecode(currentChaps.at(i).toInt(), m_tc.fps()));
78     }
79     m_view.chapters_list->clear();
80     m_view.chapters_list->addItems(chaptersString);
81
82     bool modified = m_view.vob_list->itemData(m_view.vob_list->currentIndex(), Qt::UserRole + 2).toInt();
83     m_view.button_save->setEnabled(modified);
84 }
85
86 void DvdWizardChapters::slotAddChapter()
87 {
88     int pos = m_monitor->position().frames(m_tc.fps());
89     QStringList currentChaps = m_view.vob_list->itemData(m_view.vob_list->currentIndex(), Qt::UserRole + 1).toStringList();
90     if (currentChaps.contains(QString::number(pos))) return;
91     else currentChaps.append(QString::number(pos));
92     QList <int> chapterTimes;
93     for (int i = 0; i < currentChaps.count(); i++)
94         chapterTimes.append(currentChaps.at(i).toInt());
95     qSort(chapterTimes);
96
97     // rebuild chapters
98     QStringList chaptersString;
99     currentChaps.clear();
100     for (int i = 0; i < chapterTimes.count(); i++) {
101         chaptersString.append(Timecode::getStringTimecode(chapterTimes.at(i), m_tc.fps()));
102         currentChaps.append(QString::number(chapterTimes.at(i)));
103     }
104     // Save item chapters
105     m_view.vob_list->setItemData(m_view.vob_list->currentIndex(), currentChaps, Qt::UserRole + 1);
106     // Mark item as modified
107     m_view.vob_list->setItemData(m_view.vob_list->currentIndex(), 1, Qt::UserRole + 2);
108     m_view.chapters_list->clear();
109     m_view.chapters_list->addItems(chaptersString);
110     m_view.button_save->setEnabled(true);
111 }
112
113 void DvdWizardChapters::slotRemoveChapter()
114 {
115     int ix = m_view.chapters_list->currentRow();
116     QStringList currentChaps = m_view.vob_list->itemData(m_view.vob_list->currentIndex(), Qt::UserRole + 1).toStringList();
117     currentChaps.removeAt(ix);
118
119     // Save item chapters
120     m_view.vob_list->setItemData(m_view.vob_list->currentIndex(), currentChaps, Qt::UserRole + 1);
121     // Mark item as modified
122     m_view.vob_list->setItemData(m_view.vob_list->currentIndex(), 1, Qt::UserRole + 2);
123
124     // rebuild chapters
125     QStringList chaptersString;
126     for (int i = 0; i < currentChaps.count(); i++) {
127         chaptersString.append(Timecode::getStringTimecode(currentChaps.at(i).toInt(), m_tc.fps()));
128     }
129     m_view.chapters_list->clear();
130     m_view.chapters_list->addItems(chaptersString);
131     m_view.button_save->setEnabled(true);
132 }
133
134 void DvdWizardChapters::slotGoToChapter()
135 {
136     m_monitor->setTimePos(m_view.chapters_list->currentItem()->text() + ":00");
137 }
138
139 void DvdWizardChapters::slotGetChaptersList(int ix)
140 {
141     QString url = m_view.vob_list->itemText(ix);
142     if (QFile::exists(url + ".dvdchapter")) {
143         // insert chapters as children
144         QFile file(url + ".dvdchapter");
145         if (file.open(QIODevice::ReadOnly)) {
146             QDomDocument doc;
147             doc.setContent(&file);
148             file.close();
149             QDomNodeList chapters = doc.elementsByTagName("chapter");
150             QStringList chaptersList;
151             for (int j = 0; j < chapters.count(); j++) {
152                 chaptersList.append(QString::number(chapters.at(j).toElement().attribute("time").toInt()));
153             }
154             m_view.vob_list->setItemData(ix, chaptersList, Qt::UserRole + 1);
155         }
156     }
157 }
158
159 void DvdWizardChapters::setVobFiles(bool isPal, const QStringList movies, const QStringList durations)
160 {
161     m_isPal = isPal;
162     if (m_isPal) m_tc.setFormat(25);
163     else m_tc.setFormat(30, true);
164     m_manager->resetProfiles(m_tc);
165     m_monitor->resetProfile();
166
167     if (m_view.vob_list->count() == movies.count()) {
168         bool equal = true;
169         for (int i = 0; i < movies.count(); i++) {
170             if (movies.at(i) != m_view.vob_list->itemText(i)) {
171                 equal = false;
172                 break;
173             }
174         }
175         if (equal) return;
176     }
177     m_view.vob_list->clear();
178     for (int i = 0; i < movies.count(); i++) {
179         m_view.vob_list->addItem(movies.at(i), durations.at(i));
180         slotGetChaptersList(i);
181     }
182     slotUpdateChaptersList();
183 }
184
185 QStringList DvdWizardChapters::selectedTitles() const
186 {
187     QStringList result;
188     int max = m_view.vob_list->count();
189     for (int i = 0; i < max; i++) {
190         result.append(m_view.vob_list->itemText(i));
191         QStringList chapters = m_view.vob_list->itemData(i, Qt::UserRole + 1).toStringList();
192         for (int j = 0; j < chapters.count(); j++) {
193             result.append(Timecode::getStringTimecode(chapters.at(j).toInt(), m_tc.fps()));
194         }
195     }
196     return result;
197 }
198
199 QStringList DvdWizardChapters::chapters(int ix) const
200 {
201     QStringList result;
202     QStringList chapters = m_view.vob_list->itemData(ix, Qt::UserRole + 1).toStringList();
203     for (int j = 0; j < chapters.count(); j++) {
204         result.append(Timecode::getStringTimecode(chapters.at(j).toInt(), m_tc.fps()));
205     }
206     return result;
207 }
208
209 QStringList DvdWizardChapters::selectedTargets() const
210 {
211     QStringList result;
212     int max = m_view.vob_list->count();
213     for (int i = 0; i < max; i++) {
214         result.append("jump title " + QString::number(i + 1));
215         QStringList chapters = m_view.vob_list->itemData(i, Qt::UserRole + 1).toStringList();
216         for (int j = 0; j < chapters.count(); j++) {
217             result.append("jump title " + QString::number(i + 1) + " chapter " + QString::number(j + 1));
218         }
219     }
220     return result;
221 }
222
223 void DvdWizardChapters::slotSaveChapter()
224 {
225     QDomDocument doc;
226     QDomElement chapters = doc.createElement("chapters");
227     chapters.setAttribute("fps", m_tc.fps());
228     doc.appendChild(chapters);
229
230     QStringList chaptersList = m_view.vob_list->itemData(m_view.vob_list->currentIndex(), Qt::UserRole + 1).toStringList();
231
232     for (int i = 0; i < chaptersList.count(); i++) {
233         QDomElement chapter = doc.createElement("chapter");
234         chapters.appendChild(chapter);
235         chapter.setAttribute("title", i18n("Chapter %1", i));
236         chapter.setAttribute("time", chaptersList.at(i));
237     }
238     // save chapters file
239     QFile file(m_view.vob_list->currentText() + ".dvdchapter");
240     if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
241         kWarning() << "//////  ERROR writing DVD CHAPTER file: " << m_view.vob_list->currentText() + ".dvdchapter";
242     } else {
243         file.write(doc.toString().toUtf8());
244         if (file.error() != QFile::NoError)
245             kWarning() << "//////  ERROR writing DVD CHAPTER file: " << m_view.vob_list->currentText() + ".dvdchapter";
246         else {
247             m_view.vob_list->setItemData(m_view.vob_list->currentIndex(), 0, Qt::UserRole + 2);
248             m_view.button_save->setEnabled(false);
249         }
250         file.close();
251     }
252 }