MainWindow.cpp 29.3 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 <QSettings>
32 33
#include <QDebug>
#include <QTemporaryFile>
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"

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

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

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

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

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

74
    qRegisterMetaType<MainWorkflow::TrackType>( "MainWorkflow::TrackType" );
75
    qRegisterMetaType<MainWorkflow::FrameChangedReason>( "MainWorkflow::FrameChangedReason" );
76
    qRegisterMetaType<QVariant>( "QVariant" );
77

Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
78
    //We only install message handler here cause it uses configuration.
79
//    VlmcDebug::getInstance()->setup();
80

81
    //VLC Instance:
82
    LibVLCpp::Instance::getInstance();
83

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

87 88 89
    //Preferences
    initVlmcPreferences();

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

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

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

114 115 116 117 118 119 120 121 122
    // 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
123 124 125 126
    // Wizard
    m_pWizard = new ProjectWizard( this );
    m_pWizard->setModal( true );

127

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

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

142 143
MainWindow::~MainWindow()
{
144 145 146 147 148
    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
149
    s.setValue( "CleanQuit", true );
150 151
    s.sync();

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

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

Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
172
//use this helper when the shortcut is binded to a menu action
173 174 175
#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
176

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296
    //Setup VLMC Youtube Preference...
    VLMC_CREATE_PREFERENCE_STRING( "youtube/DeveloperKey", "AI39si7FOtp165Vq644xVkuka84TVQNbztQmQ1dC9stheBfh3-33RZaTu7eJkYJzvxp6XNbvlr4M6-ULjXDERFl62WIo6AQIEQ",
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Youtube Developer Key" ),
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "The Youtube Developer Key" ) );

    VLMC_CREATE_PREFERENCE_STRING( "youtube/Username", "username",
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Youtube Username" ),
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "VLMC won't store your passwords..." ) );

    //Setup VLMC Proxy Settings
    VLMC_CREATE_PREFERENCE_STRING( "network/ProxyUrl", "",
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Proxy" ),
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "The HTTP Proxy " ) );

    VLMC_CREATE_PREFERENCE_STRING( "network/ProxyPort", "",
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Proxy Port" ),
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "The HTTP Proxy Port" ) );

    VLMC_CREATE_PREFERENCE_STRING( "network/ProxyUsername", "",
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Proxy Username" ),
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "The HTTP Proxy Username" ) );

297
    VLMC_CREATE_PREFERENCE_PASSWORD( "network/ProxyPassword", "",
298 299 300
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Proxy Password" ),
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "The HTTP Proxy Password" ) );

301 302 303 304 305
    VLMC_CREATE_PREFERENCE_PATH( "general/DefaultProjectLocation", QDir::homePath(),
                                    QT_TRANSLATE_NOOP( "PreferencesWidget", "Project default location" ),
                                    QT_TRANSLATE_NOOP( "PreferenceWidget", "The default location where to store projects folders" ) );


306
    //Load saved preferences :
307 308 309 310 311 312 313
    QSettings       s;
    if ( s.value( "VlmcVersion" ).toString() != PROJECT_VERSION )
        s.clear();
    else
    {
        loadVlmcPreferences( "keyboard" );
        loadVlmcPreferences( "general" );
314 315
        loadVlmcPreferences( "youtube" );
        loadVlmcPreferences( "network" );
316 317
    }
    s.setValue( "VlmcVersion", PROJECT_VERSION );
318 319 320 321 322 323 324 325 326 327 328 329
}

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 );
    }
330 331
}

Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
332 333
#undef CREATE_MENU_SHORTCUT

334 335
void
MainWindow::setupLibrary()
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
336
{
337
    m_importController = new ImportController();
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
338 339
    const ClipRenderer* clipRenderer = qobject_cast<const ClipRenderer*>( m_clipPreview->getGenericRenderer() );
    Q_ASSERT( clipRenderer != NULL );
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
340

341 342 343
    MediaLibrary    *mediaLibrary = new MediaLibrary();

    DockWidgetManager::getInstance()->addDockedWidget( mediaLibrary, QT_TRANSLATE_NOOP( "DockWidgetManager", "Media Library" ),
344 345 346
                                                    Qt::AllDockWidgetAreas,
                                                    QDockWidget::AllDockWidgetFeatures,
                                                    Qt::LeftDockWidgetArea );
347
    connect( mediaLibrary, SIGNAL( clipSelected( Clip* ) ),
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
348
             clipRenderer, SLOT( setClip( Clip* ) ) );
349 350
    connect( mediaLibrary, SIGNAL( importRequired() ),
             this, SLOT( on_actionImport_triggered() ) );
351 352
    connect( Library::getInstance(), SIGNAL( clipRemoved( const QUuid& ) ),
             clipRenderer, SLOT( clipUnloaded( const QUuid& ) ) );
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
353 354
}

355 356
void
MainWindow::on_actionSave_triggered()
357
{
358
    GUIProjectManager::getInstance()->saveProject();
359 360
}

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

367
void
368
MainWindow::on_actionLoad_Project_triggered()
369
{
370
    GUIProjectManager::getInstance()->loadProject();
371 372
}

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

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

383
void
384
MainWindow::createStatusBar()
385
{
386 387 388
    //Notifications:
    createNotificationZone();

389 390 391 392 393
    // Spacer
    QWidget* spacer = new QWidget( this );
    spacer->setFixedWidth( 20 );
    m_ui.statusbar->addPermanentWidget( spacer );

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

    // Zoom slider
403 404 405 406 407 408 409 410 411
    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
412
    m_zoomSlider->setInvertedAppearance( true );
413
    m_ui.statusbar->addPermanentWidget( m_zoomSlider );
414

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

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

434
    DockWidgetManager *dockManager = DockWidgetManager::getInstance();
435

436 437
    m_clipPreview = new PreviewWidget( this );
    m_clipPreview->setRenderer( new ClipRenderer );
438
    dockManager->addDockedWidget( m_clipPreview,
Ludovic Fauvet's avatar
Ludovic Fauvet committed
439
                                  QT_TRANSLATE_NOOP( "DockWidgetManager", "Clip Preview" ),
geoff's avatar
geoff committed
440 441 442
                                  Qt::AllDockWidgetAreas,
                                  QDockWidget::AllDockWidgetFeatures,
                                  Qt::TopDockWidgetArea );
443
    KeyboardShortcutHelper* clipShortcut = new KeyboardShortcutHelper( "keyboard/mediapreview", this );
444
    connect( clipShortcut, SIGNAL( activated() ), m_clipPreview, SLOT( on_pushButtonPlay_clicked() ) );
445

446 447
    m_projectPreview = new PreviewWidget( this );
    m_projectPreview->setRenderer( m_renderer );
448
    dockManager->addDockedWidget( m_projectPreview,
Ludovic Fauvet's avatar
Ludovic Fauvet committed
449
                                  QT_TRANSLATE_NOOP( "DockWidgetManager", "Project Preview" ),
450 451
                                  Qt::AllDockWidgetAreas,
                                  QDockWidget::AllDockWidgetFeatures,
452
                                  Qt::TopDockWidgetArea );
453
    KeyboardShortcutHelper* renderShortcut = new KeyboardShortcutHelper( "keyboard/renderpreview", this );
454
    connect( renderShortcut, SIGNAL( activated() ), m_projectPreview, SLOT( on_pushButtonPlay_clicked() ) );
455

456 457 458 459 460 461
    EffectsList *effectsList = new EffectsList( this );
    dockManager->addDockedWidget( effectsList,
                                  QT_TRANSLATE_NOOP( "DockWidgetManager", "Effects List" ),
                                  Qt::AllDockWidgetAreas, QDockWidget::AllDockWidgetFeatures,
                                  Qt::LeftDockWidgetArea );

462
    QDockWidget* dock = dockManager->addDockedWidget( UndoStack::getInstance( this ),
Ludovic Fauvet's avatar
Ludovic Fauvet committed
463
                                  QT_TRANSLATE_NOOP( "DockWidgetManager", "History" ),
464 465 466
                                  Qt::AllDockWidgetAreas,
                                  QDockWidget::AllDockWidgetFeatures,
                                  Qt::LeftDockWidgetArea );
467 468
    if ( dock != 0 )
        dock->hide();
469
    setupLibrary();
470 471
}

472 473 474 475 476 477 478 479 480 481 482 483 484
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() );
}

485 486
void
MainWindow::createGlobalPreferences()
487
{
488
    m_globalPreferences = new Settings( SettingsManager::Vlmc, this );
489
    m_globalPreferences->addCategory( QT_TRANSLATE_NOOP( "Settings", "general" ), SettingsManager::Vlmc,
490
                                     QIcon( ":/images/vlmc" ),
Nikoli's avatar
Nikoli committed
491
                                     tr ( "General" ) );
492
    m_globalPreferences->addCategory( QT_TRANSLATE_NOOP( "Settings", "keyboard" ), SettingsManager::Vlmc,
493
                                     QIcon( ":/images/keyboard" ),
Nikoli's avatar
Nikoli committed
494
                                     tr( "Keyboard" ) );
495 496
    m_globalPreferences->addCategory( QT_TRANSLATE_NOOP( "Settings", "youtube" ), SettingsManager::Vlmc,
                                     QIcon( ":/images/youtube" ),
Nikoli's avatar
Nikoli committed
497
                                     tr( "Youtube" ) );
498 499
    m_globalPreferences->addCategory( QT_TRANSLATE_NOOP( "Settings", "network" ), SettingsManager::Vlmc,
                                     QIcon( ":/images/network" ),
Nikoli's avatar
Nikoli committed
500
                                     tr( "Network" ) );
501 502
}

503 504
void
MainWindow::createProjectPreferences()
505
{
506
    m_projectPreferences = new Settings( SettingsManager::Project, this );
507
    m_projectPreferences->addCategory( QT_TRANSLATE_NOOP( "Settings", "general" ), SettingsManager::Project,
508
                                   QIcon( ":/images/vlmc" ),
Nikoli's avatar
Nikoli committed
509
                                   tr ( "General" ) );
510
    m_projectPreferences->addCategory( QT_TRANSLATE_NOOP( "Settings", "video" ), SettingsManager::Project,
511
                                   QIcon( ":/images/video" ),
Nikoli's avatar
Nikoli committed
512
                                   tr ( "Video" ) );
513
    m_projectPreferences->addCategory( QT_TRANSLATE_NOOP( "Settings", "audio" ), SettingsManager::Project,
514
                                   QIcon( ":/images/audio" ),
Nikoli's avatar
Nikoli committed
515
                                   tr ( "Audio" ) );
516 517
}

518

519 520
//Private slots definition

521
void
522
MainWindow::on_actionQuit_triggered()
Ludovic Fauvet's avatar
Ludovic Fauvet committed
523 524 525
{
    QApplication::quit();
}
526

527
void
528
MainWindow::on_actionPreferences_triggered()
529
{
530
   m_globalPreferences->show();
531
}
Ludovic Fauvet's avatar
Ludovic Fauvet committed
532

533
void
534
MainWindow::on_actionAbout_triggered()
Ludovic Fauvet's avatar
Ludovic Fauvet committed
535
{
536
    About::getInstance()->exec();
Ludovic Fauvet's avatar
Ludovic Fauvet committed
537
}
538

539 540
bool
MainWindow::checkVideoLength()
541
{
542
    if ( MainWorkflow::getInstance()->getLengthFrame() <= 0 )
543
    {
544
        QMessageBox::warning( NULL, tr ( "VLMC Renderer" ), tr( "There is nothing to render." ) );
545
        return false;
546
    }
547 548 549
    return true;
}

550
void
551 552 553 554 555
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();
556

557 558 559 560 561 562 563 564 565 566
    WorkflowFileRendererDialog  *dialog = new WorkflowFileRendererDialog( m_fileRenderer, width, height );
    dialog->setModal( true );
    dialog->setOutputFileName( outputFileName );

    m_fileRenderer->initializeRenderer();
    m_fileRenderer->run( outputFileName, width, height, fps, vbitrate, abitrate );
    dialog->exec();
    delete dialog;
}

567
void
568 569 570
MainWindow::on_actionRender_triggered()
{
    if ( checkVideoLength() )
571
    {
572
        m_renderer->killRenderer();
573 574 575 576 577 578 579 580
        //Setup dialog box for querying render parameters.
        RendererSettings    *settings = new RendererSettings;
        if ( settings->exec() == QDialog::Rejected )
        {
            delete settings;
            return ;
        }
        QString     outputFileName = settings->outputFileName();
581 582 583 584 585
        quint32     width          = settings->width();
        quint32     height         = settings->height();
        double      fps            = settings->fps();
        quint32     vbitrate       = settings->videoBitrate();
        quint32     abitrate       = settings->audioBitrate();
586
        delete settings;
587

588
        renderVideo( outputFileName, width, height, fps, vbitrate, abitrate );
589
    }
590 591
}

592
void
593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633
MainWindow::on_actionShare_On_Youtube_triggered()
{
    if ( checkVideoLength() )
    {
        m_renderer->killRenderer();
        //Setup dialog box for querying youtube export parameters.
        ShareOnYoutube *exportToYoutube = new ShareOnYoutube;

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

        QString username     = exportToYoutube->username();
        QString password     = exportToYoutube->password();
        QString title        = exportToYoutube->title();
        QString category     = exportToYoutube->category();
        QString description  = exportToYoutube->description();
        QString tags         = exportToYoutube->tags();
        quint32 width        = exportToYoutube->width();
        quint32 height       = exportToYoutube->height();
        bool    videoPrivacy = exportToYoutube->videoPrivacy();

        delete exportToYoutube;

        qDebug()<< username << password << title << category << description << tags << width << height << videoPrivacy;

        //here add code to render video using WorkflowFileRenderer... to a temp folder, using QTemporaryFolder
        QTemporaryFile tmp( "vlmc-youtube.avi" );
        tmp.setAutoRemove( false );
        tmp.open();

        qDebug()<< tmp.fileTemplate() << tmp.fileName() << QDir::tempPath();

        renderVideo( tmp.fileName(), width, height, 30.0, 4000, 256 );

        //Add code here to init Youtube Uploader with the file, do stuff :D...
    }
}

634
void
635
MainWindow::on_actionNew_Project_triggered()
636
{
637
    m_pWizard->restart();
638
    m_pWizard->show();
639 640
}

641
void
642
MainWindow::on_actionHelp_triggered()
643 644
{
    QDesktopServices::openUrl( QUrl( "http://vlmc.org" ) );
645 646
}

647
void
648
MainWindow::zoomIn()
Ludovic Fauvet's avatar
Ludovic Fauvet committed
649 650 651 652
{
    m_zoomSlider->setValue( m_zoomSlider->value() - 1 );
}

653
void
654
MainWindow::zoomOut()
Ludovic Fauvet's avatar
Ludovic Fauvet committed
655 656 657
{
    m_zoomSlider->setValue( m_zoomSlider->value() + 1 );
}
Ludovic Fauvet's avatar
Ludovic Fauvet committed
658

659
void
660
MainWindow::on_actionFullscreen_triggered( bool checked )
Ludovic Fauvet's avatar
Ludovic Fauvet committed
661 662 663 664 665 666
{
    if ( checked )
        showFullScreen();
    else
        showNormal();
}
667

668
void
669
MainWindow::registerWidgetInWindowMenu( QDockWidget* widget )
670
{
671
    m_ui.menuWindow->addAction( widget->toggleViewAction() );
672
}
673

674
void
675
MainWindow::toolButtonClicked( QAction *action )
676
{
677 678 679 680 681 682
    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 !";
683
}
684

685
void
686
MainWindow::on_actionProject_Preferences_triggered()
687
{
688
  m_projectPreferences->show();
689
}
690

691
void
692
MainWindow::closeEvent( QCloseEvent* e )
693
{
694 695
    GUIProjectManager   *pm = GUIProjectManager::getInstance();
    if ( pm->askForSaveIfModified() )
696
        e->accept();
697 698
    else
        e->ignore();
699
}
700

701
void
702
MainWindow::projectUpdated( const QString& projectName, bool savedStatus )
703 704
{
    QString title = tr( "VideoLAN Movie Creator" );
705
    title += " - ";
706 707 708 709 710
    title += projectName;
    if ( savedStatus == false )
        title += " *";
    setWindowTitle( title );
}
711

712
void
713
MainWindow::on_actionClose_Project_triggered()
714
{
715
    GUIProjectManager::getInstance()->closeProject();
716 717
}

718
void
719
MainWindow::on_actionUndo_triggered()
720 721 722 723
{
    UndoStack::getInstance( this )->undo();
}

724
void
725
MainWindow::on_actionRedo_triggered()
726 727 728 729
{
    UndoStack::getInstance( this )->redo();
}

730
void
731
MainWindow::on_actionCrash_triggered()
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
732
{
733 734 735 736 737
    //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 );
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
738
}
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
739

740
bool
741
MainWindow::restoreSession()
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
742 743
{
    QSettings   s;
744
    bool        fileCreated = false;
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
745 746
    bool        ret = false;

747 748
    fileCreated = s.contains( "VlmcVersion" );
    if ( fileCreated == true )
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
749
    {
750
        bool        cleanQuit = s.value( "CleanQuit", true ).toBool();
751 752 753 754 755 756 757

        // 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
758
        {
759
            QMessageBox::StandardButton res = QMessageBox::question( this, tr( "Crash recovery" ), tr( "VLMC didn't closed nicely. Do you want to recover your project?" ),
760 761 762
                                   QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes );
            if ( res == QMessageBox::Yes )
            {
763
                if ( GUIProjectManager::getInstance()->loadEmergencyBackup() == true )
764 765
                    ret = true;
                else
766
                    QMessageBox::warning( this, tr( "Can't restore project" ), tr( "VLMC didn't manage to restore your project. We apology for the inconvenience" ) );
767
            }
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
768 769 770 771 772 773
        }
    }
    s.setValue( "CleanQuit", false );
    s.sync();
    return ret;
}
774

775
void
776
MainWindow::on_actionImport_triggered()
777 778 779
{
    m_importController->exec();
}
780

781
void
782
MainWindow::canUndoChanged( bool canUndo )
783 784 785 786
{
    m_ui.actionUndo->setEnabled( canUndo );
}

787
void
788
MainWindow::canRedoChanged( bool canRedo )
789 790 791 792
{
    m_ui.actionRedo->setEnabled( canRedo );
}

Ludovic Fauvet's avatar
Ludovic Fauvet committed
793
#ifdef WITH_CRASHBUTTON
794 795
void
MainWindow::setupCrashTester()
796 797 798 799 800 801 802 803
{
    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
804