MainWindow.cpp 31.2 KB
Newer Older
Ludovic Fauvet's avatar
Ludovic Fauvet committed
1
/*****************************************************************************
2
 * MainWindow.cpp: VLMC MainWindow
Ludovic Fauvet's avatar
Ludovic Fauvet committed
3
 *****************************************************************************
4
 * Copyright (C) 2008-2014 VideoLAN
Ludovic Fauvet's avatar
Ludovic Fauvet committed
5 6
 *
 * Authors: Ludovic Fauvet <etix@l0cal.com>
7
 *          Hugo Beauzée-Luyssen <hugo@beauzee.fr>
Ludovic Fauvet's avatar
Ludovic Fauvet committed
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
 *
 * 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.
 *****************************************************************************/

24 25
#include "config.h"

26
#include <QSizePolicy>
27
#include <QDockWidget>
28
#include <QFileDialog>
29
#include <QSlider>
30
#include <QMessageBox>
31
#include <QDesktopServices>
32 33
#include <QUndoView>
#include <QUndoStack>
34
#include <QUrl>
35
#include <QNetworkProxy>
36
#include "Main/Core.h"
37
#include "Project/Project.h"
38 39 40
#include "Library/Library.h"
#include "Tools/VlmcDebug.h"
#include "Tools/VlmcLogger.h"
41
#include "EffectsEngine/EffectsEngine.h"
42 43 44 45 46
#include "Backend/IBackend.h"
#include "Workflow/MainWorkflow.h"
#include "Renderer/WorkflowFileRenderer.h"
#include "Renderer/WorkflowRenderer.h"
#include "Renderer/ClipRenderer.h"
47 48 49 50

/* Gui */
#include "MainWindow.h"
#include "About.h"
51
#include "WorkflowFileRendererDialog.h"
52 53
#include "export/RendererSettings.h"
#include "export/ShareOnInternet.h"
54
#include "settings/SettingsDialog.h"
55 56 57

/* Widgets */
#include "DockWidgetManager.h"
58
#include "effectsengine/EffectsListView.h"
59
#include "import/ImportController.h"
60 61 62
#include "library/MediaLibrary.h"
#include "widgets/NotificationZone.h"
#include "preview/PreviewWidget.h"
63 64 65 66
#include "timeline/Timeline.h"
#include "timeline/TracksView.h"

/* Settings / Preferences */
67
#include "project/GuiProjectManager.h"
68
#include "Project/RecentProjects.h"
69
#include "wizard/ProjectWizard.h"
70
#include "Settings/Settings.h"
71
#include "LanguageHelper.h"
72
#include "Commands/KeyboardShortcutHelper.h"
Ludovic Fauvet's avatar
Ludovic Fauvet committed
73

74 75 76 77
MainWindow::MainWindow( Backend::IBackend* backend, QWidget *parent )
    : QMainWindow( parent )
    , m_backend( backend )
    , m_fileRenderer( NULL )
78
    , m_projectPreferences( NULL )
79
    , m_wizard( NULL )
Ludovic Fauvet's avatar
Ludovic Fauvet committed
80 81
{
    m_ui.setupUi( this );
82

83
    Core::getInstance()->logger()->setup();
84 85
    connect( Core::getInstance(), SIGNAL( projectLoading( Project* ) ),
             this, SLOT( onProjectLoading( Project* ) ), Qt::DirectConnection );
86 87
    //Preferences
    initVlmcPreferences();
88 89
    //All preferences have been created: restore them:
    Core::getInstance()->settings()->load();
90

91
    // GUI
92
    DockWidgetManager::getInstance( this )->setMainWindow( this );
93
    createGlobalPreferences();
94
    initializeDockWidgets();
95
    initToolbar();
96
    createStatusBar();
97 98
    checkFolders();
    loadGlobalProxySettings();
Ludovic Fauvet's avatar
Ludovic Fauvet committed
99
#ifdef WITH_CRASHBUTTON
100 101
    setupCrashTester();
#endif
102

Ludovic Fauvet's avatar
Ludovic Fauvet committed
103
    // Zoom
104 105
    connect( m_zoomSlider, SIGNAL( valueChanged( int ) ),
             m_timeline, SLOT( changeZoom( int ) ) );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
106 107 108 109
    connect( m_timeline->tracksView(), SIGNAL( zoomIn() ),
             this, SLOT( zoomIn() ) );
    connect( m_timeline->tracksView(), SIGNAL( zoomOut() ),
             this, SLOT( zoomOut() ) );
110 111
    connect( this, SIGNAL( toolChanged( ToolButtons ) ),
             m_timeline, SLOT( setTool( ToolButtons ) ) );
112

113 114 115 116 117 118 119
    //Connecting Library stuff:
    const ClipRenderer* clipRenderer = qobject_cast<const ClipRenderer*>( m_clipPreview->getGenericRenderer() );
    Q_ASSERT( clipRenderer != NULL );
    connect( m_mediaLibrary, SIGNAL( clipSelected( Clip* ) ),
             clipRenderer, SLOT( setClip( Clip* ) ) );
    connect( m_mediaLibrary, SIGNAL( importRequired() ),
             this, SLOT( on_actionImport_triggered() ) );
120

121

122
#ifdef WITH_CRASHHANDLER
123
    if ( restoreSession() == true )
124 125
        return ;
#endif
126
    // Restore the geometry
127
    restoreGeometry( VLMC_GET_BYTEARRAY( "private/MainWindowGeometry" ) );
128
    // Restore the layout
129
    restoreState( VLMC_GET_BYTEARRAY( "private/MainWindowState" ) );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
130 131
}

132 133
MainWindow::~MainWindow()
{
134 135
    if ( m_fileRenderer )
        delete m_fileRenderer;
136
    delete m_importController;
137 138
}

139 140 141
void
MainWindow::showWizard()
{
142 143
    if ( m_wizard == NULL )
    {
144
        m_wizard = new ProjectWizard( this );
145 146 147
        m_wizard->setModal( true );
    }
    m_wizard->show();
148 149
}

150
void
151
MainWindow::changeEvent( QEvent *e )
Ludovic Fauvet's avatar
Ludovic Fauvet committed
152 153 154 155 156
{
    switch ( e->type() )
    {
    case QEvent::LanguageChange:
        m_ui.retranslateUi( this );
157
        DockWidgetManager::getInstance()->retranslateUi();
Ludovic Fauvet's avatar
Ludovic Fauvet committed
158 159 160 161 162 163
        break;
    default:
        break;
    }
}

164
//use this helper when the shortcut is binded to a menu action
165 166 167
#define CREATE_MENU_SHORTCUT( key, defaultValue, name, desc, actionInstance  )      \
        VLMC_CREATE_PREFERENCE_KEYBOARD( key, defaultValue, name, desc );           \
        new KeyboardShortcutHelper( key, m_ui.actionInstance, this );
168

169 170 171
void
MainWindow::initVlmcPreferences()
{
172
    //Setup VLMC Keyboard Preference...
173 174 175
    VLMC_CREATE_PREFERENCE_KEYBOARD( "keyboard/mediapreview", "Ctrl+Return",
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Media preview" ),
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Preview the selected media, or pause the current preview" ) );
176

177 178 179
    VLMC_CREATE_PREFERENCE_KEYBOARD( "keyboard/renderpreview", "Space",
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Render preview" ),
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Preview the project, or pause the current preview" ) );
180

181
    //A bit nasty, but we better use what Qt's providing as default shortcut
182 183 184 185
    CREATE_MENU_SHORTCUT( "keyboard/undo",
                          QKeySequence( QKeySequence::Undo ).toString().toLocal8Bit(),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Undo" ),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Undo the last action" ), actionUndo );
186

187 188 189 190
    CREATE_MENU_SHORTCUT( "keyboard/redo",
                          QKeySequence( QKeySequence::Redo ).toString().toLocal8Bit(),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Redo" ),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Redo the last action" ), actionRedo );
191

192 193 194 195
    CREATE_MENU_SHORTCUT( "keyboard/help",
                          QKeySequence( QKeySequence::HelpContents ).toString().toLocal8Bit(),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Help" ),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Toggle the help page" ), actionHelp );
196

197 198 199
    CREATE_MENU_SHORTCUT( "keyboard/quit", "Ctrl+Q",
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Quit" ),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Quit VLMC" ), actionQuit );
200

201 202 203
    CREATE_MENU_SHORTCUT( "keyboard/preferences", "Alt+P",
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Preferences" ),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Open VLMC preferences" ), actionPreferences );
204

205 206 207 208
    CREATE_MENU_SHORTCUT( "keyboard/projectpreferences", "Ctrl+P",
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Project preferences" ),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Open the project preferences"), actionProject_Preferences );

209 210 211
    CREATE_MENU_SHORTCUT( "keyboard/fullscreen", "F",
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Fullscreen" ),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Switch to fullscreen mode" ), actionFullscreen );
212

213 214 215
    CREATE_MENU_SHORTCUT( "keyboard/newproject",
                          QKeySequence( QKeySequence::New ).toString().toLocal8Bit(),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "New project" ),
216
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Open the new project wizard" ), actionNew_Project );
217

218 219 220 221
    CREATE_MENU_SHORTCUT( "keyboard/openproject",
                          QKeySequence( QKeySequence::Open ).toString().toLocal8Bit(),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Open a project" ),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Open an existing project" ), actionLoad_Project );
222

223 224 225 226
    CREATE_MENU_SHORTCUT( "keyboard/save",
                          QKeySequence( QKeySequence::Save ).toString().toLocal8Bit(),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Save" ),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Save the current project" ), actionSave );
227

228 229 230
    CREATE_MENU_SHORTCUT( "keyboard/saveas", "Ctrl+Shift+S",
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Save as" ),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Save the current project to a new file" ), actionSave_As );
231

232 233 234 235
    CREATE_MENU_SHORTCUT( "keyboard/closeproject",
                          QKeySequence( QKeySequence::Close ).toString().toLocal8Bit(),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Close the project" ),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Close the current project" ), actionClose_Project );
236

237 238 239
    CREATE_MENU_SHORTCUT( "keyboard/importmedia", "Ctrl+I",
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Import media" ),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Open the import window" ), actionImport );
240

241 242 243 244
    CREATE_MENU_SHORTCUT( "keyboard/renderproject", "Ctrl+R",
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Render the project" ),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Render the project to a file" ), actionRender );

245 246 247 248 249 250 251 252
    CREATE_MENU_SHORTCUT( "keyboard/defaultmode", "n",
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Selection mode" ),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Select the selection tool in the timeline" ), actionSelection_mode );

    CREATE_MENU_SHORTCUT( "keyboard/cutmode", "x",
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Cut mode" ),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Select the cut/razor tool in the timeline" ), actionCut_mode );

253
    //Setup VLMC Lang. Preferences...
254
    VLMC_CREATE_PREFERENCE_LANGUAGE( "vlmc/VLMCLang", "default",
255
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Language" ),
256
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "The VLMC's UI language" ) );
257

258
    Core::getInstance()->settings()->watchValue( "vlmc/VLMCLang",
259
                                                LanguageHelper::getInstance(),
260
                                                SLOT( languageChanged( const QVariant& ) ) );
261
    //Setup VLMC General Preferences...
262
    VLMC_CREATE_PREFERENCE_BOOL( "vlmc/ConfirmDeletion", true,
263
                                 QT_TRANSLATE_NOOP( "PreferenceWidget", "Confirm clip deletion"),
264
                                 QT_TRANSLATE_NOOP( "PreferenceWidget", "Ask for confirmation before deleting a clip from the timeline" ) );
265

266
    VLMC_CREATE_PREFERENCE_PATH( "vlmc/DefaultProjectLocation", QDir::homePath(),
Rohit Yadav's avatar
Rohit Yadav committed
267
                                    QT_TRANSLATE_NOOP( "PreferenceWidget", "Project default location" ),
268 269
                                    QT_TRANSLATE_NOOP( "PreferenceWidget", "The default location where to store projects folders" ) );

270
    VLMC_CREATE_PREFERENCE_PATH( "vlmc/TempFolderLocation", QDir::tempPath() + "/VLMC/",
Rohit Yadav's avatar
Rohit Yadav committed
271
                                    QT_TRANSLATE_NOOP( "PreferenceWidget", "Temporary folder" ),
272 273
                                    QT_TRANSLATE_NOOP( "PreferenceWidget", "The temporary folder used by VLMC to process videos." ) );

274
    //Setup VLMC Youtube Preference...
275
    VLMC_CREATE_PREFERENCE_STRING( "youtube/DeveloperKey", "",
276
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Youtube Developer Key" ),
277
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "VLMC's Youtube Developer Key" ) );
278 279 280

    VLMC_CREATE_PREFERENCE_STRING( "youtube/Username", "username",
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Youtube Username" ),
281 282 283 284
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Valid YouTube username" ) );

    VLMC_CREATE_PREFERENCE_PASSWORD( "youtube/Password", "",
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Youtube Password" ),
285
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Leave this field empty, password will be stored in unencrypted form." ) );
286 287

    //Setup VLMC Proxy Settings
288 289 290 291 292 293 294
    VLMC_CREATE_PREFERENCE_BOOL( "network/UseProxy", false,
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Enable Proxy for VLMC"),
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Enables Global Network Proxy for VLMC." ) );

    VLMC_CREATE_PREFERENCE_STRING( "network/ProxyHost", "",
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Proxy Hostname" ),
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Set Proxy Hostname." ) );
295 296 297

    VLMC_CREATE_PREFERENCE_STRING( "network/ProxyPort", "",
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Proxy Port" ),
298
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Set Proxy Port." ) );
299 300 301

    VLMC_CREATE_PREFERENCE_STRING( "network/ProxyUsername", "",
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Proxy Username" ),
302
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Set Proxy Username, if any." ) );
303

304
    VLMC_CREATE_PREFERENCE_PASSWORD( "network/ProxyPassword", "",
305
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Proxy Password" ),
306
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Set Proxy Password, if any." ) );
307

308 309 310 311 312 313
    // Setup private variables
    VLMC_CREATE_PRIVATE_PREFERENCE_BOOL( "private/CleanQuit", true );
    VLMC_CREATE_PRIVATE_PREFERENCE_STRING( "private/EmergencyBackup", "" );
    VLMC_CREATE_PRIVATE_PREFERENCE_STRING( "private/ImportPreviouslySelectPath", QDir::homePath() );
    VLMC_CREATE_PRIVATE_PREFERENCE_BYTEARRAY( "private/MainWindowGeometry", "" );
    VLMC_CREATE_PRIVATE_PREFERENCE_BYTEARRAY( "private/MainWindowState", "" );
314 315
}

316 317
#undef CREATE_MENU_SHORTCUT

318 319
void
MainWindow::on_actionSave_triggered()
320
{
321
    Project::getInstance()->save();
322 323
}

324
void
325
MainWindow::on_actionSave_As_triggered()
326
{
327
    Project::getInstance()->saveAs();
328 329
}

330
void
331
MainWindow::on_actionLoad_Project_triggered()
332
{
333 334 335 336 337
    // FIXME: We probably could use a default folder.
    QString fileName = QFileDialog::getOpenFileName( NULL, tr( "Please choose a project file" ),
                                    "", tr( "VLMC project file(*.vlmc)" ) );
    if ( fileName.isEmpty() == true )
        return ;
338
    Project::load( fileName );
339 340
}

341 342 343 344 345 346 347 348 349 350
void
MainWindow::createNotificationZone()
{
    QWidget *notifSpacer = new QWidget( this );
    notifSpacer->setFixedWidth( 75 );
    m_ui.statusbar->addPermanentWidget( notifSpacer );

    m_ui.statusbar->addPermanentWidget( NotificationZone::getInstance() );
}

351
void
352
MainWindow::createStatusBar()
353
{
354 355 356
    //Notifications:
    createNotificationZone();

357 358 359 360 361
    // Spacer
    QWidget* spacer = new QWidget( this );
    spacer->setFixedWidth( 20 );
    m_ui.statusbar->addPermanentWidget( spacer );

362 363 364
    // Zoom Out
    QToolButton* zoomOutButton = new QToolButton( this );
    zoomOutButton->setIcon( QIcon( ":/images/zoomout" ) );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
365
    zoomOutButton->setStatusTip( tr( "Zoom out" ) );
366 367 368
    m_ui.statusbar->addPermanentWidget( zoomOutButton );
    connect( zoomOutButton, SIGNAL( clicked() ),
             this, SLOT( zoomOut() ) );
369 370

    // Zoom slider
371 372 373 374 375 376 377 378 379
    m_zoomSlider = new QSlider( this );
    m_zoomSlider->setOrientation( Qt::Horizontal );
    m_zoomSlider->setTickInterval( 1 );
    m_zoomSlider->setSingleStep( 1 );
    m_zoomSlider->setPageStep( 1 );
    m_zoomSlider->setMinimum( 0 );
    m_zoomSlider->setMaximum( 13 );
    m_zoomSlider->setValue( 10 );
    m_zoomSlider->setFixedWidth( 80 );
380
    m_zoomSlider->setInvertedAppearance( true );
381
    m_ui.statusbar->addPermanentWidget( m_zoomSlider );
382

383 384 385
    // Zoom IN
    QToolButton* zoomInButton = new QToolButton( this );
    zoomInButton->setIcon( QIcon( ":/images/zoomin" ) );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
386
    zoomInButton->setStatusTip( tr( "Zoom in" ) );
387 388 389
    m_ui.statusbar->addPermanentWidget( zoomInButton );
    connect( zoomInButton, SIGNAL( clicked() ),
             this, SLOT( zoomIn() ) );
390 391
}

392
void
393
MainWindow::initializeDockWidgets()
394
{
395
    m_timeline = new Timeline( this );
396 397 398
    m_timeline->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
    m_timeline->show();
    setCentralWidget( m_timeline );
399

400
    m_importController = new ImportController();
401

402
    setupLibrary();
403 404 405 406 407
    setupEffectsList();
    setupClipPreview();
    setupProjectPreview();
    setupUndoRedoWidget();
}
408

409 410 411 412 413 414 415
void
MainWindow::setupUndoRedoWidget()
{
    QDockWidget     *dockedWidget = DockWidgetManager::getInstance()->createDockedWidget(
                                      QT_TRANSLATE_NOOP( "DockWidgetManager", "History" ),
                                      Qt::AllDockWidgetAreas,
                                      QDockWidget::AllDockWidgetFeatures );
416
    QUndoView       *undoRedoWidget = new QUndoView( dockedWidget );
417
    DockWidgetManager::getInstance()->addDockedWidget( dockedWidget, undoRedoWidget, Qt::TopDockWidgetArea );
418
}
419

420 421 422 423 424 425 426 427 428
void
MainWindow::setupEffectsList()
{
    QDockWidget     *dockedWidget = DockWidgetManager::getInstance()->createDockedWidget(
                                        QT_TRANSLATE_NOOP( "DockWidgetManager", "Effects List" ),
                                        Qt::AllDockWidgetAreas,
                                        QDockWidget::AllDockWidgetFeatures );
    m_effectsList = new EffectsListView( dockedWidget );
    m_effectsList->setType( Effect::Filter );
429
    Core::getInstance()->effectsEngine()->loadEffects();
430
    DockWidgetManager::getInstance()->addDockedWidget( dockedWidget, m_effectsList, Qt::TopDockWidgetArea );
431 432 433 434 435 436 437 438 439 440
}

void
MainWindow::setupLibrary()
{
    QDockWidget     *dockedLibrary = DockWidgetManager::getInstance()->createDockedWidget(
                                                    QT_TRANSLATE_NOOP( "DockWidgetManager", "Media Library" ),
                                                    Qt::AllDockWidgetAreas,
                                                    QDockWidget::AllDockWidgetFeatures );
    m_mediaLibrary = new MediaLibrary( dockedLibrary );
441
    DockWidgetManager::getInstance()->addDockedWidget( dockedLibrary, m_mediaLibrary, Qt::TopDockWidgetArea );
442 443 444
}

void
445
MainWindow::setupClipPreview()
446
{
447 448 449 450 451 452
    QDockWidget *dockedWidget = DockWidgetManager::getInstance()->createDockedWidget(
                                                QT_TRANSLATE_NOOP( "DockWidgetManager", "Clip Preview" ),
                                                Qt::AllDockWidgetAreas,
                                                QDockWidget::AllDockWidgetFeatures );
    m_clipPreview = new PreviewWidget( dockedWidget );
    m_clipPreview->setRenderer( new ClipRenderer );
453

454 455 456 457 458 459 460 461 462 463 464 465 466 467
    KeyboardShortcutHelper* clipShortcut = new KeyboardShortcutHelper( "keyboard/mediapreview", this );
    connect( clipShortcut, SIGNAL( activated() ), m_clipPreview, SLOT( on_pushButtonPlay_clicked() ) );
    DockWidgetManager::getInstance()->addDockedWidget( dockedWidget, m_clipPreview, Qt::TopDockWidgetArea );
}

void
MainWindow::setupProjectPreview()
{
    QDockWidget     *dockedWidget = DockWidgetManager::getInstance()->createDockedWidget(
                                        QT_TRANSLATE_NOOP( "DockWidgetManager", "Project Preview" ),
                                        Qt::AllDockWidgetAreas,
                                        QDockWidget::AllDockWidgetFeatures );

    m_projectPreview = new PreviewWidget( dockedWidget );
468
    m_projectPreview->setClipEdition( false );
469 470 471
    KeyboardShortcutHelper* renderShortcut = new KeyboardShortcutHelper( "keyboard/renderpreview", this );
    connect( renderShortcut, SIGNAL( activated() ), m_projectPreview, SLOT( on_pushButtonPlay_clicked() ) );
    DockWidgetManager::getInstance()->addDockedWidget( dockedWidget, m_projectPreview, Qt::TopDockWidgetArea );
472 473
}

474 475 476 477 478 479 480 481 482 483 484 485 486
void
MainWindow::initToolbar()
{
    QActionGroup    *mouseActions = new QActionGroup( m_ui.toolBar );
    mouseActions->addAction( m_ui.actionSelection_mode );
    mouseActions->addAction( m_ui.actionCut_mode );
    m_ui.actionSelection_mode->setChecked( true );
    m_ui.toolBar->addActions( mouseActions->actions() );
    connect( mouseActions, SIGNAL( triggered(QAction*) ),
             this, SLOT( toolButtonClicked( QAction* ) ) );
    m_ui.menuTools->addActions( mouseActions->actions() );
}

487 488
void
MainWindow::createGlobalPreferences()
489
{
490 491 492 493 494
    m_globalPreferences = new SettingsDialog( Core::getInstance()->settings(), tr( "VLMC Preferences" ), this );
    m_globalPreferences->addCategory( "vlmc", QT_TRANSLATE_NOOP( "Settings", "General" ), QIcon( ":/images/vlmc" ) );
    m_globalPreferences->addCategory( "keyboard", QT_TRANSLATE_NOOP( "Settings", "Keyboard" ), QIcon( ":/images/keyboard" ) );
    m_globalPreferences->addCategory( "youtube", QT_TRANSLATE_NOOP( "Settings", "YouTube" ), QIcon( ":/images/youtube" ) );
    m_globalPreferences->addCategory( "network", QT_TRANSLATE_NOOP( "Settings", "Network" ), QIcon( ":/images/network" ) );
495 496
}

497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515
void
MainWindow::loadGlobalProxySettings()
{
    if( VLMC_GET_BOOL( "network/UseProxy" ) )
    {
        /* Updates Global Proxy for VLMC */
        QNetworkProxy proxy;
        proxy.setType( QNetworkProxy::HttpProxy );
        proxy.setHostName( VLMC_GET_STRING( "network/ProxyHost" ) );
        proxy.setPort( VLMC_GET_STRING( "network/ProxyPort" ).toInt() );
        proxy.setUser( VLMC_GET_STRING( "network/ProxyUsername" ) );
        proxy.setPassword( VLMC_GET_STRING( "network/ProxyPassword" ) );
        QNetworkProxy::setApplicationProxy( proxy );
        return;
    }

    QNetworkProxy::setApplicationProxy( QNetworkProxy::NoProxy );
}

516 517
void
MainWindow::createProjectPreferences()
518
{
519
    delete m_projectPreferences;
520 521 522 523
    m_projectPreferences = new SettingsDialog( Project::getInstance()->settings(), tr( "Project preferences" ), this );
    m_projectPreferences->addCategory( "general", QT_TRANSLATE_NOOP( "Settings", "General" ), QIcon( ":/images/vlmc" ) );
    m_projectPreferences->addCategory( "video", QT_TRANSLATE_NOOP( "Settings", "Video" ), QIcon( ":/images/video" ) );
    m_projectPreferences->addCategory( "audio", QT_TRANSLATE_NOOP( "Settings", "Audio" ), QIcon( ":/images/audio" ) );
524 525
}

526 527 528 529
void
MainWindow::checkFolders()
{
    QDir dirUtil;
530 531
    if ( !dirUtil.exists( VLMC_GET_STRING( "vlmc/DefaultProjectLocation" ) ) )
        dirUtil.mkdir( VLMC_GET_STRING( "vlmc/DefaultProjectLocation" ) );
532

533 534
    if ( !dirUtil.exists( VLMC_GET_STRING( "vlmc/TempFolderLocation" ) ) )
        dirUtil.mkdir( VLMC_GET_STRING( "vlmc/TempFolderLocation" ) );
535 536
}

537 538 539 540
void
MainWindow::clearTemporaryFiles()
{
    QDir dirUtil;
541
    if( dirUtil.cd( VLMC_GET_STRING( "vlmc/TempFolderLocation" ) ) )
542 543 544
        foreach ( const QString &file, dirUtil.entryList( QDir::Files ) )
            dirUtil.remove( file );
}
545

546 547
//Private slots definition

548
void
549
MainWindow::on_actionQuit_triggered()
Ludovic Fauvet's avatar
Ludovic Fauvet committed
550
{
551
    saveSettings();
Ludovic Fauvet's avatar
Ludovic Fauvet committed
552 553
    QApplication::quit();
}
554

555
void
556
MainWindow::on_actionPreferences_triggered()
557
{
558
   m_globalPreferences->show();
559
}
Ludovic Fauvet's avatar
Ludovic Fauvet committed
560

561
void
562
MainWindow::on_actionAbout_triggered()
Ludovic Fauvet's avatar
Ludovic Fauvet committed
563
{
564
    About::getInstance()->exec();
Ludovic Fauvet's avatar
Ludovic Fauvet committed
565
}
566

567 568
bool
MainWindow::checkVideoLength()
569
{
570
    if ( Project::getInstance()->workflow()->getLengthFrame() <= 0 )
571
    {
572
        QMessageBox::warning( NULL, tr ( "VLMC Renderer" ), tr( "There is nothing to render." ) );
573
        return false;
574
    }
575 576 577
    return true;
}

578
bool
579 580 581 582
MainWindow::renderVideo( const QString& outputFileName, quint32 width, quint32 height, double fps, quint32 vbitrate, quint32 abitrate )
{
    if ( m_fileRenderer )
        delete m_fileRenderer;
583
    m_fileRenderer = new WorkflowFileRenderer( m_backend, Project::getInstance()->workflow() );
584

Rohit Yadav's avatar
Rohit Yadav committed
585
    WorkflowFileRendererDialog  *dialog = new WorkflowFileRendererDialog( m_fileRenderer, width, height );
586 587 588 589
    dialog->setModal( true );
    dialog->setOutputFileName( outputFileName );

    m_fileRenderer->run( outputFileName, width, height, fps, vbitrate, abitrate );
590 591 592 593 594 595 596

    if ( dialog->exec() == QDialog::Rejected )
    {
        delete dialog;
        return false;
    }

597
    delete dialog;
598 599 600 601
    return true;
}

bool
602
MainWindow::renderVideoSettings( bool shareOnInternet )
603
{
604 605
    Project::getInstance()->workflowRenderer()->stop();

606
    RendererSettings *settings = new RendererSettings( shareOnInternet );
607 608 609 610 611 612 613

    if ( settings->exec() == QDialog::Rejected )
    {
        delete settings;
        return false;
    }

614
    QString     outputFileName = settings->outputFileName();
615 616 617 618 619 620
    quint32     width          = settings->width();
    quint32     height         = settings->height();
    double      fps            = settings->fps();
    quint32     vbitrate       = settings->videoBitrate();
    quint32     abitrate       = settings->audioBitrate();

621 622
    delete settings;

623
    return renderVideo( outputFileName, width, height, fps, vbitrate, abitrate );
624 625
}

626
void
627 628 629
MainWindow::on_actionRender_triggered()
{
    if ( checkVideoLength() )
630
    {
631
        //Setup dialog box for querying render parameters.
632
        renderVideoSettings( false );
633
    }
634 635
}

636
void
637
MainWindow::on_actionShare_On_Internet_triggered()
638 639 640
{
    if ( checkVideoLength() )
    {
641 642
        if( !renderVideoSettings( true ) )
            return;
643

644
        checkFolders();
645 646
        QString fileName = VLMC_GET_STRING( "vlmc/TempFolderLocation" ) + "/" +
                           VLMC_PROJECT_GET_STRING( "vlmc/ProjectName" ) +
647
                           "-vlmc.mp4";
648

649
        loadGlobalProxySettings();
650

651 652
        ShareOnInternet *shareVideo = new ShareOnInternet();
        shareVideo->setVideoFile( fileName );
653

654 655 656 657 658
        if ( shareVideo->exec() == QDialog::Rejected )
        {
            delete shareVideo;
            return;
        }
659

660
        delete shareVideo;
661 662 663
    }
}

664
void
665
MainWindow::on_actionNew_Project_triggered()
666
{
667 668
    m_wizard->restart();
    m_wizard->show();
669 670
}

671
void
672
MainWindow::on_actionHelp_triggered()
673
{
674
    QDesktopServices::openUrl( QUrl( "http://videolan.org/vlmc" ) );
675 676
}

677
void
678
MainWindow::zoomIn()
Ludovic Fauvet's avatar
Ludovic Fauvet committed
679 680 681 682
{
    m_zoomSlider->setValue( m_zoomSlider->value() - 1 );
}

683
void
684
MainWindow::zoomOut()
Ludovic Fauvet's avatar
Ludovic Fauvet committed
685 686 687
{
    m_zoomSlider->setValue( m_zoomSlider->value() + 1 );
}
Ludovic Fauvet's avatar
Ludovic Fauvet committed
688

689
void
690
MainWindow::on_actionFullscreen_triggered( bool checked )
Ludovic Fauvet's avatar
Ludovic Fauvet committed
691
{
692 693 694
    if ( checked && !isFullScreen() )
    {
        setUnifiedTitleAndToolBarOnMac( false );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
695
        showFullScreen();
696
    }
Ludovic Fauvet's avatar
Ludovic Fauvet committed
697
    else
698 699
    {
        setUnifiedTitleAndToolBarOnMac( true );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
700
        showNormal();
701
    }
Ludovic Fauvet's avatar
Ludovic Fauvet committed
702
}
703

704
void
705
MainWindow::registerWidgetInWindowMenu( QDockWidget* widget )
706
{
707
    m_ui.menuWindow->addAction( widget->toggleViewAction() );
708
}
709

710
void
711
MainWindow::toolButtonClicked( QAction *action )
712
{
713 714 715 716 717
    if ( action == m_ui.actionSelection_mode )
        emit toolChanged( TOOL_DEFAULT );
    else if ( action == m_ui.actionCut_mode )
        emit toolChanged( TOOL_CUT );
    else
718
        vlmcCritical() << "Unknown tool. This should not happen !";
719
}
720

721
void
722
MainWindow::on_actionProject_Preferences_triggered()
723
{
724
  m_projectPreferences->show();
725
}
726

727 728
bool
MainWindow::saveSettings()
729
{
730
    // ??????
731
    clearTemporaryFiles();
732 733 734 735 736 737 738
    Settings* settings = Core::getInstance()->settings();
    // Save the current geometry
    settings->setValue( "private/MainWindowGeometry", saveGeometry() );
    // Save the current layout
    settings->setValue( "private/MainWindowState", saveState() );
    settings->setValue( "private/CleanQuit", true );
    settings->save();
739
    Project::getInstance()->save();
740
    return true;
741 742 743 744 745 746
}

void
MainWindow::closeEvent( QCloseEvent* e )
{
    if ( saveSettings() )
747
        e->accept();
748 749
    else
        e->ignore();
750
}
751

752
void
753
MainWindow::projectUpdated( const QString& projectName )
754 755
{
    QString title = tr( "VideoLAN Movie Creator" );
756
    title += " - ";
757
    title += projectName;
758 759 760 761 762 763 764 765 766 767
    setWindowTitle( title );
}

void
MainWindow::cleanStateChanged( bool isClean )
{
    QString title = windowTitle();
    if ( isClean == true )
        title.replace(" *", "");
    else
768 769 770
        title += " *";
    setWindowTitle( title );
}
771

772
void
773
MainWindow::on_actionUndo_triggered()
774
{
775
    Project::getInstance()->undoStack()->undo();
776 777
}

778
void
779
MainWindow::on_actionRedo_triggered()
780
{
781
    Project::getInstance()->undoStack()->redo();
782 783
}

784
void
785
MainWindow::on_actionCrash_triggered()
786
{
787 788 789 790 791
    //WARNING: read this part at your own risk !!
    //I'm not responsible if you puke while reading this :D
    QString str;
    int test = 1 / str.length();
    Q_UNUSED( test );
792
}
793

794
bool
795
MainWindow::restoreSession()
796
{
797 798
    bool    cleanQuit = VLMC_GET_BOOL( "private/CleanQuit" );
    bool    ret = false;
799

800
    if ( cleanQuit == false )
801
    {
802 803 804
        QMessageBox::StandardButton res = QMessageBox::question( this, tr( "Crash recovery" ), tr( "VLMC didn't closed nicely. Do you want to recover your project?" ),
                               QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes );
        if ( res == QMessageBox::Yes )
805
        {
806
            if ( Project::getInstance()->loadEmergencyBackup() == true )
807 808 809
                ret = true;
            else
                QMessageBox::warning( this, tr( "Can't restore project" ), tr( "VLMC didn't manage to restore your project. We apology for the inconvenience" ) );
810 811
        }
    }
812
    Core::getInstance()->settings()->setValue( "private/CleanQuit", true );
813 814
    return ret;
}
815

816
void
817
MainWindow::on_actionImport_triggered()
818 819 820
{
    m_importController->exec();
}
821

822
void
823
MainWindow::canUndoChanged( bool canUndo )
824 825 826 827
{
    m_ui.actionUndo->setEnabled( canUndo );
}

828
void
829
MainWindow::canRedoChanged( bool canRedo )
830 831 832 833
{
    m_ui.actionRedo->setEnabled( canRedo );
}

834
void
835
MainWindow::onProjectLoading(Project* project)
836 837 838 839 840 841 842 843 844
{
    createProjectPreferences();
    connect( project, SIGNAL( projectUpdated( const QString&, bool ) ), this, SLOT( projectUpdated( const QString&, bool ) ) );

    // Undo/Redo
    connect( project->undoStack(), SIGNAL( canUndoChanged( bool ) ), this, SLOT( canUndoChanged( bool ) ) );
    connect( project->undoStack(), SIGNAL( canRedoChanged( bool ) ), this, SLOT( canRedoChanged( bool ) ) );
    canUndoChanged( project->undoStack()->canUndo() );
    canRedoChanged( project->undoStack()->canRedo() );
845
    m_undoView->setStack( project->undoStack() );
846 847 848

    const ClipRenderer* clipRenderer = qobject_cast<const ClipRenderer*>( m_clipPreview->getGenericRenderer() );
    connect( project->library(), SIGNAL( clipRemoved( const QUuid& ) ), clipRenderer, SLOT( clipUnloaded( const QUuid& ) ) );
849 850

    m_projectPreview->setRenderer( project->workflowRenderer() );
851 852
}

Ludovic Fauvet's avatar
Ludovic Fauvet committed
853
#ifdef WITH_CRASHBUTTON
854 855
void
MainWindow::setupCrashTester()
856 857 858 859 860 861 862 863
{
    QAction* actionCrash = new QAction( this );
    actionCrash->setObjectName( QString::fromUtf8( "actionCrash" ) );
    m_ui.menuTools->addAction( actionCrash );
    actionCrash->setText( QApplication::translate( "MainWindow", "Crash", 0, QApplication::UnicodeUTF8 ) );
    connect( actionCrash, SIGNAL( triggered( bool ) ), this, SLOT( on_actionCrash_triggered() ) );
}
#endif
864