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
    //FIXME !!!
429
    EffectsEngine::getInstance()->browseDirectory( "/usr/local/frei0r/lib/" );
430

431 432 433
    m_renderer = new WorkflowRenderer();
    m_renderer->initializeRenderer();
    m_timeline = new Timeline( m_renderer, this );
434 435 436
    m_timeline->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
    m_timeline->show();
    setCentralWidget( m_timeline );
437

438
    DockWidgetManager *dockManager = DockWidgetManager::getInstance();
439

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

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

460 461 462 463 464 465
    EffectsList *effectsList = new EffectsList( this );
    dockManager->addDockedWidget( effectsList,
                                  QT_TRANSLATE_NOOP( "DockWidgetManager", "Effects List" ),
                                  Qt::AllDockWidgetAreas, QDockWidget::AllDockWidgetFeatures,
                                  Qt::LeftDockWidgetArea );

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

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

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

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

522

523 524
//Private slots definition

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

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

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

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

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

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

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

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

596
void
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 637
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...
    }
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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