Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Multimedia
Kdenlive
Commits
eb8580c2
Commit
eb8580c2
authored
Dec 30, 2019
by
Jean-Baptiste Mardelle
Browse files
* 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
Changes
16
Pipelines
1
Expand all
Hide whitespace changes
Inline
Side-by-side
src/bin/abstractprojectitem.cpp
View file @
eb8580c2
...
...
@@ -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
;
}
src/bin/abstractprojectitem.h
View file @
eb8580c2
...
...
@@ -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
;
...
...
src/bin/bin.cpp
View file @
eb8580c2
This diff is collapsed.
Click to expand it.
src/bin/bin.h
View file @
eb8580c2
...
...
@@ -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:
...
...
src/bin/projectclip.cpp
View file @
eb8580c2
...
...
@@ -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
);
}
src/bin/projectclip.h
View file @
eb8580c2
...
...
@@ -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
;
...
...
src/bin/projectfolder.cpp
View file @
eb8580c2
...
...
@@ -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
;
...
...
src/bin/projectfolder.h
View file @
eb8580c2
...
...
@@ -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
;
};
...
...
src/bin/projectitemmodel.cpp
View file @
eb8580c2
...
...
@@ -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
,
zone
Name
);
ProjectSubClip
::
construct
(
id
,
clip
,
std
::
static_pointer_cast
<
ProjectItemModel
>
(
shared_from_this
()),
in
,
out
,
tc
,
zone
Properties
);
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
,
zone
Name
,
parentId
,
undo
,
redo
);
bool
res
=
requestAddBinSubClip
(
id
,
in
,
out
,
zone
Properties
,
parentId
,
undo
,
redo
);
if
(
res
)
{
Fun
update_doc
=
[
this
,
parentId
]()
{
std
::
shared_ptr
<
AbstractProjectItem
>
parentItem
=
getItemByBinId
(
parentId
);
...
...
src/bin/projectitemmodel.h
View file @
eb8580c2
...
...
@@ -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
...
...
src/bin/projectsortproxymodel.cpp
View file @
eb8580c2
...
...
@@ -28,8 +28,9 @@ ProjectSortProxyModel::ProjectSortProxyModel(QObject *parent)
:
QSortFilterProxyModel
(
parent
)
,
m_searchType
(
0
)
{
m_collator
.
set
NumericMode
(
true
);
m_collator
.
set
Locale
(
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
=
tru
e
;
if
(
sourceModel
()
->
data
(
indexTag
).
toInt
()
!
=
m_searchType
)
{
return
fals
e
;
}
}
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
=
tru
e
;
if
(
!
tagData
.
toString
().
contains
(
m_searchTag
,
Qt
::
CaseInsensitive
))
{
return
fals
e
;
}
}
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
::
slotSetSearch
Ta
g
(
const
QString
&
str
,
bool
reload
)
void
ProjectSortProxyModel
::
slotSetSearch
Ratin
g
(
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
)
...
...
src/bin/projectsortproxymodel.h
View file @
eb8580c2
...
...
@@ -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
src/bin/projectsubclip.cpp
View file @
eb8580c2
...
...
@@ -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
);
}