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
66216267
Commit
66216267
authored
Nov 03, 2022
by
Jean-Baptiste Mardelle
Browse files
Fix marker import, add button for default marker type
parent
cd54269b
Pipeline
#260478
failed with stage
in 12 minutes and 49 seconds
Changes
6
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
src/bin/model/markerlistmodel.cpp
View file @
66216267
...
...
@@ -626,16 +626,26 @@ void MarkerListModel::registerSnapModel(const std::weak_ptr<SnapInterface> &snap
}
}
bool
MarkerListModel
::
importFromFile
(
const
QString
&
fileData
,
bool
ignoreConflicts
)
{
Fun
undo
=
[]()
{
return
true
;
};
Fun
redo
=
[]()
{
return
true
;
};
bool
res
=
importFromJson
(
fileData
,
ignoreConflicts
,
undo
,
redo
);
if
(
!
res
)
{
res
=
importFromTxt
(
fileData
,
undo
,
redo
);
}
if
(
res
)
{
PUSH_UNDO
(
undo
,
redo
,
m_guide
?
i18n
(
"Import guides"
)
:
i18n
(
"Import markers"
));
}
return
res
;
}
bool
MarkerListModel
::
importFromJson
(
const
QString
&
data
,
bool
ignoreConflicts
,
bool
pushUndo
)
{
Fun
undo
=
[]()
{
return
true
;
};
Fun
redo
=
[]()
{
return
true
;
};
bool
result
=
importFromJson
(
data
,
ignoreConflicts
,
undo
,
redo
);
/*if (!result) {
// Import failed, try to import as txt data
result = importFromTxt(data, ignoreConflicts, undo, redo);
}*/
if
(
pushUndo
)
{
if
(
result
&&
pushUndo
)
{
PUSH_UNDO
(
undo
,
redo
,
m_guide
?
i18n
(
"Import guides"
)
:
i18n
(
"Import markers"
));
}
return
result
;
...
...
@@ -684,67 +694,61 @@ bool MarkerListModel::importFromJson(const QString &data, bool ignoreConflicts,
return
true
;
}
bool
MarkerListModel
::
importFromTxt
(
const
QString
&
file
Name
,
Fun
&
undo
,
Fun
&
redo
)
bool
MarkerListModel
::
importFromTxt
(
const
QString
&
file
Data
,
Fun
&
undo
,
Fun
&
redo
)
{
QWriteLocker
locker
(
&
m_lock
);
QFile
inputFile
(
fileName
);
bool
res
=
true
;
bool
res
=
false
;
bool
lineRead
=
false
;
// TODO: ask for a category
int
type
=
0
;
if
(
inputFile
.
open
(
QIODevice
::
ReadOnly
))
{
QTextStream
in
(
&
inputFile
);
while
(
!
in
.
atEnd
())
{
QString
line
=
in
.
readLine
().
simplified
();
if
(
line
.
isEmpty
())
{
continue
;
}
QString
pos
=
line
.
section
(
QLatin1Char
(
' '
),
0
,
0
);
GenTime
position
;
// Try to read timecode
bool
ok
=
false
;
int
separatorsCount
=
pos
.
count
(
QLatin1Char
(
':'
));
switch
(
separatorsCount
)
{
case
0
:
// assume we are dealing with seconds
position
=
GenTime
(
pos
.
toDouble
(
&
ok
));
break
;
case
1
:
{
// assume min:sec
QString
sec
=
pos
.
section
(
QLatin1Char
(
':'
),
1
);
QString
min
=
pos
.
section
(
QLatin1Char
(
':'
),
0
,
0
);
double
seconds
=
sec
.
toDouble
(
&
ok
);
int
minutes
=
ok
?
min
.
toInt
(
&
ok
)
:
0
;
position
=
GenTime
(
seconds
+
60
*
minutes
);
break
;
}
case
2
:
default:
{
// assume hh:min:sec
QString
sec
=
pos
.
section
(
QLatin1Char
(
':'
),
2
);
QString
min
=
pos
.
section
(
QLatin1Char
(
':'
),
1
,
1
);
QString
hours
=
pos
.
section
(
QLatin1Char
(
':'
),
0
,
0
);
double
seconds
=
sec
.
toDouble
(
&
ok
);
int
minutes
=
ok
?
min
.
toInt
(
&
ok
)
:
0
;
int
h
=
ok
?
hours
.
toInt
(
&
ok
)
:
0
;
position
=
GenTime
(
seconds
+
(
60
*
minutes
)
+
(
3600
*
h
));
break
;
}
}
if
(
!
ok
)
{
// Could not read timecode
qDebug
()
<<
"::: Could not read timecode from line: "
<<
line
;
continue
;
}
QString
comment
=
line
.
section
(
QLatin1Char
(
' '
),
1
);
bool
res
=
addMarker
(
position
,
comment
,
type
,
undo
,
redo
);
if
(
!
res
)
{
break
;
}
else
if
(
!
lineRead
)
{
lineRead
=
true
;
}
int
type
=
KdenliveSettings
::
default_marker_type
();
const
QStringList
lines
=
fileData
.
split
(
QLatin1Char
(
'\n'
));
for
(
auto
&
line
:
lines
)
{
if
(
line
.
isEmpty
())
{
continue
;
}
QString
pos
=
line
.
section
(
QLatin1Char
(
' '
),
0
,
0
);
GenTime
position
;
// Try to read timecode
bool
ok
=
false
;
int
separatorsCount
=
pos
.
count
(
QLatin1Char
(
':'
));
switch
(
separatorsCount
)
{
case
0
:
// assume we are dealing with seconds
position
=
GenTime
(
pos
.
toDouble
(
&
ok
));
break
;
case
1
:
{
// assume min:sec
QString
sec
=
pos
.
section
(
QLatin1Char
(
':'
),
1
);
QString
min
=
pos
.
section
(
QLatin1Char
(
':'
),
0
,
0
);
double
seconds
=
sec
.
toDouble
(
&
ok
);
int
minutes
=
ok
?
min
.
toInt
(
&
ok
)
:
0
;
position
=
GenTime
(
seconds
+
60
*
minutes
);
break
;
}
case
2
:
default:
{
// assume hh:min:sec
QString
sec
=
pos
.
section
(
QLatin1Char
(
':'
),
2
);
QString
min
=
pos
.
section
(
QLatin1Char
(
':'
),
1
,
1
);
QString
hours
=
pos
.
section
(
QLatin1Char
(
':'
),
0
,
0
);
double
seconds
=
sec
.
toDouble
(
&
ok
);
int
minutes
=
ok
?
min
.
toInt
(
&
ok
)
:
0
;
int
h
=
ok
?
hours
.
toInt
(
&
ok
)
:
0
;
position
=
GenTime
(
seconds
+
(
60
*
minutes
)
+
(
3600
*
h
));
break
;
}
}
if
(
!
ok
)
{
// Could not read timecode
qDebug
()
<<
"::: Could not read timecode from line: "
<<
line
;
continue
;
}
QString
comment
=
line
.
section
(
QLatin1Char
(
' '
),
1
);
res
=
addMarker
(
position
,
comment
,
type
,
undo
,
redo
);
if
(
!
res
)
{
break
;
}
else
if
(
!
lineRead
)
{
lineRead
=
true
;
}
inputFile
.
close
();
}
return
res
&&
lineRead
;
}
...
...
@@ -843,6 +847,7 @@ bool MarkerListModel::editMarkerGui(const GenTime &pos, QWidget *parent, bool cr
if
(
dialog
->
exec
()
==
QDialog
::
Accepted
)
{
marker
=
dialog
->
newMarker
();
emit
pCore
->
updateDefaultMarkerCategory
();
if
(
exists
&&
!
createOnly
)
{
return
editMarker
(
pos
,
marker
.
time
(),
marker
.
comment
(),
marker
.
markerType
());
}
...
...
@@ -869,6 +874,7 @@ bool MarkerListModel::addMultipleMarkersGui(const GenTime &pos, QWidget *parent,
GenTime
interval
=
dialog
->
getInterval
();
KdenliveSettings
::
setMultipleguidesinterval
(
interval
.
seconds
());
marker
=
dialog
->
newMarker
();
emit
pCore
->
updateDefaultMarkerCategory
();
GenTime
startTime
=
marker
.
time
();
QWriteLocker
locker
(
&
m_lock
);
Fun
undo
=
[]()
{
return
true
;
};
...
...
src/bin/model/markerlistmodel.hpp
View file @
66216267
...
...
@@ -176,6 +176,7 @@ public slots:
bool
importFromJson
(
const
QString
&
data
,
bool
ignoreConflicts
,
bool
pushUndo
=
true
);
bool
importFromJson
(
const
QString
&
data
,
bool
ignoreConflicts
,
Fun
&
undo
,
Fun
&
redo
);
bool
importFromTxt
(
const
QString
&
fileName
,
Fun
&
undo
,
Fun
&
redo
);
bool
importFromFile
(
const
QString
&
fileData
,
bool
ignoreConflicts
);
protected:
/** @brief Adds a snap point at marker position in the registered snap models
...
...
src/core.h
View file @
66216267
...
...
@@ -409,4 +409,6 @@ signals:
void
updateProjectTimecode
();
/** @brief Visible guide categories changed, reload snaps in timeline */
void
refreshActiveGuides
();
/** @brief The default marker category was changed, update guides list button */
void
updateDefaultMarkerCategory
();
};
src/project/dialogs/guideslist.cpp
View file @
66216267
...
...
@@ -11,13 +11,17 @@ SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
#include
"core.h"
#include
"doc/kdenlivedoc.h"
#include
"kdenlive_debug.h"
#include
"kdenlivesettings.h"
#include
"mainwindow.h"
#include
"project/projectmanager.h"
#include
<KLocalizedString>
#include
<KMessageBox>
#include
<QButtonGroup>
#include
<QCheckBox>
#include
<QDialog>
#include
<QFileDialog>
#include
<QFontDatabase>
#include
<QMenu>
#include
<QPainter>
...
...
@@ -54,11 +58,12 @@ GuidesList::GuidesList(QWidget *parent)
connect
(
guide_add
,
&
QToolButton
::
clicked
,
this
,
&
GuidesList
::
addGuide
);
connect
(
guide_edit
,
&
QToolButton
::
clicked
,
this
,
&
GuidesList
::
editGuides
);
connect
(
filter_line
,
&
QLineEdit
::
textChanged
,
this
,
&
GuidesList
::
filterView
);
connect
(
pCore
.
get
(),
&
Core
::
updateDefaultMarkerCategory
,
this
,
&
GuidesList
::
refreshDefaultCategory
);
// Settings menu
QMenu
*
settingsMenu
=
new
QMenu
(
this
);
QAction
*
importGuides
=
new
QAction
(
QIcon
::
fromTheme
(
QStringLiteral
(
"document-import"
)),
i18n
(
"Import..."
),
this
);
connect
(
importGuides
,
&
QAction
::
triggered
,
this
,
&
GuidesList
::
configure
Guides
);
connect
(
importGuides
,
&
QAction
::
triggered
,
this
,
&
GuidesList
::
import
Guides
);
settingsMenu
->
addAction
(
importGuides
);
QAction
*
exportGuides
=
new
QAction
(
QIcon
::
fromTheme
(
QStringLiteral
(
"document-export"
)),
i18n
(
"Export..."
),
this
);
connect
(
exportGuides
,
&
QAction
::
triggered
,
this
,
&
GuidesList
::
saveGuides
);
...
...
@@ -105,6 +110,8 @@ GuidesList::GuidesList(QWidget *parent)
show_categories
->
setToolTip
(
i18n
(
"Filter guide categories."
));
show_categories
->
setWhatsThis
(
xi18nc
(
"@info:whatsthis"
,
"Filter guide categories. This allows you to show or hide selected guide categories in this dialog and in the timeline."
));
default_category
->
setToolTip
(
i18n
(
"Default guide category."
));
default_category
->
setWhatsThis
(
xi18nc
(
"@info:whatsthis"
,
"Default guide category. The category used for newly created markers."
));
}
void
GuidesList
::
configureGuides
()
...
...
@@ -112,6 +119,40 @@ void GuidesList::configureGuides()
pCore
->
window
()
->
slotEditProjectSettings
(
2
);
}
void
GuidesList
::
importGuides
()
{
if
(
auto
markerModel
=
m_model
.
lock
())
{
QScopedPointer
<
QFileDialog
>
fd
(
new
QFileDialog
(
this
,
i18nc
(
"@title:window"
,
"Load Clip Markers"
),
pCore
->
projectManager
()
->
current
()
->
projectDataFolder
()));
fd
->
setMimeTypeFilters
({
QStringLiteral
(
"application/json"
),
QStringLiteral
(
"text/plain"
)});
fd
->
setFileMode
(
QFileDialog
::
ExistingFile
);
if
(
fd
->
exec
()
!=
QDialog
::
Accepted
)
{
return
;
}
QStringList
selection
=
fd
->
selectedFiles
();
QString
url
;
if
(
!
selection
.
isEmpty
())
{
url
=
selection
.
first
();
}
if
(
url
.
isEmpty
())
{
return
;
}
QFile
file
(
url
);
if
(
file
.
size
()
>
1048576
&&
KMessageBox
::
warningContinueCancel
(
this
,
i18n
(
"Marker file is larger than 1MB, are you sure you want to import ?"
))
!=
KMessageBox
::
Continue
)
{
// If marker file is larger than 1MB, ask for confirmation
return
;
}
if
(
!
file
.
open
(
QIODevice
::
ReadOnly
|
QIODevice
::
Text
))
{
KMessageBox
::
error
(
this
,
i18n
(
"Cannot read file %1"
,
QUrl
::
fromLocalFile
(
url
).
fileName
()));
return
;
}
QString
fileContent
=
QString
::
fromUtf8
(
file
.
readAll
());
file
.
close
();
markerModel
->
importFromFile
(
fileContent
,
true
);
}
}
void
GuidesList
::
saveGuides
()
{
if
(
auto
markerModel
=
m_model
.
lock
())
{
...
...
@@ -251,6 +292,20 @@ void GuidesList::rebuildCategories()
catGroup
=
new
QButtonGroup
(
this
);
catGroup
->
setExclusive
(
false
);
QPixmap
pixmap
(
32
,
32
);
// Cleanup default marker category menu
QMenu
*
markerDefaultMenu
=
default_category
->
menu
();
if
(
markerDefaultMenu
)
{
markerDefaultMenu
->
clear
();
}
else
{
markerDefaultMenu
=
new
QMenu
(
this
);
connect
(
markerDefaultMenu
,
&
QMenu
::
triggered
,
this
,
[
this
](
QAction
*
ac
)
{
int
val
=
ac
->
data
().
toInt
();
KdenliveSettings
::
setDefault_marker_type
(
val
);
default_category
->
setIcon
(
ac
->
icon
());
});
default_category
->
setMenu
(
markerDefaultMenu
);
}
QMapIterator
<
int
,
Core
::
MarkerCategory
>
i
(
pCore
->
markerTypes
);
while
(
i
.
hasNext
())
{
i
.
next
();
...
...
@@ -259,12 +314,33 @@ void GuidesList::rebuildCategories()
QCheckBox
*
cb
=
new
QCheckBox
(
i
.
value
().
displayName
,
this
);
cb
->
setProperty
(
"index"
,
i
.
key
());
cb
->
setIcon
(
colorIcon
);
QAction
*
ac
=
new
QAction
(
colorIcon
,
i
.
value
().
displayName
);
ac
->
setData
(
i
.
key
());
markerDefaultMenu
->
addAction
(
ac
);
if
(
i
.
key
()
==
KdenliveSettings
::
default_marker_type
())
{
default_category
->
setIcon
(
colorIcon
);
}
catGroup
->
addButton
(
cb
);
m_categoriesLayout
.
addWidget
(
cb
);
}
connect
(
catGroup
,
&
QButtonGroup
::
buttonToggled
,
this
,
&
GuidesList
::
updateFilter
);
}
void
GuidesList
::
refreshDefaultCategory
()
{
int
ix
=
KdenliveSettings
::
default_marker_type
();
QMenu
*
menu
=
default_category
->
menu
();
if
(
menu
)
{
QList
<
QAction
*>
actions
=
menu
->
actions
();
for
(
auto
*
ac
:
actions
)
{
if
(
ac
->
data
()
==
ix
)
{
default_category
->
setIcon
(
ac
->
icon
());
break
;
}
}
}
}
void
GuidesList
::
updateFilter
(
QAbstractButton
*
,
bool
)
{
QList
<
int
>
filters
;
...
...
src/project/dialogs/guideslist.h
View file @
66216267
...
...
@@ -32,6 +32,7 @@ public:
private
slots
:
void
saveGuides
();
void
editGuides
();
void
importGuides
();
void
editGuide
(
const
QModelIndex
&
ix
);
void
selectionChanged
(
const
QItemSelection
&
selected
,
const
QItemSelection
&
);
void
removeGuide
();
...
...
@@ -42,6 +43,7 @@ private slots:
void
filterView
(
const
QString
&
text
);
void
sortView
(
QAction
*
ac
);
void
changeSortOrder
(
bool
descending
);
void
refreshDefaultCategory
();
private:
/** @brief Set the marker model that will be displayed. */
...
...
src/ui/guideslist_ui.ui
View file @
66216267
...
...
@@ -73,7 +73,8 @@
<string>
...
</string>
</property>
<property
name=
"icon"
>
<iconset
theme=
"document-edit"
/>
<iconset
theme=
"document-edit"
>
<normaloff>
.
</normaloff>
.
</iconset>
</property>
<property
name=
"autoRaise"
>
<bool>
true
</bool>
...
...
@@ -94,6 +95,19 @@
</property>
</widget>
</item>
<item>
<widget
class=
"QToolButton"
name=
"default_category"
>
<property
name=
"text"
>
<string>
...
</string>
</property>
<property
name=
"popupMode"
>
<enum>
QToolButton::InstantPopup
</enum>
</property>
<property
name=
"autoRaise"
>
<bool>
true
</bool>
</property>
</widget>
</item>
<item>
<spacer
name=
"horizontalSpacer"
>
<property
name=
"orientation"
>
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment