MainWindow.cpp 29.4 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"

41
#include "EffectsEngine/EffectsEngine.h"
Ludovic Fauvet's avatar
Ludovic Fauvet committed
42
#include "MainWorkflow.h"
43
#include "export/RendererSettings.h"
44
#include "export/ShareOnYoutube.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
    qRegisterMetaType<MainWorkflow::TrackType>( "MainWorkflow::TrackType" );
76
    qRegisterMetaType<MainWorkflow::FrameChangedReason>( "MainWorkflow::FrameChangedReason" );
77
    qRegisterMetaType<QVariant>( "QVariant" );
78

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

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

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

88 89 90
    //Preferences
    initVlmcPreferences();

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

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

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

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

128

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

272
    VLMC_CREATE_PREFERENCE_BOOL( "general/ConfirmDeletion", true,
273
                                 QT_TRANSLATE_NOOP( "PreferenceWidget", "Confirm clip deletion"),
274
                                 QT_TRANSLATE_NOOP( "PreferenceWidget", "Ask for confirmation before deleting a clip from the timeline" ) );
275

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

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

302 303 304 305 306
    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" ) );


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

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

333 334
#undef CREATE_MENU_SHORTCUT

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

447 448
    m_projectPreview = new PreviewWidget( this );
    m_projectPreview->setRenderer( m_renderer );
449
    dockManager->addDockedWidget( m_projectPreview,
450
                                  QT_TRANSLATE_NOOP( "DockWidgetManager", "Project Preview" ),
451 452
                                  Qt::AllDockWidgetAreas,
                                  QDockWidget::AllDockWidgetFeatures,
453
                                  Qt::TopDockWidgetArea );
454
    KeyboardShortcutHelper* renderShortcut = new KeyboardShortcutHelper( "keyboard/renderpreview", this );
455
    connect( renderShortcut, SIGNAL( activated() ), m_projectPreview, SLOT( on_pushButtonPlay_clicked() ) );
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 463
    //FIXME !!!
    EffectsEngine::getInstance()->browseDirectory( "/usr/lib/frei0r-1" );
464

465
    QDockWidget* dock = dockManager->addDockedWidget( UndoStack::getInstance( this ),
466
                                  QT_TRANSLATE_NOOP( "DockWidgetManager", "History" ),
467 468 469
                                  Qt::AllDockWidgetAreas,
                                  QDockWidget::AllDockWidgetFeatures,
                                  Qt::LeftDockWidgetArea );
470 471
    if ( dock != 0 )
        dock->hide();
472
    setupLibrary();
473 474
}

475 476 477 478 479 480 481 482 483 484 485 486 487
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() );
}

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

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

521

522 523
//Private slots definition

524
void
525
MainWindow::on_actionQuit_triggered()
Ludovic Fauvet's avatar
Ludovic Fauvet committed
526 527 528
{
    QApplication::quit();
}
529

530
void
531
MainWindow::on_actionPreferences_triggered()
532
{
533
   m_globalPreferences->show();
534
}
Ludovic Fauvet's avatar
Ludovic Fauvet committed
535

536
void
537
MainWindow::on_actionAbout_triggered()
Ludovic Fauvet's avatar
Ludovic Fauvet committed
538
{
539
    About::getInstance()->exec();
Ludovic Fauvet's avatar
Ludovic Fauvet committed
540
}
541

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

553
void
554 555 556 557 558
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();
559

560 561 562 563 564 565 566 567 568 569
    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;
}

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

591
        renderVideo( outputFileName, width, height, fps, vbitrate, abitrate );
592
    }
593 594
}

595
void
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 634 635 636
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...
    }
}

637
void
638
MainWindow::on_actionNew_Project_triggered()
639
{
640
    m_pWizard->restart();
641
    m_pWizard->show();
642 643
}

644
void
645
MainWindow::on_actionHelp_triggered()
646 647
{
    QDesktopServices::openUrl( QUrl( "http://vlmc.org" ) );
648 649
}

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

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

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

671
void
672
MainWindow::registerWidgetInWindowMenu( QDockWidget* widget )
673
{
674
    m_ui.menuWindow->addAction( widget->toggleViewAction() );
675
}
676

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

688
void
689
MainWindow::on_actionProject_Preferences_triggered()
690
{
691
  m_projectPreferences->show();
692
}
693

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

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

715
void
716
MainWindow::on_actionClose_Project_triggered()
717
{
718
    GUIProjectManager::getInstance()->closeProject();
719 720
}

721
void
722
MainWindow::on_actionUndo_triggered()
723 724 725 726
{
    UndoStack::getInstance( this )->undo();
}

727
void
728
MainWindow::on_actionRedo_triggered()
729 730 731 732
{
    UndoStack::getInstance( this )->redo();
}

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

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

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

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

778
void
779
MainWindow::on_actionImport_triggered()
780 781 782
{
    m_importController->exec();
}
783

784
void
785
MainWindow::canUndoChanged( bool canUndo )
786 787 788 789
{
    m_ui.actionUndo->setEnabled( canUndo );
}

790
void
791
MainWindow::canRedoChanged( bool canRedo )
792 793 794 795
{
    m_ui.actionRedo->setEnabled( canRedo );
}

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