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"

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

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

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

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

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

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

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

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

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

86 87 88
    //Preferences
    initVlmcPreferences();

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

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

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

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

125

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

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

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

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

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

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

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

183 184 185
    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" ) );
186

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

255
    //Setup VLMC Lang. Preferences...
256
    VLMC_CREATE_PREFERENCE_LANGUAGE( "general/VLMCLang", "default",
257
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Language" ),
258
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "The VLMC's UI language" ) );
259

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

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

269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290
    //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" ) );

291
    VLMC_CREATE_PREFERENCE_PASSWORD( "network/ProxyPassword", "",
292 293 294
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "Proxy Password" ),
                                     QT_TRANSLATE_NOOP( "PreferenceWidget", "The HTTP Proxy Password" ) );

295 296 297 298 299
    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" ) );


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

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 );
    }
324 325
}

326 327
#undef CREATE_MENU_SHORTCUT

328 329
void
MainWindow::setupLibrary()
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
330
{
331
    m_importController = new ImportController();
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
332 333
    const ClipRenderer* clipRenderer = qobject_cast<const ClipRenderer*>( m_clipPreview->getGenericRenderer() );
    Q_ASSERT( clipRenderer != NULL );
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
334

335 336 337
    MediaLibrary    *mediaLibrary = new MediaLibrary();

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

349 350
void
MainWindow::on_actionSave_triggered()
351
{
352
    GUIProjectManager::getInstance()->saveProject();
353 354
}

355
void
356
MainWindow::on_actionSave_As_triggered()
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
357
{
358
    GUIProjectManager::getInstance()->saveProject( true );
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
359 360
}

361
void
362
MainWindow::on_actionLoad_Project_triggered()
363
{
364
    GUIProjectManager::getInstance()->loadProject();
365 366
}

367 368 369 370 371 372 373 374 375 376
void
MainWindow::createNotificationZone()
{
    QWidget *notifSpacer = new QWidget( this );
    notifSpacer->setFixedWidth( 75 );
    m_ui.statusbar->addPermanentWidget( notifSpacer );

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

377
void
378
MainWindow::createStatusBar()
379
{
380 381 382
    //Notifications:
    createNotificationZone();

383 384
    // Mouse (default) tool
    QToolButton* mouseTool = new QToolButton( this );
385
    mouseTool->setAutoRaise( true );
386 387
    mouseTool->setCheckable( true );
    mouseTool->setIcon( QIcon( ":/images/mouse" ) );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
388
    mouseTool->setStatusTip( tr( "Use the mouse tool to manipulate regions in the timeline" ) );
389 390 391 392
    m_ui.statusbar->addPermanentWidget( mouseTool );

    // Cut/Split tool
    QToolButton* splitTool = new QToolButton( this );
393
    splitTool->setAutoRaise( true );
394 395
    splitTool->setCheckable( true );
    splitTool->setIcon( QIcon( ":/images/editcut" ) );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
396
    splitTool->setStatusTip( tr( "Use the scissors to cut regions in the timeline" ) );
397 398 399 400 401 402 403 404 405
    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 );

406
    //Shortcut part:
407 408
    KeyboardShortcutHelper* defaultModeShortcut = new KeyboardShortcutHelper( "keyboard/defaultmode", this );
    KeyboardShortcutHelper* cutModeShortcut = new KeyboardShortcutHelper( "keyboard/cutmode", this );
409 410 411
    connect( defaultModeShortcut, SIGNAL( activated() ), mouseTool, SLOT( click() ) );
    connect( cutModeShortcut, SIGNAL( activated() ), splitTool, SLOT( click() ) );

412 413 414 415 416 417 418 419
    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
420 421 422
    // Zoom Out
    QToolButton* zoomOutButton = new QToolButton( this );
    zoomOutButton->setIcon( QIcon( ":/images/zoomout" ) );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
423
    zoomOutButton->setStatusTip( tr( "Zoom out" ) );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
424 425 426
    m_ui.statusbar->addPermanentWidget( zoomOutButton );
    connect( zoomOutButton, SIGNAL( clicked() ),
             this, SLOT( zoomOut() ) );
427 428

    // Zoom slider
429 430 431 432 433 434 435 436 437
    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
438
    m_zoomSlider->setInvertedAppearance( true );
439
    m_ui.statusbar->addPermanentWidget( m_zoomSlider );
440

Ludovic Fauvet's avatar
Ludovic Fauvet committed
441 442 443
    // Zoom IN
    QToolButton* zoomInButton = new QToolButton( this );
    zoomInButton->setIcon( QIcon( ":/images/zoomin" ) );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
444
    zoomInButton->setStatusTip( tr( "Zoom in" ) );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
445 446 447
    m_ui.statusbar->addPermanentWidget( zoomInButton );
    connect( zoomInButton, SIGNAL( clicked() ),
             this, SLOT( zoomIn() ) );
448 449
}

450
void
451
MainWindow::initializeDockWidgets( void )
452
{
453 454 455
    m_renderer = new WorkflowRenderer();
    m_renderer->initializeRenderer();
    m_timeline = new Timeline( m_renderer, this );
456 457 458
    m_timeline->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
    m_timeline->show();
    setCentralWidget( m_timeline );
459

460
    DockWidgetManager *dockManager = DockWidgetManager::getInstance();
461

462 463
    m_clipPreview = new PreviewWidget( this );
    m_clipPreview->setRenderer( new ClipRenderer );
464
    dockManager->addDockedWidget( m_clipPreview,
465
                                  QT_TRANSLATE_NOOP( "DockWidgetManager", "Clip Preview" ),
geoff's avatar
geoff committed
466 467 468
                                  Qt::AllDockWidgetAreas,
                                  QDockWidget::AllDockWidgetFeatures,
                                  Qt::TopDockWidgetArea );
469
    KeyboardShortcutHelper* clipShortcut = new KeyboardShortcutHelper( "keyboard/mediapreview", this );
470
    connect( clipShortcut, SIGNAL( activated() ), m_clipPreview, SLOT( on_pushButtonPlay_clicked() ) );
471

472 473
    m_projectPreview = new PreviewWidget( this );
    m_projectPreview->setRenderer( m_renderer );
474
    dockManager->addDockedWidget( m_projectPreview,
475
                                  QT_TRANSLATE_NOOP( "DockWidgetManager", "Project Preview" ),
476 477
                                  Qt::AllDockWidgetAreas,
                                  QDockWidget::AllDockWidgetFeatures,
478
                                  Qt::TopDockWidgetArea );
479
    KeyboardShortcutHelper* renderShortcut = new KeyboardShortcutHelper( "keyboard/renderpreview", this );
480
    connect( renderShortcut, SIGNAL( activated() ), m_projectPreview, SLOT( on_pushButtonPlay_clicked() ) );
481

482
    QDockWidget* dock = dockManager->addDockedWidget( UndoStack::getInstance( this ),
483
                                  QT_TRANSLATE_NOOP( "DockWidgetManager", "History" ),
484 485 486
                                  Qt::AllDockWidgetAreas,
                                  QDockWidget::AllDockWidgetFeatures,
                                  Qt::LeftDockWidgetArea );
487 488
    if ( dock != 0 )
        dock->hide();
489
    setupLibrary();
490 491
}

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

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

525

526 527
//Private slots definition

528
void
529
MainWindow::on_actionQuit_triggered()
Ludovic Fauvet's avatar
Ludovic Fauvet committed
530 531 532
{
    QApplication::quit();
}
533

534
void
535
MainWindow::on_actionPreferences_triggered()
536
{
537
   m_globalPreferences->show();
538
}
Ludovic Fauvet's avatar
Ludovic Fauvet committed
539

540
void
541
MainWindow::on_actionAbout_triggered()
Ludovic Fauvet's avatar
Ludovic Fauvet committed
542
{
543
    About::getInstance()->exec();
Ludovic Fauvet's avatar
Ludovic Fauvet committed
544
}
545

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

557
void
558 559 560 561 562
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();
563

564 565 566 567 568 569 570 571 572 573
    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;
}

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

595
        renderVideo( outputFileName, width, height, fps, vbitrate, abitrate );
596
    }
597 598
}

599
void
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 638 639 640
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...
    }
}

641
void
642
MainWindow::on_actionNew_Project_triggered()
643
{
644
    m_pWizard->restart();
645
    m_pWizard->show();
646 647
}

648
void
649
MainWindow::on_actionHelp_triggered()
650 651
{
    QDesktopServices::openUrl( QUrl( "http://vlmc.org" ) );
652 653
}

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

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

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

675
void
676
MainWindow::registerWidgetInWindowMenu( QDockWidget* widget )
677
{
678
    m_ui.menuWindow->addAction( widget->toggleViewAction() );
679
}
680

681
void
682
MainWindow::toolButtonClicked( int id )
683 684 685
{
    emit toolChanged( (ToolButtons)id );
}
686

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

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

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

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

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

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

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

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

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

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

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

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

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

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