X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fprojectitem.cpp;h=a462755765335f6a6474784d6d71e51d4a6abb17;hb=56aee6aedeeed3efd10ada8fe3c229eddc01ef05;hp=843d153420ecfcad81ecb37f56dba9fe7ff6e253;hpb=06fabc683a3bddc60ba59573a62458ca4f6a0ef6;p=kdenlive diff --git a/src/projectitem.cpp b/src/projectitem.cpp index 843d1534..a4627557 100644 --- a/src/projectitem.cpp +++ b/src/projectitem.cpp @@ -18,274 +18,303 @@ ***************************************************************************/ -#include -#include -#include -#include - -#include -#include -#include - - #include "projectitem.h" #include "timecode.h" #include "kdenlivesettings.h" #include "docclipbase.h" -const int NameRole = Qt::UserRole; -const int DurationRole = NameRole + 1; -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) { - m_element = xml.cloneNode().toElement(); - setSizeHint(0, QSize(65, 45)); - setFlags(Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled | Qt::ItemIsEditable); - if (!m_element.isNull()) { - m_element.setAttribute("id", clipId); - QString cType = m_element.attribute("type", QString::null); - if (!cType.isEmpty()) { - m_clipType = (CLIPTYPE) cType.toInt(); - slotSetToolTip(); - } +#include +#include +#include - if (m_clipType == COLOR || m_clipType == IMAGE) m_element.setAttribute("duration", MAXCLIPDURATION); - else if (m_element.attribute("duration").isEmpty() && !m_element.attribute("out").isEmpty()) { - m_element.setAttribute("duration", m_element.attribute("out").toInt() - m_element.attribute("in").toInt()); - } - } +#include + +const int DurationRole = Qt::UserRole + 1; +const int JobProgressRole = Qt::UserRole + 5; +const int JobTypeRole = Qt::UserRole + 6; +const int JobStatusMessage = Qt::UserRole + 7; +const int itemHeight = 38; + +ProjectItem::ProjectItem(QTreeWidget * parent, DocClipBase *clip, const QSize &pixmapSize) : + QTreeWidgetItem(parent, ProjectClipType), + m_clip(clip), + m_clipId(clip->getId()), + m_pixmapSet(false) +{ + buildItem(pixmapSize); } -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) { - m_element = xml.cloneNode().toElement(); - setSizeHint(0, QSize(65, 45)); - setFlags(Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled | Qt::ItemIsEditable); - if (!m_element.isNull()) { - m_element.setAttribute("id", clipId); - QString cType = m_element.attribute("type", QString::null); - if (!cType.isEmpty()) { - m_clipType = (CLIPTYPE) cType.toInt(); - slotSetToolTip(); +ProjectItem::ProjectItem(QTreeWidgetItem * parent, DocClipBase *clip, const QSize &pixmapSize) : + QTreeWidgetItem(parent, ProjectClipType), + m_clip(clip), + m_clipId(clip->getId()), + m_pixmapSet(false) + +{ + buildItem(pixmapSize); +} + +void ProjectItem::buildItem(const QSize &pixmapSize) +{ + setSizeHint(0, QSize(itemHeight * 3, itemHeight)); + if (m_clip->isPlaceHolder()) setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDropEnabled); + else setFlags(Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsDropEnabled); + QString name = m_clip->getProperty("name"); + if (name.isEmpty()) name = KUrl(m_clip->getProperty("resource")).fileName(); + m_clipType = (ClipType) m_clip->getProperty("type").toInt(); + switch(m_clipType) { + case Audio: + setData(0, Qt::DecorationRole, KIcon("audio-x-generic").pixmap(pixmapSize)); + m_pixmapSet = true; + break; + case Image: + case SlideShow: + setData(0, Qt::DecorationRole, KIcon("image-x-generic").pixmap(pixmapSize)); + break; + default: + setData(0, Qt::DecorationRole, KIcon("video-x-generic").pixmap(pixmapSize)); + } + if (m_clipType != Unknown) slotSetToolTip(); + + setText(0, name); + setText(1, m_clip->description()); + GenTime duration = m_clip->duration(); + QString durationText; + if (duration != GenTime()) { + durationText = Timecode::getEasyTimecode(duration, KdenliveSettings::project_fps()); + } + if (m_clipType == Playlist) { + // Check if the playlist xml contains a proxy inside, and inform user + if (playlistHasProxies(m_clip->fileURL().path())) { + durationText.prepend(i18n("Contains proxies") + " / "); } } + if (!durationText.isEmpty()) setData(0, DurationRole, durationText); } -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)) { - setSizeHint(0, QSize(65, 45)); - setFlags(Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled | Qt::ItemIsEditable); - setIcon(0, KIcon("folder")); +ProjectItem::~ProjectItem() +{ } -ProjectItem::ProjectItem(QTreeWidget * parent, DocClipBase *clip) - : QTreeWidgetItem(parent, QStringList(), QTreeWidgetItem::UserType), m_isGroup(false) { - 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(); - m_groupName = m_element.attribute("group"); - setText(1, name); - kDebug() << "PROJECT ITE;. ADDING LCIP: " << m_clipId; +bool ProjectItem::hasPixmap() const +{ + return m_pixmapSet; } +void ProjectItem::setPixmap(const QPixmap& p) +{ + m_pixmapSet = true; + setData(0, Qt::DecorationRole, p); +} -ProjectItem::~ProjectItem() { +//static +int ProjectItem::itemDefaultHeight() +{ + return itemHeight; } -int ProjectItem::numReferences() const { +int ProjectItem::numReferences() const +{ if (!m_clip) return 0; return m_clip->numReferences(); } -int ProjectItem::clipId() const { +const QString &ProjectItem::clipId() const +{ return m_clipId; } -CLIPTYPE ProjectItem::clipType() const { +ClipType ProjectItem::clipType() const +{ return m_clipType; } -int ProjectItem::clipMaxDuration() const { - return m_element.attribute("duration").toInt(); +int ProjectItem::clipMaxDuration() const +{ + return m_clip->getProperty("duration").toInt(); } -bool ProjectItem::isGroup() const { - return m_isGroup; +QDomElement ProjectItem::toXml() const +{ + return m_clip->toXML(); } -const QString ProjectItem::groupName() const { - return m_groupName; +const KUrl ProjectItem::clipUrl() const +{ + if (m_clipType != Color && m_clipType != Virtual && m_clipType != Unknown) + return KUrl(m_clip->getProperty("resource")); + else return KUrl(); } -QStringList ProjectItem::names() const { - QStringList result; - result.append(text(0)); - result.append(text(1)); - result.append(text(2)); - return result; +void ProjectItem::changeDuration(int frames) +{ + QString itemdata = data(0, DurationRole).toString(); + if (itemdata.contains('/')) itemdata = itemdata.section('/', 0, 0) + "/ "; + else itemdata.clear(); + setData(0, DurationRole, itemdata + Timecode::getEasyTimecode(GenTime(frames, KdenliveSettings::project_fps()), KdenliveSettings::project_fps())); } -QDomElement ProjectItem::toXml() const { - return m_element; +void ProjectItem::setProperties(const QMap &props) +{ + if (m_clip == NULL) return; + m_clip->setProperties(props); } -const KUrl ProjectItem::clipUrl() const { - if (m_clipType != COLOR && m_clipType != VIRTUAL && m_clipType != UNKNOWN) - return KUrl(m_element.attribute("resource")); - else return KUrl(); +QString ProjectItem::getClipHash() const +{ + if (m_clip == NULL) return QString(); + return m_clip->getClipHash(); } +void ProjectItem::setProperty(const QString &key, const QString &value) +{ + if (m_clip == NULL) return; + m_clip->setProperty(key, value); +} -void ProjectItem::slotSetToolTip() { - QString tip = ""; - switch (m_clipType) { - case 1: - tip.append(i18n("Audio clip")); - break; - case 2: - tip.append(i18n("Mute video clip")); - break; - case 3: - tip.append(i18n("Video clip")); - break; - case 4: - tip.append(i18n("Color clip")); - setData(1, DurationRole, Timecode::getEasyTimecode(GenTime(m_element.attribute("out", "250").toInt(), 25), 25)); - break; - case 5: - tip.append(i18n("Image clip")); - break; - case 6: - tip.append(i18n("Text clip")); - break; - case 7: - tip.append(i18n("Slideshow clip")); - break; - case 8: - tip.append(i18n("Virtual clip")); - break; - case 9: - tip.append(i18n("Playlist clip")); - break; - default: - tip.append(i18n("Unknown clip")); - break; - } +void ProjectItem::clearProperty(const QString &key) +{ + if (m_clip == NULL) return; + m_clip->clearProperty(key); +} - setToolTip(1, tip); +DocClipBase *ProjectItem::referencedClip() +{ + return m_clip; } -void ProjectItem::setProperties(const QMap < QString, QString > &attributes, const QMap < QString, QString > &metadata) { +void ProjectItem::slotSetToolTip() +{ + QString tip; + if (m_clip->isPlaceHolder()) tip.append(i18n("Missing") + " | "); + QString jobInfo = data(0, JobStatusMessage).toString(); + if (!jobInfo.isEmpty()) { + tip.append(jobInfo + " | "); + } + if (hasProxy() && data(0, JobTypeRole).toInt() != PROXYJOB) { + tip.append(i18n("Proxy clip") + " | "); + } + tip.append(m_clip->shortInfo()); + setToolTip(0, tip); +} + + +void ProjectItem::setProperties(const QMap < QString, QString > &attributes, const QMap < QString, QString > &metadata) +{ + if (m_clip == NULL) return; + + QString prefix; + + m_clip->setProperties(attributes); + m_clip->setMetadata(metadata); + + if (m_clipType == Unknown) { + QString cliptype = attributes.value("type"); + if (cliptype == "audio") m_clipType = Audio; + else if (cliptype == "video") m_clipType = Video; + else if (cliptype == "av") m_clipType = AV; + else if (cliptype == "playlist") m_clipType = Playlist; + else m_clipType = AV; + + m_clip->setClipType(m_clipType); + slotSetToolTip(); + if (m_clipType == Playlist) { + // Check if the playlist xml contains a proxy inside, and inform user + if (playlistHasProxies(m_clip->fileURL().path())) { + prefix = i18n("Contains proxies") + " / "; + } + } + } + else if (attributes.contains("frame_size")) slotSetToolTip(); + if (attributes.contains("duration")) { - if (m_clipType == AUDIO || m_clipType == VIDEO || m_clipType == AV) m_element.setAttribute("duration", attributes["duration"].toInt()); - m_duration = GenTime(attributes["duration"].toInt(), 25); - setData(1, DurationRole, Timecode::getEasyTimecode(m_duration, 25)); - m_durationKnown = true; - m_clip->setDuration(m_duration); - kDebug() << "//// LOADED CLIP, DURATION SET TO: " << m_duration.frames(25); - } else { + GenTime duration = GenTime(attributes.value("duration").toInt(), KdenliveSettings::project_fps()); + QString itemdata = data(0, DurationRole).toString(); + if (itemdata.contains('/')) itemdata = itemdata.section('/', 0, 0) + "/ "; + else itemdata.clear(); + if (prefix.isEmpty()) prefix = itemdata; + setData(0, DurationRole, prefix + Timecode::getEasyTimecode(duration, KdenliveSettings::project_fps())); + m_clip->setDuration(duration); + } else { // No duration known, use an arbitrary one until it is. - m_duration = GenTime(0.0); - m_durationKnown = false; } - - //extend attributes -reh - - if (m_clipType == UNKNOWN) { - if (attributes.contains("type")) { - if (attributes["type"] == "audio") - m_clipType = AUDIO; - else if (attributes["type"] == "video") - m_clipType = VIDEO; - else if (attributes["type"] == "av") - m_clipType = AV; - else if (attributes["type"] == "playlist") - m_clipType = PLAYLIST; - } else { - m_clipType = AV; + if (m_clip->description().isEmpty()) { + if (metadata.contains("description")) { + m_clip->setProperty("description", metadata.value("description")); + setText(1, m_clip->description()); + } else if (metadata.contains("comment")) { + m_clip->setProperty("description", metadata.value("comment")); + setText(1, m_clip->description()); } - m_clip->setClipType(m_clipType); } - slotSetToolTip(); - if (m_element.isNull()) { - QDomDocument doc; - m_element = doc.createElement("producer"); +} + +void ProjectItem::setJobStatus(JOBTYPE jobType, ClipJobStatus status, int progress, const QString &statusMessage) +{ + setData(0, JobTypeRole, jobType); + if (progress > 0) setData(0, JobProgressRole, qMin(100, progress)); + else { + setData(0, JobProgressRole, status); + if ((status == JobAborted || status == JobCrashed || status == JobDone) || !statusMessage.isEmpty()) + setData(0, JobStatusMessage, statusMessage); + slotSetToolTip(); + } +} + +void ProjectItem::setConditionalJobStatus(ClipJobStatus status, JOBTYPE requestedJobType) +{ + if (data(0, JobTypeRole).toInt() == requestedJobType) { + setData(0, JobProgressRole, status); } - if (m_element.attribute("duration") == QString::null) m_element.setAttribute("duration", attributes["duration"].toInt()); - m_element.setAttribute("resource", attributes["filename"]); - m_element.setAttribute("type", (int) m_clipType); - - if (KdenliveSettings::audiothumbnails()) m_clip->slotRequestAudioThumbs(); - /* - if (attributes.contains("height")) { - m_height = attributes["height"].toInt(); - } else { - m_height = 0; - } - if (attributes.contains("width")) { - m_width = attributes["width"].toInt(); - } else { - m_width = 0; - } - //decoder name - if (attributes.contains("name")) { - m_decompressor = attributes["name"]; - } else { - m_decompressor = "n/a"; - } - //video type ntsc/pal - if (attributes.contains("system")) { - m_system = attributes["system"]; - } else { - m_system = "n/a"; - } - if (attributes.contains("fps")) { - m_framesPerSecond = attributes["fps"].toInt(); - } else { - // No frame rate known. - m_framesPerSecond = 0; - } - //audio attributes -reh - if (attributes.contains("channels")) { - m_channels = attributes["channels"].toInt(); - } else { - m_channels = 0; - } - if (attributes.contains("format")) { - m_format = attributes["format"]; - } else { - m_format = "n/a"; - } - if (attributes.contains("frequency")) { - m_frequency = attributes["frequency"].toInt(); - } else { - m_frequency = 0; - } - if (attributes.contains("videocodec")) { - m_videoCodec = attributes["videocodec"]; - } - if (attributes.contains("audiocodec")) { - m_audioCodec = attributes["audiocodec"]; - } - - m_metadata = metadata; - - if (m_metadata.contains("description")) { - setDescription (m_metadata["description"]); - } - else if (m_metadata.contains("comment")) { - setDescription (m_metadata["comment"]); - } - */ +} +bool ProjectItem::hasProxy() const +{ + if (m_clip == NULL) return false; + if (m_clip->getProperty("proxy").size() < 2 || data(0, JobProgressRole).toInt() == JobCrashed) return false; + return true; } -#include "projectitem.moc" +bool ProjectItem::isProxyReady() const +{ + return (data(0, JobProgressRole).toInt() == JobDone); +} + +bool ProjectItem::isJobRunning() const +{ + int s = data(0, JobProgressRole).toInt(); + if (s == JobWaiting || s == JobWorking || s > 0) return true; + return false; +} + +bool ProjectItem::isProxyRunning() const +{ + int s = data(0, JobProgressRole).toInt(); + if ((s == JobWorking || s > 0) && data(0, JobTypeRole).toInt() == (int) PROXYJOB) return true; + return false; +} + +bool ProjectItem::playlistHasProxies(const QString& path) +{ + kDebug()<<"// CHECKING FOR PROXIES"; + QFile file(path); + QDomDocument doc; + if (!file.open(QIODevice::ReadOnly)) + return false; + if (!doc.setContent(&file)) { + file.close(); + return false; + } + file.close(); + QString root = doc.documentElement().attribute("root"); + QDomNodeList kdenliveProducers = doc.elementsByTagName("kdenlive_producer"); + for (int i = 0; i < kdenliveProducers.count(); ++i) { + QString proxy = kdenliveProducers.at(i).toElement().attribute("proxy"); + if (!proxy.isEmpty() && proxy != "-") return true; + } + return false; +} + + +