<parameter type="bool" name="obscure" default="1">
<name>Obscure</name>
</parameter>
- <parameter type="filterjob" filtertag="autotrack_rectangle" filterparams="_serialize=1 motion_vector_list=0 %params" consumer="null" consumerparams="all=1 terminate_on_pause=1">
+ <parameter type="filterjob" filtertag="autotrack_rectangle" filterparams="_serialize=1 motion_vector_list=0 %params in=%position" consumer="null" consumerparams="all=1 terminate_on_pause=1">
<jobparam name="storedata" />
<jobparam name="projecttreefilter" />
<jobparam name="key">motion_vector_list</jobparam>
m_selectedKeyframe(0),
m_keyframeFactor(1),
m_keyframeOffset(0),
- m_fps(fps)
+ m_fps(fps),
+ m_isMainSelectedClip(false)
{
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
#if QT_VERSION >= 0x040600
setRect(0, 0, cropDuration().frames(m_fps) - 0.02, rect().height());
}
-void AbstractClipItem::resizeStart(int posx, bool hasSizeLimit)
+void AbstractClipItem::resizeStart(int posx, bool hasSizeLimit, bool /*emitChange*/)
{
GenTime durationDiff = GenTime(posx, m_fps) - m_info.startPos;
if (durationDiff == GenTime()) return;
}*/
}
-void AbstractClipItem::resizeEnd(int posx)
+void AbstractClipItem::resizeEnd(int posx, bool /*emitChange*/)
{
GenTime durationDiff = GenTime(posx, m_fps) - endPos();
if (durationDiff == GenTime()) return;
return 0;
}
+void AbstractClipItem::setMainSelectedClip(bool selected)
+{
+ if (selected == m_isMainSelectedClip) return;
+ m_isMainSelectedClip = selected;
+ update();
+}
+
+bool AbstractClipItem::isMainSelectedClip()
+{
+ return m_isMainSelectedClip;
+}
/** @brief Resizes the clip from the start.
* @param posx Absolute position of new in point
* @param hasSizeLimit (optional) Whether the clip has a maximum size */
- virtual void resizeStart(int posx, bool hasSizeLimit = true);
+ virtual void resizeStart(int posx, bool hasSizeLimit = true, bool emitChange = true);
/** @brief Resizes the clip from the end.
* @param posx Absolute position of new out point */
- virtual void resizeEnd(int posx);
+ virtual void resizeEnd(int posx, bool emitChange = true);
virtual double fps() const;
virtual void updateFps(double fps);
virtual GenTime maxDuration() const;
virtual void setCropStart(GenTime pos);
+ /** @brief Set this clip as the main selected clip (or not). */
+ void setMainSelectedClip(bool selected);
+ /** @brief Is this clip selected as the main clip. */
+ bool isMainSelectedClip();
+
protected:
ItemInfo m_info;
/** The position of the current keyframe when it has moved */
/** The (keyframe) parameter that is visible and editable in timeline (on the clip) */
int m_visibleParam;
double m_fps;
+ /** @brief True if this is the last clip the user selected */
+ bool m_isMainSelectedClip;
/** @brief Draw the keyframes of a clip
* @param painter The painter device for the clip
* @param limitedKeyFrames The keyframes can be of type "keyframe" or "simplekeyframe". In the
m_speed(speed),
m_strobe(strobe),
m_framePixelWidth(0),
- m_limitedKeyFrames(false),
- m_isMainSelectedClip(false)
+ m_limitedKeyFrames(false)
{
setZValue(2);
m_effectList = EffectsList(true);
}
*/
-void ClipItem::resizeStart(int posx, bool /*size*/)
+void ClipItem::resizeStart(int posx, bool /*size*/, bool emitChange)
{
bool sizeLimit = false;
if (clipType() != IMAGE && clipType() != COLOR && clipType() != TEXT) {
m_startThumbTimer.start(150);
}
}
+ if (emitChange) slotUpdateRange();
}
-void ClipItem::resizeEnd(int posx)
+void ClipItem::slotUpdateRange()
+{
+ if (m_isMainSelectedClip) emit updateRange();
+}
+
+void ClipItem::resizeEnd(int posx, bool emitChange)
{
const int max = (startPos() - cropStart() + maxDuration()).frames(m_fps);
if (posx > max && maxDuration() != GenTime()) posx = max;
m_endThumbTimer.start(150);
}
}
+ if (emitChange) slotUpdateRange();
}
//virtual
update();
}
-void ClipItem::setMainSelectedClip(bool selected)
-{
- if (selected == m_isMainSelectedClip) return;
- m_isMainSelectedClip = selected;
- update();
-}
-
-bool ClipItem::isMainSelectedClip()
-{
- return m_isMainSelectedClip;
-}
#include "clipitem.moc"
const QStyleOptionGraphicsItem *option,
QWidget *);
virtual int type() const;
- void resizeStart(int posx, bool size = true);
- void resizeEnd(int posx);
+ void resizeStart(int posx, bool size = true, bool emitChange = true);
+ void resizeEnd(int posx, bool emitChange = true);
OPERATIONTYPE operationMode(QPointF pos);
static int itemHeight();
const QString clipProducer() const;
/** @brief Get a free index value for effect group. */
int nextFreeEffectGroupIndex() const;
- /** @brief Set this clip as the main selected clip (or not). */
- void setMainSelectedClip(bool selected);
- /** @brief Is this clip selected as the main clip. */
- bool isMainSelectedClip();
protected:
//virtual void mouseMoveEvent(QGraphicsSceneMouseEvent * event);
/** @brief Keyframes type can be "keyframe" or "simplekeyframe" which have to be painted differently.
* True if keyframe type is "keyframe" */
bool m_limitedKeyFrames;
- /** @brief True if this is the last clip the user selected */
- bool m_isMainSelectedClip;
private slots:
void slotGetStartThumb();
void slotFetchThumbs();
void slotSetStartThumb(const QPixmap pix);
void slotSetEndThumb(const QPixmap pix);
+ void slotUpdateRange();
signals:
- void getThumb(int, int);
void prepareAudioThumb(double, int, int, int);
+ void updateRange();
};
#endif
keyframe_list->selectRow(row);
}
+
#include "cornerswidget.moc"
if (parent)
parent->resizeStart((int)(snappedPos - m_dragItemInfo.startPos.frames(m_document->fps())));
} else {
- m_dragItem->resizeStart((int)(snappedPos));
+ m_dragItem->resizeStart((int)(snappedPos), true, false);
}
QString crop = m_document->timecode().getDisplayTimecode(m_dragItem->cropStart(), KdenliveSettings::frametimecode());
QString duration = m_document->timecode().getDisplayTimecode(m_dragItem->cropDuration(), KdenliveSettings::frametimecode());
if (parent)
parent->resizeEnd((int)(snappedPos - m_dragItemInfo.endPos.frames(m_document->fps())));
} else {
- m_dragItem->resizeEnd((int)(snappedPos));
+ m_dragItem->resizeEnd((int)(snappedPos), false);
}
QString duration = m_document->timecode().getDisplayTimecode(m_dragItem->cropDuration(), KdenliveSettings::frametimecode());
QString offset = m_document->timecode().getDisplayTimecode(m_dragItem->cropDuration() - m_dragItemInfo.cropDuration, KdenliveSettings::frametimecode());
new RazorClipCommand(this, clipInfo, info.startPos, false, command);
new ResizeClipCommand(this, dupInfo, newdupInfo, false, false, command);
ClipItem *dup = cutClip(clipInfo, info.startPos, true, false);
- if (dup) dup->resizeStart(info.endPos.frames(m_document->fps()));
+ if (dup) {
+ dup->resizeStart(info.endPos.frames(m_document->fps()));
+ }
} else {
ItemInfo newclipInfo = clip->info();
newclipInfo.endPos = info.startPos;
}
} else {
prepareResizeClipStart(m_dragItem, m_dragItemInfo, m_dragItem->startPos().frames(m_document->fps()));
+ if (m_dragItem->type() == AVWIDGET) static_cast <ClipItem*>(m_dragItem)->slotUpdateRange();
}
} else if (m_operationMode == RESIZEEND && m_dragItem->endPos() != m_dragItemInfo.endPos) {
// resize end
}
} else {
prepareResizeClipEnd(m_dragItem, m_dragItemInfo, m_dragItem->endPos().frames(m_document->fps()));
+ if (m_dragItem->type() == AVWIDGET) static_cast <ClipItem*>(m_dragItem)->slotUpdateRange();
}
} else if (m_operationMode == FADEIN) {
// resize fade in effect
ItemInfo clipinfo = item->info();
clipinfo.track = m_document->tracksCount() - clipinfo.track;
bool success = m_document->renderer()->mltResizeClipStart(clipinfo, end.startPos - clipinfo.startPos);
- if (success)
+ if (success) {
item->resizeStart((int) end.startPos.frames(m_document->fps()));
+ }
else
emit displayMessage(i18n("Error when resizing clip"), ErrorMessage);
} else {
#include <KIO/NetAccess>
#include <KStandardDirs>
+#include <KApplication>
#include <KDebug>
#include <QCryptographicHash>
#include <QtConcurrentRun>
#include <cstdio>
+#include <kmessagebox.h>
DocClipBase::DocClipBase(ClipManager *clipManager, QDomElement xml, const QString &id) :
QObject(),
return m_thumbProd->extractImage(frame, width, height);
}
-void DocClipBase::setAnalysisData(const QString &name, const QString &data)
+void DocClipBase::setAnalysisData(const QString &name, const QString &data, int offset)
{
if (data.isEmpty()) m_analysisdata.remove(name);
else {
if (m_analysisdata.contains(name)) {
- int i = 1;
- QString newname = name + " " + QString::number(i);
- while (m_analysisdata.contains(newname)) {
- i++;
- newname = name + " " + QString::number(i);
+ if (KMessageBox::questionYesNo(kapp->activeWindow(), i18n("Clip already contains analysis data %1", name), QString(), KGuiItem(i18n("Merge")), KGuiItem(i18n("Add"))) == KMessageBox::Yes) {
+ // Merge data
+ Mlt::Profile *profile = m_baseTrackProducers.at(0)->profile();
+ Mlt::Geometry geometry(m_analysisdata.value(name).toUtf8().data(), m_properties.value("duration").toInt(), profile->width(), profile->height());
+ Mlt::Geometry newGeometry(data.toUtf8().data(), m_properties.value("duration").toInt(), profile->width(), profile->height());
+ Mlt::GeometryItem item;
+ int pos = 0;
+ while (!newGeometry.next_key(&item, pos)) {
+ pos = item.frame();
+ item.frame(pos + offset);
+ pos++;
+ geometry.insert(item);
+ }
+ m_analysisdata.insert(name, geometry.serialise());
+ }
+ else {
+ // Add data with another name
+ int i = 1;
+ QString newname = name + " " + QString::number(i);
+ while (m_analysisdata.contains(newname)) {
+ i++;
+ newname = name + " " + QString::number(i);
+ }
+ m_analysisdata.insert(newname, geometryWithOffset(data, offset));
}
- m_analysisdata.insert(newname, data);
}
- else m_analysisdata.insert(name, data);
+ else m_analysisdata.insert(name, geometryWithOffset(data, offset));
+ }
+}
+
+const QString DocClipBase::geometryWithOffset(QString data, int offset)
+{
+ if (offset == 0) return data;
+ Mlt::Profile *profile = m_baseTrackProducers.at(0)->profile();
+ Mlt::Geometry geometry(data.toUtf8().data(), m_properties.value("duration").toInt(), profile->width(), profile->height());
+ Mlt::Geometry newgeometry("", m_properties.value("duration").toInt(), profile->width(), profile->height());
+ Mlt::GeometryItem item;
+ int pos = 0;
+ while (!geometry.next_key(&item, pos)) {
+ pos = item.frame();
+ item.frame(pos + offset);
+ pos++;
+ newgeometry.insert(item);
}
+ return newgeometry.serialise();
}
QMap <QString, QString> DocClipBase::analysisData() const
void cleanupProducers();
bool isClean() const;
bool getAudioThumbs();
- void setAnalysisData(const QString &name, const QString &data);
+ void setAnalysisData(const QString &name, const QString &data, int offset = 0);
QMap <QString, QString> analysisData() const;
int lastSeekPosition;
/** Cache for every audio Frame with 10 Bytes */
void adjustProducerProperties(Mlt::Producer *prod, const QString &id, bool mute, bool blind);
/** @brief Create another instance of a producer. */
Mlt::Producer *cloneProducer(Mlt::Producer *source);
+ /** @brief Offset all keyframes of a geometry. */
+ const QString geometryWithOffset(QString data, int offset);
public slots:
#include <QDomDocument>
#include <QTreeWidgetItem>
#include <QHeaderView>
+#include <unistd.h>
DvdTreeWidget::DvdTreeWidget(QWidget *parent) :
QTreeWidget(parent)
item->setData(1, Qt::UserRole, playTime);
int standard = -1;
int aspect = profile.dar() * 100;
- if (profile.height() == 576) {
+ if (profile.height() == 576 && profile.fps() == 25.0) {
if (aspect > 150) standard = 1;
else standard = 0;
}
- else if (profile.height() == 480) {
+ else if (profile.height() == 480 && qAbs(profile.fps() - 30000.0 / 1001) < 0.2) {
if (aspect > 150) standard = 3;
else standard = 2;
}
default:
standardName = i18n("Unknown");
}
+ standardName.append(QString(" | %1x%2, %3fps").arg(profile.width()).arg(profile.height()).arg(profile.fps()));
item->setData(0, Qt::UserRole, standardName);
item->setData(0, Qt::UserRole + 1, standard);
item->setData(0, Qt::UserRole + 2, QSize(profile.dar() * profile.height(), profile.height()));
return m_paramWidget->needsMonitorEffectScene();
}
-
+void CollapsibleEffect::setRange(int inPoint , int outPoint)
+{
+ m_paramWidget->setRange(inPoint, outPoint);
+}
void adjustButtons(int ix, int max);
/** @brief Returns true of this effect requires an on monitor adjustable effect scene. */
bool needsMonitorEffectScene() const;
+ /** @brief Set clip in / out points. */
+ void setRange(int inPoint , int outPoint);
public slots:
void slotSyncEffectsPos(int pos);
m_effects.at(i)->slotSyncEffectsPos(pos);
}
+void EffectStackView2::slotClipItemUpdate()
+{
+ int inPoint = m_clipref->cropStart().frames(KdenliveSettings::project_fps());
+ int outPoint = m_clipref->cropDuration().frames(KdenliveSettings::project_fps()) - inPoint;
+ CollapsibleEffect *effectToMove = NULL;
+ for (int i = 0; i < m_effects.count(); i++) {
+ m_effects.at(i)->setRange(inPoint, outPoint);
+ }
+}
+
void EffectStackView2::slotClipItemSelected(ClipItem* c)
{
if (c && !c->isEnabled()) return;
if (c && c == m_clipref) {
} else {
+ if (m_clipref) disconnect(m_clipref, SIGNAL(updateRange()), this, SLOT(slotClipItemUpdate()));
m_clipref = c;
if (c) {
+ connect(m_clipref, SIGNAL(updateRange()), this, SLOT(slotClipItemUpdate()));
QString cname = m_clipref->clipName();
if (cname.length() > 30) {
m_ui.checkAll->setToolTip(i18n("Effects for %1", cname));
* @param c Clip whose effect list should be managed */
void slotClipItemSelected(ClipItem* c);
+ /** @brief Update the clip range (in-out points)
+ * @param c Clip whose effect list should be managed */
+ void slotClipItemUpdate();
+
void slotTrackItemSelected(int ix, const TrackInfo info);
/** @brief Check if the mouse wheel events should be used for scrolling the widget view. */
m_geometryWidget = new GeometryWidget(m_metaInfo->monitor, m_metaInfo->timecode, 0, true, effect.hasAttribute("showrotation"), parent);
m_geometryWidget->setFrameSize(m_metaInfo->frameSize);
connect(m_geometryWidget, SIGNAL(parameterChanged()), this, SLOT(slotCollectAllParameters()));
- if (minFrame == maxFrame)
+ if (minFrame == maxFrame) {
m_geometryWidget->setupParam(pa, m_in, m_out);
+ connect(this, SIGNAL(updateRange(int,int)), m_geometryWidget, SLOT(slotUpdateRange(int,int)));
+ }
else
m_geometryWidget->setupParam(pa, minFrame, maxFrame);
m_vbox->addWidget(m_geometryWidget);
connect(this, SIGNAL(syncEffectsPos(int)), m_geometryWidget, SLOT(slotSyncPosition(int)));
} else {
Geometryval *geo = new Geometryval(m_metaInfo->profile, m_metaInfo->timecode, m_metaInfo->frameSize, 0);
- if (minFrame == maxFrame)
+ if (minFrame == maxFrame) {
geo->setupParam(pa, m_in, m_out);
+ connect(this, SIGNAL(updateRange(int,int)), geo, SLOT(slotUpdateRange(int,int)));
+ }
else
geo->setupParam(pa, minFrame, maxFrame);
m_vbox->addWidget(geo);
if (pa.attribute("widget") == "corners") {
// we want a corners-keyframe-widget
CornersWidget *corners = new CornersWidget(m_metaInfo->monitor, pa, m_in, m_out, m_metaInfo->timecode, e.attribute("active_keyframe", "-1").toInt(), parent);
+ connect(this, SIGNAL(updateRange(int,int)), corners, SLOT(slotUpdateRange(int,int)));
m_needsMonitorEffectScene = true;
connect(this, SIGNAL(syncEffectsPos(int)), corners, SLOT(slotSyncPosition(int)));
geo = static_cast<KeyframeEdit *>(corners);
} else {
geo = new KeyframeEdit(pa, m_in, m_out, m_metaInfo->timecode, e.attribute("active_keyframe", "-1").toInt());
+ connect(this, SIGNAL(updateRange(int,int)), geo, SLOT(slotUpdateRange(int,int)));
}
m_vbox->addWidget(geo);
m_valueItems[paramName+"keyframe"] = geo;
pos = m_out - pos;
}
PositionEdit *posedit = new PositionEdit(paramName, pos, 0, m_out - m_in, m_metaInfo->timecode);
+ connect(this, SIGNAL(updateRange(int,int)), posedit, SLOT(setRange(int,int)));
m_vbox->addWidget(posedit);
m_valueItems[paramName+"position"] = posedit;
connect(posedit, SIGNAL(parameterChanged()), this, SLOT(slotCollectAllParameters()));
QString type = pa.attribute("type");
if (type == "filterjob") {
QString filterparams = pa.attribute("filterparams");
+ if (filterparams.contains("%position")) {
+ if (m_geometryWidget) filterparams.replace("%position", QString::number(m_geometryWidget->currentPosition()));
+ }
if (filterparams.contains("%params")) {
// Replace with current geometry
EffectsParameterList parameters;
QDomElement e = jobparams.item(j).toElement();
extraParams.insert(e.attribute("name"), e.text().toUtf8());
}
+ extraParams.insert("offset", QString::number(m_in));
emit startFilterJob(pa.attribute("filtertag"), filterparams, pa.attribute("consumer"), pa.attribute("consumerparams"), extraParams);
kDebug()<<" - - -PROPS:\n"<<pa.attribute("filtertag")<<"-"<< filterparams<<"-"<< pa.attribute("consumer")<<"-"<< pa.attribute("consumerparams")<<"-"<< pa.attribute("extraparams");
break;
}
+void ParameterContainer::setRange(int inPoint, int outPoint)
+{
+ m_in = inPoint;
+ m_out = outPoint;
+ emit updateRange(m_in, m_out);
+}
+
+
bool needsMonitorEffectScene() const;
/** @brief Set keyframes for this param. */
void setKeyframes(const QString &data, int maximum);
+ /** @brief Update the in / out for the clip. */
+ void setRange(int inPoint, int outPoint);
private slots:
void slotCollectAllParameters();
void startFilterJob(QString filterName, QString filterParams, QString consumer, QString consumerParams, const QMap <QString, QString>extra);
/** @brief Request import of keyframes from clip data. */
void importClipKeyframes();
+ /** @brief Master clip was resized, update effect. */
+ void updateRange(int inPoint, int outPoint);
};
#endif
}
-
+void Geometryval::slotUpdateRange(int inPoint, int outPoint)
+{
+ m_helper->setKeyGeometry(m_geom, outPoint - inPoint - 1);
+ m_helper->update();
+ m_timePos.setRange(0, outPoint - inPoint - 1);
+}
void setFrameSize(QPoint p);
/** @brief Updates the timecode display according to settings (frame number or hh:mm:ss:ff) */
void updateTimecodeFormat();
+ void slotUpdateRange(int inPoint, int outPoint);
private:
MltVideoProfile m_profile;
} else {
m_ui.widgetTimeWrapper->setHidden(false);
m_timeline->setKeyGeometry(m_geometry, m_outPoint - m_inPoint);
- m_timePos->setRange(0, m_outPoint - m_inPoint);
}
+ m_timePos->setRange(0, m_outPoint - m_inPoint);
// no opacity
if (elem.attribute("opacity") == "false") {
}
}
+int GeometryWidget::currentPosition() const
+{
+ return m_inPoint + m_timePos->getValue();
+}
+
void GeometryWidget::slotRequestSeek(int pos)
{
if (KdenliveSettings::transitionfollowcursor())
emit parameterChanged();
}
+void GeometryWidget::slotUpdateRange(int inPoint, int outPoint)
+{
+ m_inPoint = inPoint;
+ m_outPoint = outPoint;
+ m_timeline->setKeyGeometry(m_geometry, m_outPoint - m_inPoint);
+ m_timePos->setRange(0, m_outPoint - m_inPoint);
+}
#include "geometrywidget.moc"
void setFrameSize(QPoint size);
void addParameter(const QDomElement elem);
void importKeyframes(const QString &data, int maximum);
+ int currentPosition() const;
public slots:
/** @brief Sets up the rect and the geometry object.
/** @brief Updates position of the local timeline to @param relTimelinePos. */
void slotSyncPosition(int relTimelinePos);
void slotResetKeyframes();
+ void slotUpdateRange(int inPoint, int outPoint);
private:
Ui::GeometryWidget_UI m_ui;
slotUpdateVisibleParameter(0);
}
+void KeyframeEdit::slotUpdateRange(int inPoint, int outPoint)
+{
+ m_min = inPoint;
+ m_max = outPoint;
+}
+
#include "keyframeedit.moc"
/** @brief Makes the first parameter visible in timeline if no parameter is selected. */
void checkVisibleParam();
+public slots:
+
+ void slotUpdateRange(int inPoint, int outPoint);
+
protected:
/** @brief Gets the position of a keyframe from the table.
* @param row Row of the keyframe in the table */
int getPosition() const;
void setPosition(int pos);
void updateTimecodeFormat();
- void setRange(int min, int max);
+public slots:
+ void setRange(int min, int max);
+
private:
TimecodeDisplay *m_display;
QSlider *m_slider;
const int JobStatusMessage = Qt::UserRole + 7;
const int itemHeight = 38;
-ProjectItem::ProjectItem(QTreeWidget * parent, DocClipBase *clip) :
+ProjectItem::ProjectItem(QTreeWidget * parent, DocClipBase *clip, QSize pixmapSize) :
QTreeWidgetItem(parent, PROJECTCLIPTYPE),
m_clip(clip),
- m_clipId(clip->getId())
+ m_clipId(clip->getId()),
+ m_pixmapSet(false)
{
- buildItem();
+ buildItem(pixmapSize);
}
-ProjectItem::ProjectItem(QTreeWidgetItem * parent, DocClipBase *clip) :
+ProjectItem::ProjectItem(QTreeWidgetItem * parent, DocClipBase *clip, QSize pixmapSize) :
QTreeWidgetItem(parent, PROJECTCLIPTYPE),
m_clip(clip),
- m_clipId(clip->getId())
+ m_clipId(clip->getId()),
+ m_pixmapSet(false)
{
- buildItem();
+ buildItem(pixmapSize);
}
-void ProjectItem::buildItem()
+void ProjectItem::buildItem(QSize pixmapSize)
{
setSizeHint(0, QSize(itemHeight * 3, itemHeight));
if (m_clip->isPlaceHolder()) setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | 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));
+ }
+
setText(0, name);
setText(1, m_clip->description());
GenTime duration = m_clip->duration();
{
}
+bool ProjectItem::hasPixmap() const
+{
+ return m_pixmapSet;
+}
+
+void ProjectItem::setPixmap(const QPixmap p)
+{
+ m_pixmapSet = true;
+ setData(0, Qt::DecorationRole, p);
+}
+
//static
int ProjectItem::itemDefaultHeight()
{
class ProjectItem : public QTreeWidgetItem
{
public:
- ProjectItem(QTreeWidget * parent, DocClipBase *clip);
- ProjectItem(QTreeWidgetItem * parent, DocClipBase *clip);
+ ProjectItem(QTreeWidget * parent, DocClipBase *clip, QSize pixmapSize);
+ ProjectItem(QTreeWidgetItem * parent, DocClipBase *clip, QSize pixmapSize);
virtual ~ProjectItem();
QDomElement toXml() const;
int numReferences() const;
bool isJobRunning() const;
/** \brief Returns true if we are currently creating the proxy for this clip. */
bool isProxyRunning() const;
+ /** \brief Returns true if the thumbnail for this clip has been loaded. */
+ bool hasPixmap() const;
+ /** \brief Sets the thumbnail for this clip. */
+ void setPixmap(const QPixmap p);
virtual bool operator<(const QTreeWidgetItem &other)const {
int column = treeWidget()->sortColumn();
CLIPTYPE m_clipType;
DocClipBase *m_clip;
QString m_clipId;
+ bool m_pixmapSet;
/** @brief Setup basic properties */
- void buildItem();
+ void buildItem(QSize pixmapSize);
/** @brief Check if an xml project file has proxies */
bool playlistHasProxies(const QString path);
};
} else {
pixmap = KIcon("view-refresh").pixmap(m_listView->iconSize());
}
- item->setData(0, Qt::DecorationRole, pixmap);
+ item->setPixmap(pixmap);
}
}
QPainter p(&pixmap);
p.drawPixmap(3, 3, icon.pixmap(width - 6, height - 6));
p.end();
- item->setData(0, Qt::DecorationRole, pixmap);
+ item->setPixmap(pixmap);
if (item->referencedClip()) {
item->referencedClip()->setPlaceHolder(true);
Mlt::Producer *newProd = m_render->invalidProducer(id);
//m_listView->setEnabled(false);
const QString parent = clip->getProperty("groupid");
QString groupName = clip->getProperty("groupname");
+ QSize pixelSize((int)(m_listView->iconSize().height() * m_render->dar()), m_listView->iconSize().height());
ProjectItem *item = NULL;
monitorItemEditing(false);
if (!parent.isEmpty()) {
}
if (parentitem)
- item = new ProjectItem(parentitem, clip);
+ item = new ProjectItem(parentitem, clip, pixelSize);
}
if (item == NULL) {
- item = new ProjectItem(m_listView, clip);
+ item = new ProjectItem(m_listView, clip, pixelSize);
}
if (item->data(0, DurationRole).isNull()) item->setData(0, DurationRole, i18n("Loading"));
connect(clip, SIGNAL(createProxy(const QString &)), this, SLOT(slotCreateProxy(const QString &)));
connect(clip, SIGNAL(abortProxy(const QString &, const QString &)), this, SLOT(slotAbortProxy(const QString, const QString)));
+
if (getProperties) {
- int height = m_listView->iconSize().height();
- int width = (int)(height * m_render->dar());
- QPixmap pix = KIcon("video-x-generic").pixmap(QSize(width, height));
- item->setData(0, Qt::DecorationRole, pix);
//item->setFlags(Qt::ItemIsSelectable);
m_listView->processLayout();
QDomElement e = clip->toXML().cloneNode().toElement();
requestClipThumbnail(item->clipId());
}
else {
- processThumbOverlays(item, pix);
- item->setData(0, Qt::DecorationRole, pix);
+ QPixmap result = roundedPixmap(pix);
+ processThumbOverlays(item, result);
+ item->setPixmap(result);
}
}
else {
}
}
+QPixmap ProjectList::roundedPixmap(QImage img)
+{
+ QPixmap pix(img.width(), img.height());
+ pix.fill(Qt::transparent);
+ QPainter p(&pix);
+ p.setRenderHint(QPainter::Antialiasing, true);
+ QPainterPath path;
+ path.addRoundedRect(0.5, 0.5, pix.width() - 1, pix.height() - 1, 2, 2);
+ p.setClipPath(path);
+ p.drawImage(0, 0, img);
+ p.end();
+ return pix;
+}
+
+QPixmap ProjectList::roundedPixmap(QPixmap source)
+{
+ QPixmap pix(source.width(), source.height());
+ pix.fill(Qt::transparent);
+ QPainter p(&pix);
+ p.setRenderHint(QPainter::Antialiasing, true);
+ QPainterPath path;
+ path.addRoundedRect(0.5, 0.5, pix.width() - 1, pix.height() - 1, 2, 2);
+ p.setClipPath(path);
+ p.drawPixmap(0, 0, source);
+ p.end();
+ return pix;
+}
+
void ProjectList::getCachedThumbnail(SubProjectItem *item)
{
if (!item) return;
}
else if (clip->isPlaceHolder()) {
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDropEnabled);
- if (item->data(0, Qt::DecorationRole).isNull()) {
- item->setData(0, Qt::DecorationRole, missingPixmap);
+ if (!item->hasPixmap()) {
+ item->setPixmap(missingPixmap);
}
else {
QPixmap pixmap = qVariantValue<QPixmap>(item->data(0, Qt::DecorationRole));
QPainter p(&pixmap);
p.drawPixmap(3, 3, KIcon("dialog-close").pixmap(pixmap.width() - 6, pixmap.height() - 6));
p.end();
- item->setData(0, Qt::DecorationRole, pixmap);
+ item->setPixmap(pixmap);
}
}
} else {
if (displayRatioChanged) {
requestClipThumbnail(clip->getId());
}
- else if (item->data(0, Qt::DecorationRole).isNull()) {
+ else if (!item->hasPixmap()) {
getCachedThumbnail(item);
}
if (item->data(0, DurationRole).toString().isEmpty()) {
QPainter p(&pixmap);
p.drawPixmap(3, 3, KIcon("dialog-close").pixmap(pixmap.width() - 6, pixmap.height() - 6));
p.end();
- item->setData(0, Qt::DecorationRole, pixmap);
+ item->setPixmap(pixmap);
}
else if (clip->getProperty("_replaceproxy") == "1") {
clip->setProperty("_replaceproxy", QString());
if (item && item->parent()) pItem = static_cast <ProjectItem *>(item->parent());
if (!item && framePos == 0) pItem = getItemById(id);
if (!item && !pItem) return;
- if (item) item->setData(0, Qt::DecorationRole, QPixmap::fromImage(img));
- else if (pItem) pItem->setData(0, Qt::DecorationRole, QPixmap::fromImage(img));
+ if (item) {
+ if (item->type() == PROJECTCLIPTYPE) static_cast<ProjectItem*>(item)->setPixmap(QPixmap::fromImage(img));
+ else item->setData(0, Qt::DecorationRole, QPixmap::fromImage(img));
+ }
+ else if (pItem) pItem->setPixmap(QPixmap::fromImage(img));
if (pItem) {
QString hash = pItem->getClipHash();
if (!hash.isEmpty()) m_doc->cacheImage(hash + '#' + QString::number(framePos), img);
slotProcessNextThumbnail();
return;
}
- QPixmap pix;
QImage img;
int height = m_listView->iconSize().height();
int swidth = (int)(height * m_render->frameRenderWidth() / m_render->renderHeight()+ 0.5);
int dwidth = (int)(height * m_render->dar() + 0.5);
- if (clip->clipType() == AUDIO)
- pix = KIcon("audio-x-generic").pixmap(QSize(dwidth, height));
- else if (clip->clipType() == IMAGE) {
+ if (clip->clipType() == IMAGE) {
img = KThumb::getFrame(item->referencedClip()->getProducer(), 0, swidth, dwidth, height);
}
- else {
+ else if (clip->clipType() != AUDIO) {
img = item->referencedClip()->extractImage(frame, dwidth, height);
}
- if (!pix.isNull() || !img.isNull()) {
+ if (!img.isNull()) {
monitorItemEditing(false);
- if (!img.isNull()) {
- pix = QPixmap::fromImage(img);
- processThumbOverlays(item, pix);
- }
- it->setData(0, Qt::DecorationRole, pix);
+ QPixmap pix = roundedPixmap(img);
+ processThumbOverlays(item, pix);
+ if (isSubItem) it->setData(0, Qt::DecorationRole, pix);
+ else item->setPixmap(pix);
monitorItemEditing(true);
QString hash = item->getClipHash();
}
}
- if (!replace && m_allClipsProcessed && item->data(0, Qt::DecorationRole).isNull()) {
+ if (!replace && m_allClipsProcessed && !item->hasPixmap()) {
getCachedThumbnail(item);
}
if (!toReload.isEmpty())
{
ProjectItem *item = getItemById(clipId);
if (item && !img.isNull()) {
- QPixmap pix(img.width(), img.height());
- pix.fill(Qt::transparent);
- QPainter p(&pix);
- p.setRenderHint(QPainter::Antialiasing, true);
- QPainterPath path;
- path.addRoundedRect(0.5, 0.5, pix.width() - 1, pix.height() - 1, 2, 2);
- p.setClipPath(path);
- p.drawImage(0, 0, img);
- p.end();
+ QPixmap pix = roundedPixmap(img);
processThumbOverlays(item, pix);
monitorItemEditing(false);
- item->setData(0, Qt::DecorationRole, pix);
+ item->setPixmap(pix);
monitorItemEditing(true);
QString hash = item->getClipHash();
if (!hash.isEmpty()) m_doc->cacheImage(hash, img);
QMap <QString, QString> extraParams;
extraParams.insert("key", "shot_change_list");
extraParams.insert("projecttreefilter", "1");
- extraParams.insert("resultmessage", i18n("Found %1 scenes.", "%count"));
+ QString keyword("%count");
+ extraParams.insert("resultmessage", i18n("Found %1 scenes.", keyword));
if (ui.add_markers->isChecked()) {
// We want to create markers
extraParams.insert("addmarkers", QString::number(ui.marker_type->currentIndex()));
}
if (!dataProcessed || filterInfo.contains("storedata")) {
// Store returned data as clip extra data
- clip->referencedClip()->setAnalysisData(filterInfo.contains("displaydataname") ? filterInfo.value("displaydataname") : key, results.value(key));
+ clip->referencedClip()->setAnalysisData(filterInfo.contains("displaydataname") ? filterInfo.value("displaydataname") : key, results.value(key), filterInfo.value("offset").toInt());
emit updateAnalysisData(clip->referencedClip());
}
}
QString subText = index.data(DurationRole).toString();
int usage = index.data(UsageRole).toInt();
if (usage != 0) subText.append(QString(" (%1)").arg(usage));
- if (option.state & (QStyle::State_Selected)) painter->setPen(option.palette.color(QPalette::Mid));
QRectF bounding;
painter->drawText(r2, Qt::AlignLeft | Qt::AlignVCenter , subText, &bounding);
-
int jobProgress = index.data(Qt::UserRole + 5).toInt();
if (jobProgress != 0 && jobProgress != JOBDONE && jobProgress != JOBABORTED) {
if (jobProgress != JOBCRASHED) {
// Draw job progress bar
QColor color = option.palette.alternateBase().color();
- painter->setPen(Qt::NoPen);
- color.setAlpha(180);
- painter->setBrush(QBrush(color));
- QRect progress(pixmapPoint.x() + 1, pixmapPoint.y() + pixmap.height() - 9, pixmap.width() - 2, 8);
- painter->drawRect(progress);
- painter->setBrush(option.palette.text());
- if (jobProgress > 0) {
- progress.adjust(1, 1, 0, -1);
- progress.setWidth((pixmap.width() - 4) * jobProgress / 100);
- painter->drawRect(progress);
- } else if (jobProgress == JOBWAITING) {
- // Draw kind of a pause icon
- progress.adjust(1, 1, 0, -1);
- progress.setWidth(2);
- painter->drawRect(progress);
- progress.moveLeft(progress.right() + 2);
+ color.setAlpha(150);
+ painter->setPen(option.palette.link().color());
+ QRect progress(pixmapPoint.x() + 2, pixmapPoint.y() + pixmap.height() - 9, pixmap.width() - 4, 7);
+ painter->setBrush(QBrush(color));
+ painter->drawRect(progress);
+ painter->setBrush(option.palette.link());
+ progress.adjust(2, 2, -2, -2);
+ if (jobProgress == JOBWAITING) {
+ progress.setLeft(progress.right() - 2);
+ painter->drawRect(progress);
+ progress.moveLeft(progress.left() - 5);
+ painter->drawRect(progress);
+ }
+ else if (jobProgress > 0) {
+ progress.setWidth(progress.width() * jobProgress / 100);
painter->drawRect(progress);
}
} else if (jobProgress == JOBCRASHED) {
QStringList getPendingJobs(const QString &id);
/** @brief Start an MLT process job. */
void processClipJob(QStringList ids, const QString&destination, bool autoAdd, QStringList jobParams, const QString &description, QMap <QString, QString>extraParams = QMap <QString, QString>());
+ /** @brief Create rounded shape pixmap for project tree thumb. */
+ QPixmap roundedPixmap(QImage img);
+ QPixmap roundedPixmap(QPixmap source);
private slots:
void slotClipSelected();
QColor bgColor = QColor(titleConfig.readEntry("rect_background_color", rectBColor->color()));
#if KDE_IS_VERSION(4,5,0)
- fgColor.setAlpha(titleConfig.readEntry("rect_background_alpha", fgColor.alpha()));
+ fgColor.setAlpha(titleConfig.readEntry("rect_foreground_alpha", fgColor.alpha()));
bgColor.setAlpha(titleConfig.readEntry("rect_background_alpha", bgColor.alpha()));
#else
rectFAlpha->setValue(titleConfig.readEntry("rect_foreground_alpha", rectFAlpha->value()));