* Add rating and sort by rating

* Fix various tagging and sorting issues
Related to #287
parent 173ed38b
Pipeline #12681 passed with stage
in 14 minutes and 55 seconds
......@@ -42,6 +42,7 @@ AbstractProjectItem::AbstractProjectItem(PROJECTITEMTYPE type, QString id, const
, m_date()
, m_binId(std::move(id))
, m_usage(0)
, m_rating(0)
, m_clipStatus(StatusReady)
, m_itemType(type)
, m_lock(QReadWriteLock::Recursive)
......@@ -157,7 +158,10 @@ QVariant AbstractProjectItem::getData(DataType type) const
data = clipType();
break;
case DataTag:
data = clipTags();
data = QVariant(m_tags);
break;
case DataRating:
data = QVariant(m_rating);
break;
case ClipHasAudioAndVideo:
data = hasAudioAndVideo();
......@@ -221,7 +225,7 @@ QVariant AbstractProjectItem::getData(DataType type) const
int AbstractProjectItem::supportedDataCount() const
{
return 7;
return 8;
}
QString AbstractProjectItem::name() const
......@@ -306,3 +310,24 @@ void AbstractProjectItem::updateParent(std::shared_ptr<TreeItem> newParent)
}
TreeItem::updateParent(newParent);
}
const QString & AbstractProjectItem::tags() const
{
return m_tags;
}
void AbstractProjectItem::setTags(const QString tags)
{
m_tags = tags;
}
uint AbstractProjectItem::rating() const
{
return m_rating;
}
void AbstractProjectItem::setRating(uint rating)
{
m_rating = rating;
}
......@@ -125,6 +125,8 @@ public:
DataDuration,
// Tag of the clip as colors
DataTag,
// Rating of the clip (0-5)
DataRating,
// Duration of the clip in frames
ParentDuration,
// Inpoint of the subclip (0 for clips)
......@@ -197,7 +199,10 @@ public:
*/
virtual bool isIncludedInTimeline() { return false; }
virtual ClipType::ProducerType clipType() const = 0;
virtual const QString clipTags() const = 0;
uint rating() const;
virtual void setRating(uint rating);
const QString &tags() const;
void setTags(const QString tags);
signals:
void childAdded(AbstractProjectItem *child);
......@@ -214,6 +219,8 @@ protected:
QDateTime m_date;
QString m_binId;
uint m_usage;
uint m_rating;
QString m_tags;
CLIPSTATUS m_clipStatus;
PROJECTITEMTYPE m_itemType;
......
This diff is collapsed.
......@@ -278,8 +278,7 @@ private slots:
/** @brief Set sorting column */
void slotSetSorting();
/** @brief Show/hide date column */
void slotShowDateColumn(bool show);
void slotShowDescColumn(bool show);
void slotShowColumn(bool show);
/** @brief Go to parent folder */
void slotBack();
/** @brief Setup the bin view type (icon view, tree view, ...).
......@@ -402,6 +401,7 @@ private:
QAction *m_inTimelineAction;
QAction *m_showDate;
QAction *m_showDesc;
QAction *m_showRating;
QAction *m_sortDescend;
/** @brief Default view type (icon, tree, ...) */
BinViewType m_listType;
......@@ -435,6 +435,7 @@ private:
TagWidget *m_tagsWidget;
QMenu *m_filterMenu;
QActionGroup m_filterGroup;
QToolButton *m_filterButton;
/** @brief The info widget for failed jobs. */
KMessageWidget *m_infoMessage;
QStringList m_errorLog;
......@@ -461,6 +462,8 @@ private:
void showSlideshowWidget(const std::shared_ptr<ProjectClip> &clip);
void processAudioThumbs();
void updateSortingAction(int ix);
/** @brief Apply Bin filtering. */
void processBinFiltering();
int wheelAccumulatedDelta;
signals:
......
......@@ -97,12 +97,16 @@ ProjectClip::ProjectClip(const QString &id, const QIcon &thumb, const std::share
}
// Make sure we have a hash for this clip
hash();
connect(m_markerModel.get(), &MarkerListModel::modelChanged, [&]() { setProducerProperty(QStringLiteral("kdenlive:markers"), m_markerModel->toJson()); });
connect(m_markerModel.get(), &MarkerListModel::modelChanged, [&]() {
setProducerProperty(QStringLiteral("kdenlive:markers"), m_markerModel->toJson());
});
QString markers = getProducerProperty(QStringLiteral("kdenlive:markers"));
if (!markers.isEmpty()) {
QMetaObject::invokeMethod(m_markerModel.get(), "importFromJson", Qt::QueuedConnection, Q_ARG(const QString &, markers), Q_ARG(bool, true),
Q_ARG(bool, false));
}
setTags(getProducerProperty(QStringLiteral("kdenlive:tags")));
AbstractProjectItem::setRating((uint) getProducerIntProperty(QStringLiteral("kdenlive:rating")));
connectEffectStack();
}
......@@ -209,14 +213,6 @@ ClipType::ProducerType ProjectClip::clipType() const
return m_clipType;
}
const QString ProjectClip::clipTags() const
{
if (!m_masterProducer || !m_masterProducer->is_valid()) {
return QString();
}
return getProducerProperty(QStringLiteral("kdenlive:tags"));
}
bool ProjectClip::hasParent(const QString &id) const
{
std::shared_ptr<AbstractProjectItem> par = parent();
......@@ -431,6 +427,8 @@ bool ProjectClip::setProducer(std::shared_ptr<Mlt::Producer> producer, bool repl
}
m_duration = getStringDuration();
m_clipStatus = StatusReady;
setTags(getProducerProperty(QStringLiteral("kdenlive:tags")));
AbstractProjectItem::setRating((uint) getProducerIntProperty(QStringLiteral("kdenlive:rating")));
if (!hasProxy()) {
if (auto ptr = m_model.lock()) emit std::static_pointer_cast<ProjectItemModel>(ptr)->refreshPanel(m_binId);
}
......@@ -1027,11 +1025,6 @@ void ProjectClip::setProperties(const QMap<QString, QString> &properties, bool r
if (refreshAnalysis) {
emit refreshAnalysisPanel();
}
if (properties.contains(QStringLiteral("kdenlive::tags"))) {
if (auto ptr = m_model.lock())
std::static_pointer_cast<ProjectItemModel>(ptr)->onItemUpdated(std::static_pointer_cast<ProjectClip>(shared_from_this()),
AbstractProjectItem::DataTag);
}
if (properties.contains(QStringLiteral("length")) || properties.contains(QStringLiteral("kdenlive:duration"))) {
m_duration = getStringDuration();
if (auto ptr = m_model.lock())
......@@ -1042,6 +1035,7 @@ void ProjectClip::setProperties(const QMap<QString, QString> &properties, bool r
}
if (properties.contains(QStringLiteral("kdenlive:tags"))) {
setTags(properties.value(QStringLiteral("kdenlive:tags")));
if (auto ptr = m_model.lock()) {
std::static_pointer_cast<ProjectItemModel>(ptr)->onItemUpdated(std::static_pointer_cast<ProjectClip>(shared_from_this()),
AbstractProjectItem::DataTag);
......@@ -1440,6 +1434,12 @@ void ProjectClip::updateZones()
QPoint zone = clip->zone();
currentZone.insert(QLatin1String("in"), QJsonValue(zone.x()));
currentZone.insert(QLatin1String("out"), QJsonValue(zone.y()));
if (clip->rating() > 0) {
currentZone.insert(QLatin1String("rating"), QJsonValue((int)clip->rating()));
}
if (!clip->tags().isEmpty()) {
currentZone.insert(QLatin1String("tags"), QJsonValue(clip->tags()));
}
list.push_back(currentZone);
}
}
......@@ -1465,3 +1465,10 @@ void ProjectClip::getThumbFromPercent(int percent)
}
}
}
void ProjectClip::setRating(uint rating)
{
AbstractProjectItem::setRating(rating);
setProducerProperty(QStringLiteral("kdenlive:rating"), (int) rating);
pCore->currentDoc()->setModified(true);
}
......@@ -98,7 +98,9 @@ public:
/** @brief Returns the clip type as defined in definitions.h */
ClipType::ProducerType clipType() const override;
const QString clipTags() const override;
/** @brief Set rating on item */
void setRating(uint rating) override;
bool selfSoftDelete(Fun &undo, Fun &redo) override;
......
......@@ -175,11 +175,6 @@ ClipType::ProducerType ProjectFolder::clipType() const
return ClipType::Unknown;
}
const QString ProjectFolder::clipTags() const
{
return QString();
}
bool ProjectFolder::hasAudioAndVideo() const
{
return false;
......
......@@ -85,7 +85,6 @@ public:
/** @brief Returns true if folder contains a clip. */
bool hasChildClips() const;
ClipType::ProducerType clipType() const override;
const QString clipTags() const override;
/** @brief Returns true if item has both audio and video enabled. */
bool hasAudioAndVideo() const override;
};
......
......@@ -100,6 +100,9 @@ int ProjectItemModel::mapToColumn(int column) const
case 6:
return AbstractProjectItem::DataId;
break;
case 7:
return AbstractProjectItem::DataRating;
break;
default:
return AbstractProjectItem::DataName;
}
......@@ -168,7 +171,7 @@ Qt::ItemFlags ProjectItemModel::flags(const QModelIndex &index) const
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsEditable;
break;
case AbstractProjectItem::SubClipItem:
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled;
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
break;
default:
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
......@@ -198,7 +201,7 @@ bool ProjectItemModel::dropMimeData(const QMimeData *data, Qt::DropAction action
QStringList clipData = ids.constFirst().split(QLatin1Char('/'));
if (clipData.length() >= 3) {
QString id;
return requestAddBinSubClip(id, clipData.at(1).toInt(), clipData.at(2).toInt(), QString(), clipData.at(0));
return requestAddBinSubClip(id, clipData.at(1).toInt(), clipData.at(2).toInt(), {}, clipData.at(0));
} else {
// error, malformed clip zone, abort
return false;
......@@ -210,7 +213,7 @@ bool ProjectItemModel::dropMimeData(const QMimeData *data, Qt::DropAction action
}
if (data->hasFormat(QStringLiteral("kdenlive/effect"))) {
// Dropping effect on a Bin item
// Dropping effect on a Bin item
QStringList effectData;
effectData << QString::fromUtf8(data->data(QStringLiteral("kdenlive/effect")));
QStringList source = QString::fromUtf8(data->data(QStringLiteral("kdenlive/effectsource"))).split(QLatin1Char('-'));
......@@ -222,13 +225,12 @@ bool ProjectItemModel::dropMimeData(const QMimeData *data, Qt::DropAction action
if (data->hasFormat(QStringLiteral("kdenlive/clip"))) {
const QStringList list = QString(data->data(QStringLiteral("kdenlive/clip"))).split(QLatin1Char(';'));
QString id;
return requestAddBinSubClip(id, list.at(1).toInt(), list.at(2).toInt(), QString(), list.at(0));
return requestAddBinSubClip(id, list.at(1).toInt(), list.at(2).toInt(), {}, list.at(0));
}
if (data->hasFormat(QStringLiteral("kdenlive/tag"))) {
// Dropping effect on a Bin item
QString tag = QString::fromUtf8(data->data(QStringLiteral("kdenlive/tag")));
qDebug()<<"=== GOT CLIP TAG: "<<tag;
emit addTag(tag, parent);
return true;
}
......@@ -263,6 +265,9 @@ QVariant ProjectItemModel::headerData(int section, Qt::Orientation orientation,
case 6:
columnName = i18n("Id");
break;
case 7:
columnName = i18n("Rating");
break;
default:
columnName = i18n("Unknown");
break;
......@@ -525,16 +530,19 @@ void ProjectItemModel::loadSubClips(const QString &id, const QString &dataMap, F
}
int in = entryObj[QLatin1String("in")].toInt();
int out = entryObj[QLatin1String("out")].toInt();
QString name = entryObj[QLatin1String("name")].toString(i18n("Zone"));
QMap <QString, QString> zoneProperties;
zoneProperties.insert(QStringLiteral("name"), entryObj[QLatin1String("name")].toString(i18n("Zone")));
zoneProperties.insert(QStringLiteral("rating"), QString::number(entryObj[QLatin1String("rating")].toInt()));
zoneProperties.insert(QStringLiteral("tags"), entryObj[QLatin1String("tags")].toString(QString()));
if (in >= out) {
qDebug() << "Warning : Invalid zone: "<<name<<", "<<in<<"-"<<out;
qDebug() << "Warning : Invalid zone: "<<zoneProperties.value("name")<<", "<<in<<"-"<<out;
continue;
}
if (maxFrame > 0) {
out = qMin(out, maxFrame);
}
QString subId;
requestAddBinSubClip(subId, in, out, name, id, undo, redo);
requestAddBinSubClip(subId, in, out, zoneProperties, id, undo, redo);
}
}
......@@ -727,7 +735,7 @@ bool ProjectItemModel::requestAddBinClip(QString &id, const std::shared_ptr<Mlt:
return res;
}
bool ProjectItemModel::requestAddBinSubClip(QString &id, int in, int out, const QString &zoneName, const QString &parentId, Fun &undo, Fun &redo)
bool ProjectItemModel::requestAddBinSubClip(QString &id, int in, int out, const QMap<QString, QString> zoneProperties, const QString &parentId, Fun &undo, Fun &redo)
{
QWriteLocker locker(&m_lock);
if (id.isEmpty()) {
......@@ -742,7 +750,7 @@ bool ProjectItemModel::requestAddBinSubClip(QString &id, int in, int out, const
Q_ASSERT(clip->itemType() == AbstractProjectItem::ClipItem);
auto tc = pCore->currentDoc()->timecode().getDisplayTimecodeFromFrames(in, KdenliveSettings::frametimecode());
std::shared_ptr<ProjectSubClip> new_clip =
ProjectSubClip::construct(id, clip, std::static_pointer_cast<ProjectItemModel>(shared_from_this()), in, out, tc, zoneName);
ProjectSubClip::construct(id, clip, std::static_pointer_cast<ProjectItemModel>(shared_from_this()), in, out, tc, zoneProperties);
bool res = addItem(new_clip, subId, undo, redo);
if (res) {
int parentJob = pCore->jobManager()->getBlockingJobId(subId, AbstractClipJob::LOADJOB);
......@@ -750,12 +758,12 @@ bool ProjectItemModel::requestAddBinSubClip(QString &id, int in, int out, const
}
return res;
}
bool ProjectItemModel::requestAddBinSubClip(QString &id, int in, int out, const QString &zoneName, const QString &parentId)
bool ProjectItemModel::requestAddBinSubClip(QString &id, int in, int out, const QMap<QString, QString> zoneProperties, const QString &parentId)
{
QWriteLocker locker(&m_lock);
Fun undo = []() { return true; };
Fun redo = []() { return true; };
bool res = requestAddBinSubClip(id, in, out, zoneName, parentId, undo, redo);
bool res = requestAddBinSubClip(id, in, out, zoneProperties, parentId, undo, redo);
if (res) {
Fun update_doc = [this, parentId]() {
std::shared_ptr<AbstractProjectItem> parentItem = getItemByBinId(parentId);
......
......@@ -170,8 +170,8 @@ public:
@param in,out : zone that corresponds to the subclip
@param undo,redo: lambdas that are updated to accumulate operation.
*/
bool requestAddBinSubClip(QString &id, int in, int out, const QString &zoneName, const QString &parentId, Fun &undo, Fun &redo);
bool requestAddBinSubClip(QString &id, int in, int out, const QString &zoneName, const QString &parentId);
bool requestAddBinSubClip(QString &id, int in, int out, const QMap<QString, QString> zoneProperties, const QString &parentId, Fun &undo, Fun &redo);
bool requestAddBinSubClip(QString &id, int in, int out, const QMap<QString, QString> zoneProperties, const QString &parentId);
/* @brief Request that a folder's name is changed
@param clip : pointer to the folder to rename
......
......@@ -28,8 +28,9 @@ ProjectSortProxyModel::ProjectSortProxyModel(QObject *parent)
: QSortFilterProxyModel(parent)
, m_searchType(0)
{
m_collator.setNumericMode(true);
m_collator.setLocale(QLocale());
m_collator.setCaseSensitivity(Qt::CaseInsensitive);
m_collator.setNumericMode(true);
m_selection = new QItemSelectionModel(this);
connect(m_selection, &QItemSelectionModel::selectionChanged, this, &ProjectSortProxyModel::onCurrentRowChanged);
setDynamicSortFilter(true);
......@@ -52,31 +53,30 @@ bool ProjectSortProxyModel::filterAcceptsRowItself(int sourceRow, const QModelIn
if (!index0.isValid()) {
return false;
}
bool typeAccepted = false;
bool tagAccepted = false;
auto data = sourceModel()->data(index0);
if (m_searchRating > 0) {
// Column 7 contains the rating
QModelIndex indexTag = sourceModel()->index(sourceRow, 7, sourceParent);
if (sourceModel()->data(indexTag).toInt() < m_searchRating) {
return false;
}
}
if (m_searchType > 0) {
// Column 3 contains the item type (video, image, title, etc)
QModelIndex indexTag = sourceModel()->index(sourceRow, 3, sourceParent);
if (sourceModel()->data(indexTag).toInt() == m_searchType) {
typeAccepted = true;
if (sourceModel()->data(indexTag).toInt() != m_searchType) {
return false;
}
} else {
typeAccepted = true;
}
if (!typeAccepted) {
return false;
}
if (!m_searchTag.isEmpty()) {
// Column 4 contains the item tag data
QModelIndex indexTag = sourceModel()->index(sourceRow, 4, sourceParent);
auto tagData = sourceModel()->data(indexTag);
if (tagData.toString().contains(m_searchTag, Qt::CaseInsensitive)) {
tagAccepted = true;
if (!tagData.toString().contains(m_searchTag, Qt::CaseInsensitive)) {
return false;
}
} else {
tagAccepted = true;
}
if (tagAccepted && data.toString().contains(m_searchString, Qt::CaseInsensitive)) {
if (data.toString().contains(m_searchString, Qt::CaseInsensitive)) {
return true;
}
}
......@@ -115,16 +115,8 @@ bool ProjectSortProxyModel::lessThan(const QModelIndex &left, const QModelIndex
int rightType = sourceModel()->data(right, AbstractProjectItem::ItemTypeRole).toInt();
if (leftType == rightType) {
// Let the normal alphabetical sort happen
QVariant leftData;
QVariant rightData;
if (leftType == AbstractProjectItem::SubClipItem) {
// Subclips, sort by start position
leftData = sourceModel()->data(left, AbstractProjectItem::DataInPoint);
rightData = sourceModel()->data(right, AbstractProjectItem::DataInPoint);
} else {
leftData = sourceModel()->data(left, Qt::DisplayRole);
rightData = sourceModel()->data(right, Qt::DisplayRole);
}
const QVariant leftData = sourceModel()->data(left, Qt::DisplayRole);
const QVariant rightData = sourceModel()->data(right, Qt::DisplayRole);
if (leftData.type() == QVariant::DateTime) {
return leftData.toDateTime() < rightData.toDateTime();
}
......@@ -147,20 +139,36 @@ void ProjectSortProxyModel::slotSetSearchString(const QString &str)
invalidateFilter();
}
void ProjectSortProxyModel::slotSetSearchTag(const QString &str, bool reload)
void ProjectSortProxyModel::slotSetSearchRating(const int type)
{
m_searchTag.clear();
m_searchType = 0;
m_searchRating = type;
invalidateFilter();
}
void ProjectSortProxyModel::slotSetSearchTag(const QString &str)
{
m_searchType = 0;
m_searchRating = 0;
m_searchTag = str;
if (reload) {
invalidateFilter();
}
invalidateFilter();
}
void ProjectSortProxyModel::slotSetSearchType(const int type, bool reload)
void ProjectSortProxyModel::slotSetSearchType(const int type)
{
m_searchTag.clear();
m_searchRating = 0;
m_searchType = type;
if (reload) {
invalidateFilter();
}
invalidateFilter();
}
void ProjectSortProxyModel::slotClearSearchType()
{
m_searchTag.clear();
m_searchRating = 0;
m_searchType = 0;
invalidateFilter();
}
void ProjectSortProxyModel::onCurrentRowChanged(const QItemSelection &current, const QItemSelection &previous)
......
......@@ -44,9 +44,13 @@ public slots:
/** @brief Set search string that will filter the view */
void slotSetSearchString(const QString &str);
/** @brief Set search tag that will filter the view */
void slotSetSearchTag(const QString &str, bool reload = true);
void slotSetSearchTag(const QString &str);
/** @brief Set search rating that will filter the view */
void slotSetSearchRating(const int type);
/** @brief Set search type that will filter the view */
void slotSetSearchType(const int type, bool reload = true);
void slotSetSearchType(const int type);
/** @brief Reset search filters */
void slotClearSearchType();
/** @brief Relay datachanged signal from view's model */
void slotDataChanged(const QModelIndex &ix1, const QModelIndex &ix2, const QVector<int> &roles);
......@@ -68,11 +72,14 @@ private:
QString m_searchString;
QString m_searchTag;
int m_searchType;
int m_searchRating;
QCollator m_collator;
signals:
/** @brief Emitted when the row changes, used to prepare action for selected item */
void selectModel(const QModelIndex &);
/** @brief Set item rating */
void updateRating(const QModelIndex &index, uint rating);
};
#endif
......@@ -38,7 +38,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
class ClipController;
ProjectSubClip::ProjectSubClip(const QString &id, const std::shared_ptr<ProjectClip> &parent, const std::shared_ptr<ProjectItemModel> &model, int in, int out,
const QString &timecode, const QString &name)
const QString &timecode, const QMap<QString, QString> zoneProperties)
: AbstractProjectItem(AbstractProjectItem::SubClipItem, id, model)
, m_masterClip(parent)
{
......@@ -50,11 +50,13 @@ ProjectSubClip::ProjectSubClip(const QString &id, const std::shared_ptr<ProjectC
QPixmap pix(64, 36);
pix.fill(Qt::lightGray);
m_thumbnail = QIcon(pix);
if (name.isEmpty()) {
m_name = zoneProperties.value(QLatin1String("name"));
if (m_name.isEmpty()) {
m_name = i18n("Zone %1", parent->childCount() + 1);
} else {
m_name = name;
}
m_rating = zoneProperties.value(QLatin1String("rating")).toUInt();
m_tags = zoneProperties.value(QLatin1String("tags"));
qDebug()<<"=== LOADING SUBCLIP WITH RATING: "<<m_rating<<", TAGS: "<<m_tags;
m_clipStatus = StatusReady;
// Save subclip in MLT
connect(parent.get(), &ProjectClip::thumbReady, this, &ProjectSubClip::gotThumb);
......@@ -62,9 +64,9 @@ ProjectSubClip::ProjectSubClip(const QString &id, const std::shared_ptr<ProjectC
std::shared_ptr<ProjectSubClip> ProjectSubClip::construct(const QString &id, const std::shared_ptr<ProjectClip> &parent,
const std::shared_ptr<ProjectItemModel> &model, int in, int out, const QString &timecode,
const QString &name)
const QMap<QString, QString> zoneProperties)
{
std::shared_ptr<ProjectSubClip> self(new ProjectSubClip(id, parent, model, in, out, timecode, name));
std::shared_ptr<ProjectSubClip> self(new ProjectSubClip(id, parent, model, in, out, timecode, zoneProperties));
baseFinishConstruct(self);
return self;
}
......@@ -182,11 +184,6 @@ ClipType::ProducerType ProjectSubClip::clipType() const
return m_masterClip->clipType();
}
const QString ProjectSubClip::clipTags() const
{
return QString();
}
bool ProjectSubClip::hasAudioAndVideo() const
{
return m_masterClip->hasAudioAndVideo();
......@@ -208,3 +205,36 @@ void ProjectSubClip::getThumbFromPercent(int percent)
}
}
}
void ProjectSubClip::setProperties(const QMap<QString, QString> &properties)
{
bool propertyFound = false;
if (properties.contains(QStringLiteral("kdenlive:tags"))) {
propertyFound = true;
m_tags = properties.value(QStringLiteral("kdenlive:tags"));
}
if (properties.contains(QStringLiteral("kdenlive:rating"))) {
propertyFound = true;
m_rating = properties.value(QStringLiteral("kdenlive:rating")).toUInt();
}
if (auto ptr = m_model.lock()) {
std::shared_ptr<AbstractProjectItem> parentItem = std::static_pointer_cast<ProjectItemModel>(ptr)->getItemByBinId(m_parentClipId);
if (parentItem && parentItem->itemType() == AbstractProjectItem::ClipItem) {
auto clipItem = std::static_pointer_cast<ProjectClip>(parentItem);
clipItem->updateZones();
}
}
}
void ProjectSubClip::setRating(uint rating)
{
AbstractProjectItem::setRating(rating);
if (auto ptr = m_model.lock()) {
std::shared_ptr<AbstractProjectItem> parentItem = std::static_pointer_cast<ProjectItemModel>(ptr)->getItemByBinId(m_parentClipId);
if (parentItem && parentItem->itemType() == AbstractProjectItem::ClipItem) {
auto clipItem = std::static_pointer_cast<ProjectClip>(parentItem);
clipItem->updateZones();
}
}
pCore->currentDoc()->setModified(true);
}
......@@ -50,11 +50,11 @@ public:
*/
static std::shared_ptr<ProjectSubClip> construct(const QString &id, const std::shared_ptr<ProjectClip> &parent,
const std::shared_ptr<ProjectItemModel> &model, int in, int out, const QString &timecode,
const QString &name = QString());
const QMap<QString, QString> zoneProperties);
protected:
ProjectSubClip(const QString &id, const std::shared_ptr<ProjectClip> &parent, const std::shared_ptr<ProjectItemModel> &model, int in, int out,
const QString &timecode, const QString &name = QString());
const QString &timecode, const QMap<QString, QString> zoneProperties);
public:
~ProjectSubClip() override;
......@@ -84,8 +84,15 @@ public:
/** @brief returns a pointer to the parent clip */
std::shared_ptr<ProjectClip> getMasterClip() const;
/** @brief Returns the clip type as defined in definitions.h */
ClipType::ProducerType clipType() const override;
const QString clipTags() const override;
/** @brief Set properties on this clip zone */
void setProperties(const QMap<QString, QString> &properties);
/** @brief Set rating on item */