X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fprojectlist.cpp;h=eae3d599cc93bbe5a87dd8a5f08d7cefca397b86;hb=c351ea9cc38ea488317206339657fcad481be9d8;hp=a0618d18cf7d13098c98ff7f2215ce014825030a;hpb=4adc452d3ef7d34ba7609fd95be61a6b7cc9961b;p=kdenlive diff --git a/src/projectlist.cpp b/src/projectlist.cpp index a0618d18..eae3d599 100644 --- a/src/projectlist.cpp +++ b/src/projectlist.cpp @@ -31,6 +31,7 @@ #include "renderer.h" #include "kthumb.h" #include "projectlistview.h" +#include "timecodedisplay.h" #include "editclipcommand.h" #include "editclipcutcommand.h" #include "editfoldercommand.h" @@ -79,6 +80,7 @@ ProjectList::ProjectList(QWidget *parent) : m_listView = new ProjectListView(this);; QVBoxLayout *layout = new QVBoxLayout; layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(0); // setup toolbar KTreeWidgetSearchLine *searchView = new KTreeWidgetSearchLine(this); @@ -172,7 +174,7 @@ void ProjectList::setupMenu(QMenu *addMenu, QAction *defaultAction) m_menu->addActions(addMenu->actions()); } -void ProjectList::setupGeneratorMenu(QMenu *addMenu, QMenu *transcodeMenu) +void ProjectList::setupGeneratorMenu(QMenu *addMenu, QMenu *transcodeMenu, QMenu *inTimelineMenu) { if (!addMenu) return; QMenu *menu = m_addButton->menu(); @@ -185,6 +187,8 @@ void ProjectList::setupGeneratorMenu(QMenu *addMenu, QMenu *transcodeMenu) if (transcodeMenu->isEmpty()) transcodeMenu->setEnabled(false); m_transcodeAction = transcodeMenu; m_menu->addAction(m_reloadAction); + m_menu->addMenu(inTimelineMenu); + inTimelineMenu->setEnabled(false); m_menu->addAction(m_editAction); m_menu->addAction(m_openAction); m_menu->addAction(m_deleteAction); @@ -202,6 +206,11 @@ void ProjectList::setHeaderInfo(const QByteArray &state) m_listView->header()->restoreState(state); } +void ProjectList::updateProjectFormat(Timecode t) +{ + m_timecode = t; +} + void ProjectList::slotEditClip() { QList list = m_listView->selectedItems(); @@ -363,13 +372,22 @@ void ProjectList::slotReloadClip(const QString &id) else selected.append(getItemById(id)); ProjectItem *item; for (int i = 0; i < selected.count(); i++) { - if (selected.at(i)->type() != PROJECTCLIPTYPE) continue; + if (selected.at(i)->type() != PROJECTCLIPTYPE) { + if (selected.at(i)->type() == PROJECTFOLDERTYPE) { + for (int j = 0; j < selected.at(i)->childCount(); j++) + selected.append(selected.at(i)->child(j)); + } + continue; + } item = static_cast (selected.at(i)); if (item) { - if (item->clipType() == IMAGE) { - item->referencedClip()->producer()->set("force_reload", 1); - } else if (item->clipType() == TEXT) { + if (item->clipType() == TEXT) { if (!item->referencedClip()->getProperty("xmltemplate").isEmpty()) regenerateTemplate(item); + } else if (item->clipType() != COLOR && item->clipType() != SLIDESHOW && item->referencedClip() && item->referencedClip()->checkHash() == false) { + item->referencedClip()->setPlaceHolder(true); + item->setProperty("file_hash", QString()); + } else if (item->clipType() == IMAGE) { + item->referencedClip()->producer()->set("force_reload", 1); } //requestClipInfo(item->toXml(), item->clipId(), true); // Clear the file_hash value, which will cause a complete reload of the clip @@ -378,6 +396,70 @@ void ProjectList::slotReloadClip(const QString &id) } } +void ProjectList::slotModifiedClip(const QString &id) +{ + ProjectItem *item = getItemById(id); + if (item) { + QPixmap pixmap = qVariantValue(item->data(0, Qt::DecorationRole)); + if (!pixmap.isNull()) { + QPainter p(&pixmap); + p.fillRect(0, 0, pixmap.width(), pixmap.height(), QColor(255, 255, 255, 200)); + p.drawPixmap(0, 0, KIcon("view-refresh").pixmap(m_listView->iconSize())); + p.end(); + } else pixmap = KIcon("view-refresh").pixmap(m_listView->iconSize()); + item->setData(0, Qt::DecorationRole, pixmap); + } +} + +void ProjectList::slotMissingClip(const QString &id) +{ + ProjectItem *item = getItemById(id); + if (item) { + item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); + if (item->referencedClip()) { + item->referencedClip()->setPlaceHolder(true); + if (m_render == NULL) kDebug() << "********* ERROR, NULL RENDR"; + item->referencedClip()->setProducer(m_render->invalidProducer(id), true); + item->slotSetToolTip(); + emit clipNeedsReload(id, true); + } + } + update(); + emit displayMessage(i18n("Check missing clips"), -2); + emit updateRenderStatus(); +} + +void ProjectList::slotAvailableClip(const QString &id) +{ + ProjectItem *item = getItemById(id); + if (item == NULL) return; + item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled | Qt::ItemIsEditable); + if (item->referencedClip()) { // && item->referencedClip()->checkHash() == false) { + item->setProperty("file_hash", QString()); + slotReloadClip(id); + } + /*else { + item->referencedClip()->setValid(); + item->slotSetToolTip(); + } + update();*/ + emit updateRenderStatus(); +} + +bool ProjectList::hasMissingClips() +{ + bool missing = false; + QTreeWidgetItemIterator it(m_listView); + while (*it) { + if ((*it)->type() == PROJECTCLIPTYPE && !((*it)->flags() & Qt::ItemIsDragEnabled)) { + missing = true; + break; + } + it++; + } + return missing; +} + void ProjectList::setRenderer(Render *projectRender) { m_render = projectRender; @@ -386,6 +468,7 @@ void ProjectList::setRenderer(Render *projectRender) void ProjectList::slotClipSelected() { + if (!m_listView->isEnabled()) return; if (m_listView->currentItem()) { if (m_listView->currentItem()->type() == PROJECTFOLDERTYPE) { emit clipSelected(NULL); @@ -421,6 +504,8 @@ void ProjectList::slotClipSelected() } else m_openAction->setEnabled(false); // Display relevant transcoding actions only adjustTranscodeActions(clip); + // Display uses in timeline + emit findInTimeline(clip->clipId()); } } else { emit clipSelected(NULL); @@ -434,7 +519,7 @@ void ProjectList::slotClipSelected() void ProjectList::adjustTranscodeActions(ProjectItem *clip) const { - if (clip == NULL || clip->type() != PROJECTCLIPTYPE || clip->clipType() == COLOR || clip->clipType() == TEXT || clip->clipType() == PLAYLIST) { + if (clip == NULL || clip->type() != PROJECTCLIPTYPE || clip->clipType() == COLOR || clip->clipType() == TEXT || clip->clipType() == PLAYLIST || clip->clipType() == SLIDESHOW) { m_transcodeAction->setEnabled(false); return; } @@ -578,6 +663,8 @@ void ProjectList::slotContextMenu(const QPoint &pos, QTreeWidgetItem *item) clip = static_cast (item); // Display relevant transcoding actions only adjustTranscodeActions(clip); + // Display uses in timeline + emit findInTimeline(clip->clipId()); } else m_transcodeAction->setEnabled(false); if (clip && clip->clipType() == IMAGE && !KdenliveSettings::defaultimageapp().isEmpty()) { m_openAction->setIcon(KIcon(KdenliveSettings::defaultimageapp())); @@ -675,8 +762,12 @@ void ProjectList::slotDeleteClip(const QString &clipId) delete item; m_doc->clipManager()->deleteClip(clipId); m_listView->blockSignals(false); - if (newSelectedItem) m_listView->setCurrentItem(newSelectedItem); - else updateButtons(); + if (newSelectedItem) { + m_listView->setCurrentItem(newSelectedItem); + } else { + updateButtons(); + emit clipSelected(NULL); + } } @@ -720,12 +811,11 @@ void ProjectList::slotAddFolder(const QString foldername, const QString &clipId, } } } else { - QStringList text; - text << foldername; m_listView->blockSignals(true); - m_listView->setCurrentItem(new FolderProjectItem(m_listView, text, clipId)); + m_listView->setCurrentItem(new FolderProjectItem(m_listView, QStringList() << foldername, clipId)); m_doc->clipManager()->addFolder(clipId, foldername); m_listView->blockSignals(false); + m_listView->editItem(m_listView->currentItem(), 0); } updateButtons(); } @@ -756,9 +846,9 @@ void ProjectList::slotAddClip(DocClipBase *clip, bool getProperties) QDomElement e = clip->toXML().cloneNode().toElement(); e.removeAttribute("file_hash"); m_infoQueue.insert(clip->getId(), e); - clip->askForAudioThumbs(); //m_render->getFileProperties(clip->toXML(), clip->getId(), true); } + clip->askForAudioThumbs(); const QString parent = clip->getProperty("groupid"); ProjectItem *item = NULL; if (!parent.isEmpty()) { @@ -906,6 +996,23 @@ void ProjectList::updateAllClips() if (m_infoQueue.isEmpty()) slotProcessNextThumbnail(); } +// static +QString ProjectList::getExtensions() +{ + // 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" << "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(' '); + } + } + return allExtensions.simplified(); +} + void ProjectList::slotAddClip(const QList givenList, const QString &groupName, const QString &groupId) { if (!m_commandStack) { @@ -913,18 +1020,8 @@ void ProjectList::slotAddClip(const QList givenList, const QString &group } 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"); + QString allExtensions = getExtensions(); + const QString dialogFilter = allExtensions + ' ' + QLatin1Char('|') + i18n("All Supported Files") + "\n* " + QLatin1Char('|') + i18n("All Files"); list = KFileDialog::getOpenUrls(KUrl("kfiledialog:///clipfolder"), dialogFilter, this); } else { @@ -970,21 +1067,29 @@ void ProjectList::slotRemoveInvalidClip(const QString &id, bool replace) void ProjectList::slotAddColorClip() { - if (!m_commandStack) { + if (!m_commandStack) kDebug() << "!!!!!!!!!!!!!!!! NO CMD STK"; - } + QDialog *dia = new QDialog(this); Ui::ColorClip_UI dia_ui; dia_ui.setupUi(dia); dia->setWindowTitle(i18n("Color Clip")); dia_ui.clip_name->setText(i18n("Color Clip")); - dia_ui.clip_duration->setText(KdenliveSettings::color_duration()); + + TimecodeDisplay *t = new TimecodeDisplay(m_timecode); + t->setValue(KdenliveSettings::color_duration()); + t->setTimeCodeFormat(false); + dia_ui.clip_durationBox->addWidget(t); + dia_ui.clip_color->setColor(KdenliveSettings::colorclipcolor()); + if (dia->exec() == QDialog::Accepted) { QString color = dia_ui.clip_color->color().name(); + KdenliveSettings::setColorclipcolor(color); color = color.replace(0, 1, "0x") + "ff"; QStringList groupInfo = getGroup(); - m_doc->slotCreateColorClip(dia_ui.clip_name->text(), color, dia_ui.clip_duration->text(), groupInfo.at(0), groupInfo.at(1)); + m_doc->slotCreateColorClip(dia_ui.clip_name->text(), color, m_timecode.getTimecode(t->gentime()), groupInfo.at(0), groupInfo.at(1)); } + delete t; delete dia; } @@ -1028,6 +1133,8 @@ void ProjectList::slotAddTitleTemplateClip() for (int i = 0; i < templateFiles.size(); ++i) { dia_ui.template_list->comboBox()->addItem(templateFiles.at(i), path + templateFiles.at(i)); } + if (!templateFiles.isEmpty()) + dia_ui.buttonBox->button(QDialogButtonBox::Ok)->setFocus(); dia_ui.template_list->fileDialog()->setFilter("*.kdenlivetitle"); //warning: setting base directory doesn't work?? KUrl startDir(path); @@ -1087,6 +1194,9 @@ void ProjectList::setDocument(KdenliveDoc *doc) m_listView->blockSignals(false); m_toolbar->setEnabled(true); connect(m_doc->clipManager(), SIGNAL(reloadClip(const QString &)), this, SLOT(slotReloadClip(const QString &))); + connect(m_doc->clipManager(), SIGNAL(modifiedClip(const QString &)), this, SLOT(slotModifiedClip(const QString &))); + connect(m_doc->clipManager(), SIGNAL(missingClip(const QString &)), this, SLOT(slotMissingClip(const QString &))); + connect(m_doc->clipManager(), SIGNAL(availableClip(const QString &)), this, SLOT(slotAvailableClip(const QString &))); connect(m_doc->clipManager(), SIGNAL(checkAllClips()), this, SLOT(updateAllClips())); } @@ -1232,11 +1342,17 @@ void ProjectList::slotReplyGetFileProperties(const QString &clipId, Mlt::Produce if (!replace && item->data(0, Qt::DecorationRole).isNull()) { requestClipThumbnail(clipId); } + if (!toReload.isEmpty()) { + item->slotSetToolTip(); + + } //emit receivedClipDuration(clipId); if (m_listView->isEnabled() && replace) { // update clip in clip monitor emit clipSelected(NULL); emit clipSelected(item->referencedClip()); + //TODO: Make sure the line below has no side effect + toReload = clipId; } /*else { // Check if duration changed. @@ -1249,13 +1365,12 @@ void ProjectList::slotReplyGetFileProperties(const QString &clipId, Mlt::Produce }*/ } else kDebug() << "//////// COULD NOT FIND CLIP TO UPDATE PRPS..."; int max = m_doc->clipManager()->clipsCount(); - emit displayMessage(i18n("Loading clips"), (int)(100 *(max - m_infoQueue.count()) / max)); - // small delay so that the app can display the progress info if (item && m_infoQueue.isEmpty() && m_thumbnailQueue.isEmpty()) { m_listView->setCurrentItem(item); emit clipSelected(item->referencedClip()); - } + } else emit displayMessage(i18n("Loading clips"), (int)(100 *(max - m_infoQueue.count()) / max)); if (!toReload.isEmpty()) emit clipNeedsReload(toReload, true); + // small delay so that the app can display the progress info QTimer::singleShot(30, this, SLOT(slotProcessNextClipInQueue())); } @@ -1446,6 +1561,7 @@ void ProjectList::addClipCut(const QString &id, int in, int out, const QString d SubProjectItem *sub = new SubProjectItem(clip, in, out, desc); if (newItem && desc.isEmpty() && !m_listView->isColumnHidden(1)) { if (!clip->isExpanded()) clip->setExpanded(true); + m_listView->scrollToItem(sub); m_listView->editItem(sub, 1); } QPixmap p = clip->referencedClip()->thumbProducer()->extractImage(in, (int)(sub->sizeHint(0).height() * m_render->dar()), sub->sizeHint(0).height() - 2);