mainwindow.cpp 185 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/***************************************************************************
 *   Copyright (C) 2007 by Jean-Baptiste Mardelle (jb@kdenlive.org)        *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA          *
 ***************************************************************************/

Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
20
#include "mainwindow.h"
21
#include "assets/assetpanel.hpp"
22
#include "bin/clipcreator.hpp"
23
#include "bin/generators/generators.h"
24
#include "bin/model/subtitlemodel.hpp"
Nicolas Carion's avatar
Nicolas Carion committed
25
#include "bin/projectclip.h"
26
27
#include "bin/projectfolder.h"
#include "bin/projectitemmodel.h"
Nicolas Carion's avatar
Nicolas Carion committed
28
#include "core.h"
29
#include "dialogs/clipcreationdialog.h"
Nicolas Carion's avatar
Nicolas Carion committed
30
31
32
#include "dialogs/kdenlivesettingsdialog.h"
#include "dialogs/renderwidget.h"
#include "dialogs/wizard.h"
33
#include "dialogs/subtitleedit.h"
34
#include "doc/docundostack.hpp"
Nicolas Carion's avatar
Nicolas Carion committed
35
#include "doc/kdenlivedoc.h"
36
#include "dockareaorientationmanager.h"
37
#include "effects/effectlist/view/effectlistwidget.hpp"
Nicolas Carion's avatar
Nicolas Carion committed
38
39
#include "effectslist/effectbasket.h"
#include "hidetitlebars.h"
40
41
#include "jobs/jobmanager.h"
#include "jobs/scenesplitjob.hpp"
42
#include "jobs/speedjob.hpp"
Nicolas Carion's avatar
Nicolas Carion committed
43
#include "jobs/stabilizejob.hpp"
44
#include "jobs/transcodeclipjob.h"
Nicolas Carion's avatar
Nicolas Carion committed
45
46
47
#include "kdenlivesettings.h"
#include "layoutmanagement.h"
#include "library/librarywidget.h"
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
48
#include "audiomixer/mixermanager.hpp"
Nicolas Carion's avatar
Nicolas Carion committed
49
50
51
52
53
54
#include "mainwindowadaptor.h"
#include "mltconnection.h"
#include "mltcontroller/clipcontroller.h"
#include "monitor/monitor.h"
#include "monitor/monitormanager.h"
#include "monitor/scopes/audiographspectrum.h"
Nicolas Carion's avatar
linting    
Nicolas Carion committed
55
#include "profiles/profilemodel.hpp"
Vincent PINON's avatar
Vincent PINON committed
56
#include "project/cliptranscode.h"
Vincent PINON's avatar
Vincent PINON committed
57
#include "project/dialogs/archivewidget.h"
Nicolas Carion's avatar
Nicolas Carion committed
58
59
#include "project/dialogs/projectsettings.h"
#include "project/projectcommands.h"
Till Theato's avatar
Till Theato committed
60
#include "project/projectmanager.h"
Nicolas Carion's avatar
Nicolas Carion committed
61
#include "scopes/scopemanager.h"
Nicolas Carion's avatar
linting    
Nicolas Carion committed
62
#include "timeline2/view/timelinecontroller.h"
63
#include "timeline2/view/timelinetabs.hpp"
64
#include "timeline2/view/timelinewidget.h"
Nicolas Carion's avatar
Nicolas Carion committed
65
66
67
68
69
#include "titler/titlewidget.h"
#include "transitions/transitionlist/view/transitionlistwidget.hpp"
#include "transitions/transitionsrepository.hpp"
#include "utils/resourcewidget.h"
#include "utils/thememanager.h"
Vincent Pinon's avatar
Vincent Pinon committed
70
#include "utils/otioconvertions.h"
71
#include "lib/localeHandling.h"
72
#include "profiles/profilerepository.hpp"
73
74
#include "widgets/progressbutton.h"
#include <config-kdenlive.h>
75

76
#include "project/dialogs/temporarydata.h"
77

78
79
80
#ifdef USE_JOGSHUTTLE
#include "jogshuttle/jogmanager.h"
#endif
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
81

82
#include <KActionCategory>
Nicolas Carion's avatar
Nicolas Carion committed
83
#include <KActionCollection>
84
#include <KActionMenu>
Nicolas Carion's avatar
Nicolas Carion committed
85
86
#include <KColorScheme>
#include <KColorSchemeManager>
87
#include <KConfigDialog>
Nicolas Carion's avatar
Nicolas Carion committed
88
89
#include <KDualAction>
#include <KEditToolBar>
90
#include <KIconTheme>
Nicolas Carion's avatar
Nicolas Carion committed
91
92
#include <KMessageBox>
#include <KNotifyConfigWidget>
93
#include <KRecentDirs>
Nicolas Carion's avatar
Nicolas Carion committed
94
95
96
97
98
#include <KShortcutsDialog>
#include <KStandardAction>
#include <KToolBar>
#include <KXMLGUIFactory>
#include <klocalizedstring.h>
99
100
#include <kns3/downloaddialog.h>
#include <kns3/knewstuffaction.h>
Nicolas Carion's avatar
Nicolas Carion committed
101
#include <ktogglefullscreenaction.h>
102

Laurent Montel's avatar
Laurent Montel committed
103
#include "kdenlive_debug.h"
Nicolas Carion's avatar
Nicolas Carion committed
104
105
106
107
#include <QAction>
#include <QFileDialog>
#include <QMenu>
#include <QMenuBar>
108
#include <QStatusBar>
Nicolas Carion's avatar
Nicolas Carion committed
109
#include <QStyleFactory>
110
#include <QUndoGroup>
Vincent PINON's avatar
Vincent PINON committed
111
112
113
#include <KConfigGroup>
#include <QDialogButtonBox>
#include <QPushButton>
114
#include <QScreen>
Nicolas Carion's avatar
Nicolas Carion committed
115
116
#include <QStandardPaths>
#include <QVBoxLayout>
117

118
static const char version[] = KDENLIVE_VERSION;
Nicolas Carion's avatar
Nicolas Carion committed
119
namespace Mlt {
120
class Producer;
Laurent Montel's avatar
Laurent Montel committed
121
}
122

Laurent Montel's avatar
Laurent Montel committed
123
124
QMap<QString, QImage> MainWindow::m_lumacache;
QMap<QString, QStringList> MainWindow::m_lumaFiles;
125

126
/*static bool sortByNames(const QPair<QString, QAction *> &a, const QPair<QString, QAction*> &b)
127
128
{
    return a.first < b.first;
129
}*/
130

Yuri Chornoivan's avatar
Yuri Chornoivan committed
131
// determine the default KDE style as defined BY THE USER
132
// (as opposed to whatever style KDE considers default)
Laurent Montel's avatar
Laurent Montel committed
133
static QString defaultStyle(const char *fallback = nullptr)
134
135
136
137
138
139
{
    KSharedConfigPtr kdeGlobals = KSharedConfig::openConfig(QStringLiteral("kdeglobals"), KConfig::NoGlobals);
    KConfigGroup cg(kdeGlobals, "KDE");
    return cg.readEntry("widgetStyle", fallback);
}

Nicolas Carion's avatar
Nicolas Carion committed
140
MainWindow::MainWindow(QWidget *parent)
141
    : KXmlGuiWindow(parent)
Nicolas Carion's avatar
Nicolas Carion committed
142

143
{
144
145
}

146
void MainWindow::init()
147
{
148
    QString desktopStyle = QApplication::style()->objectName();
149
150
151
152
153
    // Load themes
    auto themeManager = new ThemeManager(actionCollection());
    actionCollection()->addAction(QStringLiteral("themes_menu"), themeManager);
    connect(themeManager, &ThemeManager::themeChanged, this, &MainWindow::slotThemeChanged);

154
155
156
157
    if (!KdenliveSettings::widgetstyle().isEmpty() && QString::compare(desktopStyle, KdenliveSettings::widgetstyle(), Qt::CaseInsensitive) != 0) {
        // User wants a custom widget style, init
        doChangeStyle();
    }
Nicolas Carion's avatar
Nicolas Carion committed
158

159
    // Widget themes for non KDE users
Laurent Montel's avatar
Laurent Montel committed
160
    KActionMenu *stylesAction = new KActionMenu(i18n("Style"), this);
Nicolas Carion's avatar
Nicolas Carion committed
161
    auto *stylesGroup = new QActionGroup(stylesAction);
162

163
164
    // GTK theme does not work well with Kdenlive, and does not support color theming, so avoid it
    QStringList availableStyles = QStyleFactory::keys();
165
166
    if (KdenliveSettings::widgetstyle().isEmpty()) {
        // First run
167
        QStringList incompatibleStyles = {QStringLiteral("GTK+"), QStringLiteral("windowsvista"), QStringLiteral("Windows")};
168

169
        if (incompatibleStyles.contains(desktopStyle, Qt::CaseInsensitive)) {
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
170
            if (availableStyles.contains(QStringLiteral("breeze"), Qt::CaseInsensitive)) {
171
172
                // Auto switch to Breeze theme
                KdenliveSettings::setWidgetstyle(QStringLiteral("Breeze"));
173
		QApplication::setStyle(QStyleFactory::create(QStringLiteral("Breeze")));
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
174
            } else if (availableStyles.contains(QStringLiteral("fusion"), Qt::CaseInsensitive)) {
175
                KdenliveSettings::setWidgetstyle(QStringLiteral("Fusion"));
176
		QApplication::setStyle(QStyleFactory::create(QStringLiteral("Fusion")));
177
            }
178
179
        } else {
            KdenliveSettings::setWidgetstyle(QStringLiteral("Default"));
180
181
182
        }
    }

Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
183
184
    // Add default style action
    QAction *defaultStyle = new QAction(i18n("Default"), stylesGroup);
185
    defaultStyle->setData(QStringLiteral("Default"));
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
186
187
    defaultStyle->setCheckable(true);
    stylesAction->addAction(defaultStyle);
188
    if (KdenliveSettings::widgetstyle() == QLatin1String("Default") || KdenliveSettings::widgetstyle().isEmpty()) {
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
189
190
191
        defaultStyle->setChecked(true);
    }

Vincent Pinon's avatar
Vincent Pinon committed
192
    for (const QString &style : qAsConst(availableStyles)) {
Nicolas Carion's avatar
Nicolas Carion committed
193
        auto *a = new QAction(style, stylesGroup);
194
195
        a->setCheckable(true);
        a->setData(style);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
196
197
198
        if (KdenliveSettings::widgetstyle() == style) {
            a->setChecked(true);
        }
199
200
201
        stylesAction->addAction(a);
    }
    connect(stylesGroup, &QActionGroup::triggered, this, &MainWindow::slotChangeStyle);
Nicolas Carion's avatar
Nicolas Carion committed
202
    // QIcon::setThemeSearchPaths(QStringList() <<QStringLiteral(":/icons/"));
203
204

    new RenderingAdaptor(this);
205
    QString defaultProfile = KdenliveSettings::default_profile();
206
    pCore->setCurrentProfile(defaultProfile.isEmpty() ? ProjectManager::getDefaultProjectFormat() : defaultProfile);
207
    m_commandStack = new QUndoGroup();
208
209

    // If using a custom profile, make sure the file exists or fallback to default
210
211
    QString currentProfilePath = pCore->getCurrentProfile()->path();
    if (currentProfilePath.startsWith(QLatin1Char('/')) && !QFile::exists(currentProfilePath)) {
212
        KMessageBox::sorry(this, i18n("Cannot find your default profile, switching to ATSC 1080p 25"));
213
        pCore->setCurrentProfile(QStringLiteral("atsc_1080p_25"));
Laurent Montel's avatar
Laurent Montel committed
214
        KdenliveSettings::setDefault_profile(QStringLiteral("atsc_1080p_25"));
215
    }
216

217
    m_gpuAllowed = EffectsRepository::get()->hasInternalEffect(QStringLiteral("glsl.manager"));
218

219
    m_shortcutRemoveFocus = new QShortcut(QKeySequence(QStringLiteral("Esc")), this);
Laurent Montel's avatar
Laurent Montel committed
220
    connect(m_shortcutRemoveFocus, &QShortcut::activated, this, &MainWindow::slotRemoveFocus);
Simon Eugster's avatar
Simon Eugster committed
221

222
    /// Add Widgets
223
    setDockOptions(dockOptions() | QMainWindow::AllowNestedDocks | QMainWindow::AllowTabbedDocks);
224
    setDockOptions(dockOptions() | QMainWindow::GroupedDragging);
Nicolas Carion's avatar
Nicolas Carion committed
225
    setTabPosition(Qt::AllDockWidgetAreas, (QTabWidget::TabPosition)KdenliveSettings::tabposition());
226
    m_timelineToolBar = toolBar(QStringLiteral("timelineToolBar"));
227
    m_timelineToolBarContainer = new TimelineContainer(this);
Nicolas Carion's avatar
Nicolas Carion committed
228
    auto *ctnLay = new QVBoxLayout;
229
230
    ctnLay->setSpacing(0);
    ctnLay->setContentsMargins(0, 0, 0, 0);
231
    m_timelineToolBarContainer->setLayout(ctnLay);
232
233
234
235
    QFrame *topFrame = new QFrame(this);
    topFrame->setFrameShape(QFrame::HLine);
    topFrame->setFixedHeight(1);
    topFrame->setLineWidth(1);
Vincent Pinon's avatar
Vincent Pinon committed
236
    connect(this, &MainWindow::focusTimeline, this, [topFrame](bool focus, bool highlight) {
237
238
239
240
241
242
243
244
245
246
247
248
249
250
        if (focus) {
            KColorScheme scheme(QApplication::palette().currentColorGroup(), KColorScheme::Tooltip);
            if (highlight) {
                QColor col = scheme.decoration(KColorScheme::HoverColor).color();
                topFrame->setStyleSheet(QString("QFrame {border: 1px solid rgba(%1,%2,%3,70)}").arg(col.red()).arg(col.green()).arg(col.blue()));
            } else {
                QColor col = scheme.decoration(KColorScheme::FocusColor).color();
                topFrame->setStyleSheet(QString("QFrame {border: 1px solid rgba(%1,%2,%3,100)}").arg(col.red()).arg(col.green()).arg(col.blue()));
            }
        } else {
            topFrame->setStyleSheet(QString());
        }
    });
    ctnLay->addWidget(topFrame);
251
    ctnLay->addWidget(m_timelineToolBar);
252
253
254
255
    KSharedConfigPtr config = KSharedConfig::openConfig();
    KConfigGroup mainConfig(config, QStringLiteral("MainWindow"));
    KConfigGroup tbGroup(&mainConfig, QStringLiteral("Toolbar timelineToolBar"));
    m_timelineToolBar->applySettings(tbGroup);
256
257
258
259
260
    QFrame *fr = new QFrame(this);
    fr->setFrameShape(QFrame::HLine);
    fr->setMaximumHeight(1);
    fr->setLineWidth(1);
    ctnLay->addWidget(fr);
261
    setupActions();
262
    LayoutManagement *layoutManager = new LayoutManagement(this);
263

Laurent Montel's avatar
Laurent Montel committed
264
    QDockWidget *libraryDock = addDock(i18n("Library"), QStringLiteral("library"), pCore->library());
265
    QDockWidget *subtitlesDock = addDock(i18n("Subtitles"), QStringLiteral("Subtitles"), pCore->subtitleWidget());
Simon Eugster's avatar
Simon Eugster committed
266

Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
267
    m_clipMonitor = new Monitor(Kdenlive::ClipMonitor, pCore->monitorManager(), this);
268
    pCore->bin()->setMonitor(m_clipMonitor);
269
270
    connect(m_clipMonitor, &Monitor::addMarker, this, &MainWindow::slotAddMarkerGuideQuickly);
    connect(m_clipMonitor, &Monitor::deleteMarker, this, &MainWindow::slotDeleteClipMarker);
271
272
    connect(m_clipMonitor, &Monitor::seekToPreviousSnap, this, &MainWindow::slotSnapRewind);
    connect(m_clipMonitor, &Monitor::seekToNextSnap, this, &MainWindow::slotSnapForward);
273

274
    connect(pCore->bin(), &Bin::findInTimeline, this, &MainWindow::slotClipInTimeline, Qt::DirectConnection);
275
    connect(pCore->bin(), &Bin::setupTargets, this, [&] (bool hasVideo, QMap <int, QString> audioStreams) {
276
            getCurrentTimeline()->controller()->setTargetTracks(hasVideo, audioStreams);
277
278
        }
    );
279

Nicolas Carion's avatar
Nicolas Carion committed
280
    // TODO deprecated, replace with Bin methods if necessary
281
    /*connect(m_projectList, SIGNAL(loadingIsOver()), this, SLOT(slotElapsedTime()));
282
    connect(m_projectList, SIGNAL(updateRenderStatus()), this, SLOT(slotCheckRenderStatus()));
Laurent Montel's avatar
Laurent Montel committed
283
    connect(m_projectList, SIGNAL(updateProfile(QString)), this, SLOT(slotUpdateProjectProfile(QString)));
284
    connect(m_projectList, SIGNAL(refreshClip(QString,bool)), pCore->monitorManager(), SLOT(slotRefreshCurrentMonitor(QString)));
285
    connect(m_clipMonitor, SIGNAL(zoneUpdated(QPoint)), m_projectList, SLOT(slotUpdateClipCut(QPoint)));*/
286

Laurent Montel's avatar
Laurent Montel committed
287
    connect(m_clipMonitor, &Monitor::passKeyPress, this, &MainWindow::triggerKey);
288

Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
289
    m_projectMonitor = new Monitor(Kdenlive::ProjectMonitor, pCore->monitorManager(), this);
Laurent Montel's avatar
Laurent Montel committed
290
    connect(m_projectMonitor, &Monitor::passKeyPress, this, &MainWindow::triggerKey);
291
    connect(m_projectMonitor, &Monitor::addMarker, this, &MainWindow::slotAddMarkerGuideQuickly);
292
    connect(m_projectMonitor, &Monitor::deleteMarker, this, &MainWindow::slotDeleteGuide);
293
294
    connect(m_projectMonitor, &Monitor::seekToPreviousSnap, this, &MainWindow::slotSnapRewind);
    connect(m_projectMonitor, &Monitor::seekToNextSnap, this, &MainWindow::slotSnapForward);
Vincent Pinon's avatar
Vincent Pinon committed
295
    connect(m_loopClip, &QAction::triggered, this, [&]() {
296
297
298
        QPoint inOut = getMainTimeline()->controller()->selectionInOut();
        m_projectMonitor->slotLoopClip(inOut);
    });
299

300
    pCore->monitorManager()->initMonitors(m_clipMonitor, m_projectMonitor);
301
    connect(m_clipMonitor, &Monitor::addMasterEffect, pCore->bin(), &Bin::slotAddEffect);
302

303
304
    m_timelineTabs = new TimelineTabs(this);
    ctnLay->addWidget(m_timelineTabs);
305
    setCentralWidget(m_timelineToolBarContainer);
306

307
308
309
310
311
312
313
    // Screen grab widget
    QWidget *grabWidget = new QWidget(this);
    QVBoxLayout *grabLayout = new QVBoxLayout;
    grabWidget->setLayout(grabLayout);
    QToolBar *recToolbar = new QToolBar(grabWidget);
    grabLayout->addWidget(recToolbar);
    grabLayout->addStretch(10);
314
    // Check number of monitors for FFmpeg screen capture
Vincent Pinon's avatar
Vincent Pinon committed
315
    int screens = QApplication::screens().count();
316
317
318
319
320
321
322
323
324
325
    if (screens > 1) {
        QComboBox *screenCombo = new QComboBox(recToolbar);
        for (int ix = 0; ix < screens; ix++) {
            screenCombo->addItem(i18n("Monitor %1", ix));
        }
        connect(screenCombo, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), m_clipMonitor, &Monitor::slotSetScreen);
        recToolbar->addWidget(screenCombo);
        // Update screen grab monitor choice in case we changed from fullscreen
        screenCombo->setEnabled(KdenliveSettings::grab_capture_type() == 0);
    }
326
327
328
329
330
331
    QAction *recAction = m_clipMonitor->recAction();
    addAction(QStringLiteral("screengrab_record"), recAction);
    recToolbar->addAction(recAction);
    QAction *recConfig = new QAction(QIcon::fromTheme(QStringLiteral("configure")), i18n("Configure Recording"), this);
    recToolbar->addAction(recConfig);
    connect(recConfig, &QAction::triggered, [&]() {
Vincent Pinon's avatar
Vincent Pinon committed
332
        emit pCore->showConfigDialog(4, 0);
333
334
    });
    QDockWidget *screenGrabDock = addDock(i18n("Screen Grab"), QStringLiteral("screengrab"), grabWidget);
335

336
337
    // Audio spectrum scope
    m_audioSpectrum = new AudioGraphSpectrum(pCore->monitorManager());
Laurent Montel's avatar
Laurent Montel committed
338
    QDockWidget *spectrumDock = addDock(i18n("Audio Spectrum"), QStringLiteral("audiospectrum"), m_audioSpectrum);
Vincent Pinon's avatar
Vincent Pinon committed
339
    connect(spectrumDock, &QDockWidget::visibilityChanged, this, [&](bool visible) {
340
341
        m_audioSpectrum->dockVisible(visible);
    });
342
    // Close library and audiospectrum on first run
343
    screenGrabDock->close();
344
    libraryDock->close();
345
    subtitlesDock->close();
346
347
    spectrumDock->close();

348
    m_projectBinDock = addDock(i18n("Project Bin"), QStringLiteral("project_bin"), pCore->bin());
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
349

350
    m_assetPanel = new AssetPanel(this);
351
    m_effectStackDock = addDock(i18n("Effect/Composition Stack"), QStringLiteral("effect_stack"), m_assetPanel);
352
353
    connect(m_assetPanel, &AssetPanel::doSplitEffect, m_projectMonitor, &Monitor::slotSwitchCompare);
    connect(m_assetPanel, &AssetPanel::doSplitBinEffect, m_clipMonitor, &Monitor::slotSwitchCompare);
Vincent Pinon's avatar
Vincent Pinon committed
354
    connect(m_assetPanel, &AssetPanel::switchCurrentComposition, this, [&](int cid, const QString &compositionId) {
355
356
357
        getMainTimeline()->controller()->getModel()->switchComposition(cid, compositionId);
    });

358
    connect(m_timelineTabs, &TimelineTabs::showMixModel, m_assetPanel, &AssetPanel::showMix);
359
    connect(m_timelineTabs, &TimelineTabs::showTransitionModel, m_assetPanel, &AssetPanel::showTransition);
Vincent Pinon's avatar
Vincent Pinon committed
360
    connect(m_timelineTabs, &TimelineTabs::showTransitionModel, this, [&] () {
361
362
        m_effectStackDock->raise();
    });
363
    connect(m_timelineTabs, &TimelineTabs::showItemEffectStack, m_assetPanel, &AssetPanel::showEffectStack);
Vincent Pinon's avatar
Vincent Pinon committed
364
    connect(m_timelineTabs, &TimelineTabs::showItemEffectStack, this, [&] () {
365
366
367
        m_effectStackDock->raise();
    });

368
369
370
371
372
373
374
375
    connect(m_timelineTabs, &TimelineTabs::showSubtitle, this, [&, subtitlesDock] (int id) {
        if (id > -1) {
            subtitlesDock->show();
            subtitlesDock->raise();
        }
        pCore->subtitleWidget()->setActiveSubtitle(id);
    });

376
    connect(m_timelineTabs, &TimelineTabs::updateZoom, this, &MainWindow::updateZoomSlider);
377
    connect(pCore->bin(), &Bin::requestShowEffectStack, m_assetPanel, &AssetPanel::showEffectStack);
378
    connect(pCore->bin(), &Bin::requestShowEffectStack, [&] () {
379
380
        // Don't raise effect stack on clip bin in case it is docked with bin or clip monitor
        // m_effectStackDock->raise();
381
    });
382
    connect(this, &MainWindow::clearAssetPanel, m_assetPanel, &AssetPanel::clearAssetPanel);
383
    connect(this, &MainWindow::assetPanelWarning, m_assetPanel, &AssetPanel::assetPanelWarning);
Vincent Pinon's avatar
Vincent Pinon committed
384
    connect(m_assetPanel, &AssetPanel::seekToPos, this, [this](int pos) {
385
386
        ObjectId oId = m_assetPanel->effectStackOwner();
        switch (oId.first) {
Nicolas Carion's avatar
Nicolas Carion committed
387
388
389
        case ObjectType::TimelineTrack:
        case ObjectType::TimelineClip:
        case ObjectType::TimelineComposition:
390
        case ObjectType::Master:
391
        case ObjectType::TimelineMix:
392
            m_projectMonitor->requestSeek(pos);
Nicolas Carion's avatar
Nicolas Carion committed
393
394
395
396
397
398
399
            break;
        case ObjectType::BinClip:
            m_clipMonitor->requestSeek(pos);
            break;
        default:
            qDebug() << "ERROR unhandled object type";
            break;
400
401
        }
    });
402

403
404
    m_effectList2 = new EffectListWidget(this);
    connect(m_effectList2, &EffectListWidget::activateAsset, pCore->projectManager(), &ProjectManager::activateAsset);
405
    connect(m_assetPanel, &AssetPanel::reloadEffect, m_effectList2, &EffectListWidget::reloadCustomEffect);
406
    m_effectListDock = addDock(i18n("Effects"), QStringLiteral("effect_list"), m_effectList2);
Simon Eugster's avatar
Simon Eugster committed
407

408
    m_transitionList2 = new TransitionListWidget(this);
409
    m_transitionListDock = addDock(i18n("Compositions"), QStringLiteral("transition_list"), m_transitionList2);
410

Simon Eugster's avatar
Simon Eugster committed
411
    // Add monitors here to keep them at the right of the window
412
413
    m_clipMonitorDock = addDock(i18n("Clip Monitor"), QStringLiteral("clip_monitor"), m_clipMonitor);
    m_projectMonitorDock = addDock(i18n("Project Monitor"), QStringLiteral("project_monitor"), m_projectMonitor);
Simon Eugster's avatar
Simon Eugster committed
414

415
    m_undoView = new QUndoView();
416
    m_undoView->setCleanIcon(QIcon::fromTheme(QStringLiteral("edit-clear")));
417
418
    m_undoView->setEmptyLabel(i18n("Clean"));
    m_undoView->setGroup(m_commandStack);
419
    m_undoViewDock = addDock(i18n("Undo History"), QStringLiteral("undo_history"), m_undoView);
420

421
    // Color and icon theme stuff
Laurent Montel's avatar
Laurent Montel committed
422
    connect(m_commandStack, &QUndoGroup::cleanChanged, m_saveAction, &QAction::setDisabled);
423
    addAction(QStringLiteral("styles_menu"), stylesAction);
Simon Eugster's avatar
Simon Eugster committed
424

425
426
427
428
429
    QAction *iconAction = new QAction(i18n("Force Breeze Icon Theme"), this);
    iconAction->setCheckable(true);
    iconAction->setChecked(KdenliveSettings::force_breeze());
    addAction(QStringLiteral("force_icon_theme"), iconAction);
    connect(iconAction, &QAction::triggered, this, &MainWindow::forceIconSet);
430

431
    m_mixerDock = addDock(i18n("Audio Mixer"), QStringLiteral("mixer"), pCore->mixer());
432
    QAction *showMixer = new QAction(QIcon::fromTheme(QStringLiteral("view-media-equalizer")), i18n("Audio Mixer"), this);
433
434
    showMixer->setCheckable(true);
    addAction(QStringLiteral("audiomixer_button"), showMixer);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
435
    connect(m_mixerDock, &QDockWidget::visibilityChanged, this, [&, showMixer](bool visible) {
436
437
438
        pCore->mixer()->connectMixer(visible);
        showMixer->setChecked(visible);
    });
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
439
    connect(showMixer, &QAction::triggered, this, [&]() {
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
440
441
        if (m_mixerDock->isVisible() && !m_mixerDock->visibleRegion().isEmpty()) {
            m_mixerDock->close();
442
        } else {
443
444
            m_mixerDock->show();
            m_mixerDock->raise();
445
446
447
        }
    });

Simon Eugster's avatar
Simon Eugster committed
448
449
450
    // Close non-general docks for the initial layout
    // only show important ones
    m_undoViewDock->close();
451
    m_mixerDock->close();
Simon Eugster's avatar
Simon Eugster committed
452

453
    /// Tabify Widgets
454
    tabifyDockWidget(m_clipMonitorDock, m_projectMonitorDock);
455
    tabifyDockWidget(m_transitionListDock, m_effectListDock);
456
    tabifyDockWidget(m_effectStackDock, pCore->bin()->clipPropertiesDock());
457
    bool firstRun = readOptions();
Simon Eugster's avatar
Simon Eugster committed
458

459
    // Build effects menu
460
    m_effectsMenu = new QMenu(i18n("Add Effect"), this);
461
    m_effectActions = new KActionCategory(i18n("Effects"), actionCollection());
462
    m_effectList2->reloadEffectMenu(m_effectsMenu, m_effectActions);
463

464
465
466
    m_transitionsMenu = new QMenu(i18n("Add Transition"), this);
    m_transitionActions = new KActionCategory(i18n("Transitions"), actionCollection());

Nicolas Carion's avatar
Nicolas Carion committed
467
    auto *scmanager = new ScopeManager(this);
468

469
470
    HideTitleBars *titleBars = new HideTitleBars(this);
    connect(layoutManager, &LayoutManagement::updateTitleBars, titleBars, &HideTitleBars::updateTitleBars);
471
    new DockAreaOrientationManager(this);
472
473
    m_extraFactory = new KXMLGUIClient(this);
    buildDynamicActions();
474

475
    // Create Effect Basket (dropdown list of favorites)
476
477
    m_effectBasket = new EffectBasket(this);
    connect(m_effectBasket, &EffectBasket::activateAsset, pCore->projectManager(), &ProjectManager::activateAsset);
478
    connect(m_effectList2, &EffectListWidget::reloadFavorites, m_effectBasket, &EffectBasket::slotReloadBasket);
Nicolas Carion's avatar
Nicolas Carion committed
479
    auto *widgetlist = new QWidgetAction(this);
480
    widgetlist->setDefaultWidget(m_effectBasket);
Nicolas Carion's avatar
Nicolas Carion committed
481
    // widgetlist->setText(i18n("Favorite Effects"));
482
    widgetlist->setToolTip(i18n("Favorite Effects"));
483
    widgetlist->setIcon(QIcon::fromTheme(QStringLiteral("favorite")));
Nicolas Carion's avatar
Nicolas Carion committed
484
    auto *menu = new QMenu(this);
485
486
    menu->addAction(widgetlist);

Nicolas Carion's avatar
Nicolas Carion committed
487
    auto *basketButton = new QToolButton(this);
488
    basketButton->setMenu(menu);
489
    basketButton->setToolButtonStyle(toolBar()->toolButtonStyle());
490
491
    basketButton->setDefaultAction(widgetlist);
    basketButton->setPopupMode(QToolButton::InstantPopup);
Nicolas Carion's avatar
Nicolas Carion committed
492
    // basketButton->setText(i18n("Favorite Effects"));
493
    basketButton->setToolTip(i18n("Favorite Effects"));
494
    basketButton->setIcon(QIcon::fromTheme(QStringLiteral("favorite")));
495

Nicolas Carion's avatar
Nicolas Carion committed
496
    auto *toolButtonAction = new QWidgetAction(this);
497
    toolButtonAction->setText(i18n("Favorite Effects"));
498
    toolButtonAction->setIcon(QIcon::fromTheme(QStringLiteral("favorite")));
499
    toolButtonAction->setDefaultWidget(basketButton);
500
    addAction(QStringLiteral("favorite_effects"), toolButtonAction);
Laurent Montel's avatar
Laurent Montel committed
501
    connect(toolButtonAction, &QAction::triggered, basketButton, &QToolButton::showMenu);
502
    connect(m_effectBasket, &EffectBasket::activateAsset, menu, &QMenu::close);
503

504
505
    // Render button
    ProgressButton *timelineRender = new ProgressButton(i18n("Render"), 100, this);
Nicolas Carion's avatar
Nicolas Carion committed
506
    auto *tlrMenu = new QMenu(this);
507
508
    timelineRender->setMenu(tlrMenu);
    connect(this, &MainWindow::setRenderProgress, timelineRender, &ProgressButton::setProgress);
Nicolas Carion's avatar
Nicolas Carion committed
509
    auto *renderButtonAction = new QWidgetAction(this);
510
    renderButtonAction->setText(i18n("Render Button"));
511
    renderButtonAction->setIcon(QIcon::fromTheme(QStringLiteral("media-record")));
512
513
514
    renderButtonAction->setDefaultWidget(timelineRender);
    addAction(QStringLiteral("project_render_button"), renderButtonAction);

515
    // Timeline preview button
516
    ProgressButton *timelinePreview = new ProgressButton(i18n("Rendering preview"), 1000, this);
Nicolas Carion's avatar
Nicolas Carion committed
517
    auto *tlMenu = new QMenu(this);
518
    timelinePreview->setMenu(tlMenu);
519
    connect(this, &MainWindow::setPreviewProgress, timelinePreview, &ProgressButton::setProgress);
Nicolas Carion's avatar
Nicolas Carion committed
520
    auto *previewButtonAction = new QWidgetAction(this);
521
    previewButtonAction->setText(i18n("Timeline Preview"));
522
    previewButtonAction->setIcon(QIcon::fromTheme(QStringLiteral("preview-render-on")));
523
    previewButtonAction->setDefaultWidget(timelinePreview);
524
    addAction(QStringLiteral("timeline_preview_button"), previewButtonAction);
525

526
    setupGUI(KXmlGuiWindow::ToolBar | KXmlGuiWindow::StatusBar | KXmlGuiWindow::Save | KXmlGuiWindow::Create);
527
    LocaleHandling::resetLocale();
528
    if (firstRun) {
529
        if (QScreen *current = QApplication::primaryScreen()) {
530
531
            int screenHeight = current->availableSize().height();
            if (screenHeight < 1000) {
532
                resize(current->availableSize());
533
            } else if (screenHeight < 2000) {
534
                resize(current->availableSize() / 1.2);
535
            } else {
536
                resize(current->availableSize() / 1.6);
537
538
539
            }
        }
    }
540

541
542
    m_timelineToolBar->setToolButtonStyle(Qt::ToolButtonFollowStyle);
    m_timelineToolBar->setProperty("otherToolbar", true);
543
544
    timelinePreview->setToolButtonStyle(m_timelineToolBar->toolButtonStyle());
    connect(m_timelineToolBar, &QToolBar::toolButtonStyleChanged, timelinePreview, &ProgressButton::setToolButtonStyle);
545

546
    timelineRender->setToolButtonStyle(toolBar()->toolButtonStyle());
547
548
    /*ScriptingPart* sp = new ScriptingPart(this, QStringList());
    guiFactory()->addClient(sp);*/
549

550
    loadGenerators();
551
    loadDockActions();
552
    loadClipActions();
553

554
    // Timeline clip menu
555
556
    QMenu *timelineClipMenu = new QMenu(this);
    timelineClipMenu->addAction(actionCollection()->action(QStringLiteral("edit_copy")));
557
    timelineClipMenu->addAction(actionCollection()->action(QStringLiteral("paste_effects")));
558
559
560
561
562
563
564
565
    timelineClipMenu->addAction(actionCollection()->action(QStringLiteral("group_clip")));
    timelineClipMenu->addAction(actionCollection()->action(QStringLiteral("ungroup_clip")));
    timelineClipMenu->addAction(actionCollection()->action(QStringLiteral("edit_item_duration")));
    timelineClipMenu->addAction(actionCollection()->action(QStringLiteral("clip_split")));
    timelineClipMenu->addAction(actionCollection()->action(QStringLiteral("clip_switch")));
    timelineClipMenu->addAction(actionCollection()->action(QStringLiteral("delete_timeline_clip")));
    timelineClipMenu->addAction(actionCollection()->action(QStringLiteral("extract_clip")));
    timelineClipMenu->addAction(actionCollection()->action(QStringLiteral("save_to_bin")));
566
567

    QMenu *markerMenu = static_cast<QMenu *>(factory()->container(QStringLiteral("marker_menu"), this));
568
    timelineClipMenu->addMenu(markerMenu);
569

570
571
572
573
574
    timelineClipMenu->addAction(actionCollection()->action(QStringLiteral("set_audio_align_ref")));
    timelineClipMenu->addAction(actionCollection()->action(QStringLiteral("align_audio")));
    timelineClipMenu->addAction(actionCollection()->action(QStringLiteral("edit_item_speed")));
    timelineClipMenu->addAction(actionCollection()->action(QStringLiteral("clip_in_project_tree")));
    timelineClipMenu->addAction(actionCollection()->action(QStringLiteral("cut_timeline_clip")));
575

576
577
578
579
580
581
    // Timeline composition menu
    QMenu *compositionMenu = new QMenu(this);
    compositionMenu->addAction(actionCollection()->action(QStringLiteral("edit_item_duration")));
    compositionMenu->addAction(actionCollection()->action(QStringLiteral("edit_copy")));
    compositionMenu->addAction(actionCollection()->action(QStringLiteral("delete_timeline_clip")));

582
583
584
585
586
587
588
589
590
591
592
    // Timeline main menu
    QMenu *timelineMenu = new QMenu(this);
    timelineMenu->addAction(actionCollection()->action(QStringLiteral("edit_paste")));
    timelineMenu->addAction(actionCollection()->action(QStringLiteral("insert_space")));
    timelineMenu->addAction(actionCollection()->action(QStringLiteral("delete_space")));
    timelineMenu->addAction(actionCollection()->action(QStringLiteral("delete_space_all_tracks")));
    timelineMenu->addAction(actionCollection()->action(QStringLiteral("add_guide")));
    timelineMenu->addAction(actionCollection()->action(QStringLiteral("edit_guide")));
    QMenu *guideMenu = new QMenu(i18n("Go to Guide..."), this);
    timelineMenu->addMenu(guideMenu);

593
594
595
596
597
598
    // Timeline ruler menu
    QMenu *timelineRulerMenu = new QMenu(this);
    timelineRulerMenu->addAction(actionCollection()->action(QStringLiteral("add_guide")));
    timelineRulerMenu->addAction(actionCollection()->action(QStringLiteral("edit_guide")));
    timelineRulerMenu->addMenu(guideMenu);
    timelineRulerMenu->addAction(actionCollection()->action(QStringLiteral("add_project_note")));
599
    timelineRulerMenu->addAction(actionCollection()->action(QStringLiteral("add_subtitle")));
600

Sashmita Raghav's avatar
Sashmita Raghav committed
601
602
603
604
    //Timeline subtitle menu
    QMenu *timelineSubtitleMenu = new QMenu(this);
    timelineSubtitleMenu->addAction(actionCollection()->action(QStringLiteral("delete_subtitle_clip")));

605
606
607
608
    // Timeline headers menu
    QMenu *timelineHeadersMenu = new QMenu(this);
    timelineHeadersMenu->addAction(actionCollection()->action(QStringLiteral("insert_track")));
    timelineHeadersMenu->addAction(actionCollection()->action(QStringLiteral("delete_track")));
609
    timelineHeadersMenu->addAction(actionCollection()->action(QStringLiteral("show_track_record")));
610

611
612
613
    QAction *separate_channels = new QAction(QIcon(), i18n("Separate Channels"), this);
    separate_channels->setCheckable(true);
    separate_channels->setChecked(KdenliveSettings::displayallchannels());
614
    separate_channels->setData("separate_channels");
615
616
    connect(separate_channels, &QAction::triggered, this, &MainWindow::slotSeparateAudioChannel);
    timelineHeadersMenu->addAction(separate_channels);
617
618
619
620
621
622
623
    
    QAction *normalize_channels = new QAction(QIcon(), i18n("Normalize Audio Thumbnails"), this);
    normalize_channels->setCheckable(true);
    normalize_channels->setChecked(KdenliveSettings::normalizechannels());
    normalize_channels->setData("normalize_channels");
    connect(normalize_channels, &QAction::triggered, this, &MainWindow::slotNormalizeAudioChannel);
    timelineHeadersMenu->addAction(normalize_channels);
624

625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
    QMenu *thumbsMenu = new QMenu(i18n("Thumbnails"), this);
    QActionGroup *thumbGroup = new QActionGroup(this);
    QAction *inFrame = new QAction(i18n("In Frame"), thumbGroup);
    inFrame->setData(QStringLiteral("2"));
    inFrame->setCheckable(true);
    thumbsMenu->addAction(inFrame);
    QAction *inOutFrame = new QAction(i18n("In/Out Frames"), thumbGroup);
    inOutFrame->setData(QStringLiteral("0"));
    inOutFrame->setCheckable(true);
    thumbsMenu->addAction(inOutFrame);
    QAction *allFrame = new QAction(i18n("All Frames"), thumbGroup);
    allFrame->setData(QStringLiteral("1"));
    allFrame->setCheckable(true);
    thumbsMenu->addAction(allFrame);
    QAction *noFrame = new QAction(i18n("No Thumbnails"), thumbGroup);
    noFrame->setData(QStringLiteral("3"));
    noFrame->setCheckable(true);
    thumbsMenu->addAction(noFrame);
643

644
645
646
647
648
649
650
651
652
653
654
    QMenu *openGLMenu = static_cast<QMenu *>(factory()->container(QStringLiteral("qt_opengl"), this));
#if defined(Q_OS_WIN)
    connect(openGLMenu, &QMenu::triggered, [&](QAction *ac) {
        KdenliveSettings::setOpengl_backend(ac->data().toInt());
        if (KMessageBox::questionYesNo(this, i18n("Kdenlive needs to be restarted to change this setting. Do you want to proceed?")) != KMessageBox::Yes) {
            return;
        }
        slotRestart(false);
    });
#else
    if (openGLMenu) {
655
        openGLMenu->menuAction()->setVisible(false);;
656
657
    }
#endif
658
    // Connect monitor overlay info menu.
Laurent Montel's avatar
Laurent Montel committed
659
    QMenu *monitorOverlay = static_cast<QMenu *>(factory()->container(QStringLiteral("monitor_config_overlay"), this));
Laurent Montel's avatar
Laurent Montel committed
660
    connect(monitorOverlay, &QMenu::triggered, this, &MainWindow::slotSwitchMonitorOverlay);
661

Nicolas Carion's avatar
Nicolas Carion committed
662
663
664
665
    m_projectMonitor->setupMenu(static_cast<QMenu *>(factory()->container(QStringLiteral("monitor_go"), this)), monitorOverlay, m_playZone, m_loopZone, nullptr,
                                m_loopClip);
    m_clipMonitor->setupMenu(static_cast<QMenu *>(factory()->container(QStringLiteral("monitor_go"), this)), monitorOverlay, m_playZone, m_loopZone,
                             static_cast<QMenu *>(factory()->container(QStringLiteral("marker_menu"), this)));
666

Laurent Montel's avatar
Laurent Montel committed
667
    QMenu *clipInTimeline = static_cast<QMenu *>(factory()->container(QStringLiteral("clip_in_timeline"), this));
668
    clipInTimeline->setIcon(QIcon::fromTheme(QStringLiteral("go-jump")));
669
    pCore->bin()->setupGeneratorMenu();
Marco Gittler's avatar
Marco Gittler committed
670

Laurent Montel's avatar
Laurent Montel committed
671
    connect(pCore->monitorManager(), &MonitorManager::updateOverlayInfos, this, &MainWindow::slotUpdateMonitorOverlays);
672

673
    // Setup and fill effects and transitions menus.
Laurent Montel's avatar
Laurent Montel committed
674
    QMenu *m = static_cast<QMenu *>(factory()->container(QStringLiteral("video_effects_menu"), this));
675
676
    connect(m, &QMenu::triggered, this, &MainWindow::slotAddEffect);
    connect(m_effectsMenu, &QMenu::triggered, this, &MainWindow::slotAddEffect);
Laurent Montel's avatar
Laurent Montel committed
677
    connect(m_transitionsMenu, &QMenu::triggered, this, &MainWindow::slotAddTransition);
678

679
680
    m_timelineContextMenu = new QMenu(this);

681
682
    m_timelineContextMenu->addAction(actionCollection()->action(QStringLiteral("insert_space")));
    m_timelineContextMenu->addAction(actionCollection()->action(QStringLiteral("delete_space")));
683
    m_timelineContextMenu->addAction(actionCollection()->action(QStringLiteral("delete_space_all_tracks")));
684
685
    m_timelineContextMenu->addAction(actionCollection()->action(KStandardAction::name(KStandardAction::Paste)));

686
    // QMenu *markersMenu = static_cast<QMenu *>(factory()->container(QStringLiteral("marker_menu"), this));
687
688
689
690
691

    /*m_timelineClipActions->addMenu(markersMenu);
    m_timelineClipActions->addSeparator();
    m_timelineClipActions->addMenu(m_transitionsMenu);
    m_timelineClipActions->addMenu(m_effectsMenu);*/
Marco Gittler's avatar
Marco Gittler committed
692

693
    slotConnectMonitors();
694

695
    m_timelineToolBar->setToolButtonStyle(Qt::ToolButtonIconOnly);
696
    // TODO: let user select timeline toolbar toolbutton style
Nicolas Carion's avatar
Nicolas Carion committed
697
    // connect(toolBar(), &QToolBar::iconSizeChanged, m_timelineToolBar, &QToolBar::setToolButtonStyle);
698
699
    m_timelineToolBar->setContextMenuPolicy(Qt::CustomContextMenu);
    connect(m_timelineToolBar, &QWidget::customContextMenuRequested, this, &MainWindow::showTimelineToolbarMenu);
700
701

    QAction *prevRender = actionCollection()->action(QStringLiteral("prerender_timeline_zone"));
702
703
    QAction *stopPrevRender = actionCollection()->action(QStringLiteral("stop_prerender_timeline"));
    tlMenu->addAction(stopPrevRender);
704
705
    tlMenu->addAction(actionCollection()->action(QStringLiteral("set_render_timeline_zone")));
    tlMenu->addAction(actionCollection()->action(QStringLiteral("unset_render_timeline_zone")));
706
    tlMenu->addAction(actionCollection()->action(QStringLiteral("clear_render_timeline_zone")));
707
708

    // Automatic timeline preview action
709
    QAction *autoRender = new QAction(QIcon::fromTheme(QStringLiteral("view-refresh")), i18n("Automatic Preview"), this);
710
711
712
713
    autoRender->setCheckable(true);
    autoRender->setChecked(KdenliveSettings::autopreview());
    connect(autoRender, &QAction::triggered, this, &MainWindow::slotToggleAutoPreview);
    tlMenu->addAction(autoRender);
714
    tlMenu->addSeparator();
715
    tlMenu->addAction(actionCollection()->action(QStringLiteral("disable_preview")));
716
    tlMenu->addAction(actionCollection()->action(QStringLiteral("manage_cache")));
717
    timelinePreview->defineDefaultAction(prevRender, stopPrevRender);
718
    timelinePreview->setAutoRaise(true);
719

720
721
    QAction *showRender = actionCollection()->action(QStringLiteral("project_render"));
    tlrMenu->addAction(showRender);
722
    tlrMenu->addAction(actionCollection()->action(QStringLiteral("stop_project_render")));
723
    timelineRender->defineDefaultAction(showRender, showRender);
724
725
    timelineRender->setAutoRaise(true);

726
    // Populate encoding profiles
727
    KConfig conf(QStringLiteral("encodingprofiles.rc"), KConfig::CascadeConfig, QStandardPaths::AppDataLocation);
728
    /*KConfig conf(QStringLiteral("encodingprofiles.rc"), KConfig::CascadeConfig, QStandardPaths::AppDataLocation);
729
    if (KdenliveSettings::proxyparams().isEmpty() || KdenliveSettings::proxyextension().isEmpty()) {
730
        KConfigGroup group(&conf, "proxy");
Nicolas Carion's avatar
Nicolas Carion committed
731
        QMap<QString, QString> values = group.entryMap();
732
733
734
        QMapIterator<QString, QString> i(values);
        if (i.hasNext()) {
            i.next();
735
736
737
            QString proxystring = i.value();
            KdenliveSettings::setProxyparams(proxystring.section(QLatin1Char(';'), 0, 0));
            KdenliveSettings::setProxyextension(proxystring.section(QLatin1Char(';'), 1, 1));
738
        }
739
    }*/
740
    if (KdenliveSettings::v4l_parameters().isEmpty() || KdenliveSettings::v4l_extension().isEmpty()) {