From: Jean-Baptiste Mardelle Date: Sat, 22 Mar 2008 23:12:39 +0000 (+0000) Subject: folders in project view X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=ddbfd46a476d99869653afc86a92f7450ca6583d;p=kdenlive folders in project view svn path=/branches/KDE4/; revision=2102 --- diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 198fd38f..306f6fbc 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -98,6 +98,8 @@ set(kdenlive_SRCS jogshuttle.cpp addtransitioncommand.cpp edittransitioncommand.cpp + addfoldercommand.cpp + editfoldercommand.cpp ) kde4_add_kcfg_files(kdenlive_SRCS GENERATE_MOC kdenlivesettings.kcfgc ) diff --git a/src/addfoldercommand.cpp b/src/addfoldercommand.cpp new file mode 100644 index 00000000..a64a218b --- /dev/null +++ b/src/addfoldercommand.cpp @@ -0,0 +1,42 @@ +/*************************************************************************** + * Copyright (C) 2007 by Jean-Baptiste Mardelle (jb@kdenlive.org) * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +#include + +#include "addfoldercommand.h" +#include "kdenlivedoc.h" + +AddFolderCommand::AddFolderCommand(KdenliveDoc *doc, const QString folderName, int clipId, bool doIt) + : m_doc(doc), m_name(folderName), m_id(clipId), m_doIt(doIt) { + if (doIt) setText(i18n("Add folder")); + else setText(i18n("Delete folder")); +} + +// virtual +void AddFolderCommand::undo() { + if (m_doIt) m_doc->deleteFolder(m_name, m_id); + else m_doc->addFolder(m_name, m_id, false); +} +// virtual +void AddFolderCommand::redo() { + if (m_doIt) m_doc->addFolder(m_name, m_id, false); + else m_doc->deleteFolder(m_name, m_id); +} + +#include "addfoldercommand.moc" diff --git a/src/addfoldercommand.h b/src/addfoldercommand.h new file mode 100644 index 00000000..a9122b3c --- /dev/null +++ b/src/addfoldercommand.h @@ -0,0 +1,43 @@ +/*************************************************************************** + * Copyright (C) 2007 by Jean-Baptiste Mardelle (jb@kdenlive.org) * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + + +#ifndef ADDFOLDERCOMMAND_H +#define ADDFOLDERCOMMAND_H + +#include + +class KdenliveDoc; + +class AddFolderCommand : public QUndoCommand { +public: + AddFolderCommand(KdenliveDoc *doc, const QString folderName, int clipId, bool doIt); + + virtual void undo(); + virtual void redo(); + +private: + KdenliveDoc *m_doc; + QString m_name; + int m_id; + bool m_doIt; +}; + +#endif + diff --git a/src/clipmanager.cpp b/src/clipmanager.cpp index b8ec8263..b8853b47 100644 --- a/src/clipmanager.cpp +++ b/src/clipmanager.cpp @@ -57,7 +57,6 @@ void ClipManager::addClip(DocClipBase *clip) { void ClipManager::slotDeleteClip(uint clipId) { for (int i = 0; i < m_clipList.count(); i++) { if (m_clipList.at(i)->getId() == clipId) { - //m_clipList.removeAt(i); AddClipCommand *command = new AddClipCommand(m_doc, m_clipList.at(i)->toXML(), clipId, false); m_doc->commandStack()->push(command); break; @@ -89,14 +88,17 @@ DocClipBase *ClipManager::getClipById(int clipId) { return NULL; } -void ClipManager::slotAddClipFile(const KUrl url, const QString group) { +void ClipManager::slotAddClipFile(const KUrl url, const QString group, const int groupId) { kDebug() << "///// CLIP MANAGER, ADDING CLIP: " << url; QDomDocument doc; QDomElement prod = doc.createElement("producer"); prod.setAttribute("resource", url.path()); uint id = m_clipIdCounter++; prod.setAttribute("id", QString::number(id)); - if (!group.isEmpty()) prod.setAttribute("group", group); + if (!group.isEmpty()) { + prod.setAttribute("groupname", group); + prod.setAttribute("groupid", groupId); + } KMimeType::Ptr type = KMimeType::findByUrl(url); if (type->name().startsWith("image/")) { prod.setAttribute("type", (int) IMAGE); @@ -107,7 +109,7 @@ void ClipManager::slotAddClipFile(const KUrl url, const QString group) { m_doc->commandStack()->push(command); } -void ClipManager::slotAddColorClipFile(const QString name, const QString color, QString duration, const QString group) { +void ClipManager::slotAddColorClipFile(const QString name, const QString color, QString duration, const QString group, const int groupId) { QDomDocument doc; QDomElement prod = doc.createElement("producer"); prod.setAttribute("mlt_service", "colour"); @@ -118,7 +120,16 @@ void ClipManager::slotAddColorClipFile(const QString name, const QString color, prod.setAttribute("in", "0"); prod.setAttribute("out", m_doc->getFramePos(duration)); prod.setAttribute("name", name); + if (!group.isEmpty()) { + prod.setAttribute("groupname", group); + prod.setAttribute("groupid", groupId); + } 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 f6d15b26..1521fb24 100644 --- a/src/clipmanager.h +++ b/src/clipmanager.h @@ -48,13 +48,14 @@ Q_OBJECT public: void addClip(DocClipBase *clip); DocClipBase *getClipAt(int pos); void deleteClip(uint clipId); - void slotAddClipFile(const KUrl url, const QString group); - void slotAddColorClipFile(const QString name, const QString color, QString duration, const QString group); + void slotAddClipFile(const KUrl url, 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); void setThumbsProgress(KUrl url, int progress); void checkAudioThumbs(); QList documentClipList(); + int getFreeClipId(); private: // Private attributes /** the list of clips in the document */ diff --git a/src/definitions.h b/src/definitions.h index 20ea0ecc..85ccbb4d 100644 --- a/src/definitions.h +++ b/src/definitions.h @@ -25,7 +25,7 @@ #define MAXCLIPDURATION 15000 enum OPERATIONTYPE { NONE = 0, MOVE = 1, RESIZESTART = 2, RESIZEEND = 3, FADEIN = 4, FADEOUT = 5, TRANSITIONSTART = 6, TRANSITIONEND = 7}; -enum CLIPTYPE { UNKNOWN = 0, AUDIO = 1, VIDEO = 2, AV = 3, COLOR = 4, IMAGE = 5, TEXT = 6, SLIDESHOW = 7, VIRTUAL = 8, PLAYLIST = 9}; +enum CLIPTYPE { UNKNOWN = 0, AUDIO = 1, VIDEO = 2, AV = 3, COLOR = 4, IMAGE = 5, TEXT = 6, SLIDESHOW = 7, VIRTUAL = 8, PLAYLIST = 9, FOLDER = 10}; enum GRAPHICSRECTITEM { AVWIDGET = 70000 , LABELWIDGET , TRANSITIONWIDGET }; enum TRANSITIONTYPE { diff --git a/src/docclipbase.cpp b/src/docclipbase.cpp index 2c4501a4..514abdbd 100644 --- a/src/docclipbase.cpp +++ b/src/docclipbase.cpp @@ -81,6 +81,11 @@ void DocClipBase::slotClearAudioCache() { m_audioThumbCreated = false; } +void DocClipBase::setGroup(const QString name, const QString id) { + m_xml.setAttribute("groupname", name); + m_xml.setAttribute("groupid", id); +} + KThumb *DocClipBase::thumbProducer() { return m_thumbProd; } diff --git a/src/docclipbase.h b/src/docclipbase.h index 159b20a6..85b2344e 100644 --- a/src/docclipbase.h +++ b/src/docclipbase.h @@ -202,6 +202,8 @@ Q_OBJECT public: void slotRequestAudioThumbs(); /** Free cache data */ void slotClearAudioCache(); + /** puts the clip in a group (used for folder grouping) */ + void setGroup(const QString name, const QString id); private: // Private attributes diff --git a/src/editfoldercommand.cpp b/src/editfoldercommand.cpp new file mode 100644 index 00000000..227d759d --- /dev/null +++ b/src/editfoldercommand.cpp @@ -0,0 +1,40 @@ +/*************************************************************************** + * Copyright (C) 2007 by Jean-Baptiste Mardelle (jb@kdenlive.org) * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +#include + +#include "editfoldercommand.h" +#include "kdenlivedoc.h" + +EditFolderCommand::EditFolderCommand(KdenliveDoc *doc, const QString newfolderName, const QString oldfolderName, int clipId, bool doIt) + : m_doc(doc), m_name(newfolderName), m_oldname(oldfolderName), m_id(clipId), m_doIt(doIt) { + setText(i18n("Rename folder")); +} + +// virtual +void EditFolderCommand::undo() { + m_doc->addFolder(m_oldname, m_id, true); +} +// virtual +void EditFolderCommand::redo() { + if (m_doIt) m_doc->addFolder(m_name, m_id, true); + m_doIt = true; +} + +#include "editfoldercommand.moc" diff --git a/src/editfoldercommand.h b/src/editfoldercommand.h new file mode 100644 index 00000000..87840ff5 --- /dev/null +++ b/src/editfoldercommand.h @@ -0,0 +1,44 @@ +/*************************************************************************** + * Copyright (C) 2007 by Jean-Baptiste Mardelle (jb@kdenlive.org) * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + + +#ifndef EDITFOLDERCOMMAND_H +#define EDITFOLDERCOMMAND_H + +#include + +class KdenliveDoc; + +class EditFolderCommand : public QUndoCommand { +public: + EditFolderCommand(KdenliveDoc *doc, const QString newfolderName, const QString oldfolderName, int clipId, bool doIt); + + virtual void undo(); + virtual void redo(); + +private: + KdenliveDoc *m_doc; + QString m_name; + QString m_oldname; + int m_id; + bool m_doIt; +}; + +#endif + diff --git a/src/kdenlivedoc.cpp b/src/kdenlivedoc.cpp index 64ce8e17..06f6ff22 100644 --- a/src/kdenlivedoc.cpp +++ b/src/kdenlivedoc.cpp @@ -31,6 +31,8 @@ #include "kdenlivesettings.h" #include "renderer.h" #include "clipmanager.h" +#include "addfoldercommand.h" +#include "editfoldercommand.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) { m_clipManager = new ClipManager(this); @@ -287,15 +289,34 @@ QString KdenliveDoc::description() const { } void KdenliveDoc::addClip(const QDomElement &elem, const int clipId) { - kDebug() << "///////// DOCUM, CREATING NEW CLIP, ID:" << clipId; DocClipBase *clip = new DocClipBase(m_clipManager, elem, clipId); + kDebug() << "///////// DOCUM, CREATING NEW CLIP, ID:" << clipId << ", PAR ID:" << elem.attribute("groupid"); m_clipManager->addClip(clip); emit addProjectClip(clip); } -void KdenliveDoc::deleteProjectClip(const uint clipId) { - emit deletTimelineClip(clipId); - m_clipManager->slotDeleteClip(clipId); +void KdenliveDoc::addFolder(const QString foldername, int clipId, bool edit) { + emit addProjectFolder(foldername, clipId, false, edit); +} + +void KdenliveDoc::deleteFolder(const QString foldername, int clipId) { + emit addProjectFolder(foldername, clipId, true); +} + +void KdenliveDoc::deleteProjectClip(QList ids) { + for (int i = 0; i < ids.size(); ++i) { + emit deletTimelineClip(ids.at(i)); + m_clipManager->slotDeleteClip(ids.at(i)); + } + setModified(true); +} + +void KdenliveDoc::deleteProjectFolder(QMap map) { + QMapIterator i(map); + while (i.hasNext()) { + i.next(); + slotDeleteFolder(i.key(), i.value()); + } setModified(true); } @@ -304,18 +325,40 @@ void KdenliveDoc::deleteClip(const uint clipId) { m_clipManager->deleteClip(clipId); } -void KdenliveDoc::slotAddClipFile(const KUrl url, const QString group) { +void KdenliveDoc::slotAddClipFile(const KUrl url, const QString group, const int groupId) { kDebug() << "///////// DOCUM, ADD CLP: " << url; - m_clipManager->slotAddClipFile(url, group); + m_clipManager->slotAddClipFile(url, group, groupId); + setModified(true); +} + +void KdenliveDoc::slotAddFolder(const QString folderName) { + AddFolderCommand *command = new AddFolderCommand(this, folderName, m_clipManager->getFreeClipId(), true); + commandStack()->push(command); + setModified(true); +} + +void KdenliveDoc::slotDeleteFolder(const QString folderName, const int id) { + AddFolderCommand *command = new AddFolderCommand(this, folderName, id, false); + commandStack()->push(command); setModified(true); } +void KdenliveDoc::slotEditFolder(const QString newfolderName, const QString oldfolderName, int clipId) { + EditFolderCommand *command = new EditFolderCommand(this, newfolderName, oldfolderName, clipId, false); + commandStack()->push(command); + setModified(true); +} + +int KdenliveDoc::getFreeClipId() { + return m_clipManager->getFreeClipId(); +} + DocClipBase *KdenliveDoc::getBaseClip(int clipId) { return m_clipManager->getClipById(clipId); } -void KdenliveDoc::slotAddColorClipFile(const QString name, const QString color, QString duration, const QString group) { - m_clipManager->slotAddColorClipFile(name, color, duration, group); +void KdenliveDoc::slotAddColorClipFile(const QString name, const QString color, QString duration, const QString group, const int groupId) { + m_clipManager->slotAddColorClipFile(name, color, duration, group, groupId); setModified(true); } diff --git a/src/kdenlivedoc.h b/src/kdenlivedoc.h index 8f278302..4e0f51de 100644 --- a/src/kdenlivedoc.h +++ b/src/kdenlivedoc.h @@ -60,13 +60,19 @@ Q_OBJECT public: Render *renderer(); ClipManager *clipManager(); void addClip(const QDomElement &elem, const int clipId); - void slotAddClipFile(const KUrl url, const QString group); - void slotAddColorClipFile(const QString name, const QString color, QString duration, const QString group); + 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 slotAddFolder(const QString folderName); + void slotDeleteFolder(const QString folderName, const int id); + void slotEditFolder(const QString folderName, const QString oldfolderName, int clipId); + void slotAddColorClipFile(const QString name, const QString color, QString duration, const QString group, const int groupId = -1); void deleteClip(const uint clipId); int getFramePos(QString duration); DocClipBase *getBaseClip(int clipId); void updateClip(int id); - void deleteProjectClip(const uint clipId); + void deleteProjectClip(QList ids); + void deleteProjectFolder(QMap map); /** Inform application of the audio thumbnails generation progress */ void setThumbsProgress(KUrl url, int progress); QString profilePath() const; @@ -78,6 +84,7 @@ Q_OBJECT public: void setProfilePath(QString path); /** Set to true if document needs saving, false otherwise */ void setModified(bool mod); + int getFreeClipId(); private: KUrl m_url; @@ -100,6 +107,7 @@ public slots: signals: void addProjectClip(DocClipBase *); + void addProjectFolder(const QString, int, bool, bool edit = false); void signalDeleteProjectClip(int); void updateClipDisplay(int); void deletTimelineClip(int); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 4c5a35d0..9fdf58b6 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -711,6 +711,7 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) { //cha disconnect(m_projectMonitor, SIGNAL(renderPosition(int)), m_activeTimeline, SLOT(moveCursorPos(int))); disconnect(m_projectMonitor, SIGNAL(durationChanged(int)), m_activeTimeline, SLOT(setDuration(int))); disconnect(m_activeDocument, SIGNAL(addProjectClip(DocClipBase *)), m_projectList, SLOT(slotAddClip(DocClipBase *))); + disconnect(m_activeDocument, SIGNAL(addProjectFolder(const QString, int, bool, bool)), m_projectList, SLOT(slotAddFolder(const QString, int, bool, bool))); disconnect(m_activeDocument, SIGNAL(signalDeleteProjectClip(int)), m_projectList, SLOT(slotDeleteClip(int))); disconnect(m_activeDocument, SIGNAL(updateClipDisplay(int)), m_projectList, SLOT(slotUpdateClip(int))); disconnect(m_activeDocument, SIGNAL(deletTimelineClip(int)), m_activeTimeline, SLOT(slotDeleteClip(int))); @@ -738,6 +739,7 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) { //cha connect(m_projectMonitor, SIGNAL(renderPosition(int)), trackView, SLOT(moveCursorPos(int))); connect(m_projectMonitor, SIGNAL(durationChanged(int)), trackView, SLOT(setDuration(int))); connect(doc, SIGNAL(addProjectClip(DocClipBase *)), m_projectList, SLOT(slotAddClip(DocClipBase *))); + connect(doc, SIGNAL(addProjectFolder(const QString, int, bool, bool)), m_projectList, SLOT(slotAddFolder(const QString, int, bool, bool))); connect(doc, SIGNAL(signalDeleteProjectClip(int)), m_projectList, SLOT(slotDeleteClip(int))); connect(doc, SIGNAL(updateClipDisplay(int)), m_projectList, SLOT(slotUpdateClip(int))); connect(doc, SIGNAL(deletTimelineClip(int)), trackView, SLOT(slotDeleteClip(int))); diff --git a/src/projectitem.cpp b/src/projectitem.cpp index 843d1534..62c112cf 100644 --- a/src/projectitem.cpp +++ b/src/projectitem.cpp @@ -39,7 +39,7 @@ const int UsageRole = NameRole + 2; ProjectItem::ProjectItem(QTreeWidget * parent, const QStringList & strings, QDomElement xml, int clipId) - : QTreeWidgetItem(parent, strings, QTreeWidgetItem::UserType), m_clipType(UNKNOWN), m_clipId(clipId), m_isGroup(false), m_groupName(QString::null) { + : QTreeWidgetItem(parent, strings, QTreeWidgetItem::UserType), m_clipType(UNKNOWN), m_clipId(clipId) { m_element = xml.cloneNode().toElement(); setSizeHint(0, QSize(65, 45)); setFlags(Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled | Qt::ItemIsEditable); @@ -59,7 +59,7 @@ ProjectItem::ProjectItem(QTreeWidget * parent, const QStringList & strings, QDom } ProjectItem::ProjectItem(QTreeWidgetItem * parent, const QStringList & strings, QDomElement xml, int clipId) - : QTreeWidgetItem(parent, strings, QTreeWidgetItem::UserType), m_clipType(UNKNOWN), m_clipId(clipId), m_isGroup(false), m_groupName(QString::null) { + : QTreeWidgetItem(parent, strings, QTreeWidgetItem::UserType), m_clipType(UNKNOWN), m_clipId(clipId) { m_element = xml.cloneNode().toElement(); setSizeHint(0, QSize(65, 45)); setFlags(Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled | Qt::ItemIsEditable); @@ -73,15 +73,30 @@ ProjectItem::ProjectItem(QTreeWidgetItem * parent, const QStringList & strings, } } +// folder ProjectItem::ProjectItem(QTreeWidget * parent, const QStringList & strings, int clipId) - : QTreeWidgetItem(parent, strings, QTreeWidgetItem::UserType), m_element(QDomElement()), m_clipType(UNKNOWN), m_clipId(clipId), m_isGroup(true), m_groupName(strings.at(1)) { + : QTreeWidgetItem(parent, strings, QTreeWidgetItem::UserType), m_element(QDomElement()), m_clipType(FOLDER), m_groupName(strings.at(1)), m_clipId(clipId), m_clip(NULL) { setSizeHint(0, QSize(65, 45)); setFlags(Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled | Qt::ItemIsEditable); setIcon(0, KIcon("folder")); } ProjectItem::ProjectItem(QTreeWidget * parent, DocClipBase *clip) - : QTreeWidgetItem(parent, QStringList(), QTreeWidgetItem::UserType), m_isGroup(false) { + : QTreeWidgetItem(parent, QStringList(), QTreeWidgetItem::UserType) { + setSizeHint(0, QSize(65, 45)); + setFlags(Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled | Qt::ItemIsEditable); + m_clip = clip; + m_element = clip->toXML(); + m_clipId = clip->getId(); + QString name = m_element.attribute("name"); + if (name.isEmpty()) name = KUrl(m_element.attribute("resource")).fileName(); + m_clipType = (CLIPTYPE) m_element.attribute("type").toInt(); + setText(1, name); + kDebug() << "PROJECT ITE;. ADDING LCIP: " << m_clipId; +} + +ProjectItem::ProjectItem(QTreeWidgetItem * parent, DocClipBase *clip) + : QTreeWidgetItem(parent, QStringList(), QTreeWidgetItem::UserType) { setSizeHint(0, QSize(65, 45)); setFlags(Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled | Qt::ItemIsEditable); m_clip = clip; @@ -90,7 +105,6 @@ ProjectItem::ProjectItem(QTreeWidget * parent, DocClipBase *clip) QString name = m_element.attribute("name"); if (name.isEmpty()) name = KUrl(m_element.attribute("resource")).fileName(); m_clipType = (CLIPTYPE) m_element.attribute("type").toInt(); - m_groupName = m_element.attribute("group"); setText(1, name); kDebug() << "PROJECT ITE;. ADDING LCIP: " << m_clipId; } @@ -117,13 +131,21 @@ int ProjectItem::clipMaxDuration() const { } bool ProjectItem::isGroup() const { - return m_isGroup; + return m_clipType == FOLDER; } const QString ProjectItem::groupName() const { return m_groupName; } +void ProjectItem::setGroupName(const QString name) { + m_groupName = name; +} + +void ProjectItem::setGroup(const QString name, const QString id) { + if (m_clip) m_clip->setGroup(name, id); +} + QStringList ProjectItem::names() const { QStringList result; result.append(text(0)); diff --git a/src/projectitem.h b/src/projectitem.h index 139e6bbd..184d89dc 100644 --- a/src/projectitem.h +++ b/src/projectitem.h @@ -35,8 +35,10 @@ class ProjectItem : public QTreeWidgetItem { public: ProjectItem(QTreeWidget * parent, const QStringList & strings, QDomElement xml, int clipId); ProjectItem(QTreeWidgetItem * parent, const QStringList & strings, QDomElement xml, int clipId); + /** Create folder item */ ProjectItem(QTreeWidget * parent, const QStringList & strings, int clipId); ProjectItem(QTreeWidget * parent, DocClipBase *clip); + ProjectItem(QTreeWidgetItem * parent, DocClipBase *clip); virtual ~ProjectItem(); QDomElement toXml() const; int numReferences() const; @@ -46,19 +48,20 @@ public: QStringList names() const; bool isGroup() const; const QString groupName() const; + void setGroupName(const QString name); const KUrl clipUrl() const; int clipMaxDuration() const; CLIPTYPE clipType() const; + void setGroup(const QString name, const QString id); private: QDomElement m_element; GenTime m_duration; + QString m_groupName; bool m_durationKnown; CLIPTYPE m_clipType; int m_clipId; void slotSetToolTip(); - bool m_isGroup; - QString m_groupName; DocClipBase *m_clip; }; diff --git a/src/projectlist.cpp b/src/projectlist.cpp index 1f17abc0..c648dda8 100644 --- a/src/projectlist.cpp +++ b/src/projectlist.cpp @@ -132,19 +132,22 @@ void ProjectList::setRenderer(Render *projectRender) { } void ProjectList::slotClipSelected() { - ProjectItem *item = (ProjectItem*) listView->currentItem(); + ProjectItem *item = static_cast (listView->currentItem()); if (item && !item->isGroup()) emit clipSelected(item->toXml()); } void ProjectList::slotUpdateItemDescription(QTreeWidgetItem *item, int column) { - if (column != 2) return; - ProjectItem *clip = (ProjectItem*) item; + ProjectItem *clip = static_cast (item); CLIPTYPE type = clip->clipType(); - if (type == AUDIO || type == VIDEO || type == AV || type == IMAGE || type == PLAYLIST) { - // Use Nepomuk system to store clip description - Nepomuk::Resource f(clip->clipUrl().path()); - f.setDescription(item->text(2)); - kDebug() << "NEPOMUK, SETTING CLIP: " << clip->clipUrl().path() << ", TO TEXT: " << item->text(2); + if (column == 2) { + if (type == AUDIO || type == VIDEO || type == AV || type == IMAGE || type == PLAYLIST) { + // Use Nepomuk system to store clip description + Nepomuk::Resource f(clip->clipUrl().path()); + f.setDescription(item->text(2)); + kDebug() << "NEPOMUK, SETTING CLIP: " << clip->clipUrl().path() << ", TO TEXT: " << item->text(2); + } + } else if (column == 1 && type == FOLDER) { + m_doc->slotEditFolder(item->text(1), clip->groupName(), clip->clipId()); } } @@ -180,14 +183,24 @@ void ProjectList::slotContextMenu(const QPoint &pos, QTreeWidgetItem *item) { } void ProjectList::slotRemoveClip() { - - if (!m_commandStack) kDebug() << "!!!!!!!!!!!!!!!!  NO CMD STK"; if (!listView->currentItem()) return; - ProjectItem *item = ((ProjectItem *)listView->currentItem()); + ProjectItem *item = static_cast (listView->currentItem()); + QList ids; + QMap folderids; + if (item->clipType() == FOLDER) folderids[item->groupName()] = item->clipId(); + else ids << item->clipId(); if (item->numReferences() > 0) { if (KMessageBox::questionYesNo(this, i18np("Delete clip %2 ?
This will also remove the clip in timeline", "Delete clip %2 ?
This will also remove its %1 clips in timeline", item->numReferences(), item->names().at(1)), i18n("Delete Clip")) != KMessageBox::Yes) return; + } else if (item->clipType() == FOLDER && item->childCount() > 0) { + int children = item->childCount(); + if (KMessageBox::questionYesNo(this, i18n("Delete folder %2 ?
This will also remove the %1 clips in that folder", children, item->names().at(1)), i18n("Delete Folder")) != KMessageBox::Yes) return; + for (int i = 0; i < children; ++i) { + ProjectItem *child = static_cast (item->child(i)); + ids << child->clipId(); + } } - m_doc->deleteProjectClip(item->clipId()); + if (!ids.isEmpty()) m_doc->deleteProjectClip(ids); + if (!folderids.isEmpty()) m_doc->deleteProjectFolder(folderids); } void ProjectList::selectItemById(const int clipId) { @@ -200,14 +213,14 @@ void ProjectList::addClip(const QStringList &name, const QDomElement &elem, cons ProjectItem *item; ProjectItem *groupItem = NULL; QString groupName; - if (group.isEmpty()) groupName = elem.attribute("group", QString::null); + if (group.isEmpty()) groupName = elem.attribute("groupname", QString::null); else groupName = group; if (elem.isNull() && url.isEmpty()) { // this is a folder groupName = name.at(1); QList groupList = listView->findItems(groupName, Qt::MatchExactly, 1); if (groupList.isEmpty()) { - (void) new ProjectItem(listView, name, clipId); + (void) new ProjectItem(listView, name, m_doc->getFreeClipId()); } return; } @@ -222,7 +235,7 @@ void ProjectList::addClip(const QStringList &name, const QDomElement &elem, cons QStringList itemName; itemName << QString::null << groupName; kDebug() << "------- CREATING NEW GRP: " << itemName; - groupItem = new ProjectItem(listView, itemName, m_clipIdCounter++); + groupItem = new ProjectItem(listView, itemName, m_doc->getFreeClipId()); } else groupItem = (ProjectItem *) groupList.first(); } if (groupItem) item = new ProjectItem(groupItem, name, elem, clipId); @@ -267,23 +280,59 @@ void ProjectList::addClip(const QStringList &name, const QDomElement &elem, cons } void ProjectList::slotDeleteClip(int clipId) { + kDebug() << "/////// DELETE CLIP: " << clipId; ProjectItem *item = getItemById(clipId); if (item) delete item; } void ProjectList::slotAddFolder() { - /* - QString folderName = KInputDialog::getText(i18n("New Folder"), i18n("Enter new folder name: ")); - if (folderName.isEmpty()) return; - QStringList itemEntry; - itemEntry.append(QString::null); - itemEntry.append(folderName); - AddClipCommand *command = new AddClipCommand(this, itemEntry, QDomElement(), m_clipIdCounter++, KUrl(), folderName, true); - m_commandStack->push(command);*/ + + // QString folderName = KInputDialog::getText(i18n("New Folder"), i18n("Enter new folder name: ")); + // if (folderName.isEmpty()) return; + m_doc->slotAddFolder(i18n("Folder")); //folderName); +} + +void ProjectList::slotAddFolder(const QString foldername, int clipId, bool remove, bool edit) { + if (remove) { + ProjectItem *item; + QTreeWidgetItemIterator it(listView); + while (*it) { + item = static_cast (*it); + if (item->clipType() == FOLDER && item->clipId() == clipId) { + delete item; + break; + } + ++it; + } + } else { + if (edit) { + disconnect(listView, SIGNAL(itemChanged(QTreeWidgetItem *, int)), this, SLOT(slotUpdateItemDescription(QTreeWidgetItem *, int))); + ProjectItem *item; + QTreeWidgetItemIterator it(listView); + while (*it) { + item = static_cast (*it); + if (item->clipType() == FOLDER && item->clipId() == clipId) { + item->setText(1, foldername); + break; + } + ++it; + } + connect(listView, SIGNAL(itemChanged(QTreeWidgetItem *, int)), this, SLOT(slotUpdateItemDescription(QTreeWidgetItem *, int))); + } else { + QStringList text; + text << QString() << foldername; + (void) new ProjectItem(listView, text, clipId); + } + } } void ProjectList::slotAddClip(DocClipBase *clip) { - ProjectItem *item = new ProjectItem(listView, clip); + const int parent = clip->toXML().attribute("groupid").toInt(); + if (parent != 0) { + ProjectItem *parentitem = getItemById(parent); + if (parentitem)(void) new ProjectItem(parentitem, clip); + else (void) new ProjectItem(listView, clip); + } else (void) new ProjectItem(listView, clip); emit getFileProperties(clip->toXML(), clip->getId()); } @@ -292,7 +341,7 @@ void ProjectList::slotUpdateClip(int id) { item->setData(1, UsageRole, QString::number(item->numReferences())); } -void ProjectList::slotAddClip(QUrl givenUrl, const QString &group) { +void ProjectList::slotAddClip(QUrl givenUrl, QString group) { if (!m_commandStack) kDebug() << "!!!!!!!!!!!!!!!!  NO CMD STK"; KUrl::List list; if (givenUrl.isEmpty()) @@ -300,9 +349,22 @@ void ProjectList::slotAddClip(QUrl givenUrl, const QString &group) { else list.append(givenUrl); if (list.isEmpty()) return; KUrl::List::Iterator it; - + int groupId = -1; + if (group.isEmpty()) { + ProjectItem *item = static_cast (listView->currentItem()); + if (item && item->clipType() != FOLDER) { + while (item->parent()) { + item = static_cast (item->parent()); + if (item->clipType() == FOLDER) break; + } + } + if (item && item->clipType() == FOLDER) { + group = item->groupName(); + groupId = item->clipId(); + } + } for (it = list.begin(); it != list.end(); it++) { - m_doc->slotAddClipFile(*it, group); + m_doc->slotAddClipFile(*it, group, groupId); } } @@ -316,7 +378,22 @@ void ProjectList::slotAddColorClip() { if (dia->exec() == QDialog::Accepted) { QString color = dia_ui->clip_color->color().name(); color = color.replace(0, 1, "0x") + "ff"; - m_doc->slotAddColorClipFile(dia_ui->clip_name->text(), color, dia_ui->clip_duration->text(), QString::null); + + QString group = QString(); + int groupId = -1; + ProjectItem *item = static_cast (listView->currentItem()); + if (item && item->clipType() != FOLDER) { + while (item->parent()) { + item = static_cast (item->parent()); + if (item->clipType() == FOLDER) break; + } + } + if (item && item->clipType() == FOLDER) { + group = item->groupName(); + groupId = item->clipId(); + } + + m_doc->slotAddColorClipFile(dia_ui->clip_name->text(), color, dia_ui->clip_duration->text(), group, groupId); } delete dia_ui; delete dia; @@ -402,7 +479,8 @@ ProjectItem *ProjectList::getItemById(int id) { break; ++it; } - return ((ProjectItem *)(*it)); + if (*it) return ((ProjectItem *)(*it)); + return NULL; } @@ -418,7 +496,7 @@ void ProjectList::addProducer(QDomElement producer, int parentId) { //kDebug()<<"////// ADDING PRODUCER:\n "<= m_clipIdCounter) m_clipIdCounter = id + 1; else if (id == 0) id = m_clipIdCounter++; diff --git a/src/projectlist.h b/src/projectlist.h index 2b808eef..3f1ff748 100644 --- a/src/projectlist.h +++ b/src/projectlist.h @@ -61,7 +61,7 @@ public: void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { if (index.column() == 1) { - const bool hover = option.state & (QStyle::State_Selected | QStyle::State_MouseOver | QStyle::State_HasFocus); + const bool hover = option.state & (QStyle::State_Selected); QRect r1 = option.rect; painter->save(); if (hover) { @@ -133,7 +133,7 @@ private: KdenliveDoc *m_doc; private slots: - void slotAddClip(QUrl givenUrl = QUrl(), const QString &group = QString()); + void slotAddClip(QUrl givenUrl = QUrl(), QString group = QString()); void slotRemoveClip(); void slotEditClip(); void slotClipSelected(); @@ -142,6 +142,7 @@ private slots: void slotEditClip(QTreeWidgetItem *, int); void slotContextMenu(const QPoint &pos, QTreeWidgetItem *); void slotAddFolder(); + void slotAddFolder(const QString foldername, int clipId, bool remove, bool edit); /** This is triggered when a clip description has been modified */ void slotUpdateItemDescription(QTreeWidgetItem *item, int column); //void slotShowMenu(const QPoint &pos); diff --git a/src/projectlistview.cpp b/src/projectlistview.cpp index 653a82ba..63e86e62 100644 --- a/src/projectlistview.cpp +++ b/src/projectlistview.cpp @@ -49,8 +49,9 @@ void ProjectListView::contextMenuEvent(QContextMenuEvent * event) { // virtual void ProjectListView::mouseDoubleClickEvent(QMouseEvent * event) { - if (!itemAt(event->pos())) emit addClip(); - else if (columnAt(event->pos().x()) == 2) QTreeWidget::mouseDoubleClickEvent(event); + ProjectItem *item = static_cast (itemAt(event->pos())); + if (!item) emit addClip(); + else if ((item->clipType() == FOLDER && columnAt(event->pos().x()) == 1) || columnAt(event->pos().x()) == 2) QTreeWidget::mouseDoubleClickEvent(event); } // virtual @@ -78,22 +79,26 @@ void ProjectListView::dropEvent(QDropEvent *event) { emit addClip(url, groupName); } - } else if (event->mimeData()->hasText()) { - QTreeWidgetItem *item = itemAt(event->pos()); + } else if (event->mimeData()->hasFormat("kdenlive/producerslist")) { + ProjectItem *item = static_cast (itemAt(event->pos())); if (item) { - if (item->parent()) item = item->parent(); - if (((ProjectItem *) item)->isGroup()) { + if (item->parent()) item = static_cast (item->parent()); + if (item->isGroup()) { //emit addClip(event->mimeData->text()); kDebug() << "//////////////// DROPPED RIGHT 1 "; QList list; list = selectedItems(); ProjectItem *clone; + int parentId = item->clipId(); foreach(QTreeWidgetItem *it, list) { // TODO allow dragging of folders ? if (!((ProjectItem *) it)->isGroup() && ((ProjectItem *) it)->clipId() < 10000) { if (it->parent()) clone = (ProjectItem*) it->parent()->takeChild(it->parent()->indexOfChild(it)); else clone = (ProjectItem*) takeTopLevelItem(indexOfTopLevelItem(it)); - if (clone) item->addChild(clone); + if (clone) { + item->addChild(clone); + clone->setGroup(item->groupName(), QString::number(parentId)); + } } } } else item = NULL; @@ -147,8 +152,7 @@ void ProjectListView::mouseMoveEvent(QMouseEvent *event) { QStringList ids; foreach(QTreeWidgetItem *item, list) { // TODO allow dragging of folders - if (!((ProjectItem *) item)->isGroup()) - ids.append(QString::number(((ProjectItem *) item)->clipId())); + ids.append(QString::number(((ProjectItem *) item)->clipId())); } QByteArray data; data.append(ids.join(";").toUtf8()); //doc.toString().toUtf8()); @@ -183,9 +187,11 @@ void ProjectListView::dragMoveEvent(QDragMoveEvent * event) { QStringList ProjectListView::mimeTypes() const { QStringList qstrList; + qstrList << QTreeWidget::mimeTypes(); // list of accepted mime types for drop qstrList.append("text/uri-list"); qstrList.append("text/plain"); + qstrList.append("kdenlive/producerslist"); return qstrList; }