mainwindow.cpp 95.9 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          *
 ***************************************************************************/

20
#include <stdlib.h>
21 22

#include <QTextStream>
23
#include <QTimer>
24
#include <QAction>
Marco Gittler's avatar
Marco Gittler committed
25 26
#include <QtTest>
#include <QtCore>
27
#include <QKeyEvent>
28

Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
29 30 31
#include <KApplication>
#include <KAction>
#include <KLocale>
32
#include <KGlobal>
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
33 34 35 36 37 38 39 40
#include <KActionCollection>
#include <KStandardAction>
#include <KFileDialog>
#include <KMessageBox>
#include <KDebug>
#include <KIO/NetAccess>
#include <KSaveFile>
#include <KRuler>
41
#include <KConfigDialog>
42
#include <KXMLGUIFactory>
43
#include <KStatusBar>
44 45
#include <kstandarddirs.h>
#include <KUrlRequesterDialog>
46
#include <KTemporaryFile>
47 48
#include <KActionMenu>
#include <KMenu>
49
#include <locale.h>
50
#include <ktogglefullscreenaction.h>
51
#include <KFileItem>
52 53
#include <KNotification>
#include <KNotifyConfigWidget>
54 55
#include <knewstuff2/engine.h>
#include <knewstuff2/ui/knewstuffaction.h>
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
56

57 58


Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
59
#include "mainwindow.h"
60
#include "mainwindowadaptor.h"
61
#include "kdenlivesettings.h"
62
#include "kdenlivesettingsdialog.h"
63
#include "initeffects.h"
64 65
#include "profilesdialog.h"
#include "projectsettings.h"
66
#include "events.h"
67 68 69 70 71 72 73 74 75 76 77 78
#include "clipmanager.h"
#include "projectlist.h"
#include "monitor.h"
#include "recmonitor.h"
#include "monitormanager.h"
#include "kdenlivedoc.h"
#include "trackview.h"
#include "customtrackview.h"
#include "effectslistview.h"
#include "effectstackview.h"
#include "transitionsettings.h"
#include "renderwidget.h"
79
#include "renderer.h"
80
#ifndef NO_JOGSHUTTLE
81
#include "jogshuttle.h"
82
#endif /* NO_JOGSHUTTLE */
83
#include "clipproperties.h"
84
#include "wizard.h"
85 86
#include "editclipcommand.h"
#include "titlewidget.h"
87 88
#include "markerdialog.h"
#include "clipitem.h"
89

Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
90 91
#include "interfaces.h"

92 93
// #include "scriptingpart.h"

Jean-Baptiste Mardelle's avatar
cleanup  
Jean-Baptiste Mardelle committed
94 95 96 97 98 99
static const int ID_STATUS_MSG = 1;
static const int ID_EDITMODE_MSG = 2;
static const int ID_TIMELINE_MSG = 3;
static const int ID_TIMELINE_BUTTONS = 5;
static const int ID_TIMELINE_POS = 6;
static const int ID_TIMELINE_FORMAT = 7;
100

101 102 103 104
namespace Mlt {
class Producer;
};

Marco Gittler's avatar
Marco Gittler committed
105 106 107 108 109
EffectsList MainWindow::videoEffects;
EffectsList MainWindow::audioEffects;
EffectsList MainWindow::customEffects;
EffectsList MainWindow::transitions;

110
MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, QWidget *parent)
111
        : KXmlGuiWindow(parent),
112 113
        m_activeDocument(NULL), m_activeTimeline(NULL), m_renderWidget(NULL),
#ifndef NO_JOGSHUTTLE
114
        m_jogProcess(NULL),
115
#endif /* NO_JOGSHUTTLE */
116
        m_findActivated(false), m_initialized(false) {
117 118 119 120 121 122

    // Create DBus interface
    new MainWindowAdaptor(this);
    QDBusConnection dbus = QDBusConnection::sessionBus();
    dbus.registerObject("/MainWindow", this);

123
    setlocale(LC_NUMERIC, "POSIX");
124
    setFont(KGlobalSettings::toolBarFont());
125
    parseProfiles(MltPath);
126
    m_commandStack = new QUndoGroup;
127 128
    m_timelineArea = new KTabWidget(this);
    m_timelineArea->setTabReorderingEnabled(true);
129
    m_timelineArea->setTabBarHidden(true);
130 131

    QToolButton *closeTabButton = new QToolButton;
132
    connect(closeTabButton, SIGNAL(clicked()), this, SLOT(closeCurrentDocument()));
133 134 135 136
    closeTabButton->setIcon(KIcon("tab-close"));
    closeTabButton->adjustSize();
    closeTabButton->setToolTip(i18n("Close the current tab"));
    m_timelineArea->setCornerWidget(closeTabButton);
137
    connect(m_timelineArea, SIGNAL(currentChanged(int)), this, SLOT(activateDocument()));
138

139 140 141
    connect(&m_findTimer, SIGNAL(timeout()), this, SLOT(findTimeout()));
    m_findTimer.setSingleShot(true);

Marco Gittler's avatar
Marco Gittler committed
142
    initEffects::parseEffectFiles();
143
    //initEffects::parseCustomEffectsFile();
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
144

145 146 147 148 149 150 151 152 153 154
    m_monitorManager = new MonitorManager();

    projectListDock = new QDockWidget(i18n("Project Tree"), this);
    projectListDock->setObjectName("project_tree");
    m_projectList = new ProjectList(this);
    projectListDock->setWidget(m_projectList);
    addDockWidget(Qt::TopDockWidgetArea, projectListDock);

    effectListDock = new QDockWidget(i18n("Effect List"), this);
    effectListDock->setObjectName("effect_list");
Marco Gittler's avatar
Marco Gittler committed
155
    m_effectList = new EffectsListView();
156 157 158 159 160 161 162

    //m_effectList = new KListWidget(this);
    effectListDock->setWidget(m_effectList);
    addDockWidget(Qt::TopDockWidgetArea, effectListDock);

    effectStackDock = new QDockWidget(i18n("Effect Stack"), this);
    effectStackDock->setObjectName("effect_stack");
Marco Gittler's avatar
Marco Gittler committed
163
    effectStack = new EffectStackView(this);
164 165 166 167 168
    effectStackDock->setWidget(effectStack);
    addDockWidget(Qt::TopDockWidgetArea, effectStackDock);

    transitionConfigDock = new QDockWidget(i18n("Transition"), this);
    transitionConfigDock->setObjectName("transition");
Marco Gittler's avatar
Marco Gittler committed
169
    transitionConfig = new TransitionSettings(this);
170 171 172
    transitionConfigDock->setWidget(transitionConfig);
    addDockWidget(Qt::TopDockWidgetArea, transitionConfigDock);

173 174 175 176
    KdenliveSettings::setCurrent_profile(KdenliveSettings::default_profile());
    m_fileOpenRecent = KStandardAction::openRecent(this, SLOT(openFile(const KUrl &)),
                       actionCollection());
    readOptions();
177 178 179 180 181 182 183 184 185 186 187 188 189 190

    clipMonitorDock = new QDockWidget(i18n("Clip Monitor"), this);
    clipMonitorDock->setObjectName("clip_monitor");
    m_clipMonitor = new Monitor("clip", m_monitorManager, this);
    clipMonitorDock->setWidget(m_clipMonitor);
    addDockWidget(Qt::TopDockWidgetArea, clipMonitorDock);
    //m_clipMonitor->stop();

    projectMonitorDock = new QDockWidget(i18n("Project Monitor"), this);
    projectMonitorDock->setObjectName("project_monitor");
    m_projectMonitor = new Monitor("project", m_monitorManager, this);
    projectMonitorDock->setWidget(m_projectMonitor);
    addDockWidget(Qt::TopDockWidgetArea, projectMonitorDock);

191 192 193 194 195 196 197
    recMonitorDock = new QDockWidget(i18n("Record Monitor"), this);
    recMonitorDock->setObjectName("record_monitor");
    m_recMonitor = new RecMonitor("record", this);
    recMonitorDock->setWidget(m_recMonitor);
    addDockWidget(Qt::TopDockWidgetArea, recMonitorDock);

    connect(m_recMonitor, SIGNAL(addProjectClip(KUrl)), this, SLOT(slotAddProjectClip(KUrl)));
198
    connect(m_recMonitor, SIGNAL(showConfigDialog(int, int)), this, SLOT(slotPreferences(int, int)));
199

200 201 202
    undoViewDock = new QDockWidget(i18n("Undo History"), this);
    undoViewDock->setObjectName("undo_history");
    m_undoView = new QUndoView(this);
203 204
    m_undoView->setCleanIcon(KIcon("edit-clear"));
    m_undoView->setEmptyLabel(i18n("Clean"));
205
    undoViewDock->setWidget(m_undoView);
206
    m_undoView->setGroup(m_commandStack);
207 208
    addDockWidget(Qt::TopDockWidgetArea, undoViewDock);

209 210
    //overviewDock = new QDockWidget(i18n("Project Overview"), this);
    //overviewDock->setObjectName("project_overview");
211 212
    //m_overView = new CustomTrackView(NULL, NULL, this);
    //overviewDock->setWidget(m_overView);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
213
    //addDockWidget(Qt::TopDockWidgetArea, overviewDock);
214 215

    setupActions();
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
216
    //tabifyDockWidget(projectListDock, effectListDock);
217 218
    tabifyDockWidget(projectListDock, effectStackDock);
    tabifyDockWidget(projectListDock, transitionConfigDock);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
219
    //tabifyDockWidget(projectListDock, undoViewDock);
220

221 222

    tabifyDockWidget(clipMonitorDock, projectMonitorDock);
223
    tabifyDockWidget(clipMonitorDock, recMonitorDock);
224 225
    setCentralWidget(m_timelineArea);

226

227
    setupGUI();
228 229 230
    /*ScriptingPart* sp = new ScriptingPart(this, QStringList());
    guiFactory()->addClient(sp);*/

Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
231
    loadPlugins();
232 233
    //kDebug() << factory() << " " << factory()->container("video_effects_menu", this);

234 235
    m_projectMonitor->setupMenu(static_cast<QMenu*>(factory()->container("monitor_go", this)), m_playZone, m_loopZone);
    m_clipMonitor->setupMenu(static_cast<QMenu*>(factory()->container("monitor_go", this)), m_playZone, m_loopZone, static_cast<QMenu*>(factory()->container("marker_menu", this)));
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
236
    m_projectList->setupGeneratorMenu(static_cast<QMenu*>(factory()->container("generators", this)));
Marco Gittler's avatar
Marco Gittler committed
237

238 239
    // build effects menus
    QAction *action;
240
    QMenu *videoEffectsMenu = static_cast<QMenu*>(factory()->container("video_effects_menu", this));
241 242

    QStringList effectInfo;
243
    QMap<QString, QStringList> effectsList;
244
    for (int ix = 0; ix < videoEffects.count(); ix++) {
245
        effectInfo = videoEffects.effectIdInfo(ix);
246 247 248 249 250 251
        effectsList.insert(effectInfo.at(0).toLower(), effectInfo);
    }

    foreach(QStringList value, effectsList) {
        action = new QAction(value.at(0), this);
        action->setData(value);
252 253
        videoEffectsMenu->addAction(action);
    }
254

255
    QMenu *audioEffectsMenu = static_cast<QMenu*>(factory()->container("audio_effects_menu", this));
256

257 258

    effectsList.clear();
259
    for (int ix = 0; ix < audioEffects.count(); ix++) {
260
        effectInfo = audioEffects.effectIdInfo(ix);
261 262 263 264 265 266
        effectsList.insert(effectInfo.at(0).toLower(), effectInfo);
    }

    foreach(QStringList value, effectsList) {
        action = new QAction(value.at(0), this);
        action->setData(value);
267 268
        audioEffectsMenu->addAction(action);
    }
269

270
    m_customEffectsMenu = static_cast<QMenu*>(factory()->container("custom_effects_menu", this));
271 272

    if (customEffects.isEmpty()) m_customEffectsMenu->setEnabled(false);
273 274
    else m_customEffectsMenu->setEnabled(true);

275
    effectsList.clear();
276 277
    for (int ix = 0; ix < customEffects.count(); ix++) {
        effectInfo = customEffects.effectIdInfo(ix);
278 279 280 281 282 283
        effectsList.insert(effectInfo.at(0).toLower(), effectInfo);
    }

    foreach(QStringList value, effectsList) {
        action = new QAction(value.at(0), this);
        action->setData(value);
284
        m_customEffectsMenu->addAction(action);
285 286
    }

287 288 289 290 291 292 293
    QMenu *newEffect = new QMenu(this);
    newEffect->addMenu(videoEffectsMenu);
    newEffect->addMenu(audioEffectsMenu);
    newEffect->addMenu(m_customEffectsMenu);
    effectStack->setMenu(newEffect);


294
    QMenu *viewMenu = static_cast<QMenu*>(factory()->container("dockwindows", this));
295 296 297
    const QList<QAction *> viewActions = createPopupMenu()->actions();
    viewMenu->insertActions(NULL, viewActions);

298 299
    connect(videoEffectsMenu, SIGNAL(triggered(QAction *)), this, SLOT(slotAddVideoEffect(QAction *)));
    connect(audioEffectsMenu, SIGNAL(triggered(QAction *)), this, SLOT(slotAddAudioEffect(QAction *)));
300
    connect(m_customEffectsMenu, SIGNAL(triggered(QAction *)), this, SLOT(slotAddCustomEffect(QAction *)));
301 302 303 304 305

    m_timelineContextMenu = new QMenu(this);
    m_timelineContextClipMenu = new QMenu(this);
    m_timelineContextTransitionMenu = new QMenu(this);

306 307

    QMenu *transitionsMenu = new QMenu(i18n("Add Transition"), this);
308
    QStringList effects = transitions.effectNames();
309 310 311 312 313 314 315 316 317

    effectsList.clear();
    for (int ix = 0; ix < transitions.count(); ix++) {
        effectInfo = transitions.effectIdInfo(ix);
        effectsList.insert(effectInfo.at(0).toLower(), effectInfo);
    }
    foreach(QStringList value, effectsList) {
        action = new QAction(value.at(0), this);
        action->setData(value);
318 319 320 321
        transitionsMenu->addAction(action);
    }
    connect(transitionsMenu, SIGNAL(triggered(QAction *)), this, SLOT(slotAddTransition(QAction *)));

322
    m_timelineContextMenu->addAction(actionCollection()->action("insert_space"));
323
    m_timelineContextMenu->addAction(actionCollection()->action("delete_space"));
324 325
    m_timelineContextMenu->addAction(actionCollection()->action(KStandardAction::name(KStandardAction::Paste)));

326
    m_timelineContextClipMenu->addAction(actionCollection()->action("delete_timeline_clip"));
327
    m_timelineContextClipMenu->addAction(actionCollection()->action("change_clip_speed"));
328
    m_timelineContextClipMenu->addAction(actionCollection()->action("cut_timeline_clip"));
329
    m_timelineContextClipMenu->addAction(actionCollection()->action(KStandardAction::name(KStandardAction::Copy)));
330
    m_timelineContextClipMenu->addAction(actionCollection()->action("paste_effects"));
331

332 333
    QMenu *markersMenu = (QMenu*)(factory()->container("marker_menu", this));
    m_timelineContextClipMenu->addMenu(markersMenu);
334
    m_timelineContextClipMenu->addMenu(transitionsMenu);
335 336
    m_timelineContextClipMenu->addMenu(videoEffectsMenu);
    m_timelineContextClipMenu->addMenu(audioEffectsMenu);
337
    //TODO: re-enable custom effects menu when it is implemented
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
338
    m_timelineContextClipMenu->addMenu(m_customEffectsMenu);
Marco Gittler's avatar
Marco Gittler committed
339

340
    m_timelineContextTransitionMenu->addAction(actionCollection()->action("delete_timeline_clip"));
341
    m_timelineContextTransitionMenu->addAction(actionCollection()->action(KStandardAction::name(KStandardAction::Copy)));
342

343 344
    m_timelineContextTransitionMenu->addAction(actionCollection()->action("auto_transition"));

345 346
    connect(projectMonitorDock, SIGNAL(visibilityChanged(bool)), m_projectMonitor, SLOT(refreshMonitor(bool)));
    connect(clipMonitorDock, SIGNAL(visibilityChanged(bool)), m_clipMonitor, SLOT(refreshMonitor(bool)));
347
    //connect(m_monitorManager, SIGNAL(connectMonitors()), this, SLOT(slotConnectMonitors()));
348 349
    connect(m_monitorManager, SIGNAL(raiseClipMonitor(bool)), this, SLOT(slotRaiseMonitor(bool)));
    connect(m_effectList, SIGNAL(addEffect(QDomElement)), this, SLOT(slotAddEffect(QDomElement)));
350 351
    connect(m_effectList, SIGNAL(reloadEffects()), this, SLOT(slotReloadEffects()));

352
    m_monitorManager->initMonitors(m_clipMonitor, m_projectMonitor);
353
    slotConnectMonitors();
354

355 356 357 358 359
    // Open or create a file.  Command line argument passed in Url has
    // precedence, then "openlastproject", then just a plain empty file.
    // If opening Url fails, openlastproject will _not_ be used.
    if (!Url.isEmpty()) {
        openFile(Url);
360
    } else {
361 362
        if (KdenliveSettings::openlastproject()) {
            openLastFile();
363
        }
364 365
    }
    if (m_timelineArea->count() == 0) {
366
        newFile(false);
367
    }
368

369
#ifndef NO_JOGSHUTTLE
370
    activateShuttleDevice();
371
#endif /* NO_JOGSHUTTLE */
372
    projectListDock->raise();
373
}
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
374

375 376 377 378 379
void MainWindow::queryQuit() {
    kDebug() << "----- SAVING CONFUIG";
    if (queryClose()) kapp->quit();
}

380
//virtual
381 382
bool MainWindow::queryClose() {
    saveOptions();
383
    if (m_monitorManager) m_monitorManager->stopActiveMonitor();
384 385 386 387
    if (m_activeDocument && m_activeDocument->isModified()) {
        switch (KMessageBox::warningYesNoCancel(this, i18n("Save changes to document ?"))) {
        case KMessageBox::Yes :
            // save document here. If saving fails, return false;
388
            return saveFile();
389 390 391 392 393
        case KMessageBox::No :
            return true;
        default: // cancel
            return false;
        }
394
    }
395
    return true;
396 397
}

Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
398 399

void MainWindow::loadPlugins() {
400 401
    foreach(QObject *plugin, QPluginLoader::staticInstances())
    populateMenus(plugin);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
402 403 404 405 406

    QStringList directories = KGlobal::dirs()->findDirs("module", QString());
    QStringList filters;
    filters << "libkdenlive*";
    foreach(const QString &folder, directories) {
407 408 409 410 411 412 413 414 415 416 417
        kDebug() << "// PARSING FIOLER: " << folder;
        QDir pluginsDir(folder);
        foreach(QString fileName, pluginsDir.entryList(filters, QDir::Files)) {
            kDebug() << "// FOUND PLUGIN: " << fileName << "= " << pluginsDir.absoluteFilePath(fileName);
            QPluginLoader loader(pluginsDir.absoluteFilePath(fileName));
            QObject *plugin = loader.instance();
            if (plugin) {
                populateMenus(plugin);
                m_pluginFileNames += fileName;
            } else kDebug() << "// ERROR LOADING PLUGIN: " << fileName << ", " << loader.errorString();
        }
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
418 419 420 421
    }
    //exit(1);
}

422
void MainWindow::populateMenus(QObject *plugin) {
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
423 424 425 426
    QMenu *addMenu = static_cast<QMenu*>(factory()->container("generators", this));
    ClipGenerator *iGenerator = qobject_cast<ClipGenerator *>(plugin);
    if (iGenerator)
        addToMenu(plugin, iGenerator->generators(), addMenu, SLOT(generateClip()),
427
                  NULL);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
428 429 430
}

void MainWindow::addToMenu(QObject *plugin, const QStringList &texts,
431 432 433 434
                           QMenu *menu, const char *member,
                           QActionGroup *actionGroup) {
    kDebug() << "// ADD to MENU" << texts;
    foreach(QString text, texts) {
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
435
        QAction *action = new QAction(text, plugin);
436
        action->setData(text);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
437 438 439 440 441 442 443 444 445 446
        connect(action, SIGNAL(triggered()), this, member);
        menu->addAction(action);

        if (actionGroup) {
            action->setCheckable(true);
            actionGroup->addAction(action);
        }
    }
}

447
void MainWindow::aboutPlugins() {
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
448 449 450 451 452
    //PluginDialog dialog(pluginsDir.path(), m_pluginFileNames, this);
    //dialog.exec();
}


453
void MainWindow::generateClip() {
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
454 455 456
    QAction *action = qobject_cast<QAction *>(sender());
    ClipGenerator *iGenerator = qobject_cast<ClipGenerator *>(action->parent());

457
    KUrl clipUrl = iGenerator->generatedClip(action->data().toString(), m_activeDocument->projectFolder(), QStringList(), QStringList(), 25, 720, 576);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
458
    if (!clipUrl.isEmpty()) {
459
        m_projectList->slotAddClip(clipUrl);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
460 461 462
    }
}

463 464 465 466 467 468 469 470 471 472 473 474
void MainWindow::saveProperties(KConfig*) {
    // save properties here,used by session management
    saveFile();
}


void MainWindow::readProperties(KConfig *config) {
    // read properties here,used by session management
    QString Lastproject = config->group("Recent Files").readPathEntry("File1", QString());
    openFile(KUrl(Lastproject));
}

475 476 477
void MainWindow::slotReloadEffects() {
    initEffects::parseCustomEffectsFile();
    m_customEffectsMenu->clear();
478
    const QStringList effects = customEffects.effectNames();
479
    QAction *action;
480 481 482
    if (effects.isEmpty()) m_customEffectsMenu->setEnabled(false);
    else m_customEffectsMenu->setEnabled(true);

483 484 485 486 487 488 489 490
    foreach(const QString &name, effects) {
        action = new QAction(name, this);
        action->setData(name);
        m_customEffectsMenu->addAction(action);
    }
    m_effectList->reloadEffectList();
}

491
#ifndef NO_JOGSHUTTLE
492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527
void MainWindow::activateShuttleDevice() {
    if (m_jogProcess) delete m_jogProcess;
    m_jogProcess = NULL;
    if (KdenliveSettings::enableshuttle() == false) return;
    m_jogProcess = new JogShuttle(KdenliveSettings::shuttledevice());
    connect(m_jogProcess, SIGNAL(rewind1()), m_monitorManager, SLOT(slotRewindOneFrame()));
    connect(m_jogProcess, SIGNAL(forward1()), m_monitorManager, SLOT(slotForwardOneFrame()));
    connect(m_jogProcess, SIGNAL(rewind(double)), m_monitorManager, SLOT(slotRewind(double)));
    connect(m_jogProcess, SIGNAL(forward(double)), m_monitorManager, SLOT(slotForward(double)));
    connect(m_jogProcess, SIGNAL(stop()), m_monitorManager, SLOT(slotPlay()));
    connect(m_jogProcess, SIGNAL(button(int)), this, SLOT(slotShuttleButton(int)));
}

void MainWindow::slotShuttleButton(int code) {
    switch (code) {
    case 5:
        slotShuttleAction(KdenliveSettings::shuttle1());
        break;
    case 6:
        slotShuttleAction(KdenliveSettings::shuttle2());
        break;
    case 7:
        slotShuttleAction(KdenliveSettings::shuttle3());
        break;
    case 8:
        slotShuttleAction(KdenliveSettings::shuttle4());
        break;
    case 9:
        slotShuttleAction(KdenliveSettings::shuttle5());
        break;
    }
}

void MainWindow::slotShuttleAction(int code) {
    switch (code) {
    case 0:
528
        return;
529 530 531 532 533 534 535 536
    case 1:
        m_monitorManager->slotPlay();
        break;
    default:
        m_monitorManager->slotPlay();
        break;
    }
}
537
#endif /* NO_JOGSHUTTLE */
538

539 540 541 542
void MainWindow::configureNotifications() {
    KNotifyConfigWidget::configure(this);
}

543
void MainWindow::slotFullScreen() {
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
544
    KToggleFullScreenAction::setFullScreen(this, actionCollection()->action("fullscreen")->isChecked());
545 546
}

547 548 549 550 551 552 553
void MainWindow::slotAddEffect(QDomElement effect, GenTime pos, int track) {
    if (!m_activeDocument) return;
    if (effect.isNull()) {
        kDebug() << "--- ERROR, TRYING TO APPEND NULL EFFECT";
        return;
    }
    TrackView *currentTimeLine = (TrackView *) m_timelineArea->currentWidget();
554
    currentTimeLine->projectView()->slotAddEffect(effect.cloneNode().toElement(), pos, track);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
555 556
}

557 558 559
void MainWindow::slotRaiseMonitor(bool clipMonitor) {
    if (clipMonitor) clipMonitorDock->raise();
    else projectMonitorDock->raise();
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
560
}
561

562
void MainWindow::slotSetClipDuration(const QString &id, int duration) {
563 564
    if (!m_activeDocument) return;
    m_activeDocument->setProducerDuration(id, duration);
565 566
}

567
void MainWindow::slotConnectMonitors() {
568

569
    m_projectList->setRenderer(m_projectMonitor->render);
570
    connect(m_projectList, SIGNAL(receivedClipDuration(const QString &, int)), this, SLOT(slotSetClipDuration(const QString &, int)));
571
    connect(m_projectList, SIGNAL(showClipProperties(DocClipBase *)), this, SLOT(slotShowClipProperties(DocClipBase *)));
572 573 574
    connect(m_projectList, SIGNAL(getFileProperties(const QDomElement &, const QString &)), m_projectMonitor->render, SLOT(getFileProperties(const QDomElement &, const QString &)));
    connect(m_projectMonitor->render, SIGNAL(replyGetImage(const QString &, int, const QPixmap &, int, int)), m_projectList, SLOT(slotReplyGetImage(const QString &, int, const QPixmap &, int, int)));
    connect(m_projectMonitor->render, SIGNAL(replyGetFileProperties(const QString &, Mlt::Producer*, const QMap < QString, QString > &, const QMap < QString, QString > &)), m_projectList, SLOT(slotReplyGetFileProperties(const QString &, Mlt::Producer*, const QMap < QString, QString > &, const QMap < QString, QString > &)));
575

576
    connect(m_projectMonitor->render, SIGNAL(removeInvalidClip(const QString &)), m_projectList, SLOT(slotRemoveInvalidClip(const QString &)));
577

578
    connect(m_clipMonitor, SIGNAL(refreshClipThumbnail(const QString &)), m_projectList, SLOT(slotRefreshClipThumbnail(const QString &)));
579 580 581

    connect(m_clipMonitor, SIGNAL(adjustMonitorSize()), this, SLOT(slotAdjustClipMonitor()));
    connect(m_projectMonitor, SIGNAL(adjustMonitorSize()), this, SLOT(slotAdjustProjectMonitor()));
582 583 584

    connect(m_clipMonitor, SIGNAL(saveZone(Render *, QPoint)), this, SLOT(slotSaveZone(Render *, QPoint)));
    connect(m_projectMonitor, SIGNAL(saveZone(Render *, QPoint)), this, SLOT(slotSaveZone(Render *, QPoint)));
585 586 587 588 589 590 591 592 593 594 595 596
}

void MainWindow::slotAdjustClipMonitor() {
    clipMonitorDock->updateGeometry();
    clipMonitorDock->adjustSize();
    m_clipMonitor->resetSize();
}

void MainWindow::slotAdjustProjectMonitor() {
    projectMonitorDock->updateGeometry();
    projectMonitorDock->adjustSize();
    m_projectMonitor->resetSize();
597 598
}

599
void MainWindow::setupActions() {
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
600

601
    KActionCollection* collection = actionCollection();
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617
    m_timecodeFormat = new KComboBox(this);
    m_timecodeFormat->addItem(i18n("hh:mm:ss::ff"));
    m_timecodeFormat->addItem(i18n("Frames"));

    statusProgressBar = new QProgressBar(this);
    statusProgressBar->setMinimum(0);
    statusProgressBar->setMaximum(100);
    statusProgressBar->setMaximumWidth(150);
    statusProgressBar->setVisible(false);

    QWidget *w = new QWidget;

    QHBoxLayout *layout = new QHBoxLayout;
    w->setLayout(layout);
    layout->setContentsMargins(5, 0, 5, 0);
    QToolBar *toolbar = new QToolBar("statusToolBar", this);
618

Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
619 620 621

    m_toolGroup = new QActionGroup(this);

622
    QString style1 = "QToolButton {background-color: rgba(230, 230, 230, 220); border-style: inset; border:1px solid #999999;border-radius: 3px;margin: 0px 3px;padding: 0px;} QToolButton:checked { background-color: rgba(224, 224, 0, 100); border-style: inset; border:1px solid #cc6666;border-radius: 3px;}";
623

624 625
    m_buttonSelectTool = new KAction(KIcon("kdenlive-select-tool"), i18n("Selection tool"), this);
    toolbar->addAction(m_buttonSelectTool);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
626 627 628
    m_buttonSelectTool->setCheckable(true);
    m_buttonSelectTool->setChecked(true);

629 630
    m_buttonRazorTool = new KAction(KIcon("edit-cut"), i18n("Razor tool"), this);
    toolbar->addAction(m_buttonRazorTool);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
631 632 633
    m_buttonRazorTool->setCheckable(true);
    m_buttonRazorTool->setChecked(false);

634 635 636 637 638
    m_buttonSpacerTool = new KAction(KIcon("kdenlive-spacer-tool"), i18n("Spacer tool"), this);
    toolbar->addAction(m_buttonSpacerTool);
    m_buttonSpacerTool->setCheckable(true);
    m_buttonSpacerTool->setChecked(false);

Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
639 640
    m_toolGroup->addAction(m_buttonSelectTool);
    m_toolGroup->addAction(m_buttonRazorTool);
641
    m_toolGroup->addAction(m_buttonSpacerTool);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
642
    m_toolGroup->setExclusive(true);
643
    toolbar->setToolButtonStyle(Qt::ToolButtonIconOnly);
644

645 646 647 648
    QWidget * actionWidget;
    actionWidget = toolbar->widgetForAction(m_buttonSelectTool);
    actionWidget->setMaximumWidth(24);
    actionWidget->setMinimumHeight(17);
649

650 651 652
    actionWidget = toolbar->widgetForAction(m_buttonRazorTool);
    actionWidget->setMaximumWidth(24);
    actionWidget->setMinimumHeight(17);
653

654 655 656 657
    actionWidget = toolbar->widgetForAction(m_buttonSpacerTool);
    actionWidget->setMaximumWidth(24);
    actionWidget->setMinimumHeight(17);

658
    toolbar->setStyleSheet(style1);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
659 660 661
    connect(m_toolGroup, SIGNAL(triggered(QAction *)), this, SLOT(slotChangeTool(QAction *)));

    toolbar->addSeparator();
662 663
    m_buttonFitZoom = new KAction(KIcon("zoom-fit-best"), i18n("Fit zoom to project"), this);
    toolbar->addAction(m_buttonFitZoom);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
664 665 666
    m_buttonFitZoom->setCheckable(false);
    connect(m_buttonFitZoom, SIGNAL(triggered()), this, SLOT(slotFitZoom()));

667 668 669
    actionWidget = toolbar->widgetForAction(m_buttonFitZoom);
    actionWidget->setMaximumWidth(24);
    actionWidget->setMinimumHeight(17);
670

Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
671 672
    m_zoomSlider = new QSlider(Qt::Horizontal, this);
    m_zoomSlider->setMaximum(13);
673
    m_zoomSlider->setPageStep(1);
674

Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
675 676
    m_zoomSlider->setMaximumWidth(150);
    m_zoomSlider->setMinimumWidth(100);
677

678
    const int contentHeight = QFontMetrics(w->font()).height() + 8;
679

680 681
    QString style = "QSlider::groove:horizontal { background-color: rgba(230, 230, 230, 220);border: 1px solid #999999;height: 8px;border-radius: 3px;margin-top:3px }";
    style.append("QSlider::handle:horizontal {  background-color: white; border: 1px solid #999999;width: 9px;margin: -2px 0;border-radius: 3px; }");
682

683 684 685
    m_zoomSlider->setStyleSheet(style);

    //m_zoomSlider->height() + 5;
686
    statusBar()->setMinimumHeight(contentHeight);
687 688


Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
689 690
    toolbar->addWidget(m_zoomSlider);

691 692
    m_buttonVideoThumbs = new KAction(KIcon("kdenlive-show-videothumb"), i18n("Show video thumbnails"), this);
    toolbar->addAction(m_buttonVideoThumbs);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
693
    m_buttonVideoThumbs->setCheckable(true);
694
    m_buttonVideoThumbs->setChecked(KdenliveSettings::videothumbnails());
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
695 696
    connect(m_buttonVideoThumbs, SIGNAL(triggered()), this, SLOT(slotSwitchVideoThumbs()));

697 698
    m_buttonAudioThumbs = new KAction(KIcon("kdenlive-show-audiothumb"), i18n("Show audio thumbnails"), this);
    toolbar->addAction(m_buttonAudioThumbs);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
699
    m_buttonAudioThumbs->setCheckable(true);
700
    m_buttonAudioThumbs->setChecked(KdenliveSettings::audiothumbnails());
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
701
    connect(m_buttonAudioThumbs, SIGNAL(triggered()), this, SLOT(slotSwitchAudioThumbs()));
702

703 704
    m_buttonShowMarkers = new KAction(KIcon("kdenlive-show-markers"), i18n("Show markers comments"), this);
    toolbar->addAction(m_buttonShowMarkers);
705 706 707
    m_buttonShowMarkers->setCheckable(true);
    m_buttonShowMarkers->setChecked(KdenliveSettings::showmarkers());
    connect(m_buttonShowMarkers, SIGNAL(triggered()), this, SLOT(slotSwitchMarkersComments()));
708

709 710
    m_buttonSnap = new KAction(KIcon("kdenlive-snap"), i18n("Snap"), this);
    toolbar->addAction(m_buttonSnap);
711 712 713
    m_buttonSnap->setCheckable(true);
    m_buttonSnap->setChecked(KdenliveSettings::snaptopoints());
    connect(m_buttonSnap, SIGNAL(triggered()), this, SLOT(slotSwitchSnap()));
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
714 715
    layout->addWidget(toolbar);

716

717 718 719
    actionWidget = toolbar->widgetForAction(m_buttonVideoThumbs);
    actionWidget->setMaximumWidth(24);
    actionWidget->setMinimumHeight(17);
720

721 722 723
    actionWidget = toolbar->widgetForAction(m_buttonAudioThumbs);
    actionWidget->setMaximumWidth(24);
    actionWidget->setMinimumHeight(17);
724

725 726 727
    actionWidget = toolbar->widgetForAction(m_buttonShowMarkers);
    actionWidget->setMaximumWidth(24);
    actionWidget->setMinimumHeight(17);
728

729 730 731
    actionWidget = toolbar->widgetForAction(m_buttonSnap);
    actionWidget->setMaximumWidth(24);
    actionWidget->setMinimumHeight(17);
732

733
    m_messageLabel = new StatusBarMessageLabel(this);
734
    m_messageLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::MinimumExpanding);
735 736 737

    statusBar()->addWidget(m_messageLabel, 10);
    statusBar()->addWidget(statusProgressBar, 0);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
738 739 740 741
    statusBar()->insertPermanentWidget(ID_TIMELINE_BUTTONS, w);
    statusBar()->insertPermanentFixedItem("00:00:00:00", ID_TIMELINE_POS);
    statusBar()->insertPermanentWidget(ID_TIMELINE_FORMAT, m_timecodeFormat);
    statusBar()->setMaximumHeight(statusBar()->font().pointSize() * 4);
742
    m_messageLabel->hide();
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
743

744 745
    collection->addAction("select_tool", m_buttonSelectTool);
    collection->addAction("razor_tool", m_buttonRazorTool);
746
    collection->addAction("spacer_tool", m_buttonSpacerTool);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
747

748 749 750 751 752
    collection->addAction("show_video_thumbs", m_buttonVideoThumbs);
    collection->addAction("show_audio_thumbs", m_buttonAudioThumbs);
    collection->addAction("show_markers", m_buttonShowMarkers);
    collection->addAction("snap", m_buttonSnap);
    collection->addAction("zoom_fit", m_buttonFitZoom);
753

754 755 756 757 758 759 760 761 762 763
    KAction* zoomIn = new KAction(KIcon("zoom-in"), i18n("Zoom In"), this);
    collection->addAction("zoom_in", zoomIn);
    connect(zoomIn, SIGNAL(triggered(bool)), this, SLOT(slotZoomIn()));
    zoomIn->setShortcut(Qt::CTRL + Qt::Key_Plus);

    KAction* zoomOut = new KAction(KIcon("zoom-out"), i18n("Zoom Out"), this);
    collection->addAction("zoom_out", zoomOut);
    connect(zoomOut, SIGNAL(triggered(bool)), this, SLOT(slotZoomOut()));
    zoomOut->setShortcut(Qt::CTRL + Qt::Key_Minus);

764
    m_projectSearch = new KAction(KIcon("edit-find"), i18n("Find"), this);
765
    collection->addAction("project_find", m_projectSearch);
766 767
    connect(m_projectSearch, SIGNAL(triggered(bool)), this, SLOT(slotFind()));
    m_projectSearch->setShortcut(Qt::Key_Slash);
768

769
    m_projectSearchNext = new KAction(KIcon("go-down-search"), i18n("Find Next"), this);
770
    collection->addAction("project_find_next", m_projectSearchNext);
771 772 773 774
    connect(m_projectSearchNext, SIGNAL(triggered(bool)), this, SLOT(slotFindNext()));
    m_projectSearchNext->setShortcut(Qt::Key_F3);
    m_projectSearchNext->setEnabled(false);

775
    KAction* profilesAction = new KAction(KIcon("document-new"), i18n("Manage Profiles"), this);
776
    collection->addAction("manage_profiles", profilesAction);
777 778
    connect(profilesAction, SIGNAL(triggered(bool)), this, SLOT(slotEditProfiles()));

779 780
    KAction* fileGHNS = KNS::standardAction(i18n("Download New Lumas..."), this, SLOT(slotGetNewStuff()), actionCollection(), "get_new_stuff");

781 782 783 784
    KAction* wizAction = new KAction(KIcon("configure"), i18n("Run Config Wizard"), this);
    collection->addAction("run_wizard", wizAction);
    connect(wizAction, SIGNAL(triggered(bool)), this, SLOT(slotRunWizard()));

Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
785
    KAction* projectAction = new KAction(KIcon("configure"), i18n("Project Settings"), this);
786
    collection->addAction("project_settings", projectAction);
787 788
    connect(projectAction, SIGNAL(triggered(bool)), this, SLOT(slotEditProjectSettings()));

Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
789
    KAction* projectRender = new KAction(KIcon("media-record"), i18n("Render"), this);
790
    collection->addAction("project_render", projectRender);
791
    projectRender->setShortcut(Qt::CTRL + Qt::Key_Return);
792 793
    connect(projectRender, SIGNAL(triggered(bool)), this, SLOT(slotRenderProject()));

794
    KAction* monitorPlay = new KAction(KIcon("media-playback-start"), i18n("Play"), this);
795 796 797 798
    KShortcut playShortcut;
    playShortcut.setPrimary(Qt::Key_Space);
    playShortcut.setAlternate(Qt::Key_K);
    monitorPlay->setShortcut(playShortcut);
799
    collection->addAction("monitor_play", monitorPlay);
800
    connect(monitorPlay, SIGNAL(triggered(bool)), m_monitorManager, SLOT(slotPlay()));
801

802 803 804 805 806 807 808 809 810 811
    m_playZone = new KAction(KIcon("media-playback-start"), i18n("Play Zone"), this);
    m_playZone->setShortcut(Qt::CTRL + Qt::Key_Space);
    collection->addAction("monitor_play_zone", m_playZone);
    connect(m_playZone, SIGNAL(triggered(bool)), m_monitorManager, SLOT(slotPlayZone()));

    m_loopZone = new KAction(KIcon("media-playback-start"), i18n("Loop Zone"), this);
    m_loopZone->setShortcut(Qt::ALT + Qt::Key_Space);
    collection->addAction("monitor_loop_zone", m_loopZone);
    connect(m_loopZone, SIGNAL(triggered(bool)), m_monitorManager, SLOT(slotLoopZone()));

812
    KAction *markIn = collection->addAction("mark_in");
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
813
    markIn->setText(i18n("Set In Point"));
814 815 816
    markIn->setShortcut(Qt::Key_I);
    connect(markIn, SIGNAL(triggered(bool)), this, SLOT(slotSetInPoint()));

817 818 819 820
    KAction *markOut = collection->addAction("mark_out");
    markOut->setText(i18n("Set Out Point"));
    markOut->setShortcut(Qt::Key_O);
    connect(markOut, SIGNAL(triggered(bool)), this, SLOT(slotSetOutPoint()));
821

822
    KAction* monitorSeekBackward = new KAction(KIcon("media-seek-backward"), i18n("Rewind"), this);
823
    monitorSeekBackward->setShortcut(Qt::Key_J);
824
    collection->addAction("monitor_seek_backward", monitorSeekBackward);
825 826
    connect(monitorSeekBackward, SIGNAL(triggered(bool)), m_monitorManager, SLOT(slotRewind()));

827
    KAction* monitorSeekBackwardOneFrame = new KAction(KIcon("media-skip-backward"), i18n("Rewind 1 Frame"), this);
828
    monitorSeekBackwardOneFrame->setShortcut(Qt::Key_Left);
829
    collection->addAction("monitor_seek_backward-one-frame", monitorSeekBackwardOneFrame);
830 831
    connect(monitorSeekBackwardOneFrame, SIGNAL(triggered(bool)), m_monitorManager, SLOT(slotRewindOneFrame()));

832 833 834 835 836
    KAction* monitorSeekBackwardOneSecond = new KAction(KIcon("media-skip-backward"), i18n("Rewind 1 Second"), this);
    monitorSeekBackwardOneSecond->setShortcut(Qt::SHIFT + Qt::Key_Left);
    collection->addAction("monitor_seek_backward-one-second", monitorSeekBackwardOneSecond);
    connect(monitorSeekBackwardOneSecond, SIGNAL(triggered(bool)), m_monitorManager, SLOT(slotRewindOneSecond()));

837 838
    KAction* monitorSeekSnapBackward = new KAction(KIcon("media-seek-backward"), i18n("Go to Previous Snap Point"), this);
    monitorSeekSnapBackward->setShortcut(Qt::ALT + Qt::Key_Left);
839
    collection->addAction("monitor_seek_snap_backward", monitorSeekSnapBackward);
840 841 842
    connect(monitorSeekSnapBackward, SIGNAL(triggered(bool)), this, SLOT(slotSnapRewind()));

    KAction* monitorSeekForward = new KAction(KIcon("media-seek-forward"), i18n("Forward"), this);
843
    monitorSeekForward->setShortcut(Qt::Key_L);
844
    collection->addAction("monitor_seek_forward", monitorSeekForward);
845 846
    connect(monitorSeekForward, SIGNAL(triggered(bool)), m_monitorManager, SLOT(slotForward()));

847 848
    KAction* clipStart = new KAction(KIcon("media-seek-backward"), i18n("Go to Clip Start"), this);
    clipStart->setShortcut(Qt::Key_Home);
849
    collection->addAction("seek_clip_start", clipStart);
850 851 852 853
    connect(clipStart, SIGNAL(triggered(bool)), this, SLOT(slotClipStart()));

    KAction* clipEnd = new KAction(KIcon("media-seek-forward"), i18n("Go to Clip End"), this);
    clipEnd->setShortcut(Qt::Key_End);
854
    collection->addAction("seek_clip_end", clipEnd);
855 856
    connect(clipEnd, SIGNAL(triggered(bool)), this, SLOT(slotClipEnd()));

857
    KAction* projectStart = new KAction(KIcon("go-first"), i18n("Go to Project Start"), this);
858
    projectStart->setShortcut(Qt::CTRL + Qt::Key_Home);
859
    collection->addAction("seek_start", projectStart);
860 861
    connect(projectStart, SIGNAL(triggered(bool)), m_monitorManager, SLOT(slotStart()));

862
    KAction* projectEnd = new KAction(KIcon("go-last"), i18n("Go to Project End"), this);
863
    projectEnd->setShortcut(Qt::CTRL + Qt::Key_End);
864
    collection->addAction("seek_end", projectEnd);
865 866
    connect(projectEnd, SIGNAL(triggered(bool)), m_monitorManager, SLOT(slotEnd()));

867
    KAction* monitorSeekForwardOneFrame = new KAction(KIcon("media-skip-forward"), i18n("Forward 1 Frame"), this);
868
    monitorSeekForwardOneFrame->setShortcut(Qt::Key_Right);
869
    collection->addAction("monitor_seek_forward-one-frame", monitorSeekForwardOneFrame);
870 871
    connect(monitorSeekForwardOneFrame, SIGNAL(triggered(bool)), m_monitorManager, SLOT(slotForwardOneFrame()));

872 873 874 875 876
    KAction* monitorSeekForwardOneSecond = new KAction(KIcon("media-skip-forward"), i18n("Forward 1 Second"), this);
    monitorSeekForwardOneSecond->setShortcut(Qt::SHIFT + Qt::Key_Right);
    collection->addAction("monitor_seek_forward-one-second", monitorSeekForwardOneSecond);
    connect(monitorSeekForwardOneSecond, SIGNAL(triggered(bool)), m_monitorManager, SLOT(slotForwardOneSecond()));

877 878
    KAction* monitorSeekSnapForward = new KAction(KIcon("media-seek-forward"), i18n("Go to Next Snap Point"), this);
    monitorSeekSnapForward->setShortcut(Qt::ALT + Qt::Key_Right);
879
    collection->addAction("monitor_seek_snap_forward", monitorSeekSnapForward);
880 881
    connect(monitorSeekSnapForward, SIGNAL(triggered(bool)), this, SLOT(slotSnapForward()));

882
    KAction* deleteTimelineClip = new KAction(KIcon("edit-delete"), i18n("Delete Selected Item"), this);
883
    deleteTimelineClip->setShortcut(Qt::Key_Delete);
884
    collection->addAction("delete_timeline_clip", deleteTimelineClip);
885 886
    connect(deleteTimelineClip, SIGNAL(triggered(bool)), this, SLOT(slotDeleteTimelineClip()));

887
    KAction* editTimelineClipSpeed = new KAction(i18n("Change Clip Speed"), this);
888
    collection->addAction("change_clip_speed", editTimelineClipSpeed);
889 890
    connect(editTimelineClipSpeed, SIGNAL(triggered(bool)), this, SLOT(slotChangeClipSpeed()));

891
    KAction *stickTransition = collection->addAction("auto_transition");
892 893 894
    stickTransition->setData(QString("auto"));
    stickTransition->setCheckable(true);
    stickTransition->setEnabled(false);
895 896 897
    stickTransition->setText(i18n("Automatic Transition"));
    connect(stickTransition, SIGNAL(triggered(bool)), this, SLOT(slotAutoTransition()));

Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
898 899
    KAction* cutTimelineClip = new KAction(KIcon("edit-cut"), i18n("Cut Clip"), this);
    cutTimelineClip->setShortcut(Qt::SHIFT + Qt::Key_R);
900
    collection->addAction("cut_timeline_clip", cutTimelineClip);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
901 902
    connect(cutTimelineClip, SIGNAL(triggered(bool)), this, SLOT(slotCutTimelineClip()));

903
    KAction* addClipMarker = new KAction(KIcon("bookmark-new"), i18n("Add Marker"), this);
904
    collection->addAction("add_clip_marker", addClipMarker);
905 906
    connect(addClipMarker, SIGNAL(triggered(bool)), this, SLOT(slotAddClipMarker()));

907
    KAction* deleteClipMarker = new KAction(KIcon("edit-delete"), i18n("Delete Marker"), this);
908
    collection->addAction("delete_clip_marker", deleteClipMarker);
909 910
    connect(deleteClipMarker, SIGNAL(triggered(bool)), this, SLOT(slotDeleteClipMarker()));

911
    KAction* deleteAllClipMarkers = new KAction(KIcon("edit-delete"), i18n("Delete All Markers"), this);
912
    collection->addAction("delete_all_clip_markers", deleteAllClipMarkers);
913 914
    connect(deleteAllClipMarkers, SIGNAL(triggered(bool)), this, SLOT(slotDeleteAllClipMarkers()));

915
    KAction* editClipMarker = new KAction(KIcon("document-properties"), i18n("Edit Marker"), this);
916
    collection->addAction("edit_clip_marker", editClipMarker);
917 918
    connect(editClipMarker, SIGNAL(triggered(bool)), this, SLOT(slotEditClipMarker()));

919 920 921 922
    KAction *insertSpace = new KAction(KIcon(), i18n("Insert Space"), this);
    collection->addAction("insert_space", insertSpace);
    connect(insertSpace, SIGNAL(triggered()), this, SLOT(slotInsertSpace()));

923 924 925 926
    KAction *removeSpace = new KAction(KIcon(), i18n("Remove Space"), this);
    collection->addAction("delete_space", removeSpace);
    connect(removeSpace, SIGNAL(triggered()), this, SLOT(slotRemoveSpace()));

927 928 929 930 931 932 933 934
    KAction *insertTrack = new KAction(KIcon(), i18n("Insert Track"), this);
    collection->addAction("insert_track", insertTrack);
    connect(insertTrack, SIGNAL(triggered()), this, SLOT(slotInsertTrack()));

    KAction *deleteTrack = new KAction(KIcon(), i18n("Delete Track"), this);
    collection->addAction("delete_track", deleteTrack);
    connect(deleteTrack, SIGNAL(triggered()), this, SLOT(slotDeleteTrack()));

935 936 937 938
    KAction *changeTrack = new KAction(KIcon(), i18n("Change Track"), this);
    collection->addAction("change_track", changeTrack);
    connect(changeTrack, SIGNAL(triggered()), this, SLOT(slotChangeTrack()));

939
    KAction *addGuide = new KAction(KIcon("document-new"), i18n("Add Guide"), this);
940
    collection->addAction("add_guide", addGuide);
941 942 943
    connect(addGuide, SIGNAL(triggered()), this, SLOT(slotAddGuide()));

    QAction *delGuide = new KAction(KIcon("edit-delete"), i18n("Delete Guide"), this);
944
    collection->addAction("delete_guide", delGuide);
945 946 947
    connect(delGuide, SIGNAL(triggered()), this, SLOT(slotDeleteGuide()));

    QAction *editGuide = new KAction(KIcon("document-properties"), i18n("Edit Guide"), this);
948
    collection->addAction("edit_guide", editGuide);
949 950 951
    connect(editGuide, SIGNAL(triggered()), this, SLOT(slotEditGuide()));

    QAction *delAllGuides = new KAction(KIcon("edit-delete"), i18n("Delete All Guides"), this);
952
    collection->addAction("delete_all_guides", delAllGuides);
953 954
    connect(delAllGuides, SIGNAL(triggered()), this, SLOT(slotDeleteAllGuides()));

955
    QAction *pasteEffects = new KAction(KIcon("edit-paste"), i18n("Paste Effects"), this);
956
    collection->addAction("paste_effects", pasteEffects);
957 958
    connect(pasteEffects , SIGNAL(triggered()), this, SLOT(slotPasteEffects()));

959
    m_closeAction = KStandardAction::close(this, SLOT(closeCurrentDocument()), collection);
960

Jean-Baptiste Mardelle's avatar