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

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

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

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

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

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

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

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

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

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

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

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

85 86 87
    //Preferences
    initVlmcPreferences();

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

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

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

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

124

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

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

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

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

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

Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
169
//use this helper when the shortcut is binded to a menu action
170 171 172
#define CREATE_MENU_SHORTCUT( key, defaultValue, name, desc, actionInstance  )      \
        VLMC_CREATE_PREFERENCE_KEYBOARD( key, defaultValue, name, desc );           \
        new KeyboardShortcutHelper( key, m_ui.actionInstance, this );
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
173

174 175 176
void
MainWindow::initVlmcPreferences()
{
177
    //Setup VLMC Keyboard Preference...
178 179 180
    VLMC_CREATE_PREFERENCE_KEYBOARD( "keyboard/defaultmode", "n",
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Select mode" ),
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Select the selection tool in the timeline" ) );
181

182 183 184
    VLMC_CREATE_PREFERENCE_KEYBOARD( "keyboard/cutmode", "x",
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Cut mode" ),
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Select the cut/razor tool in the timeline" ) );
185

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

190 191 192
    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" ) );
193

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

200 201 202 203
    CREATE_MENU_SHORTCUT( "keyboard/redo",
                          QKeySequence( QKeySequence::Redo ).toString().toLocal8Bit(),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Redo" ),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Redo the last action" ), actionRedo );
204

205 206 207 208
    CREATE_MENU_SHORTCUT( "keyboard/help",
                          QKeySequence( QKeySequence::HelpContents ).toString().toLocal8Bit(),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Help" ),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Toggle the help page" ), actionHelp );
209

210 211 212
    CREATE_MENU_SHORTCUT( "keyboard/quit", "Ctrl+Q",
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Quit" ),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Quit VLMC" ), actionQuit );
213

214 215 216
    CREATE_MENU_SHORTCUT( "keyboard/preferences", "Alt+P",
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Preferences" ),
                          QT_TRANSLATE_NOOP( "PreferenceWidget", "Open VLMC preferences" ), actionPreferences );
217

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
    //Setup VLMC Lang. Preferences...
255
    VLMC_CREATE_PREFERENCE_LANGUAGE( "general/VLMCLang", "default",
256
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Language" ),
257
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "The VLMC's UI language" ) );
258

259 260 261 262
    SettingsManager::getInstance()->watchValue( "general/VLMCLang",
                                                LanguageHelper::getInstance(),
                                                SLOT( languageChanged( const QVariant& ) ),
                                                SettingsManager::Vlmc );
263

264
    VLMC_CREATE_PREFERENCE_BOOL( "general/ConfirmDeletion", true,
265
                                 QT_TRANSLATE_NOOP( "PreferenceWidget", "Confirm clip deletion"),
266
                                 QT_TRANSLATE_NOOP( "PreferenceWidget", "Ask for confirmation before deleting a clip from the timeline" ) );
267

268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294
    //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
    //FIXME: The widgets get sorted...
    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" ) );

    VLMC_CREATE_PREFERENCE_STRING( "network/ProxyPassword", "",
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Proxy Password" ),
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "The HTTP Proxy Password" ) );

295
    //Load saved preferences :
296 297 298 299 300 301 302
    QSettings       s;
    if ( s.value( "VlmcVersion" ).toString() != PROJECT_VERSION )
        s.clear();
    else
    {
        loadVlmcPreferences( "keyboard" );
        loadVlmcPreferences( "general" );
303 304
        loadVlmcPreferences( "youtube" );
        loadVlmcPreferences( "network" );
305 306
    }
    s.setValue( "VlmcVersion", PROJECT_VERSION );
307 308 309 310 311 312 313 314 315 316 317 318
}

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 );
    }
319 320
}

Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
321 322
#undef CREATE_MENU_SHORTCUT

323 324
void
MainWindow::setupLibrary()
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
325
{
326
    m_importController = new ImportController();
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
327 328
    const ClipRenderer* clipRenderer = qobject_cast<const ClipRenderer*>( m_clipPreview->getGenericRenderer() );
    Q_ASSERT( clipRenderer != NULL );
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
329

330 331 332
    MediaLibrary    *mediaLibrary = new MediaLibrary();

    DockWidgetManager::getInstance()->addDockedWidget( mediaLibrary, QT_TRANSLATE_NOOP( "DockWidgetManager", "Media Library" ),
333 334 335
                                                    Qt::AllDockWidgetAreas,
                                                    QDockWidget::AllDockWidgetFeatures,
                                                    Qt::LeftDockWidgetArea );
336
    connect( mediaLibrary, SIGNAL( clipSelected( Clip* ) ),
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
337
             clipRenderer, SLOT( setClip( Clip* ) ) );
338 339
    connect( mediaLibrary, SIGNAL( importRequired() ),
             this, SLOT( on_actionImport_triggered() ) );
340 341
    connect( Library::getInstance(), SIGNAL( clipRemoved( const QUuid& ) ),
             clipRenderer, SLOT( clipUnloaded( const QUuid& ) ) );
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
342 343
}

344 345
void
MainWindow::on_actionSave_triggered()
346
{
347
    GUIProjectManager::getInstance()->saveProject();
348 349
}

350
void
351
MainWindow::on_actionSave_As_triggered()
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
352
{
353
    GUIProjectManager::getInstance()->saveProject( true );
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
354 355
}

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

362
void
363
MainWindow::createStatusBar()
364
{
365 366
    // Mouse (default) tool
    QToolButton* mouseTool = new QToolButton( this );
367
    mouseTool->setAutoRaise( true );
368 369
    mouseTool->setCheckable( true );
    mouseTool->setIcon( QIcon( ":/images/mouse" ) );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
370
    mouseTool->setStatusTip( tr( "Use the mouse tool to manipulate regions in the timeline" ) );
371 372 373 374
    m_ui.statusbar->addPermanentWidget( mouseTool );

    // Cut/Split tool
    QToolButton* splitTool = new QToolButton( this );
375
    splitTool->setAutoRaise( true );
376 377
    splitTool->setCheckable( true );
    splitTool->setIcon( QIcon( ":/images/editcut" ) );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
378
    splitTool->setStatusTip( tr( "Use the scissors to cut regions in the timeline" ) );
379 380 381 382 383 384 385 386 387
    m_ui.statusbar->addPermanentWidget( splitTool );

    // Group the two previous buttons
    QButtonGroup* toolButtonGroup = new QButtonGroup( this );
    toolButtonGroup->addButton( mouseTool, TOOL_DEFAULT);
    toolButtonGroup->addButton( splitTool, TOOL_CUT );
    toolButtonGroup->setExclusive( true );
    mouseTool->setChecked( true );

388
    //Shortcut part:
389 390
    KeyboardShortcutHelper* defaultModeShortcut = new KeyboardShortcutHelper( "keyboard/defaultmode", this );
    KeyboardShortcutHelper* cutModeShortcut = new KeyboardShortcutHelper( "keyboard/cutmode", this );
391 392 393
    connect( defaultModeShortcut, SIGNAL( activated() ), mouseTool, SLOT( click() ) );
    connect( cutModeShortcut, SIGNAL( activated() ), splitTool, SLOT( click() ) );

394 395 396 397 398 399 400 401
    connect( toolButtonGroup, SIGNAL( buttonClicked( int ) ),
             this, SLOT( toolButtonClicked( int ) ) );

    // Spacer
    QWidget* spacer = new QWidget( this );
    spacer->setFixedWidth( 20 );
    m_ui.statusbar->addPermanentWidget( spacer );

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

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

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

432
void
433
MainWindow::initializeDockWidgets( void )
434
{
435 436 437
    m_renderer = new WorkflowRenderer();
    m_renderer->initializeRenderer();
    m_timeline = new Timeline( m_renderer, this );
438 439 440
    m_timeline->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
    m_timeline->show();
    setCentralWidget( m_timeline );
441

442
    DockWidgetManager *dockManager = DockWidgetManager::getInstance();
443

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

453
    m_projectPreview = new PreviewWidget( m_renderer, this );
454
    dockManager->addDockedWidget( m_projectPreview,
Ludovic Fauvet's avatar
Ludovic Fauvet committed
455
                                  QT_TRANSLATE_NOOP( "DockWidgetManager", "Project Preview" ),
456 457
                                  Qt::AllDockWidgetAreas,
                                  QDockWidget::AllDockWidgetFeatures,
458
                                  Qt::TopDockWidgetArea );
459
    KeyboardShortcutHelper* renderShortcut = new KeyboardShortcutHelper( "keyboard/renderpreview", this );
460
    connect( renderShortcut, SIGNAL( activated() ), m_projectPreview, SLOT( on_pushButtonPlay_clicked() ) );
461

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

472 473
void
MainWindow::createGlobalPreferences()
474
{
475
    m_globalPreferences = new Settings( SettingsManager::Vlmc, this );
476
    m_globalPreferences->addCategory( QT_TRANSLATE_NOOP( "Settings", "general" ), SettingsManager::Vlmc,
477
                                     QIcon( ":/images/images/vlmc.png" ),
Nikoli's avatar
Nikoli committed
478
                                     tr ( "General" ) );
479
    m_globalPreferences->addCategory( QT_TRANSLATE_NOOP( "Settings", "keyboard" ), SettingsManager::Vlmc,
480
                                     QIcon( ":/images/keyboard" ),
Nikoli's avatar
Nikoli committed
481
                                     tr( "Keyboard" ) );
482 483
    m_globalPreferences->addCategory( QT_TRANSLATE_NOOP( "Settings", "youtube" ), SettingsManager::Vlmc,
                                     QIcon( ":/images/youtube" ),
Nikoli's avatar
Nikoli committed
484
                                     tr( "Youtube" ) );
485 486
    m_globalPreferences->addCategory( QT_TRANSLATE_NOOP( "Settings", "network" ), SettingsManager::Vlmc,
                                     QIcon( ":/images/network" ),
Nikoli's avatar
Nikoli committed
487
                                     tr( "Network" ) );
488 489
}

490 491
void
MainWindow::createProjectPreferences()
492
{
493
    m_projectPreferences = new Settings( SettingsManager::Project, this );
494
    m_projectPreferences->addCategory( QT_TRANSLATE_NOOP( "Settings", "general" ), SettingsManager::Project,
495
                                   QIcon( ":/images/images/vlmc.png" ),
Nikoli's avatar
Nikoli committed
496
                                   tr ( "General" ) );
497
    m_projectPreferences->addCategory( QT_TRANSLATE_NOOP( "Settings", "video" ), SettingsManager::Project,
498
                                   QIcon( ":/images/images/video.png" ),
Nikoli's avatar
Nikoli committed
499
                                   tr ( "Video" ) );
500
    m_projectPreferences->addCategory( QT_TRANSLATE_NOOP( "Settings", "audio" ), SettingsManager::Project,
501
                                   QIcon( ":/images/images/audio.png" ),
Nikoli's avatar
Nikoli committed
502
                                   tr ( "Audio" ) );
503 504
}

505

506 507
//Private slots definition

508
void
509
MainWindow::on_actionQuit_triggered()
Ludovic Fauvet's avatar
Ludovic Fauvet committed
510 511 512
{
    QApplication::quit();
}
513

514
void
515
MainWindow::on_actionPreferences_triggered()
516
{
517
   m_globalPreferences->show();
518
}
Ludovic Fauvet's avatar
Ludovic Fauvet committed
519

520
void
521
MainWindow::on_actionAbout_triggered()
Ludovic Fauvet's avatar
Ludovic Fauvet committed
522
{
523
    About::getInstance()->exec();
Ludovic Fauvet's avatar
Ludovic Fauvet committed
524
}
525

526
void
527
MainWindow::on_actionTranscode_triggered()
528
{
529 530
    QMessageBox::information( this, tr( "Sorry" ),
                              tr( "This feature is currently disabled." ) );
531
    //Transcode::instance( this )->exec();
532
}
533

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

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

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

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

583
        renderVideo( outputFileName, width, height, fps, vbitrate, abitrate );
584
    }
585 586
}

587
void
588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628
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...
    }
}

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

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

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

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

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

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

669
void
670
MainWindow::toolButtonClicked( int id )
671 672 673
{
    emit toolChanged( (ToolButtons)id );
}
674

675
void
676
MainWindow::on_actionBypass_effects_engine_toggled(bool)
677
{
678 679 680 681 682 683 684
//    EffectsEngine*  ee;
//
//    ee = MainWorkflow::getInstance()->getEffectsEngine();
//    if (toggled)
//        ee->enable();
//    else
//       ee->disable();
685 686
    return ;
}
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()
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
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 );
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
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