From 2356a3cd98b41bf328eacf2501cd2a09cac5ea41 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Mardelle Date: Wed, 16 Jan 2008 10:47:26 +0000 Subject: [PATCH] =?utf8?q?project=20tree=20view:=C2=A0Add=20drag=20and=20d?= =?utf8?q?rop=20support?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit svn path=/branches/KDE4/; revision=1802 --- src/addclipcommand.cpp | 8 +- src/addclipcommand.h | 3 +- src/projectitem.cpp | 33 ++++++-- src/projectitem.h | 12 +-- src/projectlist.cpp | 67 +++++++++++----- src/projectlist.h | 5 +- src/projectlistview.cpp | 167 +++++++++++++++++++++++++++++++++++++++- src/projectlistview.h | 11 ++- 8 files changed, 265 insertions(+), 41 deletions(-) diff --git a/src/addclipcommand.cpp b/src/addclipcommand.cpp index 2121c3db..0242f694 100644 --- a/src/addclipcommand.cpp +++ b/src/addclipcommand.cpp @@ -19,8 +19,8 @@ #include "addclipcommand.h" -AddClipCommand::AddClipCommand(ProjectList *list, const QStringList &names, const QDomElement &xml, const int id, const KUrl &url, bool doIt) - : m_list(list), m_names(names), m_xml(xml), m_id(id), m_url(url), m_doIt(doIt) { +AddClipCommand::AddClipCommand(ProjectList *list, const QStringList &names, const QDomElement &xml, const int id, const KUrl &url, const QString &group, bool doIt) + : m_list(list), m_names(names), m_xml(xml), m_id(id), m_url(url), m_group(group), m_doIt(doIt) { if (doIt) setText(i18n("Add clip")); else setText(i18n("Delete clip")); } @@ -32,14 +32,14 @@ void AddClipCommand::undo() if (!m_list) kDebug()<<"---- ERROR, NO LIST FOR undoing action"; kDebug()<<"---- undoing action"; if (m_doIt) m_list->deleteClip(m_id); - else m_list->addClip(m_names, m_xml, m_id, m_url); + else m_list->addClip(m_names, m_xml, m_id, m_url, m_group); } // virtual void AddClipCommand::redo() { if (!m_list) kDebug()<<"---- ERROR, NO LIST FOR redoing action"; kDebug()<<"---- redoing action"; - if (m_doIt) m_list->addClip(m_names, m_xml, m_id, m_url); + if (m_doIt) m_list->addClip(m_names, m_xml, m_id, m_url, m_group); else m_list->deleteClip(m_id); } diff --git a/src/addclipcommand.h b/src/addclipcommand.h index 2fb455bd..705815dd 100644 --- a/src/addclipcommand.h +++ b/src/addclipcommand.h @@ -29,7 +29,7 @@ class AddClipCommand : public QUndoCommand { public: - AddClipCommand(ProjectList *list, const QStringList &names, const QDomElement &xml, const int id, const KUrl &url, bool doIt); + AddClipCommand(ProjectList *list, const QStringList &names, const QDomElement &xml, const int id, const KUrl &url, const QString &group, bool doIt); virtual void undo(); virtual void redo(); @@ -41,6 +41,7 @@ class AddClipCommand : public QUndoCommand int m_id; KUrl m_url; bool m_doIt; + QString m_group; }; #endif diff --git a/src/projectitem.cpp b/src/projectitem.cpp index bcdac14a..db4c4ca7 100644 --- a/src/projectitem.cpp +++ b/src/projectitem.cpp @@ -68,8 +68,8 @@ ProjectItem::ProjectItem(QTreeWidgetItem * parent, const QStringList & strings, } } -ProjectItem::ProjectItem(QTreeWidget * parent, const QStringList & strings) - : QTreeWidgetItem(parent, strings, QTreeWidgetItem::UserType), m_element(QDomElement()), m_clipType(DocClipBase::NONE), m_clipId(-1), m_isGroup(true) +ProjectItem::ProjectItem(QTreeWidget * parent, const QStringList & strings, int clipId) + : QTreeWidgetItem(parent, strings, QTreeWidgetItem::UserType), m_element(QDomElement()), m_clipType(DocClipBase::NONE), m_clipId(clipId), m_isGroup(true) { setSizeHint(0, QSize(65, 45)); setFlags(Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled); @@ -80,18 +80,39 @@ ProjectItem::~ProjectItem() { } -int ProjectItem::clipId() +ProjectItem *ProjectItem::clone() const +{ + ProjectItem *item = (ProjectItem *) this->QTreeWidgetItem::clone(); + /*if (isGroup()) + { + item = new ProjectItem(new QTreeWidget(), names(), clipId()); + } + else { + if (parent()) + item = new ProjectItem(new QTreeWidgetItem(), names(), toXml().cloneNode().toElement(), clipId()); + else + item = new ProjectItem(new QTreeWidget(), names(), toXml().cloneNode().toElement(), clipId()); + }*/ + return item; +} + +int ProjectItem::clipId() const { return m_clipId; } -bool ProjectItem::isGroup() +bool ProjectItem::isGroup() const { return m_isGroup; } +const QString &ProjectItem::groupName() const +{ + if (isGroup()) return text(1); + else return QString::null; +} -QStringList ProjectItem::names() +QStringList ProjectItem::names() const { QStringList result; result.append(text(0)); @@ -100,7 +121,7 @@ QStringList ProjectItem::names() return result; } -QDomElement ProjectItem::toXml() +QDomElement ProjectItem::toXml() const { return m_element; } diff --git a/src/projectitem.h b/src/projectitem.h index 34d39f9d..23d0acf2 100644 --- a/src/projectitem.h +++ b/src/projectitem.h @@ -34,14 +34,16 @@ 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); - ProjectItem(QTreeWidget * parent, const QStringList & strings); + ProjectItem(QTreeWidget * parent, const QStringList & strings, int clipId); virtual ~ProjectItem(); - QDomElement toXml(); + QDomElement toXml() const; void setProperties(const QMap < QString, QString > &attributes, const QMap < QString, QString > &metadata); - int clipId(); - QStringList names(); - bool isGroup(); + int clipId() const; + QStringList names() const; + bool isGroup() const; + const QString &groupName() const; + virtual ProjectItem *clone() const; private: QDomElement m_element; diff --git a/src/projectlist.cpp b/src/projectlist.cpp index f6c33a5a..f4a91115 100644 --- a/src/projectlist.cpp +++ b/src/projectlist.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -107,7 +108,7 @@ ProjectList::ProjectList(QWidget *parent) addButton->setMenu( addMenu ); addButton->setPopupMode(QToolButton::MenuButtonPopup); m_toolbar->addWidget (addButton); - + QAction *addClipButton = addMenu->addAction (KIcon("document-new"), i18n("Add Clip")); connect(addClipButton, SIGNAL(triggered()), this, SLOT(slotAddClip())); @@ -120,6 +121,9 @@ ProjectList::ProjectList(QWidget *parent) m_editAction = m_toolbar->addAction (KIcon("document-properties"), i18n("Edit Clip")); connect(m_editAction, SIGNAL(triggered()), this, SLOT(slotEditClip())); + QAction *addFolderButton = addMenu->addAction (KIcon("folder-new"), i18n("Create Folder")); + connect(addFolderButton, SIGNAL(triggered()), this, SLOT(slotAddFolder())); + addButton->setDefaultAction( addClipButton ); layout->addWidget( m_toolbar ); @@ -129,8 +133,6 @@ ProjectList::ProjectList(QWidget *parent) searchView->setTreeWidget(listView); listView->setColumnCount(3); - listView->setDragEnabled(true); - listView->setDragDropMode(QAbstractItemView::DragDrop); QStringList headers; headers<setHeaderLabels(headers); @@ -141,11 +143,13 @@ ProjectList::ProjectList(QWidget *parent) m_menu->addAction(addColorClip); m_menu->addAction(m_editAction); m_menu->addAction(m_deleteAction); + m_menu->addAction(addFolderButton); m_menu->insertSeparator(m_deleteAction); connect(listView, SIGNAL(itemSelectionChanged()), this, SLOT(slotClipSelected())); connect(listView, SIGNAL(requestMenu ( const QPoint &, QTreeWidgetItem * )), this, SLOT(slotContextMenu(const QPoint &, QTreeWidgetItem *))); connect(listView, SIGNAL(addClip ()), this, SLOT(slotAddClip())); + connect(listView, SIGNAL(addClip (QUrl, const QString &)), this, SLOT(slotAddClip(QUrl, const QString &))); listView->setItemDelegate(new ItemDelegate(listView)); @@ -199,7 +203,7 @@ void ProjectList::slotRemoveClip() if (!m_commandStack) kDebug()<<"!!!!!!!!!!!!!!!!  NO CMD STK"; if (!listView->currentItem()) return; ProjectItem *item = ((ProjectItem *)listView->currentItem()); - AddClipCommand *command = new AddClipCommand(this, item->names(), item->toXml(), item->clipId(), KUrl(item->data(1, FullPathRole).toString()), false); + AddClipCommand *command = new AddClipCommand(this, item->names(), item->toXml(), item->clipId(), KUrl(item->data(1, FullPathRole).toString()), item->groupName(), false); m_commandStack->push(command); } @@ -210,24 +214,36 @@ void ProjectList::selectItemById(const int clipId) if (item) listView->setCurrentItem(item); } -void ProjectList::addClip(const QStringList &name, const QDomElement &elem, const int clipId, const KUrl &url, int parentId) +void ProjectList::addClip(const QStringList &name, const QDomElement &elem, const int clipId, const KUrl &url, const QString &group, int parentId) { kDebug()<<"///////// ADDING VCLIP=: "< groupList = listView->findItems(groupName, Qt::MatchExactly, 1); + if (groupList.isEmpty()) { + (void) new ProjectItem(listView, name, clipId); + } + return; + } + if (parentId != -1) { groupItem = getItemById(parentId); } - else if (!group.isEmpty()) { + else if (!groupName.isEmpty()) { // Clip is in a group - QList groupList = listView->findItems(group, Qt::MatchExactly, 1); + QList groupList = listView->findItems(groupName, Qt::MatchExactly, 1); if (groupList.isEmpty()) { - QStringList groupName; - groupName<push(command); +} + +void ProjectList::slotAddClip(QUrl givenUrl, const QString &group) { if (!m_commandStack) kDebug()<<"!!!!!!!!!!!!!!!!  NO CMD STK"; - KUrl::List list = KFileDialog::getOpenUrls( KUrl(), "application/vnd.kde.kdenlive application/vnd.westley.scenelist application/flv application/vnd.rn-realmedia video/x-dv video/x-msvideo video/mpeg video/x-ms-wmv audio/x-mp3 audio/x-wav application/ogg *.m2t *.dv video/mp4 video/quicktime image/gif image/jpeg image/png image/x-bmp image/svg+xml image/tiff image/x-xcf-gimp image/x-vnd.adobe.photoshop image/x-pcx image/x-exr"); + KUrl::List list; + if (givenUrl.isEmpty()) + list = KFileDialog::getOpenUrls( KUrl(), "application/vnd.kde.kdenlive application/vnd.westley.scenelist application/flv application/vnd.rn-realmedia video/x-dv video/x-msvideo video/mpeg video/x-ms-wmv audio/x-mp3 audio/x-wav application/ogg *.m2t *.dv video/mp4 video/quicktime image/gif image/jpeg image/png image/x-bmp image/svg+xml image/tiff image/x-xcf-gimp image/x-vnd.adobe.photoshop image/x-pcx image/x-exr"); + else list.append(givenUrl); if (list.isEmpty()) return; KUrl::List::Iterator it; KUrl url; @@ -293,7 +323,7 @@ void ProjectList::slotAddClip() QStringList itemEntry; itemEntry.append(QString::null); itemEntry.append((*it).fileName()); - AddClipCommand *command = new AddClipCommand(this, itemEntry, QDomElement(), m_clipIdCounter++, *it, true); + AddClipCommand *command = new AddClipCommand(this, itemEntry, QDomElement(), m_clipIdCounter++, *it, group, true); m_commandStack->push(command); //item = new ProjectItem(listView, itemEntry, QDomElement()); //item->setData(1, FullPathRole, (*it).path()); @@ -324,7 +354,7 @@ void ProjectList::slotAddColorClip() QStringList itemEntry; itemEntry.append(QString::null); itemEntry.append(dia_ui->clip_name->text()); - AddClipCommand *command = new AddClipCommand(this, itemEntry, element, m_clipIdCounter++, KUrl(), true); + AddClipCommand *command = new AddClipCommand(this, itemEntry, element, m_clipIdCounter++, KUrl(), QString::null, true); m_commandStack->push(command); // ProjectItem *item = new ProjectItem(listView, itemEntry, element, m_clipIdCounter++); /*QPixmap pix(60, 40); @@ -412,6 +442,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++; @@ -422,7 +453,7 @@ void ProjectList::addProducer(QDomElement producer, int parentId) QStringList itemEntry; itemEntry.append(QString::null); itemEntry.append(resource.fileName()); - addClip(itemEntry, producer, id, resource, parentId); + addClip(itemEntry, producer, id, resource, groupName, parentId); /*AddClipCommand *command = new AddClipCommand(this, itemEntry, producer, id, resource, true); m_commandStack->push(command);*/ @@ -441,7 +472,7 @@ void ProjectList::addProducer(QDomElement producer, int parentId) QStringList itemEntry; itemEntry.append(QString::null); itemEntry.append(producer.attribute("name", i18n("Color clip"))); - addClip(itemEntry, producer, id, KUrl(), parentId); + addClip(itemEntry, producer, id, KUrl(), groupName, parentId); /*AddClipCommand *command = new AddClipCommand(this, itemEntry, producer, id, KUrl(), true); m_commandStack->push(command);*/ //ProjectItem *item = new ProjectItem(listView, itemEntry, producer); diff --git a/src/projectlist.h b/src/projectlist.h index 8e555fb9..fc59cd42 100644 --- a/src/projectlist.h +++ b/src/projectlist.h @@ -47,7 +47,7 @@ class ProjectList : public QWidget QDomElement producersList(); void setRenderer(Render *projectRender); - void addClip(const QStringList &name, const QDomElement &elem, const int clipId, const KUrl &url = KUrl(), int parentId = -1); + void addClip(const QStringList &name, const QDomElement &elem, const int clipId, const KUrl &url = KUrl(), const QString &group = QString::null, int parentId = -1); void deleteClip(const int clipId); public slots: @@ -73,13 +73,14 @@ class ProjectList : public QWidget QAction *m_deleteAction; private slots: - void slotAddClip(); + void slotAddClip(QUrl givenUrl = QUrl(), const QString &group = QString::null); void slotRemoveClip(); void slotEditClip(); void slotClipSelected(); void slotAddColorClip(); void slotEditClip(QTreeWidgetItem *, int); void slotContextMenu( const QPoint &pos, QTreeWidgetItem * ); + void slotAddFolder(); //void slotShowMenu(const QPoint &pos); diff --git a/src/projectlistview.cpp b/src/projectlistview.cpp index 9e1033f0..a6338a02 100644 --- a/src/projectlistview.cpp +++ b/src/projectlistview.cpp @@ -17,13 +17,22 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * ***************************************************************************/ +#include "QApplication" + +#include "KDebug" + +#include "projectitem.h" #include "projectlistview.h" ProjectListView::ProjectListView(QWidget *parent) - : QTreeWidget(parent) + : QTreeWidget(parent), m_dragStarted(false) { - + setSelectionMode(QAbstractItemView::ExtendedSelection); + setDragDropMode(QAbstractItemView::DragDrop); + setDropIndicatorShown(true); + setDragEnabled(true); + setAcceptDrops(true); } ProjectListView::~ProjectListView() @@ -33,14 +42,164 @@ ProjectListView::~ProjectListView() // virtual void ProjectListView::contextMenuEvent ( QContextMenuEvent * event ) { - emit requestMenu(event->globalPos(), itemAt(event->pos())); + emit requestMenu(event->globalPos(), itemAt(event->pos())); } // virtual void ProjectListView::mouseDoubleClickEvent ( QMouseEvent * event ) { - if (!itemAt(event->pos())) emit addClip(); + if (!itemAt(event->pos())) emit addClip(); +} + +// virtual +void ProjectListView::dragEnterEvent(QDragEnterEvent *event) +{ + if (event->mimeData()->hasUrls() || event->mimeData()->hasText()) { + kDebug()<<"//////////////// DRAG ENTR OK"; + } + event->acceptProposedAction(); +} + +// virtual +void ProjectListView::dropEvent(QDropEvent *event) +{ + kDebug()<<"//////////////// DROPPED EVENT"; + if (event->mimeData()->hasUrls()) { + QTreeWidgetItem *item = itemAt(event->pos()); + QString groupName; + if (item) { + if (((ProjectItem *) item)->isGroup()) groupName = item->text(1); + else if (item->parent() && ((ProjectItem *) item->parent())->isGroup()) + groupName = item->parent()->text(1); + } + QList list; + list = event->mimeData()->urls(); + foreach (QUrl url, list) { + emit addClip(url, groupName); + } + + } + else if (event->mimeData()->hasText()) + { + QTreeWidgetItem *item = itemAt(event->pos()); + if (item) { + if (item->parent()) item = item->parent(); + if (((ProjectItem *) item)->isGroup()) { + //emit addClip(event->mimeData->text()); + kDebug()<<"//////////////// DROPPED RIGHT 1"; + QList list; + list = selectedItems (); + ProjectItem *clone; + foreach (QTreeWidgetItem *it, list) { + // TODO allow dragging of folders + if (!((ProjectItem *) it)->isGroup()) { + if (it->parent()) clone = (ProjectItem* ) it->parent()->takeChild(it->parent()->indexOfChild(it)); + else clone = (ProjectItem* ) takeTopLevelItem(indexOfTopLevelItem(it)); + if (clone) item->addChild(clone); + } + } + } + else item = NULL; + } + if (!item) { + kDebug()<<"//////////////// DROPPED ON EMPTY ZONE"; + // item dropped in empty zone, move it to top level + QList list; + list = selectedItems(); + ProjectItem *clone; + foreach (QTreeWidgetItem *it, list) { + QTreeWidgetItem *parent = it->parent(); + if (parent) { + kDebug()<<"++ item parent: "<text(1); + clone = (ProjectItem* ) parent->takeChild(parent->indexOfChild(it)); + if (clone) addTopLevelItem(clone); + } + } + } + } + event->acceptProposedAction(); +} + +// virtual +void ProjectListView::mousePressEvent(QMouseEvent *event) +{ + if( event->button() == Qt::LeftButton ) + { + this->m_DragStartPosition = event->pos(); + m_dragStarted = true; + } + QTreeWidget::mousePressEvent(event); } +// virtual +void ProjectListView::mouseMoveEvent(QMouseEvent *event) +{ + kDebug()<<"// DRAG STARTED, MOUSE MOVED: "; + if (!m_dragStarted) return; + + if ((event->pos() - m_DragStartPosition).manhattanLength() + < QApplication::startDragDistance()) + return; + + { + ProjectItem *clickItem = (ProjectItem *) itemAt(event->pos()); + if (clickItem) { + QDrag *drag = new QDrag(this); + QMimeData *mimeData = new QMimeData; + QDomDocument doc; + QList list; + list = selectedItems (); + foreach (QTreeWidgetItem *item, list) { + // TODO allow dragging of folders + if (!((ProjectItem *) item)->isGroup()) + doc.appendChild(doc.importNode(((ProjectItem *) item)->toXml(), true)); + } + //QByteArray data; + //data.append(doc.toString().toUtf8()); + //mimeData->setData("kdenlive/westley",data ); + mimeData->setText(doc.toString()); + //mimeData->setImageData(image); + drag->setMimeData(mimeData); + drag->setPixmap(clickItem->icon(0).pixmap(40 *16/9.0, 40)); + drag->setHotSpot(QPoint(0, 20)); + drag->start(Qt::MoveAction); + + //Qt::DropAction dropAction; + //dropAction = drag->start(Qt::CopyAction | Qt::MoveAction); + + //Qt::DropAction dropAction = drag->exec(); + + } + //event->accept(); + } +} + +void ProjectListView::dragMoveEvent(QDragMoveEvent * event) { + QTreeWidgetItem * item = itemAt(event->pos()); + event->setDropAction(Qt::IgnoreAction); + //if (item) { + event->setDropAction(Qt::MoveAction); + if (event->mimeData()->hasText()) { + event->acceptProposedAction(); + } + //} +} + +QStringList ProjectListView::mimeTypes () const +{ + QStringList qstrList; + // list of accepted mime types for drop + qstrList.append("text/uri-list"); + qstrList.append("text/plain"); + return qstrList; +} + + +Qt::DropActions ProjectListView::supportedDropActions () const +{ + // returns what actions are supported when dropping + return Qt::MoveAction | Qt::MoveAction; +} + #include "projectlistview.moc" diff --git a/src/projectlistview.h b/src/projectlistview.h index 304d6ba9..da5756a5 100644 --- a/src/projectlistview.h +++ b/src/projectlistview.h @@ -35,18 +35,27 @@ class ProjectListView : public QTreeWidget protected: virtual void contextMenuEvent ( QContextMenuEvent * event ); virtual void mouseDoubleClickEvent ( QMouseEvent * event ); + virtual void mousePressEvent(QMouseEvent *event); + virtual void mouseMoveEvent(QMouseEvent *event); + virtual void dragEnterEvent(QDragEnterEvent *event); + virtual void dropEvent(QDropEvent *event); + virtual QStringList mimeTypes() const; + virtual Qt::DropActions supportedDropActions () const; + virtual void dragMoveEvent(QDragMoveEvent * event); public slots: private: - + bool m_dragStarted; + QPoint m_DragStartPosition; private slots: signals: void requestMenu(const QPoint &, QTreeWidgetItem *); void addClip(); + void addClip(QUrl, const QString &); }; #endif -- 2.39.5