MainWindow.cpp 30.5 KB
Newer Older
Ludovic Fauvet's avatar
Ludovic Fauvet committed
1
/*****************************************************************************
2
 * MainWindow.cpp: VLMC MainWindow
Ludovic Fauvet's avatar
Ludovic Fauvet committed
3
 *****************************************************************************
Ludovic Fauvet's avatar
Ludovic Fauvet committed
4
 * Copyright (C) 2008-2010 VideoLAN
Ludovic Fauvet's avatar
Ludovic Fauvet committed
5 6
 *
 * Authors: Ludovic Fauvet <etix@l0cal.com>
7
 *          Hugo Beauzée-Luyssen <beauze.h@gmail.com>
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
#include <QSizePolicy>
Christophe Courtaut's avatar
Christophe Courtaut committed
25
#include <QDockWidget>
26
#include <QFileDialog>
27
#include <QSlider>
28
#include <QMessageBox>
29 30
#include <QDesktopServices>
#include <QUrl>
31
#include <QNetworkProxy>
32
#include <QSettings>
33
#include <QDebug>
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
34

Ludovic Fauvet's avatar
Ludovic Fauvet committed
35
#include "MainWindow.h"
36
#include "config.h"
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
37
#include "Library.h"
Ludovic Fauvet's avatar
Ludovic Fauvet committed
38
#include "About.h"
39 40
#include "VlmcDebug.h"

41
#include "EffectsEngine/EffectsEngine.h"
Ludovic Fauvet's avatar
Ludovic Fauvet committed
42
#include "MainWorkflow.h"
43
#include "export/RendererSettings.h"
44
#include "export/ShareOnInternet.h"
Ludovic Fauvet's avatar
Ludovic Fauvet committed
45
#include "WorkflowFileRenderer.h"
46
#include "WorkflowRenderer.h"
47
#include "ClipRenderer.h"
48 49 50

/* Widgets */
#include "DockWidgetManager.h"
51
#include "EffectsListView.h"
52
#include "ImportController.h"
53
#include "MediaLibrary.h"
54
#include "NotificationZone.h"
55
#include "PreviewWidget.h"
56 57
#include "timeline/Timeline.h"
#include "timeline/TracksView.h"
58
#include "UndoStack.h"
59 60

/* Settings / Preferences */
61
#include "project/GuiProjectManager.h"
Ludovic Fauvet's avatar
Ludovic Fauvet committed
62 63
#include "ProjectWizard.h"
#include "Settings.h"
64
#include "SettingsManager.h"
65
#include "LanguageHelper.h"
Ludovic Fauvet's avatar
Ludovic Fauvet committed
66

67 68 69
/* VLCpp */
#include "VLCInstance.h"

Ludovic Fauvet's avatar
Ludovic Fauvet committed
70
MainWindow::MainWindow( QWidget *parent ) :
71
    QMainWindow( parent ), m_fileRenderer( NULL )
Ludovic Fauvet's avatar
Ludovic Fauvet committed
72 73
{
    m_ui.setupUi( this );
74

75
    //We only install message handler here cause it uses configuration.
76
//    VlmcDebug::getInstance()->setup();
77

78
    //VLC Instance:
79
    LibVLCpp::Instance::getInstance();
80

81
    //Creating the project manager first (so it can create all the project variables)
82
    GUIProjectManager::getInstance();
83

84 85 86
    //Preferences
    initVlmcPreferences();

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

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

110
    connect( GUIProjectManager::getInstance(), SIGNAL( projectUpdated( const QString&, bool ) ),
111
             this, SLOT( projectUpdated( const QString&, bool ) ) );
112

113 114 115 116 117 118 119 120 121
    // Undo/Redo
    connect( UndoStack::getInstance( this ), SIGNAL( canRedoChanged( bool ) ),
             this, SLOT( canRedoChanged( bool ) ) );
    connect( UndoStack::getInstance( this ), SIGNAL( canUndoChanged( bool ) ),
             this, SLOT( canUndoChanged( bool ) ) );
    canRedoChanged( UndoStack::getInstance( this )->canRedo() );
    canUndoChanged( UndoStack::getInstance( this )->canUndo() );


Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
122 123 124 125
    // Wizard
    m_pWizard = new ProjectWizard( this );
    m_pWizard->setModal( true );

126

127
#ifdef WITH_CRASHHANDLER
128
    if ( restoreSession() == true )
129 130
        return ;
#endif
131
    QSettings s;
132

133
    if ( s.value( "ShowWizardStartup", true ).toBool() )
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
134
    {
135
        //If a project was opened from the command line: don't show the wizard.
136 137
        if ( qApp->arguments().size() == 1 )
            m_pWizard->show();
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
138
    }
Ludovic Fauvet's avatar
Ludovic Fauvet committed
139 140
}

141 142
MainWindow::~MainWindow()
{
143 144 145 146 147
    QSettings s;
    // Save the current geometry
    s.setValue( "MainWindowGeometry", saveGeometry() );
    // Save the current layout
    s.setValue( "MainWindowState", saveState() );
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
148
    s.setValue( "CleanQuit", true );
149 150
    s.sync();

151 152
    if ( m_fileRenderer )
        delete m_fileRenderer;
153
    delete m_importController;
154
    LibVLCpp::Instance::destroyInstance();
155 156
}

157
void
158
MainWindow::changeEvent( QEvent *e )
Ludovic Fauvet's avatar
Ludovic Fauvet committed
159 160 161 162 163
{
    switch ( e->type() )
    {
    case QEvent::LanguageChange:
        m_ui.retranslateUi( this );
164
        DockWidgetManager::getInstance()->retranslateUi();
Ludovic Fauvet's avatar
Ludovic Fauvet committed
165 166 167 168 169 170
        break;
    default:
        break;
    }
}

171
//use this helper when the shortcut is binded to a menu action
172 173 174
#define CREATE_MENU_SHORTCUT( key, defaultValue, name, desc, actionInstance  )      \
        VLMC_CREATE_PREFERENCE_KEYBOARD( key, defaultValue, name, desc );           \
        new KeyboardShortcutHelper( key, m_ui.actionInstance, this );
175

176 177 178
void
MainWindow::initVlmcPreferences()
{
179
    //Setup VLMC Keyboard Preference...
180 181 182
    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" ) );
183

184 185 186
    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" ) );
187

188
    //A bit nasty, but we better use what Qt's providing as default shortcut
189 190 191 192
    CREATE_MENU_SHORTCUT( "keyboard/undo",
                          QKeySequence( QKeySequence::Undo ).toString().toLocal8Bit(),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Undo" ),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Undo the last action" ), actionUndo );
193

194 195 196 197
    CREATE_MENU_SHORTCUT( "keyboard/redo",
                          QKeySequence( QKeySequence::Redo ).toString().toLocal8Bit(),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Redo" ),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Redo the last action" ), actionRedo );
198

199 200 201 202
    CREATE_MENU_SHORTCUT( "keyboard/help",
                          QKeySequence( QKeySequence::HelpContents ).toString().toLocal8Bit(),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Help" ),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Toggle the help page" ), actionHelp );
203

204 205 206
    CREATE_MENU_SHORTCUT( "keyboard/quit", "Ctrl+Q",
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Quit" ),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Quit VLMC" ), actionQuit );
207

208 209 210
    CREATE_MENU_SHORTCUT( "keyboard/preferences", "Alt+P",
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Preferences" ),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Open VLMC preferences" ), actionPreferences );
211

212 213 214 215
    CREATE_MENU_SHORTCUT( "keyboard/projectpreferences", "Ctrl+P",
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Project preferences" ),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Open the project preferences"), actionProject_Preferences );

216 217 218
    CREATE_MENU_SHORTCUT( "keyboard/fullscreen", "F",
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Fullscreen" ),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Switch to fullscreen mode" ), actionFullscreen );
219

220 221 222
    CREATE_MENU_SHORTCUT( "keyboard/newproject",
                          QKeySequence( QKeySequence::New ).toString().toLocal8Bit(),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "New project" ),
223
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Open the new project wizard" ), actionNew_Project );
224

225 226 227 228
    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 );
229

230 231 232 233
    CREATE_MENU_SHORTCUT( "keyboard/save",
                          QKeySequence( QKeySequence::Save ).toString().toLocal8Bit(),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Save" ),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Save the current project" ), actionSave );
234

235 236 237
    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 );
238

239 240 241 242
    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 );
243

244 245 246
    CREATE_MENU_SHORTCUT( "keyboard/importmedia", "Ctrl+I",
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Import media" ),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Open the import window" ), actionImport );
247

248 249 250 251
    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 );

252 253 254 255 256 257 258 259
    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 );

260
    //Setup VLMC Lang. Preferences...
261
    VLMC_CREATE_PREFERENCE_LANGUAGE( "general/VLMCLang", "default",
262
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Language" ),
263
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "The VLMC's UI language" ) );
264

265 266 267 268
    SettingsManager::getInstance()->watchValue( "general/VLMCLang",
                                                LanguageHelper::getInstance(),
                                                SLOT( languageChanged( const QVariant& ) ),
                                                SettingsManager::Vlmc );
269

270
    //Setup VLMC General Preferences...
271
    VLMC_CREATE_PREFERENCE_BOOL( "general/ConfirmDeletion", true,
272
                                 QT_TRANSLATE_NOOP( "PreferenceWidget", "Confirm clip deletion"),
273
                                 QT_TRANSLATE_NOOP( "PreferenceWidget", "Ask for confirmation before deleting a clip from the timeline" ) );
274

275
    VLMC_CREATE_PREFERENCE_PATH( "general/DefaultProjectLocation", QDir::homePath(),
276 277 278
                                    QT_TRANSLATE_NOOP( "PreferencesWidget", "Project default location" ),
                                    QT_TRANSLATE_NOOP( "PreferenceWidget", "The default location where to store projects folders" ) );

279
    VLMC_CREATE_PREFERENCE_PATH( "general/TempFolderLocation", QDir::tempPath() + "/VLMC/",
280 281 282
                                    QT_TRANSLATE_NOOP( "PreferencesWidget", "Temporary folder" ),
                                    QT_TRANSLATE_NOOP( "PreferenceWidget", "The temporary folder used by VLMC to process videos." ) );

283 284 285
    //Setup VLMC Youtube Preference...
    VLMC_CREATE_PREFERENCE_STRING( "youtube/DeveloperKey", "AI39si7FOtp165Vq644xVkuka84TVQNbztQmQ1dC9stheBfh3-33RZaTu7eJkYJzvxp6XNbvlr4M6-ULjXDERFl62WIo6AQIEQ",
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Youtube Developer Key" ),
286
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "VLMC's Youtube Developer Key" ) );
287 288 289

    VLMC_CREATE_PREFERENCE_STRING( "youtube/Username", "username",
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Youtube Username" ),
290 291 292 293 294
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Valid YouTube username" ) );

    VLMC_CREATE_PREFERENCE_PASSWORD( "youtube/Password", "",
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Youtube Password" ),
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Leave this field, password will be stored in unencryped form." ) );
295 296

    //Setup VLMC Proxy Settings
297 298 299 300 301 302 303
    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." ) );
304 305 306

    VLMC_CREATE_PREFERENCE_STRING( "network/ProxyPort", "",
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Proxy Port" ),
307
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Set Proxy Port." ) );
308 309 310

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

313
    VLMC_CREATE_PREFERENCE_PASSWORD( "network/ProxyPassword", "",
314
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Proxy Password" ),
315
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Set Proxy Password, if any." ) );
316

317
    //Load saved preferences :
318 319 320 321 322 323 324
    QSettings       s;
    if ( s.value( "VlmcVersion" ).toString() != PROJECT_VERSION )
        s.clear();
    else
    {
        loadVlmcPreferences( "keyboard" );
        loadVlmcPreferences( "general" );
325 326
        loadVlmcPreferences( "youtube" );
        loadVlmcPreferences( "network" );
327 328
    }
    s.setValue( "VlmcVersion", PROJECT_VERSION );
329 330 331 332 333 334 335 336 337 338 339 340
}

void
MainWindow::loadVlmcPreferences( const QString &subPart )
{
    QSettings       s;
    s.beginGroup( subPart );
    foreach ( QString key, s.allKeys() )
    {
        SettingsManager::getInstance()->setValue( subPart + "/" + key, s.value( key ),
                                                  SettingsManager::Vlmc );
    }
341 342
}

343 344
#undef CREATE_MENU_SHORTCUT

345 346
void
MainWindow::on_actionSave_triggered()
347
{
348
    GUIProjectManager::getInstance()->saveProject();
349 350
}

351
void
352
MainWindow::on_actionSave_As_triggered()
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
353
{
354
    GUIProjectManager::getInstance()->saveProject( true );
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
355 356
}

357
void
358
MainWindow::on_actionLoad_Project_triggered()
359
{
360
    GUIProjectManager::getInstance()->loadProject();
361 362
}

363 364 365 366 367 368 369 370 371 372
void
MainWindow::createNotificationZone()
{
    QWidget *notifSpacer = new QWidget( this );
    notifSpacer->setFixedWidth( 75 );
    m_ui.statusbar->addPermanentWidget( notifSpacer );

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

373
void
374
MainWindow::createStatusBar()
375
{
376 377 378
    //Notifications:
    createNotificationZone();

379 380 381 382 383
    // Spacer
    QWidget* spacer = new QWidget( this );
    spacer->setFixedWidth( 20 );
    m_ui.statusbar->addPermanentWidget( spacer );

Ludovic Fauvet's avatar
Ludovic Fauvet committed
384 385 386
    // Zoom Out
    QToolButton* zoomOutButton = new QToolButton( this );
    zoomOutButton->setIcon( QIcon( ":/images/zoomout" ) );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
387
    zoomOutButton->setStatusTip( tr( "Zoom out" ) );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
388 389 390
    m_ui.statusbar->addPermanentWidget( zoomOutButton );
    connect( zoomOutButton, SIGNAL( clicked() ),
             this, SLOT( zoomOut() ) );
391 392

    // Zoom slider
393 394 395 396 397 398 399 400 401
    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 );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
402
    m_zoomSlider->setInvertedAppearance( true );
403
    m_ui.statusbar->addPermanentWidget( m_zoomSlider );
404

Ludovic Fauvet's avatar
Ludovic Fauvet committed
405 406 407
    // Zoom IN
    QToolButton* zoomInButton = new QToolButton( this );
    zoomInButton->setIcon( QIcon( ":/images/zoomin" ) );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
408
    zoomInButton->setStatusTip( tr( "Zoom in" ) );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
409 410 411
    m_ui.statusbar->addPermanentWidget( zoomInButton );
    connect( zoomInButton, SIGNAL( clicked() ),
             this, SLOT( zoomIn() ) );
412 413
}

414
void
415
MainWindow::initializeDockWidgets( void )
416
{
417 418
    m_effectsList = new EffectsListView( this );
    m_effectsList->setType( Effect::Filter );
419
    EffectsEngine::getInstance()->loadEffects();
420

421 422 423
    m_renderer = new WorkflowRenderer();
    m_renderer->initializeRenderer();
    m_timeline = new Timeline( m_renderer, this );
424 425 426
    m_timeline->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
    m_timeline->show();
    setCentralWidget( m_timeline );
427

428 429
    m_clipPreview = new PreviewWidget( this );
    m_clipPreview->setRenderer( new ClipRenderer );
430

431
    KeyboardShortcutHelper* clipShortcut = new KeyboardShortcutHelper( "keyboard/mediapreview", this );
432
    connect( clipShortcut, SIGNAL( activated() ), m_clipPreview, SLOT( on_pushButtonPlay_clicked() ) );
433

434 435
    m_projectPreview = new PreviewWidget( this );
    m_projectPreview->setRenderer( m_renderer );
436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466
    KeyboardShortcutHelper* renderShortcut = new KeyboardShortcutHelper( "keyboard/renderpreview", this );
    connect( renderShortcut, SIGNAL( activated() ), m_projectPreview, SLOT( on_pushButtonPlay_clicked() ) );

    m_importController = new ImportController();
    const ClipRenderer* clipRenderer = qobject_cast<const ClipRenderer*>( m_clipPreview->getGenericRenderer() );
    Q_ASSERT( clipRenderer != NULL );

    m_mediaLibrary = new MediaLibrary( this );
    connect( m_mediaLibrary, SIGNAL( clipSelected( Clip* ) ),
             clipRenderer, SLOT( setClip( Clip* ) ) );
    connect( m_mediaLibrary, SIGNAL( importRequired() ),
             this, SLOT( on_actionImport_triggered() ) );
    connect( Library::getInstance(), SIGNAL( clipRemoved( const QUuid& ) ),
             clipRenderer, SLOT( clipUnloaded( const QUuid& ) ) );
    setupDockedWidgets();
}

void
MainWindow::setupDockedWidgets()
{
    DockWidgetManager *dockManager = DockWidgetManager::getInstance();

    dockManager->addDockedWidget( m_mediaLibrary, QT_TRANSLATE_NOOP( "DockWidgetManager", "Media Library" ),
                                                    Qt::AllDockWidgetAreas,
                                                    QDockWidget::AllDockWidgetFeatures,
                                                    Qt::TopDockWidgetArea );
    dockManager->addDockedWidget( m_clipPreview,
                                  QT_TRANSLATE_NOOP( "DockWidgetManager", "Clip Preview" ),
                                  Qt::AllDockWidgetAreas,
                                  QDockWidget::AllDockWidgetFeatures,
                                  Qt::TopDockWidgetArea );
467
    dockManager->addDockedWidget( m_projectPreview,
468
                                  QT_TRANSLATE_NOOP( "DockWidgetManager", "Project Preview" ),
469 470
                                  Qt::AllDockWidgetAreas,
                                  QDockWidget::AllDockWidgetFeatures,
471
                                  Qt::TopDockWidgetArea );
472 473 474 475
    dockManager->addDockedWidget( m_effectsList,
                                  QT_TRANSLATE_NOOP( "DockWidgetManager", "Effects List" ),
                                  Qt::AllDockWidgetAreas, QDockWidget::AllDockWidgetFeatures,
                                  Qt::LeftDockWidgetArea );
476
    dockManager->addDockedWidget( UndoStack::getInstance( this ),
477
                                  QT_TRANSLATE_NOOP( "DockWidgetManager", "History" ),
478 479 480
                                  Qt::AllDockWidgetAreas,
                                  QDockWidget::AllDockWidgetFeatures,
                                  Qt::LeftDockWidgetArea );
481 482
}

483 484 485 486 487 488 489 490 491 492 493 494 495
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() );
}

496 497
void
MainWindow::createGlobalPreferences()
498
{
499
    m_globalPreferences = new Settings( SettingsManager::Vlmc, this );
500
    m_globalPreferences->addCategory( QT_TRANSLATE_NOOP( "Settings", "general" ), SettingsManager::Vlmc,
501
                                     QIcon( ":/images/vlmc" ),
Nikoli's avatar
Nikoli committed
502
                                     tr ( "General" ) );
503
    m_globalPreferences->addCategory( QT_TRANSLATE_NOOP( "Settings", "keyboard" ), SettingsManager::Vlmc,
504
                                     QIcon( ":/images/keyboard" ),
Nikoli's avatar
Nikoli committed
505
                                     tr( "Keyboard" ) );
506 507
    m_globalPreferences->addCategory( QT_TRANSLATE_NOOP( "Settings", "youtube" ), SettingsManager::Vlmc,
                                     QIcon( ":/images/youtube" ),
Nikoli's avatar
Nikoli committed
508
                                     tr( "Youtube" ) );
509 510
    m_globalPreferences->addCategory( QT_TRANSLATE_NOOP( "Settings", "network" ), SettingsManager::Vlmc,
                                     QIcon( ":/images/network" ),
Nikoli's avatar
Nikoli committed
511
                                     tr( "Network" ) );
512 513
}

514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532
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 );
}

533 534
void
MainWindow::createProjectPreferences()
535
{
536
    m_projectPreferences = new Settings( SettingsManager::Project, this );
537
    m_projectPreferences->addCategory( QT_TRANSLATE_NOOP( "Settings", "general" ), SettingsManager::Project,
538
                                   QIcon( ":/images/vlmc" ),
Nikoli's avatar
Nikoli committed
539
                                   tr ( "General" ) );
540
    m_projectPreferences->addCategory( QT_TRANSLATE_NOOP( "Settings", "video" ), SettingsManager::Project,
541
                                   QIcon( ":/images/video" ),
Nikoli's avatar
Nikoli committed
542
                                   tr ( "Video" ) );
543
    m_projectPreferences->addCategory( QT_TRANSLATE_NOOP( "Settings", "audio" ), SettingsManager::Project,
544
                                   QIcon( ":/images/audio" ),
Nikoli's avatar
Nikoli committed
545
                                   tr ( "Audio" ) );
546 547
}

548 549 550 551 552 553 554 555 556 557 558
void
MainWindow::checkFolders()
{
    QDir dirUtil;
    if( !dirUtil.exists( VLMC_GET_STRING( "general/DefaultProjectLocation" ) ) )
        dirUtil.mkdir( VLMC_GET_STRING( "general/DefaultProjectLocation" ) );

    if( !dirUtil.exists( VLMC_GET_STRING( "general/TempFolderLocation" ) ) )
        dirUtil.mkdir( VLMC_GET_STRING( "general/TempFolderLocation" ) );
}

559

560 561
//Private slots definition

562
void
563
MainWindow::on_actionQuit_triggered()
Ludovic Fauvet's avatar
Ludovic Fauvet committed
564 565 566
{
    QApplication::quit();
}
567

568
void
569
MainWindow::on_actionPreferences_triggered()
570
{
571
   m_globalPreferences->show();
572
}
Ludovic Fauvet's avatar
Ludovic Fauvet committed
573

574
void
575
MainWindow::on_actionAbout_triggered()
Ludovic Fauvet's avatar
Ludovic Fauvet committed
576
{
577
    About::getInstance()->exec();
Ludovic Fauvet's avatar
Ludovic Fauvet committed
578
}
579

580 581
bool
MainWindow::checkVideoLength()
582
{
583
    if ( MainWorkflow::getInstance()->getLengthFrame() <= 0 )
584
    {
585
        QMessageBox::warning( NULL, tr ( "VLMC Renderer" ), tr( "There is nothing to render." ) );
586
        return false;
587
    }
588 589 590
    return true;
}

591
bool
592 593 594 595 596
MainWindow::renderVideo( const QString& outputFileName, quint32 width, quint32 height, double fps, quint32 vbitrate, quint32 abitrate )
{
    if ( m_fileRenderer )
        delete m_fileRenderer;
    m_fileRenderer = new WorkflowFileRenderer();
597

Rohit Yadav's avatar
Rohit Yadav committed
598
    WorkflowFileRendererDialog  *dialog = new WorkflowFileRendererDialog( m_fileRenderer, width, height );
599 600 601 602 603
    dialog->setModal( true );
    dialog->setOutputFileName( outputFileName );

    m_fileRenderer->initializeRenderer();
    m_fileRenderer->run( outputFileName, width, height, fps, vbitrate, abitrate );
604 605 606 607 608 609 610

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

611
    delete dialog;
612 613 614 615 616 617 618 619 620 621 622 623 624 625
    return true;
}

bool
MainWindow::renderVideoSettings( bool exportType )
{
    RendererSettings *settings = new RendererSettings( exportType );

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

626
    QString     outputFileName = settings->outputFileName();
627 628 629 630 631 632
    quint32     width          = settings->width();
    quint32     height         = settings->height();
    double      fps            = settings->fps();
    quint32     vbitrate       = settings->videoBitrate();
    quint32     abitrate       = settings->audioBitrate();

633 634
    delete settings;

635
    return renderVideo( outputFileName, width, height, fps, vbitrate, abitrate );
636 637
}

638
void
639 640 641
MainWindow::on_actionRender_triggered()
{
    if ( checkVideoLength() )
642
    {
643
        m_renderer->killRenderer();
644
        //Setup dialog box for querying render parameters.
645
        renderVideoSettings( false );
646
    }
647 648
}

649
void
650
MainWindow::on_actionShare_On_Internet_triggered()
651 652 653 654 655
{
    if ( checkVideoLength() )
    {
        m_renderer->killRenderer();

656 657
        if( !renderVideoSettings( true ) )
            return;
658

659 660
        checkFolders();
        QString fileName = VLMC_GET_STRING( "general/TempFolderLocation" ) + "/" +
661
                           VLMC_PROJECT_GET_STRING( "general/ProjectName" ) +
662
                           "-vlmc.mp4";
663

664
        loadGlobalProxySettings();
665

666 667
        ShareOnInternet *shareVideo = new ShareOnInternet();
        shareVideo->setVideoFile( fileName );
668

669 670 671 672 673
        if ( shareVideo->exec() == QDialog::Rejected )
        {
            delete shareVideo;
            return;
        }
674

675
        delete shareVideo;
676 677 678
    }
}

679
void
680
MainWindow::on_actionNew_Project_triggered()
681
{
682
    m_pWizard->restart();
683
    m_pWizard->show();
684 685
}

686
void
687
MainWindow::on_actionHelp_triggered()
688 689
{
    QDesktopServices::openUrl( QUrl( "http://vlmc.org" ) );
690 691
}

692
void
693
MainWindow::zoomIn()
Ludovic Fauvet's avatar
Ludovic Fauvet committed
694 695 696 697
{
    m_zoomSlider->setValue( m_zoomSlider->value() - 1 );
}

698
void
699
MainWindow::zoomOut()
Ludovic Fauvet's avatar
Ludovic Fauvet committed
700 701 702
{
    m_zoomSlider->setValue( m_zoomSlider->value() + 1 );
}
Ludovic Fauvet's avatar
Ludovic Fauvet committed
703

704
void
705
MainWindow::on_actionFullscreen_triggered( bool checked )
Ludovic Fauvet's avatar
Ludovic Fauvet committed
706 707 708 709 710 711
{
    if ( checked )
        showFullScreen();
    else
        showNormal();
}
712

713
void
714
MainWindow::registerWidgetInWindowMenu( QDockWidget* widget )
715
{
716
    m_ui.menuWindow->addAction( widget->toggleViewAction() );
717
}
718

719
void
720
MainWindow::toolButtonClicked( QAction *action )
721
{
722 723 724 725 726 727
    if ( action == m_ui.actionSelection_mode )
        emit toolChanged( TOOL_DEFAULT );
    else if ( action == m_ui.actionCut_mode )
        emit toolChanged( TOOL_CUT );
    else
        qCritical() << "Unknown tool. This should not happen !";
728
}
729

730
void
731
MainWindow::on_actionProject_Preferences_triggered()
732
{
733
  m_projectPreferences->show();
734
}
735

736
void
737
MainWindow::closeEvent( QCloseEvent* e )
738
{
739 740
    GUIProjectManager   *pm = GUIProjectManager::getInstance();
    if ( pm->askForSaveIfModified() )
741
        e->accept();
742 743
    else
        e->ignore();
744
}
745

746
void
747
MainWindow::projectUpdated( const QString& projectName, bool savedStatus )
748 749
{
    QString title = tr( "VideoLAN Movie Creator" );
750
    title += " - ";
751 752 753 754 755
    title += projectName;
    if ( savedStatus == false )
        title += " *";
    setWindowTitle( title );
}
756

757
void
758
MainWindow::on_actionClose_Project_triggered()
759
{
760
    GUIProjectManager::getInstance()->closeProject();
761 762
}

763
void
764
MainWindow::on_actionUndo_triggered()
765 766 767 768
{
    UndoStack::getInstance( this )->undo();
}

769
void
770
MainWindow::on_actionRedo_triggered()
771 772 773 774
{
    UndoStack::getInstance( this )->redo();
}

775
void
776
MainWindow::on_actionCrash_triggered()
777
{
778 779 780 781 782
    //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 );
783
}
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
784

785
bool
786
MainWindow::restoreSession()
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
787 788
{
    QSettings   s;
789
    bool        fileCreated = false;
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
790 791
    bool        ret = false;

792 793
    fileCreated = s.contains( "VlmcVersion" );
    if ( fileCreated == true )
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
794
    {
795
        bool        cleanQuit = s.value( "CleanQuit", true ).toBool();
796 797 798 799 800 801 802

        // Restore the geometry
        restoreGeometry( s.value( "MainWindowGeometry" ).toByteArray() );
        // Restore the layout
        restoreState( s.value( "MainWindowState" ).toByteArray() );

        if ( cleanQuit == false )
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
803
        {
804
            QMessageBox::StandardButton res = QMessageBox::question( this, tr( "Crash recovery" ), tr( "VLMC didn't closed nicely. Do you want to recover your project?" ),
805 806 807
                                   QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes );
            if ( res == QMessageBox::Yes )
            {
808
                if ( GUIProjectManager::getInstance()->loadEmergencyBackup() == true )
809 810
                    ret = true;
                else
811
                    QMessageBox::warning( this, tr( "Can't restore project" ), tr( "VLMC didn't manage to restore your project. We apology for the inconvenience" ) );
812
            }
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
813 814 815 816 817 818
        }
    }
    s.setValue( "CleanQuit", false );
    s.sync();
    return ret;
}
819

820
void
821
MainWindow::on_actionImport_triggered()
822 823 824
{
    m_importController->exec();
}
825

826
void
827
MainWindow::canUndoChanged( bool canUndo )
828 829 830 831
{
    m_ui.actionUndo->setEnabled( canUndo );
}

832
void
833
MainWindow::canRedoChanged( bool canRedo )
834 835 836 837
{
    m_ui.actionRedo->setEnabled( canRedo );
}

Ludovic Fauvet's avatar
Ludovic Fauvet committed
838
#ifdef WITH_CRASHBUTTON
839 840
void
MainWindow::setupCrashTester()
841 842 843 844 845 846 847 848
{
    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
849