Skip to content
GitLab
Menu
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
e20a4a4a
Commit
e20a4a4a
authored
Mar 19, 2021
by
Jean-Baptiste Mardelle
Browse files
Workaround app translation mess, small fixes for locale matching
CCBUG: 434179
parent
46a5ae7d
Changes
10
Hide whitespace changes
Inline
Side-by-side
src/bin/projectitemmodel.cpp
View file @
e20a4a4a
...
...
@@ -54,7 +54,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
ProjectItemModel
::
ProjectItemModel
(
QObject
*
parent
)
:
AbstractTreeModel
(
parent
)
,
m_lock
(
QReadWriteLock
::
Recursive
)
,
m_binPlaylist
(
n
ew
BinPlaylist
()
)
,
m_binPlaylist
(
n
ullptr
)
,
m_fileWatcher
(
new
FileWatcher
())
,
m_nextId
(
1
)
,
m_blankThumb
()
...
...
@@ -77,6 +77,11 @@ std::shared_ptr<ProjectItemModel> ProjectItemModel::construct(QObject *parent)
ProjectItemModel
::~
ProjectItemModel
()
=
default
;
void
ProjectItemModel
::
buildPlaylist
()
{
m_binPlaylist
.
reset
(
new
BinPlaylist
());
}
int
ProjectItemModel
::
mapToColumn
(
int
column
)
const
{
switch
(
column
)
{
...
...
src/bin/projectitemmodel.h
View file @
e20a4a4a
...
...
@@ -64,6 +64,9 @@ public:
~
ProjectItemModel
()
override
;
friend
class
ProjectClip
;
/** @brief Builds the MLT playlist, can only be done after MLT is correctly initialized */
void
buildPlaylist
();
/** @brief Returns a clip from the hierarchy, given its id */
std
::
shared_ptr
<
ProjectClip
>
getClipByBinID
(
const
QString
&
binId
);
...
...
src/core.cpp
View file @
e20a4a4a
...
...
@@ -71,7 +71,7 @@ Core::~Core()
ClipController
::
mediaUnavailable
.
reset
();
}
bool
Core
::
build
(
bool
isAppImage
,
const
QString
&
MltPath
)
bool
Core
::
build
()
{
if
(
m_self
)
{
return
true
;
...
...
@@ -105,43 +105,16 @@ bool Core::build(bool isAppImage, const QString &MltPath)
lockFile
.
close
();
}
if
(
isAppImage
)
{
QString
appPath
=
qApp
->
applicationDirPath
();
KdenliveSettings
::
setFfmpegpath
(
QDir
::
cleanPath
(
appPath
+
QStringLiteral
(
"/ffmpeg"
)));
KdenliveSettings
::
setFfplaypath
(
QDir
::
cleanPath
(
appPath
+
QStringLiteral
(
"/ffplay"
)));
KdenliveSettings
::
setFfprobepath
(
QDir
::
cleanPath
(
appPath
+
QStringLiteral
(
"/ffprobe"
)));
KdenliveSettings
::
setRendererpath
(
QDir
::
cleanPath
(
appPath
+
QStringLiteral
(
"/melt"
)));
MltConnection
::
construct
(
QDir
::
cleanPath
(
appPath
+
QStringLiteral
(
"/../share/mlt/profiles"
)));
}
else
{
// Open connection with Mlt
MltConnection
::
construct
(
MltPath
);
}
// load the profile from disk
ProfileRepository
::
get
()
->
refresh
();
// load default profile
m_self
->
m_profile
=
KdenliveSettings
::
default_profile
();
if
(
m_self
->
m_profile
.
isEmpty
())
{
m_self
->
m_profile
=
ProjectManager
::
getDefaultProjectFormat
();
KdenliveSettings
::
setDefault_profile
(
m_self
->
m_profile
);
}
// Init producer shown for unavailable media
// TODO make it a more proper image, it currently causes a crash on exit
ClipController
::
mediaUnavailable
=
std
::
make_shared
<
Mlt
::
Producer
>
(
ProfileRepository
::
get
()
->
getProfile
(
m_self
->
m_profile
)
->
profile
(),
"color:blue"
);
ClipController
::
mediaUnavailable
->
set
(
"length"
,
99999999
);
m_self
->
m_projectItemModel
=
ProjectItemModel
::
construct
();
// Job manager must be created before bin to correctly connect
m_self
->
m_jobManager
.
reset
(
new
JobManager
(
m_self
.
get
()));
return
true
;
}
void
Core
::
initGUI
(
const
QUrl
&
Url
,
const
QString
&
clipsToLoad
)
void
Core
::
initGUI
(
bool
isAppImage
,
const
QString
&
MltPath
,
const
QUrl
&
Url
,
const
QString
&
clipsToLoad
)
{
m_profile
=
KdenliveSettings
::
default_profile
();
m_currentProfile
=
m_profile
;
profileChanged
();
m_mainWindow
=
new
MainWindow
();
m_guiConstructed
=
true
;
QStringList
styles
=
QQuickStyle
::
availableStyles
();
...
...
@@ -152,13 +125,54 @@ void Core::initGUI(const QUrl &Url, const QString &clipsToLoad)
}
connect
(
this
,
&
Core
::
showConfigDialog
,
m_mainWindow
,
&
MainWindow
::
slotPreferences
);
m_projectManager
=
new
ProjectManager
(
this
);
m_binWidget
=
new
Bin
(
m_projectItemModel
,
m_mainWindow
);
m_library
=
new
LibraryWidget
(
m_projectManager
,
m_mainWindow
);
m_subtitleWidget
=
new
SubtitleEdit
(
m_mainWindow
);
m_mixerWidget
=
new
MixerManager
(
m_mainWindow
);
m_textEditWidget
=
new
TextBasedEdit
(
m_mainWindow
);
connect
(
m_library
,
SIGNAL
(
addProjectClips
(
QList
<
QUrl
>
)),
m_binWidget
,
SLOT
(
droppedUrls
(
QList
<
QUrl
>
)));
connect
(
this
,
&
Core
::
updateLibraryPath
,
m_library
,
&
LibraryWidget
::
slotUpdateLibraryPath
);
connect
(
m_capture
.
get
(),
&
MediaCapture
::
recordStateChanged
,
m_mixerWidget
,
&
MixerManager
::
recordStateChanged
);
connect
(
m_mixerWidget
,
&
MixerManager
::
updateRecVolume
,
m_capture
.
get
(),
&
MediaCapture
::
setAudioVolume
);
m_monitorManager
=
new
MonitorManager
(
this
);
connect
(
m_monitorManager
,
&
MonitorManager
::
cleanMixer
,
m_mixerWidget
,
&
MixerManager
::
clearMixers
);
connect
(
m_subtitleWidget
,
&
SubtitleEdit
::
addSubtitle
,
[
this
]()
{
if
(
m_guiConstructed
&&
m_mainWindow
->
getCurrentTimeline
()
->
controller
())
{
m_mainWindow
->
getCurrentTimeline
()
->
controller
()
->
addSubtitle
();
}
});
connect
(
m_subtitleWidget
,
&
SubtitleEdit
::
cutSubtitle
,
[
this
](
int
id
,
int
cursorPos
)
{
if
(
m_guiConstructed
&&
m_mainWindow
->
getCurrentTimeline
()
->
controller
())
{
m_mainWindow
->
getCurrentTimeline
()
->
controller
()
->
cutSubtitle
(
id
,
cursorPos
);
}
});
// The MLT Factory will be initiated there, all MLT classes will be usable only after this
if
(
isAppImage
)
{
QString
appPath
=
qApp
->
applicationDirPath
();
KdenliveSettings
::
setFfmpegpath
(
QDir
::
cleanPath
(
appPath
+
QStringLiteral
(
"/ffmpeg"
)));
KdenliveSettings
::
setFfplaypath
(
QDir
::
cleanPath
(
appPath
+
QStringLiteral
(
"/ffplay"
)));
KdenliveSettings
::
setFfprobepath
(
QDir
::
cleanPath
(
appPath
+
QStringLiteral
(
"/ffprobe"
)));
KdenliveSettings
::
setRendererpath
(
QDir
::
cleanPath
(
appPath
+
QStringLiteral
(
"/melt"
)));
m_mainWindow
->
init
(
QDir
::
cleanPath
(
appPath
+
QStringLiteral
(
"/../share/mlt/profiles"
)));
}
else
{
// Open connection with Mlt
m_mainWindow
->
init
(
MltPath
);
}
m_projectItemModel
->
buildPlaylist
();
// load the profiles from disk
ProfileRepository
::
get
()
->
refresh
();
// load default profile
m_profile
=
KdenliveSettings
::
default_profile
();
// load default profile and ask user to select one if not found.
if
(
m_profile
.
isEmpty
())
{
m_profile
=
ProjectManager
::
getDefaultProjectFormat
();
profileChanged
();
KdenliveSettings
::
setDefault_profile
(
m_profile
);
}
profileChanged
();
if
(
!
ProfileRepository
::
get
()
->
profileExists
(
m_profile
))
{
KMessageBox
::
sorry
(
m_mainWindow
,
i18n
(
"The default profile of Kdenlive is not set or invalid, press OK to set it to a correct value."
));
...
...
@@ -192,45 +206,11 @@ void Core::initGUI(const QUrl &Url, const QString &clipsToLoad)
KdenliveSettings
::
setDefault_profile
(
m_profile
);
profileChanged
();
}
// Init producer shown for unavailable media
// TODO make it a more proper image, it currently causes a crash on exit
ClipController
::
mediaUnavailable
=
std
::
make_shared
<
Mlt
::
Producer
>
(
ProfileRepository
::
get
()
->
getProfile
(
m_self
->
m_profile
)
->
profile
(),
"color:blue"
);
ClipController
::
mediaUnavailable
->
set
(
"length"
,
99999999
);
m_projectManager
=
new
ProjectManager
(
this
);
m_binWidget
=
new
Bin
(
m_projectItemModel
,
m_mainWindow
);
m_library
=
new
LibraryWidget
(
m_projectManager
,
m_mainWindow
);
m_subtitleWidget
=
new
SubtitleEdit
(
m_mainWindow
);
m_mixerWidget
=
new
MixerManager
(
m_mainWindow
);
m_textEditWidget
=
new
TextBasedEdit
(
m_mainWindow
);
connect
(
m_library
,
SIGNAL
(
addProjectClips
(
QList
<
QUrl
>
)),
m_binWidget
,
SLOT
(
droppedUrls
(
QList
<
QUrl
>
)));
connect
(
this
,
&
Core
::
updateLibraryPath
,
m_library
,
&
LibraryWidget
::
slotUpdateLibraryPath
);
connect
(
m_capture
.
get
(),
&
MediaCapture
::
recordStateChanged
,
m_mixerWidget
,
&
MixerManager
::
recordStateChanged
);
connect
(
m_mixerWidget
,
&
MixerManager
::
updateRecVolume
,
m_capture
.
get
(),
&
MediaCapture
::
setAudioVolume
);
m_monitorManager
=
new
MonitorManager
(
this
);
connect
(
m_monitorManager
,
&
MonitorManager
::
cleanMixer
,
m_mixerWidget
,
&
MixerManager
::
clearMixers
);
connect
(
m_subtitleWidget
,
&
SubtitleEdit
::
addSubtitle
,
[
this
]()
{
if
(
m_guiConstructed
&&
m_mainWindow
->
getCurrentTimeline
()
->
controller
())
{
m_mainWindow
->
getCurrentTimeline
()
->
controller
()
->
addSubtitle
();
}
});
connect
(
m_subtitleWidget
,
&
SubtitleEdit
::
cutSubtitle
,
[
this
](
int
id
,
int
cursorPos
)
{
if
(
m_guiConstructed
&&
m_mainWindow
->
getCurrentTimeline
()
->
controller
())
{
m_mainWindow
->
getCurrentTimeline
()
->
controller
()
->
cutSubtitle
(
id
,
cursorPos
);
}
});
// Producer queue, creating MLT::Producers on request
/*
m_producerQueue = new ProducerQueue(m_binController);
connect(m_producerQueue, &ProducerQueue::gotFileProperties, m_binWidget, &Bin::slotProducerReady);
connect(m_producerQueue, &ProducerQueue::replyGetImage, m_binWidget, &Bin::slotThumbnailReady);
connect(m_producerQueue, &ProducerQueue::requestProxy,
[this](const QString &id){ m_binWidget->startJob(id, AbstractClipJob::PROXYJOB);});
connect(m_producerQueue, &ProducerQueue::removeInvalidClip, m_binWidget, &Bin::slotRemoveInvalidClip, Qt::DirectConnection);
connect(m_producerQueue, SIGNAL(addClip(QString, QMap<QString, QString>)), m_binWidget, SLOT(slotAddUrl(QString, QMap<QString, QString>)));
connect(m_binController.get(), SIGNAL(createThumb(QDomElement, QString, int)), m_producerQueue, SLOT(getFileProperties(QDomElement, QString, int)));
connect(m_binWidget, &Bin::producerReady, m_producerQueue, &ProducerQueue::slotProcessingDone, Qt::DirectConnection);
// TODO
connect(m_producerQueue, SIGNAL(removeInvalidProxy(QString,bool)), m_binWidget, SLOT(slotRemoveInvalidProxy(QString,bool)));*/
m_mainWindow
->
init
();
if
(
!
Url
.
isEmpty
())
{
emit
loadingMessageUpdated
(
i18n
(
"Loading project..."
));
}
...
...
src/core.h
View file @
e20a4a4a
...
...
@@ -80,7 +80,7 @@ public:
* other binaries paths (melt, ffmpeg, etc)
* @param MltPath (optional) path to MLT environment
*/
static
bool
build
(
bool
isAppImage
,
const
QString
&
MltPath
=
QString
()
);
static
bool
build
();
/**
* @brief Init the GUI part of the app and show the main window
...
...
@@ -88,7 +88,7 @@ public:
* If Url is present, it will be opened, otherwise, if openlastproject is
* set, latest project will be opened. If no file is open after trying this,
* a default new file will be created. */
void
initGUI
(
const
QUrl
&
Url
,
const
QString
&
clipsToLoad
=
QString
());
void
initGUI
(
bool
isAppImage
,
const
QString
&
MltPath
,
const
QUrl
&
Url
,
const
QString
&
clipsToLoad
=
QString
());
/** @brief Returns a pointer to the singleton object. */
static
std
::
unique_ptr
<
Core
>
&
self
();
...
...
src/lib/localeHandling.cpp
View file @
e20a4a4a
...
...
@@ -59,29 +59,33 @@ void LocaleHandling::resetAllLocale()
QPair
<
QLocale
,
LocaleHandling
::
MatchType
>
LocaleHandling
::
getQLocaleForDecimalPoint
(
const
QString
&
requestedLocale
,
const
QString
&
decimalPoint
)
{
// Parse installed locales to find one matching
const
QList
<
QLocale
>
list
=
QLocale
::
matchingLocales
(
QLocale
::
AnyLanguage
,
QLocale
().
script
(),
QLocale
::
AnyCountry
);
QLocale
locale
;
// Best matching locale
MatchType
matchType
=
MatchType
::
NoMatch
;
// Parse installed locales to find one matching. Check matching language first
QList
<
QLocale
>
list
=
QLocale
::
matchingLocales
(
QLocale
().
language
(),
QLocale
().
script
(),
QLocale
::
AnyCountry
);
for
(
const
QLocale
&
loc
:
list
)
{
if
(
loc
.
name
().
startsWith
(
requestedLocale
))
{
if
(
loc
.
decimalPoint
()
==
decimalPoint
)
{
locale
=
loc
;
matchType
=
MatchType
::
Exact
;
}
if
(
loc
.
decimalPoint
()
==
decimalPoint
)
{
locale
=
loc
;
matchType
=
MatchType
::
Exact
;
break
;
}
}
if
(
matchType
==
MatchType
::
NoMatch
)
{
// Parse installed locales to find one matching. Check in all languages
list
=
QLocale
::
matchingLocales
(
QLocale
::
AnyLanguage
,
QLocale
().
script
(),
QLocale
::
AnyCountry
);
for
(
const
QLocale
&
loc
:
list
)
{
if
(
loc
.
decimalPoint
()
==
decimalPoint
)
{
locale
=
loc
;
matchType
=
MatchType
::
DecimalOnly
;
break
;
}
}
}
if
(
matchType
==
MatchType
::
NoMatch
&&
requestedLocale
==
QLatin1String
(
"C"
))
{
locale
=
QLocale
::
c
();
matchType
=
MatchType
::
DecimalOnly
;
}
return
QPair
<
QLocale
,
LocaleHandling
::
MatchType
>
(
locale
,
matchType
);
}
src/main.cpp
View file @
e20a4a4a
...
...
@@ -263,7 +263,7 @@ int main(int argc, char *argv[])
}
qApp
->
processEvents
(
QEventLoop
::
AllEvents
);
int
result
=
0
;
if
(
!
Core
::
build
(
!
parser
.
value
(
QStringLiteral
(
"config"
)).
isEmpty
(),
parser
.
value
(
QStringLiteral
(
"mlt-path"
))
))
{
if
(
!
Core
::
build
())
{
// App is crashing, delete config files and restart
result
=
EXIT_CLEAN_RESTART
;
}
else
{
...
...
@@ -271,7 +271,7 @@ int main(int argc, char *argv[])
QObject
::
connect
(
pCore
.
get
(),
&
Core
::
closeSplash
,
[
&
]
()
{
splash
.
finish
(
pCore
->
window
());
});
pCore
->
initGUI
(
url
,
clipsToLoad
);
pCore
->
initGUI
(
!
parser
.
value
(
QStringLiteral
(
"config"
)).
isEmpty
(),
parser
.
value
(
QStringLiteral
(
"mlt-path"
)),
url
,
clipsToLoad
);
result
=
app
.
exec
();
}
Core
::
clean
();
...
...
src/mainwindow.cpp
View file @
e20a4a4a
...
...
@@ -144,7 +144,7 @@ MainWindow::MainWindow(QWidget *parent)
{
}
void
MainWindow
::
init
()
void
MainWindow
::
init
(
const
QString
&
mltPath
)
{
QString
desktopStyle
=
QApplication
::
style
()
->
objectName
();
// Load themes
...
...
@@ -204,6 +204,10 @@ void MainWindow::init()
new
RenderingAdaptor
(
this
);
QString
defaultProfile
=
KdenliveSettings
::
default_profile
();
// Initialise MLT connection
MltConnection
::
construct
(
mltPath
);
pCore
->
setCurrentProfile
(
defaultProfile
.
isEmpty
()
?
ProjectManager
::
getDefaultProjectFormat
()
:
defaultProfile
);
m_commandStack
=
new
QUndoGroup
();
...
...
@@ -214,7 +218,6 @@ void MainWindow::init()
pCore
->
setCurrentProfile
(
QStringLiteral
(
"atsc_1080p_25"
));
KdenliveSettings
::
setDefault_profile
(
QStringLiteral
(
"atsc_1080p_25"
));
}
m_gpuAllowed
=
EffectsRepository
::
get
()
->
hasInternalEffect
(
QStringLiteral
(
"glsl.manager"
));
m_shortcutRemoveFocus
=
new
QShortcut
(
QKeySequence
(
QStringLiteral
(
"Esc"
)),
this
);
...
...
src/mainwindow.h
View file @
e20a4a4a
...
...
@@ -90,7 +90,7 @@ public:
* If Url is present, it will be opened, otherwise, if openlastproject is
* set, latest project will be opened. If no file is open after trying this,
* a default new file will be created. */
void
init
();
void
init
(
const
QString
&
mltPath
);
~
MainWindow
()
override
;
/** @brief Cache for luma files thumbnails. */
...
...
src/profiles/profilerepository.cpp
View file @
e20a4a4a
...
...
@@ -37,6 +37,7 @@ std::vector<std::pair<int, QString>> ProfileRepository::colorProfiles{
ProfileRepository
::
ProfileRepository
()
{
qDebug
()
<<
"=================BUILDING PROFILE REPOSITORY
\n\n
========================"
;
refresh
();
}
...
...
tests/TestMain.cpp
View file @
e20a4a4a
...
...
@@ -18,7 +18,8 @@ int main(int argc, char *argv[])
app
.
setApplicationName
(
QStringLiteral
(
"kdenlive"
));
std
::
unique_ptr
<
Mlt
::
Repository
>
repo
(
Mlt
::
Factory
::
init
(
nullptr
));
qputenv
(
"MLT_TESTS"
,
QByteArray
(
"1"
));
Core
::
build
(
false
);
Mlt
::
Factory
::
init
();
Core
::
build
();
// if Kdenlive is not installed, ensure we have one keyframable effect
EffectsRepository
::
get
()
->
reloadCustom
(
QFileInfo
(
"../data/effects/audiobalance.xml"
).
absoluteFilePath
());
...
...
Julius Künzel
💬
@jlskuz
mentioned in issue
#923
·
Mar 25, 2021
mentioned in issue
#923
mentioned in issue #923
Toggle commit list
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a 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