Commit 5f37ff2e authored by Jean-Baptiste Mardelle's avatar Jean-Baptiste Mardelle

Merge branch 'release/20.08' of invent.kde.org:multimedia/kdenlive into 2008

parents 3716ef32 0bec5cae
......@@ -6,7 +6,7 @@ cmake_minimum_required(VERSION 3.0)
# KDE Application Version, managed by release script
set (RELEASE_SERVICE_VERSION_MAJOR "20")
set (RELEASE_SERVICE_VERSION_MINOR "08")
set (RELEASE_SERVICE_VERSION_MICRO "0")
set (RELEASE_SERVICE_VERSION_MICRO "1")
set(KDENLIVE_VERSION "${RELEASE_SERVICE_VERSION_MAJOR}.${RELEASE_SERVICE_VERSION_MINOR}.${RELEASE_SERVICE_VERSION_MICRO}")
......
This diff is collapsed.
......@@ -267,6 +267,7 @@
</ul>
</description>
<releases>
<release version="20.08.1" date="2020-09-03"/>
<release version="20.08.0" date="2020-08-13"/>
<release date="2020-04-15" version="20.07.70"/>
</releases>
......
......@@ -39,6 +39,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "projectclip.h"
#include "projectfolder.h"
#include "projectsubclip.h"
#include "lib/localeHandling.h"
#include "xml/xml.hpp"
#include <KLocalizedString>
......@@ -996,8 +997,8 @@ void ProjectItemModel::loadBinPlaylist(Mlt::Tractor *documentTractor, Mlt::Tract
pCore->loadingMessageUpdated(i18n("Loading project clips..."));
}
// Load bin clips
auto currentLocale = strdup(setlocale(LC_ALL, nullptr));
qDebug() << "Init bin; Current LC_ALL" << currentLocale;
auto currentLocale = strdup(setlocale(MLT_LC_CATEGORY, nullptr));
qDebug() << "Init bin; Current LC" << currentLocale;
// Load folders
Mlt::Properties folderProperties;
Mlt::Properties playlistProps(playlist.get_properties());
......
......@@ -29,7 +29,6 @@ the Free Software Foundation, either version 3 of the License, or
#include "timeline2/model/timelineitemmodel.hpp"
#include "timeline2/view/timelinecontroller.h"
#include "timeline2/view/timelinewidget.h"
#include <mlt++/MltRepository.h>
#include <KMessageBox>
......
......@@ -40,6 +40,11 @@ void HideTitleBars::slotInstallRightClick()
connect(dock, &QDockWidget::dockLocationChanged, pCore->window(), &MainWindow::slotUpdateDockLocation);
connect(dock, &QDockWidget::topLevelChanged, pCore->window(), &MainWindow::updateDockTitleBars);
}
updateTitleBars();
}
void HideTitleBars::updateTitleBars()
{
slotShowTitleBars(KdenliveSettings::showtitlebars());
}
......
......@@ -27,6 +27,10 @@ class HideTitleBars : public QObject
public:
explicit HideTitleBars(QObject *parent = nullptr);
public slots:
/** @brief Correctly hide/show dock widget title bars depending on position (floating, tabbed, docked) */
void updateTitleBars();
private:
QAction *m_switchAction;
......
......@@ -26,9 +26,13 @@ the Free Software Foundation, either version 3 of the License, or
#include <KXMLGUIFactory>
#include <klocalizedstring.h>
static QMap <QString, QString> translatedLayoutNames;
LayoutManagement::LayoutManagement(QObject *parent)
: QObject(parent)
{
translatedLayoutNames = {{QStringLiteral("kdenlive_logging"), i18n("Logging")},{QStringLiteral("kdenlive_editing"), i18n("Editing")},{QStringLiteral("kdenlive_audio"), i18n("Audio")},{QStringLiteral("kdenlive_effects"), i18n("Effects")},{QStringLiteral("kdenlive_color"), i18n("Color")}};
// Prepare layout actions
KActionCategory *layoutActions = new KActionCategory(i18n("Layouts"), pCore->window()->actionCollection());
m_loadLayout = new KSelectAction(i18n("Load Layout"), pCore->window()->actionCollection());
......@@ -101,10 +105,6 @@ void LayoutManagement::initializeLayouts()
layoutGroup2.copyTo(&layoutGroup);
}
}
if (!layoutGroup.exists()) {
defaultLayout.copyTo(&layoutGroup);
defaultOrder.copyTo(&layoutOrder);
}
m_loadLayout->removeAllActions();
QStringList entries;
bool addedDefault = false;
......@@ -127,7 +127,6 @@ void LayoutManagement::initializeLayouts()
addedDefault = true;
}
}
if (addedDefault) {
// Write updated order
layoutOrder.deleteGroup();
......@@ -142,15 +141,19 @@ void LayoutManagement::initializeLayouts()
QString layoutName;
if (i <= entries.count()) {
layoutName = entries.at(i - 1);
} else {
break;
}
QAction *load = m_layoutActions.at(i - 1);
if (layoutName.isEmpty()) {
load->setText(QString());
load->setIcon(QIcon());
} else {
load->setText(i18n("Layout %1: %2", i, layoutName));
QString translatedName = translatedLayoutNames.contains(layoutName) ? translatedLayoutNames.value(layoutName) : layoutName;
load->setText(i18n("Layout %1: %2", i, translatedName));
if (i < 6) {
QPushButton *lab = new QPushButton(layoutName, m_container);
QPushButton *lab = new QPushButton(translatedName, m_container);
lab->setProperty("layoutid", layoutName);
lab->setFocusPolicy(Qt::NoFocus);
lab->setCheckable(true);
lab->setFlat(true);
......@@ -179,7 +182,7 @@ void LayoutManagement::activateLayout(QAbstractButton *button)
if (!button) {
return;
}
loadLayout(button->text(), false);
loadLayout(button->property("layoutid").toString(), false);
}
void LayoutManagement::slotLoadLayout(QAction *action)
......@@ -216,7 +219,7 @@ bool LayoutManagement::loadLayout(const QString &layoutId, bool selectButton)
QList<QAbstractButton *>buttons = m_containerGrp->buttons();
bool buttonFound = false;
for (auto *button : buttons) {
if (button->text() == layoutId) {
if (button->property("layoutid").toString() == layoutId) {
QSignalBlocker bk(m_containerGrp);
button->setChecked(true);
buttonFound = true;
......@@ -228,6 +231,7 @@ bool LayoutManagement::loadLayout(const QString &layoutId, bool selectButton)
m_containerGrp->setExclusive(true);
}
}
emit updateTitleBars();
return true;
}
......@@ -242,6 +246,13 @@ void LayoutManagement::slotSaveLayout()
if (layoutName.isEmpty()) {
return;
}
if (saveName == layoutName) {
// No rename, check button id
if (button && button->property("layoutid").toString() != saveName) {
// This is a default layout, save under id
layoutName = button->property("layoutid").toString();
}
}
KSharedConfigPtr config = KSharedConfig::openConfig(QStringLiteral("kdenlive-layoutsrc"));
KConfigGroup layouts(config, "Layouts");
KConfigGroup order(config, "Order");
......@@ -359,9 +370,9 @@ void LayoutManagement::slotManageLayouts()
// Re-add missing default layouts
for (const QString &name : defaultLayoutNames) {
if (!currentNames.contains(name)) {
if (!currentNames.contains(name) && translatedLayoutNames.contains(name)) {
// Insert default layout
QListWidgetItem *item = new QListWidgetItem(name);
QListWidgetItem *item = new QListWidgetItem(translatedLayoutNames.value(name));
item->setData(Qt::UserRole, name);
item->setFlags(Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
list.insertItem(pos, item);
......@@ -381,8 +392,14 @@ void LayoutManagement::slotManageLayouts()
l2->addStretch();
// Add layouts to list
for (const QString &name : names) {
QListWidgetItem *item = new QListWidgetItem(name, &list);
QString visibleName;
for (const QString &name : qAsConst(names)) {
if (translatedLayoutNames.contains(name)) {
visibleName = translatedLayoutNames.value(name);
} else {
visibleName = name;
}
QListWidgetItem *item = new QListWidgetItem(visibleName, &list);
item->setData(Qt::UserRole, name);
item->setFlags(Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
}
......@@ -405,10 +422,23 @@ void LayoutManagement::slotManageLayouts()
// Update order and new names
for (int i = 0; i < list.count(); i++) {
QListWidgetItem *item = list.item(i);
order.writeEntry(QString::number(i + 1), item->text());
if (item->text() != item->data(Qt::UserRole).toString() && !item->text().isEmpty()) {
layouts.writeEntry(item->text(), layouts.readEntry(item->data(Qt::UserRole).toString()));
layouts.deleteEntry(item->data(Qt::UserRole).toString());
QString layoutId = item->data(Qt::UserRole).toString();
if (translatedLayoutNames.contains(layoutId)) {
// This is a default layout, no rename
if (item->text() != translatedLayoutNames.value(layoutId)) {
// A default layout was renamed
order.writeEntry(QString::number(i + 1), item->text());
layouts.writeEntry(item->text(), layouts.readEntry(layoutId));
layouts.deleteEntry(layoutId);
} else {
order.writeEntry(QString::number(i + 1), layoutId);
}
continue;
}
order.writeEntry(QString::number(i + 1), layoutId);
if (item->text() != layoutId && !item->text().isEmpty()) {
layouts.writeEntry(item->text(), layouts.readEntry(layoutId));
layouts.deleteEntry(layoutId);
}
}
config->reparseConfiguration();
......
......@@ -47,6 +47,10 @@ private:
QHBoxLayout *m_containerLayout;
KSelectAction *m_loadLayout;
QList <QAction *> m_layoutActions;
signals:
/** @brief Layout changed, ensure title bars are correctly displayed. */
void updateTitleBars();
};
#endif
......@@ -21,12 +21,12 @@ auto LocaleHandling::setLocale(const QString &lcName) -> QString
localesToTest << lcName << lcName + ".utf-8" << lcName + ".UTF-8" << lcName + ".utf8" << lcName + ".UTF8";
for (const auto &locale : localesToTest) {
#ifdef Q_OS_FREEBSD
auto *result = setlocale(LC_NUMERIC, locale.toStdString().c_str());
auto *result = setlocale(MLT_LC_CATEGORY, locale.toStdString().c_str());
#else
auto *result = std::setlocale(LC_NUMERIC, locale.toStdString().c_str());
auto *result = std::setlocale(MLT_LC_CATEGORY, locale.toStdString().c_str());
#endif
if (result != nullptr) {
::qputenv("LC_NUMERIC", locale.toStdString().c_str());
::qputenv(MLT_LC_NAME, locale.toStdString().c_str());
newLocale = locale;
break;
}
......@@ -40,11 +40,11 @@ auto LocaleHandling::setLocale(const QString &lcName) -> QString
void LocaleHandling::resetLocale()
{
#ifdef Q_OS_FREEBSD
setlocale(LC_NUMERIC, "C");
setlocale(MLT_LC_CATEGORY, "C");
#else
std::setlocale(LC_NUMERIC, "C");
std::setlocale(MLT_LC_CATEGORY, "C");
#endif
::qputenv("LC_NUMERIC", "C");
::qputenv(MLT_LC_NAME, "C");
qDebug() << "LC_NUMERIC reset to C";
}
......
......@@ -13,6 +13,15 @@ the Free Software Foundation, either version 3 of the License, or
#include <QtCore/QLocale>
#include <QtCore/QString>
#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC)
# define MLT_LC_CATEGORY LC_NUMERIC
# define MLT_LC_NAME "LC_NUMERIC"
#else
# define MLT_LC_CATEGORY LC_ALL
# define MLT_LC_NAME "LC_ALL"
#endif
class LocaleHandling
{
public:
......
......@@ -66,7 +66,7 @@
#include "utils/resourcewidget.h"
#include "utils/thememanager.h"
#include "utils/otioconvertions.h"
#include "lib/localeHandling.h"
#include "profiles/profilerepository.hpp"
#include "widgets/progressbutton.h"
#include <config-kdenlive.h>
......@@ -418,13 +418,13 @@ void MainWindow::init()
QAction *showMixer = new QAction(QIcon::fromTheme(QStringLiteral("view-media-equalizer")), i18n("Audio Mixer"), this);
showMixer->setCheckable(true);
addAction(QStringLiteral("audiomixer_button"), showMixer);
connect(mixerDock, &QDockWidget::visibilityChanged, [&, showMixer](bool visible) {
connect(m_mixerDock, &QDockWidget::visibilityChanged, [&, showMixer](bool visible) {
pCore->mixer()->connectMixer(visible);
showMixer->setChecked(visible);
});
connect(showMixer, &QAction::triggered, [&, mixerDock]() {
if (mixerDock->isVisible() && !mixerDock->visibleRegion().isEmpty()) {
mixerDock->close();
connect(showMixer, &QAction::triggered, [&]() {
if (m_mixerDock->isVisible() && !m_mixerDock->visibleRegion().isEmpty()) {
m_mixerDock->close();
} else {
m_mixerDock->show();
m_mixerDock->raise();
......@@ -452,7 +452,8 @@ void MainWindow::init()
auto *scmanager = new ScopeManager(this);
new HideTitleBars(this);
HideTitleBars *titleBars = new HideTitleBars(this);
connect(layoutManager, &LayoutManagement::updateTitleBars, titleBars, &HideTitleBars::updateTitleBars);
new DockAreaOrientationManager(this);
m_extraFactory = new KXMLGUIClient(this);
buildDynamicActions();
......@@ -509,6 +510,7 @@ void MainWindow::init()
addAction(QStringLiteral("timeline_preview_button"), previewButtonAction);
setupGUI(KXmlGuiWindow::ToolBar | KXmlGuiWindow::StatusBar | KXmlGuiWindow::Save | KXmlGuiWindow::Create);
LocaleHandling::resetLocale();
if (firstRun) {
if (QScreen *current = QApplication::primaryScreen()) {
int screenHeight = current->availableSize().height();
......@@ -747,7 +749,8 @@ void MainWindow::init()
updateActionsToolTip();
if (firstRun) {
layoutManager->loadLayout(QStringLiteral("Editing"), true);
// Load editing layout
layoutManager->loadLayout(QStringLiteral("kdenlive_editing"), true);
}
QTimer::singleShot(0, this, &MainWindow::GUISetupDone);
......
......@@ -86,12 +86,11 @@ MltConnection::MltConnection(const QString &mltPath)
// After initialising the MLT factory, set the locale back from user default to C
// to ensure numbers are always serialised with . as decimal point.
m_repository = std::unique_ptr<Mlt::Repository>(Mlt::Factory::init());
LocaleHandling::resetLocale();
#ifdef Q_OS_FREEBSD
auto locale = strdup(setlocale(LC_ALL, nullptr));
auto locale = strdup(setlocale(MLT_LC_CATEGORY, nullptr));
#else
auto locale = strdup(std::setlocale(LC_ALL, nullptr));
auto locale = strdup(std::setlocale(MLT_LC_CATEGORY, nullptr));
#endif
qDebug() << "NEW LC_ALL" << locale;
......
......@@ -1292,6 +1292,7 @@ void GLWidget::mouseReleaseEvent(QMouseEvent *event)
void GLWidget::purgeCache()
{
if (m_consumer) {
//m_consumer->set("buffer", 1);
m_consumer->purge();
m_producer->seek(m_proxy->getPosition() + 1);
}
......@@ -1365,7 +1366,8 @@ const QString GLWidget::sceneList(const QString &root, const QString &fullPath)
// Disabling meta creates cleaner files, but then we don't have access to metadata on the fly (meta channels, etc)
// And we must use "avformat" instead of "avformat-novalidate" on project loading which causes a big delay on project opening
// xmlConsumer.set("no_meta", 1);
xmlConsumer.connect(*m_producer.get());
Mlt::Service s(m_producer->get_service());
xmlConsumer.connect(s);
xmlConsumer.run();
playlist = fullPath.isEmpty() ? QString::fromUtf8(xmlConsumer.get("kdenlive_playlist")) : fullPath;
return playlist;
......
......@@ -679,6 +679,11 @@ void ProjectManager::slotAutoSave()
scene.replace(i.key(), i.value());
}
}
if (!scene.contains(QLatin1String("<track "))) {
// In some unexplained cases, the MLT playlist is corrupted and all tracks are deleted. Don't save in that case.
pCore->displayMessage(i18n("Project was corrupted, cannot backup. Please close and reopen your project file to recover last backup"), ErrorMessage);
return;
}
m_project->slotAutoSave(scene);
m_lastSave.start();
}
......
......@@ -1065,6 +1065,7 @@ bool TimelineModel::requestClipInsertion(const QString &binClipId, int trackId,
binIdWithInOut.remove(0, 1);
}
if (!pCore->projectItemModel()->hasClip(bid)) {
qDebug()<<"=== NO CLIP FOUND IN BIN FOR ID: "<<bid;
return false;
}
......@@ -1086,22 +1087,29 @@ bool TimelineModel::requestClipInsertion(const QString &binClipId, int trackId,
useTargets = false;
}
if ((dropType == PlaylistState::Disabled || dropType == PlaylistState::AudioOnly) && (type == ClipType::AV || type == ClipType::Playlist)) {
bool useAudioTarget = false;
if (useTargets && !m_audioTarget.isEmpty() && m_videoTarget == -1) {
// If audio target is set but no video target, only insert audio
trackId = m_audioTarget.firstKey();
if (trackId > -1 && (getTrackById_const(trackId)->isLocked() || !allowedTracks.contains(trackId))) {
trackId = -1;
}
useAudioTarget = true;
} else if (useTargets && (getTrackById_const(trackId)->isLocked() || !allowedTracks.contains(trackId))) {
// Video target set but locked
trackId = m_audioTarget.firstKey();
if (trackId > -1 && (getTrackById_const(trackId)->isLocked() || !allowedTracks.contains(trackId))) {
trackId = -1;
useAudioTarget = true;
}
if (useAudioTarget) {
// Find first possible audio target
QList <int> audioTargetTracks = m_audioTarget.keys();
trackId = -1;
for (int tid : audioTargetTracks) {
if (tid > -1 && !getTrackById_const(tid)->isLocked() && allowedTracks.contains(tid)) {
trackId = tid;
break;
}
}
}
if (trackId == -1) {
if (!allowedTracks.isEmpty()) {
// No active tracks, aborting
qDebug()<<"=== NO ACTIVE TRACK FOUND; ABORTING!!!";
return true;
}
pCore->displayMessage(i18n("No available track for insert operation"), ErrorMessage);
......
......@@ -362,7 +362,7 @@ Rectangle {
cursorShape: Qt.PointingHandCursor
hoverEnabled: true
onDoubleClicked: timeline.editMarker(clipRoot.clipId, model.frame)
onClicked: proxy.position = (clipRoot.x + markerBase.x) / timeline.scaleFactor
onClicked: proxy.position = clipRoot.modelStart + (clipRoot.speed < 0 ? (clipRoot.maxDuration - clipRoot.inPoint) * timeScale + (Math.round(model.frame / clipRoot.speed)) : (Math.round(model.frame / clipRoot.speed) - clipRoot.inPoint))
}
}
TextMetrics {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment