MainWindow.cpp 28.9 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 "ImportController.h"
51
#include "MediaLibrary.h"
52
#include "NotificationZone.h"
53
#include "PreviewWidget.h"
54 55
#include "timeline/Timeline.h"
#include "timeline/TracksView.h"
56
#include "UndoStack.h"
57 58

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

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

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

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

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

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

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

86 87 88
    //Preferences
    initVlmcPreferences();

89
    // GUI
90
    DockWidgetManager::getInstance( this )->setMainWindow( this );
91
    createGlobalPreferences();
92
    createProjectPreferences();
93
    initializeDockWidgets();
94
    initToolbar();
95
    createStatusBar();
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
    VLMC_CREATE_PREFERENCE_BOOL( "general/ConfirmDeletion", true,
271
                                 QT_TRANSLATE_NOOP( "PreferenceWidget", "Confirm clip deletion"),
272
                                 QT_TRANSLATE_NOOP( "PreferenceWidget", "Ask for confirmation before deleting a clip from the timeline" ) );
273

274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295
    //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" ) );

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

300 301 302 303 304
    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" ) );


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

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

331 332
#undef CREATE_MENU_SHORTCUT

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

455
    QDockWidget* dock = dockManager->addDockedWidget( UndoStack::getInstance( this ),
456
                                  QT_TRANSLATE_NOOP( "DockWidgetManager", "History" ),
457 458 459
                                  Qt::AllDockWidgetAreas,
                                  QDockWidget::AllDockWidgetFeatures,
                                  Qt::LeftDockWidgetArea );
460 461
    if ( dock != 0 )
        dock->hide();
462
    setupLibrary();
463 464
}

465 466 467 468 469 470 471 472 473 474 475 476 477
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() );
}

478 479
void
MainWindow::createGlobalPreferences()
480
{
481
    m_globalPreferences = new Settings( SettingsManager::Vlmc, this );
482
    m_globalPreferences->addCategory( QT_TRANSLATE_NOOP( "Settings", "general" ), SettingsManager::Vlmc,
483
                                     QIcon( ":/images/vlmc" ),
Nikoli's avatar
Nikoli committed
484
                                     tr ( "General" ) );
485
    m_globalPreferences->addCategory( QT_TRANSLATE_NOOP( "Settings", "keyboard" ), SettingsManager::Vlmc,
486
                                     QIcon( ":/images/keyboard" ),
Nikoli's avatar
Nikoli committed
487
                                     tr( "Keyboard" ) );
488 489
    m_globalPreferences->addCategory( QT_TRANSLATE_NOOP( "Settings", "youtube" ), SettingsManager::Vlmc,
                                     QIcon( ":/images/youtube" ),
Nikoli's avatar
Nikoli committed
490
                                     tr( "Youtube" ) );
491 492
    m_globalPreferences->addCategory( QT_TRANSLATE_NOOP( "Settings", "network" ), SettingsManager::Vlmc,
                                     QIcon( ":/images/network" ),
Nikoli's avatar
Nikoli committed
493
                                     tr( "Network" ) );
494 495
}

496 497
void
MainWindow::createProjectPreferences()
498
{
499
    m_projectPreferences = new Settings( SettingsManager::Project, this );
500
    m_projectPreferences->addCategory( QT_TRANSLATE_NOOP( "Settings", "general" ), SettingsManager::Project,
501
                                   QIcon( ":/images/vlmc" ),
Nikoli's avatar
Nikoli committed
502
                                   tr ( "General" ) );
503
    m_projectPreferences->addCategory( QT_TRANSLATE_NOOP( "Settings", "video" ), SettingsManager::Project,
504
                                   QIcon( ":/images/video" ),
Nikoli's avatar
Nikoli committed
505
                                   tr ( "Video" ) );
506
    m_projectPreferences->addCategory( QT_TRANSLATE_NOOP( "Settings", "audio" ), SettingsManager::Project,
507
                                   QIcon( ":/images/audio" ),
Nikoli's avatar
Nikoli committed
508
                                   tr ( "Audio" ) );
509 510
}

511

512 513
//Private slots definition

514
void
515
MainWindow::on_actionQuit_triggered()
Ludovic Fauvet's avatar
Ludovic Fauvet committed
516 517 518
{
    QApplication::quit();
}
519

520
void
521
MainWindow::on_actionPreferences_triggered()
522
{
523
   m_globalPreferences->show();
524
}
Ludovic Fauvet's avatar
Ludovic Fauvet committed
525

526
void
527
MainWindow::on_actionAbout_triggered()
Ludovic Fauvet's avatar
Ludovic Fauvet committed
528
{
529
    About::getInstance()->exec();
Ludovic Fauvet's avatar
Ludovic Fauvet committed
530
}
531

532 533
bool
MainWindow::checkVideoLength()
534
{
535
    if ( MainWorkflow::getInstance()->getLengthFrame() <= 0 )
536
    {
537
        QMessageBox::warning( NULL, tr ( "VLMC Renderer" ), tr( "There is nothing to render." ) );
538
        return false;
539
    }
540 541 542
    return true;
}

543
void
544 545 546 547 548
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();
549

550 551 552 553 554 555 556 557 558 559
    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;
}

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

581
        renderVideo( outputFileName, width, height, fps, vbitrate, abitrate );
582
    }
583 584
}

585
void
586 587 588 589 590 591 592 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
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...
    }
}

627
void
628
MainWindow::on_actionNew_Project_triggered()
629
{
630
    m_pWizard->restart();
631
    m_pWizard->show();
632 633
}

634
void
635
MainWindow::on_actionHelp_triggered()
636 637
{
    QDesktopServices::openUrl( QUrl( "http://vlmc.org" ) );
638 639
}

640
void
641
MainWindow::zoomIn()
Ludovic Fauvet's avatar
Ludovic Fauvet committed
642 643 644 645
{
    m_zoomSlider->setValue( m_zoomSlider->value() - 1 );
}

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

652
void
653
MainWindow::on_actionFullscreen_triggered( bool checked )
Ludovic Fauvet's avatar
Ludovic Fauvet committed
654 655 656 657 658 659
{
    if ( checked )
        showFullScreen();
    else
        showNormal();
}
660

661
void
662
MainWindow::registerWidgetInWindowMenu( QDockWidget* widget )
663
{
664
    m_ui.menuWindow->addAction( widget->toggleViewAction() );
665
}
666

667
void
668
MainWindow::toolButtonClicked( QAction *action )
669
{
670 671 672 673 674 675
    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 !";
676
}
677

678
void
679
MainWindow::on_actionProject_Preferences_triggered()
680
{
681
  m_projectPreferences->show();
682
}
683

684
void
685
MainWindow::closeEvent( QCloseEvent* e )
686
{
687 688
    GUIProjectManager   *pm = GUIProjectManager::getInstance();
    if ( pm->askForSaveIfModified() )
689
        e->accept();
690 691
    else
        e->ignore();
692
}
693

694
void
695
MainWindow::projectUpdated( const QString& projectName, bool savedStatus )
696 697
{
    QString title = tr( "VideoLAN Movie Creator" );
698
    title += " - ";
699 700 701 702 703
    title += projectName;
    if ( savedStatus == false )
        title += " *";
    setWindowTitle( title );
}
704

705
void
706
MainWindow::on_actionClose_Project_triggered()
707
{
708
    GUIProjectManager::getInstance()->closeProject();
709 710
}

711
void
712
MainWindow::on_actionUndo_triggered()
713 714 715 716
{
    UndoStack::getInstance( this )->undo();
}

717
void
718
MainWindow::on_actionRedo_triggered()
719 720 721 722
{
    UndoStack::getInstance( this )->redo();
}

723
void
724
MainWindow::on_actionCrash_triggered()
725
{
726 727 728 729 730
    //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 );
731
}
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
732

733
bool
734
MainWindow::restoreSession()
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
735 736
{
    QSettings   s;
737
    bool        fileCreated = false;
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
738 739
    bool        ret = false;

740 741
    fileCreated = s.contains( "VlmcVersion" );
    if ( fileCreated == true )
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
742
    {
743
        bool        cleanQuit = s.value( "CleanQuit", true ).toBool();
744 745 746 747 748 749 750

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

768
void
769
MainWindow::on_actionImport_triggered()
770 771 772
{
    m_importController->exec();
}
773

774
void
775
MainWindow::canUndoChanged( bool canUndo )
776 777 778 779
{
    m_ui.actionUndo->setEnabled( canUndo );
}

780
void
781
MainWindow::canRedoChanged( bool canRedo )
782 783 784 785
{
    m_ui.actionRedo->setEnabled( canRedo );
}

Ludovic Fauvet's avatar
Ludovic Fauvet committed
786
#ifdef WITH_CRASHBUTTON
787 788
void
MainWindow::setupCrashTester()
789 790 791 792 793 794 795 796
{
    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
797