MainWindow.cpp 32 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>
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
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
#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>
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
33

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

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

Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
75
    //We only install message handler here cause it uses configuration.
76
    VlmcLogger::getInstance()->setup();
77

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

81 82 83
    //Preferences
    initVlmcPreferences();

84 85 86
    //Creating the project manager so it can create all the project variables
    GUIProjectManager::getInstance();

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
    // 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() );

121 122 123 124 125 126 127 128 129
    //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() ) );
    connect( Library::getInstance(), SIGNAL( clipRemoved( const QUuid& ) ),
             clipRenderer, SLOT( clipUnloaded( const QUuid& ) ) );
130

131
    //FIXME: Lazy init this
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
132 133 134 135
    // Wizard
    m_pWizard = new ProjectWizard( this );
    m_pWizard->setModal( true );

136

137
#ifdef WITH_CRASHHANDLER
138
    if ( restoreSession() == true )
139 140
        return ;
#endif
141
    // Restore the geometry
142
    restoreGeometry( VLMC_GET_BYTEARRAY( "private/MainWindowGeometry" ) );
143
    // Restore the layout
144
    restoreState( VLMC_GET_BYTEARRAY( "private/MainWindowState" ) );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
145 146
}

147 148
MainWindow::~MainWindow()
{
149 150
    if ( m_fileRenderer )
        delete m_fileRenderer;
151
    delete m_importController;
152
    LibVLCpp::Instance::destroyInstance();
153 154
}

155 156 157
void
MainWindow::showWizard()
{
158
    if ( VLMC_GET_BOOL( "private/ShowWizardStartup" ) )
159 160 161
        m_pWizard->show();
}

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

Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
176
//use this helper when the shortcut is binded to a menu action
177 178 179
#define CREATE_MENU_SHORTCUT( key, defaultValue, name, desc, actionInstance  )      \
        VLMC_CREATE_PREFERENCE_KEYBOARD( key, defaultValue, name, desc );           \
        new KeyboardShortcutHelper( key, m_ui.actionInstance, this );
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
180

181 182 183
void
MainWindow::initVlmcPreferences()
{
184
    //Setup VLMC Keyboard Preference...
185 186 187
    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" ) );
188

189 190 191
    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" ) );
192

193
    //A bit nasty, but we better use what Qt's providing as default shortcut
194 195 196 197
    CREATE_MENU_SHORTCUT( "keyboard/undo",
                          QKeySequence( QKeySequence::Undo ).toString().toLocal8Bit(),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Undo" ),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Undo the last action" ), actionUndo );
198

199 200 201 202
    CREATE_MENU_SHORTCUT( "keyboard/redo",
                          QKeySequence( QKeySequence::Redo ).toString().toLocal8Bit(),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Redo" ),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Redo the last action" ), actionRedo );
203

204 205 206 207
    CREATE_MENU_SHORTCUT( "keyboard/help",
                          QKeySequence( QKeySequence::HelpContents ).toString().toLocal8Bit(),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Help" ),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Toggle the help page" ), actionHelp );
208

209 210 211
    CREATE_MENU_SHORTCUT( "keyboard/quit", "Ctrl+Q",
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Quit" ),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Quit VLMC" ), actionQuit );
212

213 214 215
    CREATE_MENU_SHORTCUT( "keyboard/preferences", "Alt+P",
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Preferences" ),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Open VLMC preferences" ), actionPreferences );
216

217 218 219 220
    CREATE_MENU_SHORTCUT( "keyboard/projectpreferences", "Ctrl+P",
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Project preferences" ),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Open the project preferences"), actionProject_Preferences );

221 222 223
    CREATE_MENU_SHORTCUT( "keyboard/fullscreen", "F",
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Fullscreen" ),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Switch to fullscreen mode" ), actionFullscreen );
224

225 226 227
    CREATE_MENU_SHORTCUT( "keyboard/newproject",
                          QKeySequence( QKeySequence::New ).toString().toLocal8Bit(),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "New project" ),
228
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Open the new project wizard" ), actionNew_Project );
229

230 231 232 233
    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 );
234

235 236 237 238
    CREATE_MENU_SHORTCUT( "keyboard/save",
                          QKeySequence( QKeySequence::Save ).toString().toLocal8Bit(),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Save" ),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Save the current project" ), actionSave );
239

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

244 245 246 247
    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 );
248

249 250 251
    CREATE_MENU_SHORTCUT( "keyboard/importmedia", "Ctrl+I",
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Import media" ),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Open the import window" ), actionImport );
252

253 254 255 256
    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 );

257 258 259 260 261 262 263 264
    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 );

265
    //Setup VLMC Lang. Preferences...
266
    VLMC_CREATE_PREFERENCE_LANGUAGE( "general/VLMCLang", "default",
267
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Language" ),
268
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "The VLMC's UI language" ) );
269

270 271 272 273
    SettingsManager::getInstance()->watchValue( "general/VLMCLang",
                                                LanguageHelper::getInstance(),
                                                SLOT( languageChanged( const QVariant& ) ),
                                                SettingsManager::Vlmc );
274

275
    //Setup VLMC General Preferences...
276
    VLMC_CREATE_PREFERENCE_BOOL( "general/ConfirmDeletion", true,
277
                                 QT_TRANSLATE_NOOP( "PreferenceWidget", "Confirm clip deletion"),
278
                                 QT_TRANSLATE_NOOP( "PreferenceWidget", "Ask for confirmation before deleting a clip from the timeline" ) );
279

280
    VLMC_CREATE_PREFERENCE_PATH( "general/DefaultProjectLocation", QDir::homePath(),
Rohit Yadav's avatar
Rohit Yadav committed
281
                                    QT_TRANSLATE_NOOP( "PreferenceWidget", "Project default location" ),
282 283
                                    QT_TRANSLATE_NOOP( "PreferenceWidget", "The default location where to store projects folders" ) );

284
    VLMC_CREATE_PREFERENCE_PATH( "general/TempFolderLocation", QDir::tempPath() + "/VLMC/",
Rohit Yadav's avatar
Rohit Yadav committed
285
                                    QT_TRANSLATE_NOOP( "PreferenceWidget", "Temporary folder" ),
286 287
                                    QT_TRANSLATE_NOOP( "PreferenceWidget", "The temporary folder used by VLMC to process videos." ) );

288 289 290
    //Setup VLMC Youtube Preference...
    VLMC_CREATE_PREFERENCE_STRING( "youtube/DeveloperKey", "AI39si7FOtp165Vq644xVkuka84TVQNbztQmQ1dC9stheBfh3-33RZaTu7eJkYJzvxp6XNbvlr4M6-ULjXDERFl62WIo6AQIEQ",
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Youtube Developer Key" ),
291
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "VLMC's Youtube Developer Key" ) );
292 293 294

    VLMC_CREATE_PREFERENCE_STRING( "youtube/Username", "username",
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Youtube Username" ),
295 296 297 298
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Valid YouTube username" ) );

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

    //Setup VLMC Proxy Settings
302 303 304 305 306 307 308
    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." ) );
309 310 311

    VLMC_CREATE_PREFERENCE_STRING( "network/ProxyPort", "",
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Proxy Port" ),
312
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Set Proxy Port." ) );
313 314 315

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

318
    VLMC_CREATE_PREFERENCE_PASSWORD( "network/ProxyPassword", "",
319
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Proxy Password" ),
320
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Set Proxy Password, if any." ) );
321

322 323 324 325 326 327 328 329 330 331
    // 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", "" );
    VLMC_CREATE_PRIVATE_PREFERENCE_STRING( "private/RecentsProjects", "" );
    VLMC_CREATE_PRIVATE_PREFERENCE_BOOL( "private/ShowWizardStartup", true );
    VLMC_CREATE_PRIVATE_PREFERENCE_STRING( "private/VlmcVersion", PROJECT_VERSION_MAJOR );

332
    //Load saved preferences :
333
    loadVlmcPreferences();
334
    SettingsManager::getInstance()->setValue( "private/VlmcVersion", PROJECT_VERSION_MAJOR, SettingsManager::Vlmc );
335 336 337
}

void
338
MainWindow::loadVlmcPreferences()
339
{
340
    //FIXME: Manually load vlmc version to force settings clear?
341 342 343
    QSettings       s;
    foreach ( QString key, s.allKeys() )
    {
344 345
        QVariant value = s.value( key );
        vlmcDebug() << "Loading" << key << "=>" << value;
346
        SettingsManager::getInstance()->setValue( key, value, SettingsManager::Vlmc );
347
    }
348 349
}

Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
350 351
#undef CREATE_MENU_SHORTCUT

352 353
void
MainWindow::on_actionSave_triggered()
354
{
355
    GUIProjectManager::getInstance()->saveProject();
356 357
}

358
void
359
MainWindow::on_actionSave_As_triggered()
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
360
{
361
    GUIProjectManager::getInstance()->saveProject( true );
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
362 363
}

364
void
365
MainWindow::on_actionLoad_Project_triggered()
366
{
367
    GUIProjectManager::getInstance()->loadProject();
368 369
}

370 371 372 373 374 375 376 377 378 379
void
MainWindow::createNotificationZone()
{
    QWidget *notifSpacer = new QWidget( this );
    notifSpacer->setFixedWidth( 75 );
    m_ui.statusbar->addPermanentWidget( notifSpacer );

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

380
void
381
MainWindow::createStatusBar()
382
{
383 384 385
    //Notifications:
    createNotificationZone();

386 387 388 389 390
    // Spacer
    QWidget* spacer = new QWidget( this );
    spacer->setFixedWidth( 20 );
    m_ui.statusbar->addPermanentWidget( spacer );

Ludovic Fauvet's avatar
Ludovic Fauvet committed
391 392 393
    // Zoom Out
    QToolButton* zoomOutButton = new QToolButton( this );
    zoomOutButton->setIcon( QIcon( ":/images/zoomout" ) );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
394
    zoomOutButton->setStatusTip( tr( "Zoom out" ) );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
395 396 397
    m_ui.statusbar->addPermanentWidget( zoomOutButton );
    connect( zoomOutButton, SIGNAL( clicked() ),
             this, SLOT( zoomOut() ) );
398 399

    // Zoom slider
400 401 402 403 404 405 406 407 408
    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 );
Rohit Yadav's avatar
Rohit Yadav committed
409
    m_zoomSlider->setInvertedAppearance( true );
410
    m_ui.statusbar->addPermanentWidget( m_zoomSlider );
411

Ludovic Fauvet's avatar
Ludovic Fauvet committed
412 413 414
    // Zoom IN
    QToolButton* zoomInButton = new QToolButton( this );
    zoomInButton->setIcon( QIcon( ":/images/zoomin" ) );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
415
    zoomInButton->setStatusTip( tr( "Zoom in" ) );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
416 417 418
    m_ui.statusbar->addPermanentWidget( zoomInButton );
    connect( zoomInButton, SIGNAL( clicked() ),
             this, SLOT( zoomIn() ) );
419 420
}

421
void
422
MainWindow::initializeDockWidgets()
423
{
424 425 426
    m_renderer = new WorkflowRenderer();
    m_renderer->initializeRenderer();
    m_timeline = new Timeline( m_renderer, this );
427 428 429
    m_timeline->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
    m_timeline->show();
    setCentralWidget( m_timeline );
430

431
    m_importController = new ImportController();
432

433
    setupLibrary();
434 435 436 437 438
    setupEffectsList();
    setupClipPreview();
    setupProjectPreview();
    setupUndoRedoWidget();
}
439

440 441 442 443 444 445 446 447 448 449
void
MainWindow::setupUndoRedoWidget()
{
    QDockWidget     *dockedWidget = DockWidgetManager::getInstance()->createDockedWidget(
                                      QT_TRANSLATE_NOOP( "DockWidgetManager", "History" ),
                                      Qt::AllDockWidgetAreas,
                                      QDockWidget::AllDockWidgetFeatures );
    QWidget         *undoRedoWidget = UndoStack::getInstance( dockedWidget );
    DockWidgetManager::getInstance()->addDockedWidget( dockedWidget, undoRedoWidget, Qt::LeftDockWidgetArea );
}
450

451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471
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 );
    EffectsEngine::getInstance()->loadEffects();
    DockWidgetManager::getInstance()->addDockedWidget( dockedWidget, m_effectsList, Qt::LeftDockWidgetArea );
}

void
MainWindow::setupLibrary()
{
    QDockWidget     *dockedLibrary = DockWidgetManager::getInstance()->createDockedWidget(
                                                    QT_TRANSLATE_NOOP( "DockWidgetManager", "Media Library" ),
                                                    Qt::AllDockWidgetAreas,
                                                    QDockWidget::AllDockWidgetFeatures );
    m_mediaLibrary = new MediaLibrary( dockedLibrary );
472
    DockWidgetManager::getInstance()->addDockedWidget( dockedLibrary, m_mediaLibrary, Qt::TopDockWidgetArea );
473 474 475
}

void
476
MainWindow::setupClipPreview()
477
{
478 479 480 481 482 483
    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 );
484

485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502
    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 );
    m_projectPreview->setRenderer( m_renderer );
    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 );
503 504
}

505 506 507 508 509 510 511 512 513 514 515 516 517
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() );
}

518 519
void
MainWindow::createGlobalPreferences()
520
{
521
    m_globalPreferences = new Settings( SettingsManager::Vlmc, this );
522
    m_globalPreferences->addCategory( "general", QT_TRANSLATE_NOOP( "Settings", "General" ), SettingsManager::Vlmc,
523
                                     QIcon( ":/images/vlmc" ) );
524
    m_globalPreferences->addCategory( "keyboard", QT_TRANSLATE_NOOP( "Settings", "Keyboard" ), SettingsManager::Vlmc,
525
                                     QIcon( ":/images/keyboard" ) );
526
    m_globalPreferences->addCategory( "youtube", QT_TRANSLATE_NOOP( "Settings", "YouTube" ), SettingsManager::Vlmc,
527
                                     QIcon( ":/images/youtube" ) );
528
    m_globalPreferences->addCategory( "network", QT_TRANSLATE_NOOP( "Settings", "Network" ), SettingsManager::Vlmc,
529
                                     QIcon( ":/images/network" ) );
530 531
}

532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550
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 );
}

551 552
void
MainWindow::createProjectPreferences()
553
{
554
    m_projectPreferences = new Settings( SettingsManager::Project, this );
555
    m_projectPreferences->addCategory( "general", QT_TRANSLATE_NOOP( "Settings", "General" ), SettingsManager::Project,
556
                                   QIcon( ":/images/vlmc" ) );
557
    m_projectPreferences->addCategory( "video", QT_TRANSLATE_NOOP( "Settings", "Video" ), SettingsManager::Project,
558
                                   QIcon( ":/images/video" ) );
559
    m_projectPreferences->addCategory( "audio", QT_TRANSLATE_NOOP( "Settings", "Audio" ), SettingsManager::Project,
560
                                   QIcon( ":/images/audio" ) );
561 562
}

563 564 565 566
void
MainWindow::checkFolders()
{
    QDir dirUtil;
567
    if ( !dirUtil.exists( VLMC_GET_STRING( "general/DefaultProjectLocation" ) ) )
568 569
        dirUtil.mkdir( VLMC_GET_STRING( "general/DefaultProjectLocation" ) );

570
    if ( !dirUtil.exists( VLMC_GET_STRING( "general/TempFolderLocation" ) ) )
571 572 573
        dirUtil.mkdir( VLMC_GET_STRING( "general/TempFolderLocation" ) );
}

574 575 576 577 578 579 580 581
void
MainWindow::clearTemporaryFiles()
{
    QDir dirUtil;
    if( dirUtil.cd( VLMC_GET_STRING( "general/TempFolderLocation" ) ) )
        foreach ( const QString &file, dirUtil.entryList( QDir::Files ) )
            dirUtil.remove( file );
}
582

583 584
//Private slots definition

585
void
586
MainWindow::on_actionQuit_triggered()
Ludovic Fauvet's avatar
Ludovic Fauvet committed
587
{
588
    saveSettings();
Ludovic Fauvet's avatar
Ludovic Fauvet committed
589 590
    QApplication::quit();
}
591

592
void
593
MainWindow::on_actionPreferences_triggered()
594
{
595
   m_globalPreferences->show();
596
}
Ludovic Fauvet's avatar
Ludovic Fauvet committed
597

598
void
599
MainWindow::on_actionAbout_triggered()
Ludovic Fauvet's avatar
Ludovic Fauvet committed
600
{
601
    About::getInstance()->exec();
Ludovic Fauvet's avatar
Ludovic Fauvet committed
602
}
603

604 605
bool
MainWindow::checkVideoLength()
606
{
607
    if ( MainWorkflow::getInstance()->getLengthFrame() <= 0 )
608
    {
609
        QMessageBox::warning( NULL, tr ( "VLMC Renderer" ), tr( "There is nothing to render." ) );
610
        return false;
611
    }
612 613 614
    return true;
}

615
bool
616 617 618 619 620
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();
621

Rohit Yadav's avatar
Rohit Yadav committed
622
    WorkflowFileRendererDialog  *dialog = new WorkflowFileRendererDialog( m_fileRenderer, width, height );
623 624 625 626 627
    dialog->setModal( true );
    dialog->setOutputFileName( outputFileName );

    m_fileRenderer->initializeRenderer();
    m_fileRenderer->run( outputFileName, width, height, fps, vbitrate, abitrate );
628 629 630 631 632 633 634

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

635
    delete dialog;
636 637 638 639
    return true;
}

bool
640
MainWindow::renderVideoSettings( bool shareOnInternet )
641
{
642
    RendererSettings *settings = new RendererSettings( shareOnInternet );
643 644 645 646 647 648 649

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

650
    QString     outputFileName = settings->outputFileName();
651 652 653 654 655 656
    quint32     width          = settings->width();
    quint32     height         = settings->height();
    double      fps            = settings->fps();
    quint32     vbitrate       = settings->videoBitrate();
    quint32     abitrate       = settings->audioBitrate();

657 658
    delete settings;

659
    return renderVideo( outputFileName, width, height, fps, vbitrate, abitrate );
660 661
}

662
void
663 664 665
MainWindow::on_actionRender_triggered()
{
    if ( checkVideoLength() )
666
    {
667
        m_renderer->killRenderer();
668
        //Setup dialog box for querying render parameters.
669
        renderVideoSettings( false );
670
    }
671 672
}

673
void
674
MainWindow::on_actionShare_On_Internet_triggered()
675 676 677 678 679
{
    if ( checkVideoLength() )
    {
        m_renderer->killRenderer();

680 681
        if( !renderVideoSettings( true ) )
            return;
682

683 684
        checkFolders();
        QString fileName = VLMC_GET_STRING( "general/TempFolderLocation" ) + "/" +
685
                           VLMC_PROJECT_GET_STRING( "general/ProjectName" ) +
686
                           "-vlmc.mp4";
687

688
        loadGlobalProxySettings();
689

690 691
        ShareOnInternet *shareVideo = new ShareOnInternet();
        shareVideo->setVideoFile( fileName );
692

693 694 695 696 697
        if ( shareVideo->exec() == QDialog::Rejected )
        {
            delete shareVideo;
            return;
        }
698

699
        delete shareVideo;
700 701 702
    }
}

703
void
704
MainWindow::on_actionNew_Project_triggered()
705
{
706
    m_pWizard->restart();
707
    m_pWizard->show();
708 709
}

710
void
711
MainWindow::on_actionHelp_triggered()
712 713
{
    QDesktopServices::openUrl( QUrl( "http://vlmc.org" ) );
714 715
}

716
void
717
MainWindow::zoomIn()
Ludovic Fauvet's avatar
Ludovic Fauvet committed
718 719 720 721
{
    m_zoomSlider->setValue( m_zoomSlider->value() - 1 );
}

722
void
723
MainWindow::zoomOut()
Ludovic Fauvet's avatar
Ludovic Fauvet committed
724 725 726
{
    m_zoomSlider->setValue( m_zoomSlider->value() + 1 );
}
Ludovic Fauvet's avatar
Ludovic Fauvet committed
727

728
void
729
MainWindow::on_actionFullscreen_triggered( bool checked )
Ludovic Fauvet's avatar
Ludovic Fauvet committed
730
{
731 732 733
    if ( checked && !isFullScreen() )
    {
        setUnifiedTitleAndToolBarOnMac( false );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
734
        showFullScreen();
735
    }
Ludovic Fauvet's avatar
Ludovic Fauvet committed
736
    else
737 738
    {
        setUnifiedTitleAndToolBarOnMac( true );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
739
        showNormal();
740
    }
Ludovic Fauvet's avatar
Ludovic Fauvet committed
741
}
742

743
void
744
MainWindow::registerWidgetInWindowMenu( QDockWidget* widget )
745
{
746
    m_ui.menuWindow->addAction( widget->toggleViewAction() );
747
}
748

749
void
750
MainWindow::toolButtonClicked( QAction *action )
751
{
752 753 754 755 756
    if ( action == m_ui.actionSelection_mode )
        emit toolChanged( TOOL_DEFAULT );
    else if ( action == m_ui.actionCut_mode )
        emit toolChanged( TOOL_CUT );
    else
757
        vlmcCritical() << "Unknown tool. This should not happen !";
758
}
759

760
void
761
MainWindow::on_actionProject_Preferences_triggered()
762
{
763
  m_projectPreferences->show();
764
}
765

766 767
bool
MainWindow::saveSettings()
768
{
769
    GUIProjectManager   *pm = GUIProjectManager::getInstance();
770
    clearTemporaryFiles();
771
    if ( pm->askForSaveIfModified() )
772
    {
773
        SettingsManager* sm = SettingsManager::getInstance();
774
        // Save the current geometry
775
        sm->setValue( "private/MainWindowGeometry", saveGeometry(), SettingsManager::Vlmc );
776
        // Save the current layout
777 778
        sm->setValue( "private/MainWindowState", saveState(), SettingsManager::Vlmc );
        sm->setValue( "private/CleanQuit", true, SettingsManager::Vlmc );
779 780 781 782 783 784 785 786 787
        return true;
    }
    return false;
}

void
MainWindow::closeEvent( QCloseEvent* e )
{
    if ( saveSettings() )
788
        e->accept();
789 790
    else
        e->ignore();
791
}
792

793
void
794
MainWindow::projectUpdated( const QString& projectName, bool savedStatus )
795 796
{
    QString title = tr( "VideoLAN Movie Creator" );
797
    title += " - ";
798 799 800 801 802
    title += projectName;
    if ( savedStatus == false )
        title += " *";
    setWindowTitle( title );
}
803

804
void
805
MainWindow::on_actionClose_Project_triggered()
806
{
807
    GUIProjectManager::getInstance()->closeProject();
808 809
}

810
void
811
MainWindow::on_actionUndo_triggered()
812 813 814 815
{
    UndoStack::getInstance( this )->undo();
}