+ AddFolderCommand *command = new AddFolderCommand(this, i18n("Folder"), QString::number(m_doc->clipManager()->getFreeFolderId()), true);
+ m_commandStack->push(command);
+}
+
+void ProjectList::slotAddFolder(const QString foldername, const QString &clipId, bool remove, bool edit)
+{
+ if (remove) {
+ FolderProjectItem *item = getFolderItemById(clipId);
+ if (item) {
+ m_doc->clipManager()->deleteFolder(clipId);
+ delete item;
+ }
+ } else {
+ if (edit) {
+ FolderProjectItem *item = getFolderItemById(clipId);
+ if (item) {
+ m_listView->blockSignals(true);
+ item->setGroupName(foldername);
+ m_listView->blockSignals(false);
+ m_doc->clipManager()->addFolder(clipId, foldername);
+ const int children = item->childCount();
+ for (int i = 0; i < children; i++) {
+ ProjectItem *child = static_cast <ProjectItem *>(item->child(i));
+ child->setProperty("groupname", foldername);
+ }
+ }
+ } else {
+ QStringList text;
+ text << foldername;
+ m_listView->blockSignals(true);
+ m_listView->setCurrentItem(new FolderProjectItem(m_listView, text, clipId));
+ m_doc->clipManager()->addFolder(clipId, foldername);
+ m_listView->blockSignals(false);
+ }
+ }
+ m_doc->setModified(true);
+}
+
+
+
+void ProjectList::deleteProjectFolder(QMap <QString, QString> map)
+{
+ QMapIterator<QString, QString> i(map);
+ QUndoCommand *delCommand = new QUndoCommand();
+ delCommand->setText(i18n("Delete Folder"));
+ while (i.hasNext()) {
+ i.next();
+ new AddFolderCommand(this, i.key(), i.value(), false, delCommand);
+ }
+ m_commandStack->push(delCommand);
+}
+
+void ProjectList::slotAddClip(DocClipBase *clip, bool getProperties)
+{
+ m_listView->setEnabled(false);
+ if (getProperties) {
+ m_listView->blockSignals(true);
+ m_refreshed = false;
+ // remove file_hash so that we load all properties for the clip
+ QDomElement e = clip->toXML().cloneNode().toElement();
+ e.removeAttribute("file_hash");
+ m_infoQueue.insert(clip->getId(), e);
+ //m_render->getFileProperties(clip->toXML(), clip->getId(), true);
+ }
+ const QString parent = clip->getProperty("groupid");
+ ProjectItem *item = NULL;
+ if (!parent.isEmpty()) {
+ FolderProjectItem *parentitem = getFolderItemById(parent);
+ if (!parentitem) {
+ QStringList text;
+ QString groupName = clip->getProperty("groupname");
+ //kDebug() << "Adding clip to new group: " << groupName;
+ if (groupName.isEmpty()) groupName = i18n("Folder");
+ text << groupName;
+ parentitem = new FolderProjectItem(m_listView, text, parent);
+ } else {
+ //kDebug() << "Adding clip to existing group: " << parentitem->groupName();
+ }
+ if (parentitem) item = new ProjectItem(parentitem, clip);
+ }
+ if (item == NULL) item = new ProjectItem(m_listView, clip);
+ KUrl url = clip->fileURL();
+
+ if (getProperties == false && !clip->getClipHash().isEmpty()) {
+ QString cachedPixmap = m_doc->projectFolder().path(KUrl::AddTrailingSlash) + "thumbs/" + clip->getClipHash() + ".png";
+ if (QFile::exists(cachedPixmap)) {
+ item->setData(0, Qt::DecorationRole, QPixmap(cachedPixmap));
+ }
+ }
+#ifdef NEPOMUK
+ if (!url.isEmpty() && KdenliveSettings::activate_nepomuk()) {
+ // if file has Nepomuk comment, use it
+ Nepomuk::Resource f(url.path());
+ QString annotation = f.description();
+ if (!annotation.isEmpty()) item->setText(1, annotation);
+ item->setText(2, QString::number(f.rating()));
+ }
+#endif
+ // Add cut zones
+ QList <CutZoneInfo> cuts = clip->cutZones();
+ if (!cuts.isEmpty()) {
+ for (int i = 0; i < cuts.count(); i++) {
+ SubProjectItem *sub = new SubProjectItem(item, cuts.at(i).zone.x(), cuts.at(i).zone.y(), cuts.at(i).description);
+ if (!clip->getClipHash().isEmpty()) {
+ QString cachedPixmap = m_doc->projectFolder().path(KUrl::AddTrailingSlash) + "thumbs/" + clip->getClipHash() + '#' + QString::number(cuts.at(i).zone.x()) + ".png";
+ if (QFile::exists(cachedPixmap)) {
+ sub->setData(0, Qt::DecorationRole, QPixmap(cachedPixmap));
+ }
+ }
+ }
+ }
+
+ if (getProperties && m_listView->isEnabled()) m_listView->blockSignals(false);
+ if (getProperties && !m_queueTimer.isActive()) m_queueTimer.start();
+}
+
+void ProjectList::slotResetProjectList()
+{
+ m_listView->clear();
+ emit clipSelected(NULL);
+ m_thumbnailQueue.clear();
+ m_infoQueue.clear();
+ m_refreshed = false;
+}
+
+void ProjectList::requestClipInfo(const QDomElement xml, const QString id)
+{
+ m_refreshed = false;
+ m_infoQueue.insert(id, xml);
+ //if (m_infoQueue.count() == 1 || ) QTimer::singleShot(300, this, SLOT(slotProcessNextClipInQueue()));
+}
+
+void ProjectList::slotProcessNextClipInQueue()
+{
+ if (m_infoQueue.isEmpty()) {
+ slotProcessNextThumbnail();
+ return;
+ }
+
+ QMap<QString, QDomElement>::const_iterator j = m_infoQueue.constBegin();
+ if (j != m_infoQueue.constEnd()) {
+ const QDomElement dom = j.value();
+ const QString id = j.key();
+ m_infoQueue.remove(j.key());
+ emit getFileProperties(dom, id, m_listView->iconSize().height(), false);
+ }
+}
+
+void ProjectList::slotUpdateClip(const QString &id)
+{
+ ProjectItem *item = getItemById(id);
+ m_listView->blockSignals(true);
+ if (item) item->setData(1, UsageRole, QString::number(item->numReferences()));
+ m_listView->blockSignals(false);
+}
+
+void ProjectList::updateAllClips()
+{
+ m_listView->setSortingEnabled(false);
+ kDebug() << "// UPDATE ALL CLPY";
+
+ QTreeWidgetItemIterator it(m_listView);
+ DocClipBase *clip;
+ ProjectItem *item;
+ m_listView->blockSignals(true);
+ while (*it) {
+ if ((*it)->type() == PROJECTSUBCLIPTYPE) {
+ // subitem
+ SubProjectItem *sub = static_cast <SubProjectItem *>(*it);
+ if (sub->data(0, Qt::DecorationRole).isNull()) {
+ item = static_cast <ProjectItem *>((*it)->parent());
+ requestClipThumbnail(item->clipId() + '#' + QString::number(sub->zone().x()));
+ }
+ ++it;
+ continue;
+ } else if ((*it)->type() == PROJECTFOLDERTYPE) {
+ // folder
+ ++it;
+ continue;
+ } else {
+ item = static_cast <ProjectItem *>(*it);
+ clip = item->referencedClip();
+ if (item->referencedClip()->producer() == NULL) {
+ if (clip->isPlaceHolder() == false) {
+ requestClipInfo(clip->toXML(), clip->getId());
+ } else if (!clip->isPlaceHolder()) item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
+ } else {
+ if (item->data(0, Qt::DecorationRole).isNull()) {
+ requestClipThumbnail(clip->getId());
+ }
+ if (item->data(0, DurationRole).toString().isEmpty()) {
+ item->changeDuration(item->referencedClip()->producer()->get_playtime());
+ }
+ }
+ item->setData(1, UsageRole, QString::number(item->numReferences()));
+ }
+ //qApp->processEvents();
+ ++it;
+ }
+ if (!m_queueTimer.isActive()) m_queueTimer.start();
+ if (m_listView->isEnabled()) m_listView->blockSignals(false);
+ m_listView->setSortingEnabled(true);
+ if (m_infoQueue.isEmpty()) slotProcessNextThumbnail();
+}
+
+void ProjectList::slotAddClip(const QList <QUrl> givenList, const QString &groupName, const QString &groupId)
+{
+ if (!m_commandStack) {
+ kDebug() << "!!!!!!!!!!!!!!!! NO CMD STK";
+ }
+ KUrl::List list;
+ if (givenList.isEmpty()) {
+ // Build list of mime types
+ QStringList mimeTypes = QStringList() << "application/x-kdenlive" << "application/x-kdenlivetitle" << "video/x-flv" << "application/vnd.rn-realmedia" << "video/x-dv" << "video/dv" << "video/x-msvideo" << "video/x-matroska" << "video/mlt-playlist" << "video/mpeg" << "video/ogg" << "video/x-ms-wmv" << "audio/x-flac" << "audio/x-matroska" << "audio/mp4" << "audio/mpeg" << "audio/x-mp3" << "audio/ogg" << "audio/x-wav" << "application/ogg" << "video/mp4" << "video/quicktime" << "image/gif" << "image/jpeg" << "image/png" << "image/x-tga" << "image/x-bmp" << "image/svg+xml" << "image/tiff" << "image/x-xcf-gimp" << "image/x-vnd.adobe.photoshop" << "image/x-pcx" << "image/x-exr";
+
+ QString allExtensions;
+ foreach(const QString& mimeType, mimeTypes) {
+ KMimeType::Ptr mime(KMimeType::mimeType(mimeType));
+ if (mime) {
+ allExtensions.append(mime->patterns().join(" "));
+ allExtensions.append(' ');
+ }
+ }
+ const QString dialogFilter = allExtensions.simplified() + ' ' + QLatin1Char('|') + i18n("All Supported Files") + "\n* " + QLatin1Char('|') + i18n("All Files");
+ list = KFileDialog::getOpenUrls(KUrl("kfiledialog:///clipfolder"), dialogFilter, this);
+
+ } else {
+ for (int i = 0; i < givenList.count(); i++)
+ list << givenList.at(i);
+ }
+
+ foreach(const KUrl &file, list) {
+ // Check there is no folder here
+ KMimeType::Ptr type = KMimeType::findByUrl(file);
+ if (type->is("inode/directory")) {
+ // user dropped a folder
+ list.removeAll(file);
+ }
+ }
+
+ if (list.isEmpty()) return;
+
+ if (givenList.isEmpty()) {
+ QStringList groupInfo = getGroup();
+ m_doc->slotAddClipList(list, groupInfo.at(0), groupInfo.at(1));
+ } else m_doc->slotAddClipList(list, groupName, groupId);
+}
+
+void ProjectList::slotRemoveInvalidClip(const QString &id, bool replace)
+{
+ ProjectItem *item = getItemById(id);
+ QTimer::singleShot(300, this, SLOT(slotProcessNextClipInQueue()));
+ if (item) {
+ const QString path = item->referencedClip()->fileURL().path();
+ if (!path.isEmpty()) {
+ if (replace) KMessageBox::sorry(this, i18n("Clip <b>%1</b><br>is invalid, will be removed from project.", path));
+ else {
+ if (KMessageBox::questionYesNo(this, i18n("Clip <b>%1</b><br>is missing or invalid. Remove it from project?", path), i18n("Invalid clip")) == KMessageBox::Yes) replace = true;
+ }
+ }
+ QStringList ids;
+ ids << id;
+ if (replace) m_doc->deleteProjectClip(ids);
+ }