MainWindow.cpp 30.7 KB
Newer Older
Ludovic Fauvet's avatar
Ludovic Fauvet committed
1
/*****************************************************************************
2
 * MainWindow.cpp: VLMC MainWindow
Ludovic Fauvet's avatar
Ludovic Fauvet committed
3
 *****************************************************************************
Ludovic Fauvet's avatar
Ludovic Fauvet committed
4
 * Copyright (C) 2008-2010 VideoLAN
Ludovic Fauvet's avatar
Ludovic Fauvet committed
5 6
 *
 * Authors: Ludovic Fauvet <etix@l0cal.com>
7
 *          Hugo Beauzée-Luyssen <beauze.h@gmail.com>
Ludovic Fauvet's avatar
Ludovic Fauvet committed
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

24
#include <QSizePolicy>
Christophe Courtaut's avatar
Christophe Courtaut committed
25
#include <QDockWidget>
26
#include <QFileDialog>
27
#include <QSlider>
28
#include <QMessageBox>
29 30
#include <QDesktopServices>
#include <QUrl>
31
#include <QNetworkProxy>
32
#include <QSettings>
33
#include <QDebug>
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
34

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

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

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

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

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

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

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

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

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

84 85 86
    //Preferences
    initVlmcPreferences();

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

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

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

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


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

126

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

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

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

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

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

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

176 177 178
void
MainWindow::initVlmcPreferences()
{
179
    //Setup VLMC Keyboard Preference...
180 181 182
    VLMC_CREATE_PREFERENCE_KEYBOARD( "keyboard/mediapreview", "Ctrl+Return",
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Media preview" ),
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Preview the selected media, or pause the current preview" ) );
183

184 185 186
    VLMC_CREATE_PREFERENCE_KEYBOARD( "keyboard/renderpreview", "Space",
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Render preview" ),
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Preview the project, or pause the current preview" ) );
187

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

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

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

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

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

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

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

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

225 226 227 228
    CREATE_MENU_SHORTCUT( "keyboard/openproject",
                          QKeySequence( QKeySequence::Open ).toString().toLocal8Bit(),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Open a project" ),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Open an existing project" ), actionLoad_Project );
229

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

235 236 237
    CREATE_MENU_SHORTCUT( "keyboard/saveas", "Ctrl+Shift+S",
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Save as" ),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Save the current project to a new file" ), actionSave_As );
238

239 240 241 242
    CREATE_MENU_SHORTCUT( "keyboard/closeproject",
                          QKeySequence( QKeySequence::Close ).toString().toLocal8Bit(),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Close the project" ),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Close the current project" ), actionClose_Project );
243

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

248 249 250 251
    CREATE_MENU_SHORTCUT( "keyboard/renderproject", "Ctrl+R",
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Render the project" ),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Render the project to a file" ), actionRender );

252 253 254 255 256 257 258 259
    CREATE_MENU_SHORTCUT( "keyboard/defaultmode", "n",
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Selection mode" ),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Select the selection tool in the timeline" ), actionSelection_mode );

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

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

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

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

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

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

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

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

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

    //Setup VLMC Proxy Settings
297 298 299 300 301 302 303
    VLMC_CREATE_PREFERENCE_BOOL( "network/UseProxy", false,
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Enable Proxy for VLMC"),
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Enables Global Network Proxy for VLMC." ) );

    VLMC_CREATE_PREFERENCE_STRING( "network/ProxyHost", "",
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Proxy Hostname" ),
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Set Proxy Hostname." ) );
304 305 306

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

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

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

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

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

343 344
#undef CREATE_MENU_SHORTCUT

345 346
void
MainWindow::setupLibrary()
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
347
{
348
    m_importController = new ImportController();
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
349 350
    const ClipRenderer* clipRenderer = qobject_cast<const ClipRenderer*>( m_clipPreview->getGenericRenderer() );
    Q_ASSERT( clipRenderer != NULL );
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
351

352 353 354
    MediaLibrary    *mediaLibrary = new MediaLibrary();

    DockWidgetManager::getInstance()->addDockedWidget( mediaLibrary, QT_TRANSLATE_NOOP( "DockWidgetManager", "Media Library" ),
355 356 357
                                                    Qt::AllDockWidgetAreas,
                                                    QDockWidget::AllDockWidgetFeatures,
                                                    Qt::LeftDockWidgetArea );
358
    connect( mediaLibrary, SIGNAL( clipSelected( Clip* ) ),
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
359
             clipRenderer, SLOT( setClip( Clip* ) ) );
360 361
    connect( mediaLibrary, SIGNAL( importRequired() ),
             this, SLOT( on_actionImport_triggered() ) );
362 363
    connect( Library::getInstance(), SIGNAL( clipRemoved( const QUuid& ) ),
             clipRenderer, SLOT( clipUnloaded( const QUuid& ) ) );
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
364 365
}

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

372
void
373
MainWindow::on_actionSave_As_triggered()
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
374
{
375
    GUIProjectManager::getInstance()->saveProject( true );
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
376 377
}

378
void
379
MainWindow::on_actionLoad_Project_triggered()
380
{
381
    GUIProjectManager::getInstance()->loadProject();
382 383
}

384 385 386 387 388 389 390 391 392 393
void
MainWindow::createNotificationZone()
{
    QWidget *notifSpacer = new QWidget( this );
    notifSpacer->setFixedWidth( 75 );
    m_ui.statusbar->addPermanentWidget( notifSpacer );

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

394
void
395
MainWindow::createStatusBar()
396
{
397 398 399
    //Notifications:
    createNotificationZone();

400 401 402 403 404
    // Spacer
    QWidget* spacer = new QWidget( this );
    spacer->setFixedWidth( 20 );
    m_ui.statusbar->addPermanentWidget( spacer );

Ludovic Fauvet's avatar
Ludovic Fauvet committed
405 406 407
    // Zoom Out
    QToolButton* zoomOutButton = new QToolButton( this );
    zoomOutButton->setIcon( QIcon( ":/images/zoomout" ) );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
408
    zoomOutButton->setStatusTip( tr( "Zoom out" ) );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
409 410 411
    m_ui.statusbar->addPermanentWidget( zoomOutButton );
    connect( zoomOutButton, SIGNAL( clicked() ),
             this, SLOT( zoomOut() ) );
412 413

    // Zoom slider
414 415 416 417 418 419 420 421 422
    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
423
    m_zoomSlider->setInvertedAppearance( true );
424
    m_ui.statusbar->addPermanentWidget( m_zoomSlider );
425

Ludovic Fauvet's avatar
Ludovic Fauvet committed
426 427 428
    // Zoom IN
    QToolButton* zoomInButton = new QToolButton( this );
    zoomInButton->setIcon( QIcon( ":/images/zoomin" ) );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
429
    zoomInButton->setStatusTip( tr( "Zoom in" ) );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
430 431 432
    m_ui.statusbar->addPermanentWidget( zoomInButton );
    connect( zoomInButton, SIGNAL( clicked() ),
             this, SLOT( zoomIn() ) );
433 434
}

435
void
436
MainWindow::initializeDockWidgets( void )
437
{
438 439 440 441 442 443 444
    DockWidgetManager *dockManager = DockWidgetManager::getInstance();

    EffectsList *effectsList = new EffectsList( this );
    dockManager->addDockedWidget( effectsList,
                                  QT_TRANSLATE_NOOP( "DockWidgetManager", "Effects List" ),
                                  Qt::AllDockWidgetAreas, QDockWidget::AllDockWidgetFeatures,
                                  Qt::LeftDockWidgetArea );
445
    EffectsEngine::getInstance()->loadEffects();
446

447 448 449
    m_renderer = new WorkflowRenderer();
    m_renderer->initializeRenderer();
    m_timeline = new Timeline( m_renderer, this );
450 451 452
    m_timeline->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
    m_timeline->show();
    setCentralWidget( m_timeline );
453

454 455
    m_clipPreview = new PreviewWidget( this );
    m_clipPreview->setRenderer( new ClipRenderer );
456
    dockManager->addDockedWidget( m_clipPreview,
457
                                  QT_TRANSLATE_NOOP( "DockWidgetManager", "Clip Preview" ),
geoff's avatar
geoff committed
458 459 460
                                  Qt::AllDockWidgetAreas,
                                  QDockWidget::AllDockWidgetFeatures,
                                  Qt::TopDockWidgetArea );
461
    KeyboardShortcutHelper* clipShortcut = new KeyboardShortcutHelper( "keyboard/mediapreview", this );
462
    connect( clipShortcut, SIGNAL( activated() ), m_clipPreview, SLOT( on_pushButtonPlay_clicked() ) );
463

464 465
    m_projectPreview = new PreviewWidget( this );
    m_projectPreview->setRenderer( m_renderer );
466
    dockManager->addDockedWidget( m_projectPreview,
467
                                  QT_TRANSLATE_NOOP( "DockWidgetManager", "Project Preview" ),
468 469
                                  Qt::AllDockWidgetAreas,
                                  QDockWidget::AllDockWidgetFeatures,
470
                                  Qt::TopDockWidgetArea );
471
    KeyboardShortcutHelper* renderShortcut = new KeyboardShortcutHelper( "keyboard/renderpreview", this );
472
    connect( renderShortcut, SIGNAL( activated() ), m_projectPreview, SLOT( on_pushButtonPlay_clicked() ) );
473

474
    QDockWidget* dock = dockManager->addDockedWidget( UndoStack::getInstance( this ),
475
                                  QT_TRANSLATE_NOOP( "DockWidgetManager", "History" ),
476 477 478
                                  Qt::AllDockWidgetAreas,
                                  QDockWidget::AllDockWidgetFeatures,
                                  Qt::LeftDockWidgetArea );
479 480
    if ( dock != 0 )
        dock->hide();
481
    setupLibrary();
482 483
}

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

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

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

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

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

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

560

561 562
//Private slots definition

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

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

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

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

592
bool
593 594 595 596 597
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();
598

599
    WorkflowFileRendererDialog  *dialog = new WorkflowFileRendererDialog( m_fileRenderer, 640, 480 );
600 601 602 603 604
    dialog->setModal( true );
    dialog->setOutputFileName( outputFileName );

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

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

612
    delete dialog;
613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636
    return true;
}

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

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

    QString     outputFileName;
    quint32     width          = settings->width();
    quint32     height         = settings->height();
    double      fps            = settings->fps();
    quint32     vbitrate       = settings->videoBitrate();
    quint32     abitrate       = settings->audioBitrate();
    delete settings;

    if ( exportType )
        outputFileName = VLMC_GET_STRING( "general/TempFolderLocation" ) + "/" +
637
                         VLMC_PROJECT_GET_STRING( "general/ProjectName" ) +
638 639 640 641 642
                         "-vlmc.mp4";
    else
        outputFileName = settings->outputFileName();

    return renderVideo( outputFileName, width, height, fps, vbitrate, abitrate );
643 644
}

645
void
646 647 648
MainWindow::on_actionRender_triggered()
{
    if ( checkVideoLength() )
649
    {
650
        m_renderer->killRenderer();
651
        //Setup dialog box for querying render parameters.
652
        renderVideoSettings( false );
653
    }
654 655
}

656
void
657
MainWindow::on_actionShare_On_Internet_triggered()
658 659 660 661 662
{
    if ( checkVideoLength() )
    {
        m_renderer->killRenderer();

663 664
        if( !renderVideoSettings( true ) )
            return;
665

666 667
        checkFolders();
        QString fileName = VLMC_GET_STRING( "general/TempFolderLocation" ) + "/" +
668
                           VLMC_PROJECT_GET_STRING( "general/ProjectName" ) +
669
                           "-vlmc.mp4";
670

671
        loadGlobalProxySettings();
672

673 674
        ShareOnInternet *shareVideo = new ShareOnInternet();
        shareVideo->setVideoFile( fileName );
675

676 677 678 679 680
        if ( shareVideo->exec() == QDialog::Rejected )
        {
            delete shareVideo;
            return;
        }
681

682
        delete shareVideo;
683 684 685
    }
}

686
void
687
MainWindow::on_actionNew_Project_triggered()
688
{
689
    m_pWizard->restart();
690
    m_pWizard->show();
691 692
}

693
void
694
MainWindow::on_actionHelp_triggered()
695 696
{
    QDesktopServices::openUrl( QUrl( "http://vlmc.org" ) );
697 698
}

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

705
void
706
MainWindow::zoomOut()
Ludovic Fauvet's avatar
Ludovic Fauvet committed
707 708 709
{
    m_zoomSlider->setValue( m_zoomSlider->value() + 1 );
}
Ludovic Fauvet's avatar
Ludovic Fauvet committed
710

711
void
712
MainWindow::on_actionFullscreen_triggered( bool checked )
Ludovic Fauvet's avatar
Ludovic Fauvet committed
713 714 715 716 717 718
{
    if ( checked )
        showFullScreen();
    else
        showNormal();
}
719

720
void
721
MainWindow::registerWidgetInWindowMenu( QDockWidget* widget )
722
{
723
    m_ui.menuWindow->addAction( widget->toggleViewAction() );
724
}
725

726
void
727
MainWindow::toolButtonClicked( QAction *action )
728
{
729 730 731 732 733 734
    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 !";
735
}
736

737
void
738
MainWindow::on_actionProject_Preferences_triggered()
739
{
740
  m_projectPreferences->show();
741
}
742

743
void
744
MainWindow::closeEvent( QCloseEvent* e )
745
{
746 747
    GUIProjectManager   *pm = GUIProjectManager::getInstance();
    if ( pm->askForSaveIfModified() )
748
        e->accept();
749 750
    else
        e->ignore();
751
}
752

753
void
754
MainWindow::projectUpdated( const QString& projectName, bool savedStatus )
755 756
{
    QString title = tr( "VideoLAN Movie Creator" );
757
    title += " - ";
758 759 760 761 762
    title += projectName;
    if ( savedStatus == false )
        title += " *";
    setWindowTitle( title );
}
763

764
void
765
MainWindow::on_actionClose_Project_triggered()
766
{
767
    GUIProjectManager::getInstance()->closeProject();
768 769
}

770
void
771
MainWindow::on_actionUndo_triggered()
772 773 774 775
{
    UndoStack::getInstance( this )->undo();
}

776
void
777
MainWindow::on_actionRedo_triggered()
778 779 780 781
{
    UndoStack::getInstance( this )->redo();
}

782
void
783
MainWindow::on_actionCrash_triggered()
784
{
785 786 787 788 789
    //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 );
790
}
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
791

792
bool
793
MainWindow::restoreSession()
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
794 795
{
    QSettings   s;
796
    bool        fileCreated = false;
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
797 798
    bool        ret = false;

799 800
    fileCreated = s.contains( "VlmcVersion" );
    if ( fileCreated == true )
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
801
    {
802
        bool        cleanQuit = s.value( "CleanQuit", true ).toBool();
803 804 805 806 807 808 809

        // 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
810
        {
811
            QMessageBox::StandardButton res = QMessageBox::question( this, tr( "Crash recovery" ), tr( "VLMC didn't closed nicely. Do you want to recover your project?" ),
812 813 814
                                   QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes );
            if ( res == QMessageBox::Yes )
            {
815
                if ( GUIProjectManager::getInstance()->loadEmergencyBackup() == true )
816 817
                    ret = true;
                else
818
                    QMessageBox::warning( this, tr( "Can't restore project" ), tr( "VLMC didn't manage to restore your project. We apology for the inconvenience" ) );
819
            }
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
820 821 822 823 824 825
        }
    }
    s.setValue( "CleanQuit", false );
    s.sync();
    return ret;
}
826

827
void
828
MainWindow::on_actionImport_triggered()
829 830 831
{
    m_importController->exec();
}
832

833
void
834
MainWindow::canUndoChanged( bool canUndo )
835 836 837 838
{
    m_ui.actionUndo->setEnabled( canUndo );
}

839
void
840
MainWindow::canRedoChanged( bool canRedo )
841 842 843 844
{
    m_ui.actionRedo->setEnabled( canRedo );
}

Ludovic Fauvet's avatar
Ludovic Fauvet committed
845
#ifdef WITH_CRASHBUTTON
846 847
void
MainWindow::setupCrashTester()
848 849 850 851 852 853 854 855
{
    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
856