]> git.sesse.net Git - kdenlive/blob - src/dvdwizardvob.cpp
Updated Dvd wizard
[kdenlive] / src / dvdwizardvob.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 "dvdwizardvob.h"
21 #include "kthumb.h"
22 #include "timecode.h"
23
24 #include <mlt++/Mlt.h>
25
26 #include <KUrlRequester>
27 #include <KDebug>
28 #include <KStandardDirs>
29 #include <KFileItem>
30 #include <KFileDialog>
31
32 #include <QHBoxLayout>
33 #include <QDomDocument>
34 #include <QTreeWidgetItem>
35
36 DvdWizardVob::DvdWizardVob(const QString &profile, QWidget *parent) :
37         QWizardPage(parent)
38 {
39     m_view.setupUi(this);
40     m_view.intro_vob->setEnabled(false);
41     m_view.intro_vob->setFilter("video/mpeg");
42     m_view.button_add->setIcon(KIcon("document-new"));
43     m_view.button_delete->setIcon(KIcon("edit-delete"));
44     m_view.button_up->setIcon(KIcon("go-up"));
45     m_view.button_down->setIcon(KIcon("go-down"));
46     connect(m_view.use_intro, SIGNAL(toggled(bool)), m_view.intro_vob, SLOT(setEnabled(bool)));
47     connect(m_view.button_add, SIGNAL(clicked()), this, SLOT(slotAddVobFile()));
48     connect(m_view.button_delete, SIGNAL(clicked()), this, SLOT(slotDeleteVobFile()));
49     connect(m_view.button_up, SIGNAL(clicked()), this, SLOT(slotItemUp()));
50     connect(m_view.button_down, SIGNAL(clicked()), this, SLOT(slotItemDown()));
51     connect(m_view.vobs_list, SIGNAL(itemSelectionChanged()), this, SLOT(slotCheckVobList()));
52     m_view.vobs_list->setIconSize(QSize(60, 45));
53
54     if (KStandardDirs::findExe("dvdauthor").isEmpty()) m_errorMessage.append(i18n("<strong>Program %1 is required for the DVD wizard.", i18n("dvdauthor")));
55     if (KStandardDirs::findExe("mkisofs").isEmpty()) m_errorMessage.append(i18n("<strong>Program %1 is required for the DVD wizard.", i18n("mkisofs")));
56     if (m_errorMessage.isEmpty()) m_view.error_message->setVisible(false);
57     else m_view.error_message->setText(m_errorMessage);
58
59     m_view.dvd_profile->addItems(QStringList() << i18n("PAL") << i18n("NTSC"));
60     if (profile == "dv_ntsc" || profile == "dv_ntsc_wide") {
61         m_view.dvd_profile->setCurrentIndex(1);
62     }
63     connect(m_view.dvd_profile, SIGNAL(activated(int)), this, SLOT(changeFormat()));
64     m_view.vobs_list->header()->setStretchLastSection(false);
65     m_view.vobs_list->header()->setResizeMode(0, QHeaderView::Stretch);
66     m_view.vobs_list->header()->setResizeMode(1, QHeaderView::Custom);
67     m_view.vobs_list->header()->setResizeMode(2, QHeaderView::Custom);
68
69 #if KDE_IS_VERSION(4,2,0)
70     m_capacityBar = new KCapacityBar(KCapacityBar::DrawTextInline, this);
71     QHBoxLayout *layout = new QHBoxLayout;
72     layout->addWidget(m_capacityBar);
73     m_view.size_box->setLayout(layout);
74 #else
75     m_view.size_box->setHidden(true);
76 #endif
77     slotCheckVobList();
78 }
79
80 DvdWizardVob::~DvdWizardVob()
81 {
82 #if KDE_IS_VERSION(4,2,0)
83     delete m_capacityBar;
84 #endif
85 }
86
87
88 void DvdWizardVob::slotAddVobFile(KUrl url)
89 {
90     if (url.isEmpty()) url = KFileDialog::getOpenUrl(KUrl("kfiledialog:///projectfolder"), "video/mpeg", this, i18n("Add new video file"));
91     if (url.isEmpty()) return;
92     QFile f(url.path());
93     qint64 fileSize = f.size();
94     QString profilename;
95     if (m_view.dvd_profile->currentIndex() == 0) profilename = "dv_pal";
96     else profilename = "dv_ntsc";
97     Mlt::Profile profile((char*) profilename.data());
98     QTreeWidgetItem *item = new QTreeWidgetItem(m_view.vobs_list, QStringList() << url.path() << QString() << KIO::convertSize(fileSize));
99     item->setData(0, Qt::UserRole, fileSize);
100     item->setIcon(0, KIcon("video-x-generic"));
101     if (QFile::exists(url.path() + ".dvdchapter")) {
102         // insert chapters as children
103         QFile file(url.path() + ".dvdchapter");
104         if (file.open(QIODevice::ReadOnly)) {
105             QDomDocument doc;
106             doc.setContent(&file);
107             file.close();
108             QDomNodeList chapters = doc.elementsByTagName("chapter");
109             QStringList chaptersList;
110             for (int j = 0; j < chapters.count(); j++) {
111                 QTreeWidgetItem *sub = new QTreeWidgetItem(item, QStringList() << QString::number(j) + " - " + chapters.at(j).toElement().attribute("title"));
112                 sub->setText(1, Timecode::getStringTimecode(chapters.at(j).toElement().attribute("time").toInt(), profile.fps()));
113                 sub->setData(1, Qt::UserRole, chapters.at(j).toElement().attribute("time").toInt());
114             }
115         }
116     }
117
118     QPixmap pix(60, 45);
119
120     char *tmp = (char *) qstrdup(url.path().toUtf8().data());
121     Mlt::Producer *producer = new Mlt::Producer(profile, tmp);
122     delete[] tmp;
123
124     if (producer->is_blank() == false) {
125         pix = KThumb::getFrame(producer, 0, 60, 45);
126         item->setIcon(0, pix);
127         item->setText(1, Timecode::getStringTimecode(producer->get_playtime(), profile.fps()));
128     }
129     delete producer;
130
131     slotCheckVobList();
132 }
133
134 void DvdWizardVob::changeFormat()
135 {
136     int max = m_view.vobs_list->topLevelItemCount();
137     QString profilename;
138     if (m_view.dvd_profile->currentIndex() == 0) profilename = "dv_pal";
139     else profilename = "dv_ntsc";
140     Mlt::Profile profile((char*) profilename.data());
141     QPixmap pix(180, 135);
142
143     for (int i = 0; i < max; i++) {
144         QTreeWidgetItem *item = m_view.vobs_list->topLevelItem(i);
145         char *tmp = (char *) qstrdup(item->text(0).toUtf8().data());
146         Mlt::Producer *producer = new Mlt::Producer(profile, tmp);
147         delete[] tmp;
148
149         if (producer->is_blank() == false) {
150             //pix = KThumb::getFrame(producer, 0, 180, 135);
151             //item->setIcon(0, pix);
152             item->setText(1, Timecode::getStringTimecode(producer->get_playtime(), profile.fps()));
153         }
154         delete producer;
155         int submax = item->childCount();
156         for (int j = 0; j < submax; j++) {
157             QTreeWidgetItem *subitem = item->child(j);
158             subitem->setText(1, Timecode::getStringTimecode(subitem->data(1, Qt::UserRole).toInt(), profile.fps()));
159         }
160     }
161     slotCheckVobList();
162 }
163
164 void DvdWizardVob::slotDeleteVobFile()
165 {
166     QTreeWidgetItem *item = m_view.vobs_list->currentItem();
167     if (item == NULL) return;
168     delete item;
169     slotCheckVobList();
170 }
171
172
173 // virtual
174 bool DvdWizardVob::isComplete() const
175 {
176     if (!m_view.error_message->text().isEmpty()) return false;
177     if (m_view.vobs_list->topLevelItemCount() == 0) return false;
178     return true;
179 }
180
181 bool DvdWizardVob::useChapters() const
182 {
183     return true; //m_view.use_chapters->isChecked();
184 }
185
186 void DvdWizardVob::setUrl(const QString &url)
187 {
188     slotAddVobFile(KUrl(url));
189 }
190
191 QStringList DvdWizardVob::selectedUrls() const
192 {
193     QStringList result;
194     QString path;
195     int max = m_view.vobs_list->topLevelItemCount();
196     for (int i = 0; i < max; i++) {
197         QTreeWidgetItem *item = m_view.vobs_list->topLevelItem(i);
198         if (item) result.append(item->text(0));
199     }
200     return result;
201 }
202
203 QStringList DvdWizardVob::selectedTitles() const
204 {
205     QStringList result;
206     int max = m_view.vobs_list->topLevelItemCount();
207     for (int i = 0; i < max; i++) {
208         QTreeWidgetItem *item = m_view.vobs_list->topLevelItem(i);
209         if (item) {
210             result.append(item->text(0));
211             int submax = item->childCount();
212             for (int j = 0; j < submax; j++) {
213                 QTreeWidgetItem *subitem = item->child(j);
214                 result.append(subitem->text(0) + ' ' + subitem->text(1));
215             }
216         }
217     }
218     return result;
219 }
220
221 QStringList DvdWizardVob::chapter(int ix) const
222 {
223     QStringList result;
224     QTreeWidgetItem *item = m_view.vobs_list->topLevelItem(ix);
225     if (item) {
226         int submax = item->childCount();
227         for (int j = 0; j < submax; j++) {
228             QTreeWidgetItem *subitem = item->child(j);
229             result.append(subitem->text(1));
230         }
231     }
232     return result;
233 }
234
235 QStringList DvdWizardVob::selectedTargets() const
236 {
237     QStringList result;
238     int max = m_view.vobs_list->topLevelItemCount();
239     for (int i = 0; i < max; i++) {
240         QTreeWidgetItem *item = m_view.vobs_list->topLevelItem(i);
241         if (item) {
242             result.append("jump title " + QString::number(i + 1));
243             int submax = item->childCount();
244             for (int j = 0; j < submax; j++) {
245                 QTreeWidgetItem *subitem = item->child(j);
246                 result.append("jump title " + QString::number(i + 1) + " chapter " + QString::number(j + 1));
247             }
248         }
249     }
250     return result;
251 }
252
253
254 QString DvdWizardVob::introMovie() const
255 {
256     if (!m_view.use_intro->isChecked()) return QString();
257     return m_view.intro_vob->url().path();
258 }
259
260 void DvdWizardVob::slotCheckVobList()
261 {
262     emit completeChanged();
263     int max = m_view.vobs_list->topLevelItemCount();
264     QTreeWidgetItem *item = m_view.vobs_list->currentItem();
265     bool hasItem = true;
266     if (item == NULL) hasItem = false;
267     m_view.button_delete->setEnabled(hasItem);
268     if (hasItem && m_view.vobs_list->indexOfTopLevelItem(item) == 0) m_view.button_up->setEnabled(false);
269     else m_view.button_up->setEnabled(hasItem);
270     if (hasItem && m_view.vobs_list->indexOfTopLevelItem(item) == max - 1) m_view.button_down->setEnabled(false);
271     else m_view.button_down->setEnabled(hasItem);
272
273 #if KDE_IS_VERSION(4,2,0)
274     qint64 totalSize = 0;
275     for (int i = 0; i < max; i++) {
276         item = m_view.vobs_list->topLevelItem(i);
277         if (item) totalSize += (qint64) item->data(0, Qt::UserRole).toInt();
278     }
279
280     qint64 maxSize = (qint64) 47000 * 100000;
281     m_capacityBar->setValue(100 * totalSize / maxSize);
282     m_capacityBar->setText(KIO::convertSize(totalSize));
283 #endif
284 }
285
286 void DvdWizardVob::slotItemUp()
287 {
288     QTreeWidgetItem *item = m_view.vobs_list->currentItem();
289     if (item == NULL) return;
290     int index = m_view.vobs_list->indexOfTopLevelItem(item);
291     if (index == 0) return;
292     m_view.vobs_list->insertTopLevelItem(index - 1, m_view.vobs_list->takeTopLevelItem(index));
293 }
294
295 void DvdWizardVob::slotItemDown()
296 {
297     int max = m_view.vobs_list->topLevelItemCount();
298     QTreeWidgetItem *item = m_view.vobs_list->currentItem();
299     if (item == NULL) return;
300     int index = m_view.vobs_list->indexOfTopLevelItem(item);
301     if (index == max - 1) return;
302     m_view.vobs_list->insertTopLevelItem(index + 1, m_view.vobs_list->takeTopLevelItem(index));
303 }
304
305 bool DvdWizardVob::isPal() const
306 {
307     return m_view.dvd_profile->currentIndex() == 0;
308 }
309
310
311