From: Jean-Baptiste Mardelle Date: Sun, 6 Apr 2008 14:37:28 +0000 (+0000) Subject: Title clips now really usable (only transparency & duration change still missing) X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=83a64649db3395ff9ee7230ef46f9b7ca6b1576f;p=kdenlive Title clips now really usable (only transparency & duration change still missing) svn path=/branches/KDE4/; revision=2159 --- diff --git a/src/clipitem.cpp b/src/clipitem.cpp index c1ffe8bc..21d24e3d 100644 --- a/src/clipitem.cpp +++ b/src/clipitem.cpp @@ -87,9 +87,10 @@ ClipItem::ClipItem(DocClipBase *clip, ItemInfo info, double scale, double fps) QString colour = m_xml.attribute("colour"); colour = colour.replace(0, 2, "#"); setBrush(QColor(colour.left(7))); - } else if (m_clipType == IMAGE) { + } else if (m_clipType == IMAGE || m_clipType == TEXT) { m_maxDuration = GenTime(10000, m_fps); m_startPix = KThumb::getImage(KUrl(m_xml.attribute("resource")), (int)(50 * KdenliveSettings::project_display_ratio()), 50); + m_endPix = m_startPix; } else if (m_clipType == AUDIO) { connect(clip, SIGNAL(gotAudioData()), this, SLOT(slotGotAudioData())); } diff --git a/src/clipmanager.cpp b/src/clipmanager.cpp index b8853b47..9b43fed2 100644 --- a/src/clipmanager.cpp +++ b/src/clipmanager.cpp @@ -128,6 +128,27 @@ void ClipManager::slotAddColorClipFile(const QString name, const QString color, m_doc->commandStack()->push(command); } + + +void ClipManager::slotAddTextClipFile(const QString path, const QString group, const int groupId) { + kDebug() << "///// CLIP MANAGER, ADDING CLIP: " << path; + QDomDocument doc; + QDomElement prod = doc.createElement("producer"); + prod.setAttribute("resource", path + ".png"); + prod.setAttribute("xml", path); + uint id = m_clipIdCounter++; + prod.setAttribute("id", QString::number(id)); + if (!group.isEmpty()) { + prod.setAttribute("groupname", group); + prod.setAttribute("groupid", groupId); + } + prod.setAttribute("type", (int) TEXT); + prod.setAttribute("in", "0"); + prod.setAttribute("out", m_doc->getFramePos(KdenliveSettings::image_duration())); + AddClipCommand *command = new AddClipCommand(m_doc, prod, id, true); + m_doc->commandStack()->push(command); +} + int ClipManager::getFreeClipId() { return m_clipIdCounter++; } diff --git a/src/clipmanager.h b/src/clipmanager.h index 1521fb24..d4062aef 100644 --- a/src/clipmanager.h +++ b/src/clipmanager.h @@ -49,6 +49,7 @@ Q_OBJECT public: DocClipBase *getClipAt(int pos); void deleteClip(uint clipId); void slotAddClipFile(const KUrl url, const QString group, const int groupId); + void slotAddTextClipFile(const QString path, const QString group, const int groupId); void slotAddColorClipFile(const QString name, const QString color, QString duration, const QString group, const int groupId); DocClipBase *getClipById(int clipId); void slotDeleteClip(uint clipId); diff --git a/src/clipproperties.cpp b/src/clipproperties.cpp index 9118efc5..81e4c88a 100644 --- a/src/clipproperties.cpp +++ b/src/clipproperties.cpp @@ -55,12 +55,12 @@ ClipProperties::ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidg QPixmap pix = m_clip->thumbProducer()->getImage(url, 240, 180); m_view.clip_thumb->setPixmap(pix); - if (t == IMAGE || t == VIDEO) m_view.tabWidget->removeTab(1); + if (t == IMAGE || t == VIDEO || t == COLOR) m_view.tabWidget->removeTab(1); } else { m_view.tabWidget->removeTab(0); m_view.clip_thumb->setHidden(true); } - if (t != IMAGE && t != COLOR) m_view.clip_duration->setReadOnly(true); + if (t != IMAGE && t != COLOR && t != TEXT) m_view.clip_duration->setReadOnly(true); KFileItem f(KFileItem::Unknown, KFileItem::Unknown, url, true); m_view.clip_filesize->setText(KIO::convertSize(f.size())); diff --git a/src/docclipbase.cpp b/src/docclipbase.cpp index b96cdf58..5b85e6cc 100644 --- a/src/docclipbase.cpp +++ b/src/docclipbase.cpp @@ -144,6 +144,10 @@ const QString DocClipBase::description() const { return m_properties.value("description"); } +const QString DocClipBase::getProperty(const QString prop) const { + return m_properties.value(prop); +} + void DocClipBase::setDuration(GenTime dur) { m_duration = dur; } diff --git a/src/docclipbase.h b/src/docclipbase.h index 230b3d4b..e7ec0ae3 100644 --- a/src/docclipbase.h +++ b/src/docclipbase.h @@ -85,6 +85,9 @@ Q_OBJECT public: /** Returns the description of this clip. */ const QString description() const; + /** Returns any property of this clip. */ + const QString getProperty(const QString prop) const; + /** Returns the internal unique id of the clip. */ uint getId() const; void setId(const uint &newId); diff --git a/src/kdenlivedoc.cpp b/src/kdenlivedoc.cpp index 0d7fd96c..df368746 100644 --- a/src/kdenlivedoc.cpp +++ b/src/kdenlivedoc.cpp @@ -35,7 +35,7 @@ #include "editfoldercommand.h" #include "titlewidget.h" -KdenliveDoc::KdenliveDoc(const KUrl &url, MltVideoProfile profile, QUndoGroup *undoGroup, QWidget *parent): QObject(parent), m_render(NULL), m_url(url), m_profile(profile), m_fps((double)profile.frame_rate_num / profile.frame_rate_den), m_width(profile.width), m_height(profile.height), m_commandStack(new KUndoStack(undoGroup)), m_modified(false) { +KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, MltVideoProfile profile, QUndoGroup *undoGroup, QWidget *parent): QObject(parent), m_render(NULL), m_url(url), m_projectFolder(projectFolder), m_profile(profile), m_fps((double)profile.frame_rate_num / profile.frame_rate_den), m_width(profile.width), m_height(profile.height), m_commandStack(new KUndoStack(undoGroup)), m_modified(false) { m_clipManager = new ClipManager(this); if (!url.isEmpty()) { QString tmpFile; @@ -147,6 +147,11 @@ ClipManager *KdenliveDoc::clipManager() { return m_clipManager; } +KUrl KdenliveDoc::projectFolder() const { + if (m_projectFolder.isEmpty()) return KUrl(KStandardDirs::locateLocal("appdata", "/projects/")); + return m_projectFolder; +} + QString KdenliveDoc::getDocumentStandard() { //WARNING: this way to tell the video standard is a bit hackish... if (m_profile.description.contains("pal", Qt::CaseInsensitive) || m_profile.description.contains("25", Qt::CaseInsensitive) || m_profile.description.contains("50", Qt::CaseInsensitive)) return "PAL"; @@ -283,7 +288,7 @@ void KdenliveDoc::setModified(bool mod) { emit docModified(m_modified); } -bool KdenliveDoc::isModified() { +bool KdenliveDoc::isModified() const { return m_modified; } @@ -337,6 +342,12 @@ void KdenliveDoc::slotAddClipFile(const KUrl url, const QString group, const int setModified(true); } +void KdenliveDoc::slotAddTextClipFile(const QString path, const QString group, const int groupId) { + kDebug() << "///////// DOCUM, ADD TXT CLP: " << path; + m_clipManager->slotAddTextClipFile(path, group, groupId); + setModified(true); +} + void KdenliveDoc::slotAddFolder(const QString folderName) { AddFolderCommand *command = new AddFolderCommand(this, folderName, m_clipManager->getFreeClipId(), true); commandStack()->push(command); @@ -369,11 +380,33 @@ void KdenliveDoc::slotAddColorClipFile(const QString name, const QString color, } void KdenliveDoc::slotCreateTextClip(QString group, int groupId) { - TitleWidget *dia_ui = new TitleWidget(m_render, 0); + QString titlesFolder = projectFolder().path() + "/titles/"; + KStandardDirs::makeDir(titlesFolder); + TitleWidget *dia_ui = new TitleWidget(KUrl(), titlesFolder, m_render, 0); + if (dia_ui->exec() == QDialog::Accepted) { + QString titleName = "title"; + int counter = 0; + QString path = titlesFolder + titleName + QString::number(counter).rightJustified(3, '0', false); + while (QFile::exists(path + ".kdenlivetitle")) { + counter++; + path = titlesFolder + titleName + QString::number(counter).rightJustified(3, '0', false); + } + QPixmap pix = dia_ui->renderedPixmap(); + pix.save(path + ".png"); + dia_ui->saveTitle(path + ".kdenlivetitle"); + slotAddTextClipFile(path, QString(), -1); + } + delete dia_ui; +} + +void KdenliveDoc::editTextClip(QString path, int id) { + TitleWidget *dia_ui = new TitleWidget(KUrl(path + ".kdenlivetitle"), path, m_render, 0); if (dia_ui->exec() == QDialog::Accepted) { - QPixmap p = dia_ui->renderedPixmap(); - p.save("/tmp/kdenlivetitle.png"); - slotAddClipFile(KUrl("/tmp/kdenlivetitle.png"), QString(), -1); + QPixmap pix = dia_ui->renderedPixmap(); + pix.save(path + ".png"); + dia_ui->saveTitle(path + ".kdenlivetitle"); + //slotAddClipFile(KUrl("/tmp/kdenlivetitle.png"), QString(), -1); + emit refreshClipThumbnail(id); } delete dia_ui; } diff --git a/src/kdenlivedoc.h b/src/kdenlivedoc.h index 85761018..cfb922f9 100644 --- a/src/kdenlivedoc.h +++ b/src/kdenlivedoc.h @@ -42,7 +42,7 @@ class DocClipBase; class KdenliveDoc: public QObject { Q_OBJECT public: - KdenliveDoc(const KUrl &url, MltVideoProfile profile, QUndoGroup *undoGroup, QWidget *parent = 0); + KdenliveDoc(const KUrl &url, const KUrl &projectFolder, MltVideoProfile profile, QUndoGroup *undoGroup, QWidget *parent = 0); ~KdenliveDoc(); QDomNodeList producersList(); double fps() const; @@ -63,6 +63,8 @@ Q_OBJECT public: void addFolder(const QString foldername, int clipId, bool edit); void deleteFolder(const QString foldername, int clipId); void slotAddClipFile(const KUrl url, const QString group, const int groupId = -1); + void slotAddTextClipFile(const QString path, const QString group, const int groupId = -1); + void editTextClip(QString path, int id); void slotAddFolder(const QString folderName); void slotDeleteFolder(const QString folderName, const int id); void slotEditFolder(const QString folderName, const QString oldfolderName, int clipId); @@ -86,7 +88,9 @@ Q_OBJECT public: void setModified(bool mod); int getFreeClipId(); /** does the document need saving */ - bool isModified(); + bool isModified() const; + /** Returns project folder, used to store project files (titles, effects,...) */ + KUrl projectFolder() const; private: KUrl m_url; @@ -104,6 +108,8 @@ private: QString m_scenelist; /** tells whether current doc has been changed since last save event */ bool m_modified; + /** Project folder, used to store project files (titles, effects,...) */ + KUrl m_projectFolder; public slots: void slotCreateTextClip(QString group, int groupId); @@ -117,6 +123,7 @@ signals: void thumbsProgress(KUrl, int); /** emited when the document state has been modified (= needs saving or not) */ void docModified(bool); + void refreshClipThumbnail(int); }; #endif diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 0bec81b7..5176dec8 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -504,16 +504,18 @@ void MainWindow::readOptions() { void MainWindow::newFile() { QString profileName; + KUrl projectFolder; if (m_timelineArea->count() == 0) profileName = KdenliveSettings::default_profile(); else { ProjectSettings *w = new ProjectSettings; - w->exec(); + if (w->exec() != QDialog::Accepted) return; profileName = w->selectedProfile(); + projectFolder = w->selectedFolder(); delete w; } MltVideoProfile prof = ProfilesDialog::getVideoProfile(profileName); if (prof.width == 0) prof = ProfilesDialog::getVideoProfile("dv_pal"); - KdenliveDoc *doc = new KdenliveDoc(KUrl(), prof, m_commandStack); + KdenliveDoc *doc = new KdenliveDoc(KUrl(), projectFolder, prof, m_commandStack); TrackView *trackView = new TrackView(doc, this); m_timelineArea->addTab(trackView, KIcon("kdenlive"), i18n("Untitled") + " / " + prof.description); if (m_timelineArea->count() == 1) @@ -578,7 +580,7 @@ void MainWindow::openFile(const KUrl &url) { //new //TODO: get video profile from url before opening it MltVideoProfile prof = ProfilesDialog::getVideoProfile(KdenliveSettings::default_profile()); if (prof.width == 0) prof = ProfilesDialog::getVideoProfile("dv_pal"); - KdenliveDoc *doc = new KdenliveDoc(url, prof, m_commandStack); + KdenliveDoc *doc = new KdenliveDoc(url, KUrl(), prof, m_commandStack); TrackView *trackView = new TrackView(doc, this); m_timelineArea->setCurrentIndex(m_timelineArea->addTab(trackView, KIcon("kdenlive"), doc->description())); m_timelineArea->setTabToolTip(m_timelineArea->currentIndex(), doc->url().path()); @@ -589,6 +591,8 @@ void MainWindow::openFile(const KUrl &url) { //new void MainWindow::parseProfiles() { //kdDebug()<<" + + YOUR MLT INSTALL WAS FOUND IN: "<< MLT_PREFIX <clipType() == TEXT) { + m_activeDocument->editTextClip(clip->getProperty("xml"), clip->getId()); + return; + } ClipProperties dia(clip, m_activeDocument->timecode(), m_activeDocument->fps(), this); if (dia.exec() == QDialog::Accepted) { m_projectList->slotUpdateClipProperties(dia.clipId(), dia.properties()); diff --git a/src/projectlist.cpp b/src/projectlist.cpp index cee7dbd0..33678dc9 100644 --- a/src/projectlist.cpp +++ b/src/projectlist.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -46,8 +47,8 @@ #include "docclipbase.h" #include "kdenlivedoc.h" #include "renderer.h" +#include "kthumb.h" #include "projectlistview.h" -#include ProjectList::ProjectList(QWidget *parent) : QWidget(parent), m_render(NULL), m_fps(-1), m_commandStack(NULL) { @@ -465,6 +466,15 @@ QDomElement ProjectList::producersList() { return prods; } +void ProjectList::slotRefreshClipThumbnail(int clipId) { + ProjectItem *item = getItemById(clipId); + if (item) { + int height = 40; + int width = (int)(height * (double) m_render->renderWidth() / m_render->renderHeight()); + QPixmap pix = KThumb::getImage(item->clipUrl(), item->referencedClip()->getProjectThumbFrame(), width, height); + item->setIcon(0, pix); + } +} void ProjectList::slotReplyGetFileProperties(int clipId, const QMap < QString, QString > &properties, const QMap < QString, QString > &metadata) { ProjectItem *item = getItemById(clipId); @@ -475,8 +485,6 @@ void ProjectList::slotReplyGetFileProperties(int clipId, const QMap < QString, Q } } - - void ProjectList::slotReplyGetImage(int clipId, int pos, const QPixmap &pix, int w, int h) { ProjectItem *item = getItemById(clipId); if (item) item->setIcon(0, pix); diff --git a/src/projectlist.h b/src/projectlist.h index 80498cb6..4bc08c82 100644 --- a/src/projectlist.h +++ b/src/projectlist.h @@ -116,6 +116,7 @@ public slots: void slotAddClip(DocClipBase *clip); void slotDeleteClip(int clipId); void slotUpdateClip(int id); + void slotRefreshClipThumbnail(int clipId); private: diff --git a/src/projectsettings.cpp b/src/projectsettings.cpp index 1aaa15e2..c1c726d4 100644 --- a/src/projectsettings.cpp +++ b/src/projectsettings.cpp @@ -60,10 +60,14 @@ void ProjectSettings::slotUpdateButton(const QString &path) { else buttonOk->setEnabled(true); } -QString ProjectSettings::selectedProfile() { +QString ProjectSettings::selectedProfile() const { return ProfilesDialog::getPathFromDescription(m_view.profiles_list->currentText()); } +KUrl ProjectSettings::selectedFolder() const { + return m_view.project_folder->url(); +} + #include "projectsettings.moc" diff --git a/src/projectsettings.h b/src/projectsettings.h index a36f50c5..e36fe8df 100644 --- a/src/projectsettings.h +++ b/src/projectsettings.h @@ -31,7 +31,8 @@ class ProjectSettings : public QDialog { public: ProjectSettings(QWidget * parent = 0); - QString selectedProfile(); + QString selectedProfile() const; + KUrl selectedFolder() const; private slots: void slotUpdateDisplay(); diff --git a/src/renderer.cpp b/src/renderer.cpp index 8ecfc69d..0e53393a 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -373,7 +373,7 @@ bool Render::isValid(KUrl url) { void Render::getFileProperties(const QDomElement &xml, int clipId) { int height = 40; - int width = (int)(height * 16 / 9.0); //KdenliveSettings::displayratio(); + int width = (int)(height * m_mltProfile->dar()); QDomDocument doc; QDomElement westley = doc.createElement("westley"); doc.appendChild(westley); diff --git a/src/titlewidget.cpp b/src/titlewidget.cpp index 01719d8c..83a03d1f 100644 --- a/src/titlewidget.cpp +++ b/src/titlewidget.cpp @@ -35,7 +35,7 @@ int settingUp = false; -TitleWidget::TitleWidget(Render *render, QWidget *parent): QDialog(parent), m_render(render), m_count(0) { +TitleWidget::TitleWidget(KUrl url, QString projectPath, Render *render, QWidget *parent): QDialog(parent), m_render(render), m_count(0), m_projectPath(projectPath) { setupUi(this); //frame_properties-> setFont(KGlobalSettings::toolBarFont()); @@ -155,7 +155,6 @@ TitleWidget::TitleWidget(Render *render, QWidget *parent): QDialog(parent), m_re QPen framepen(Qt::DotLine); framepen.setColor(Qt::red); - slotRectTool(); m_frameBorder = new QGraphicsRectItem(QRectF(0, 0, m_frameWidth, m_frameHeight)); m_frameBorder->setPen(framepen); @@ -174,6 +173,10 @@ TitleWidget::TitleWidget(Render *render, QWidget *parent): QDialog(parent), m_re kDebug() << "// TITLE WIDGWT: " << graphicsView->viewport()->width() << "x" << graphicsView->viewport()->height(); toolBox->setItemEnabled(2, false); toolBox->setItemEnabled(3, false); + if (!url.isEmpty()) { + m_count = m_titledocument.loadDocument(url, startViewport, endViewport) + 1; + slotSelectTool(); + } else slotRectTool(); } @@ -549,7 +552,7 @@ void TitleWidget::setupViewports() { } void TitleWidget::loadTitle() { - KUrl url = KFileDialog::getOpenUrl(KUrl(), "*.kdenlivetitle", this, tr("Save Title")); + KUrl url = KFileDialog::getOpenUrl(KUrl(m_projectPath), "*.kdenlivetitle", this, tr("Save Title")); if (!url.isEmpty()) { QList items = m_scene->items(); for (int i = 0; i < items.size(); i++) { @@ -560,9 +563,9 @@ void TitleWidget::loadTitle() { } } -void TitleWidget::saveTitle() { - KUrl url = KFileDialog::getSaveUrl(KUrl(), "*.kdenlivetitle", this, tr("Save Title")); - m_titledocument.saveDocument(url, startViewport, endViewport); +void TitleWidget::saveTitle(KUrl url) { + if (url.isEmpty()) KUrl url = KFileDialog::getSaveUrl(KUrl(m_projectPath), "*.kdenlivetitle", this, tr("Save Title")); + if (!url.isEmpty()) m_titledocument.saveDocument(url, startViewport, endViewport); } QPixmap TitleWidget::renderedPixmap() { diff --git a/src/titlewidget.h b/src/titlewidget.h index 55392513..e213b779 100644 --- a/src/titlewidget.h +++ b/src/titlewidget.h @@ -44,7 +44,7 @@ public: class TitleWidget : public QDialog , public Ui::TitleWidget_UI { Q_OBJECT public: - TitleWidget(Render *render, QWidget *parent = 0); + TitleWidget(KUrl url, QString projectPath, Render *render, QWidget *parent = 0); protected: virtual void resizeEvent(QResizeEvent * event); @@ -67,6 +67,8 @@ private: QAction *m_buttonCursor; QAction *m_buttonSave; QAction *m_buttonLoad; + /** project path for storing title clips */ + QString m_projectPath; public slots: void slotNewText(QGraphicsTextItem *tt); @@ -81,7 +83,7 @@ public slots: void svgSelected(const KUrl&); void itemScaled(int); void itemRotate(int); - void saveTitle(); + void saveTitle(KUrl url = KUrl()); void loadTitle(); QPixmap renderedPixmap();