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 "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

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 );
162
        DockWidgetManager::getInstance()->retranslateUi();
Ludovic Fauvet's avatar
Ludovic Fauvet committed
163 164 165 166 167 168
        break;
    default:
        break;
    }
}

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 );
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
    //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" ) );

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

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


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

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

325 326
#undef CREATE_MENU_SHORTCUT

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

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

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

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

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

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

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

    // Cut/Split tool
    QToolButton* splitTool = new QToolButton( this );
379
    splitTool->setAutoRaise( true );
380 381
    splitTool->setCheckable( true );
    splitTool->setIcon( QIcon( ":/images/editcut" ) );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
382
    splitTool->setStatusTip( tr( "Use the scissors to cut regions in the timeline" ) );
383 384 385 386 387 388 389 390 391
    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 );

392
    //Shortcut part:
393 394
    KeyboardShortcutHelper* defaultModeShortcut = new KeyboardShortcutHelper( "keyboard/defaultmode", this );
    KeyboardShortcutHelper* cutModeShortcut = new KeyboardShortcutHelper( "keyboard/cutmode", this );
395 396 397
    connect( defaultModeShortcut, SIGNAL( activated() ), mouseTool, SLOT( click() ) );
    connect( cutModeShortcut, SIGNAL( activated() ), splitTool, SLOT( click() ) );

398 399 400 401 402 403 404 405
    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
406 407 408
    // Zoom Out
    QToolButton* zoomOutButton = new QToolButton( this );
    zoomOutButton->setIcon( QIcon( ":/images/zoomout" ) );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
409
    zoomOutButton->setStatusTip( tr( "Zoom out" ) );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
410 411 412
    m_ui.statusbar->addPermanentWidget( zoomOutButton );
    connect( zoomOutButton, SIGNAL( clicked() ),
             this, SLOT( zoomOut() ) );
413 414

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

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

436
void
437
MainWindow::initializeDockWidgets( void )
438
{
439 440 441
    m_renderer = new WorkflowRenderer();
    m_renderer->initializeRenderer();
    m_timeline = new Timeline( m_renderer, this );
442 443 444
    m_timeline->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
    m_timeline->show();
    setCentralWidget( m_timeline );
445

446
    DockWidgetManager *dockManager = DockWidgetManager::getInstance();
447

448 449
    m_clipPreview = new PreviewWidget( this );
    m_clipPreview->setRenderer( new ClipRenderer );
450
    dockManager->addDockedWidget( m_clipPreview,
451
                                  QT_TRANSLATE_NOOP( "DockWidgetManager", "Clip Preview" ),
geoff's avatar
geoff committed
452 453 454
                                  Qt::AllDockWidgetAreas,
                                  QDockWidget::AllDockWidgetFeatures,
                                  Qt::TopDockWidgetArea );
455
    KeyboardShortcutHelper* clipShortcut = new KeyboardShortcutHelper( "keyboard/mediapreview", this );
456
    connect( clipShortcut, SIGNAL( activated() ), m_clipPreview, SLOT( on_pushButtonPlay_clicked() ) );
457

458 459
    m_projectPreview = new PreviewWidget( this );
    m_projectPreview->setRenderer( m_renderer );
460
    dockManager->addDockedWidget( m_projectPreview,
461
                                  QT_TRANSLATE_NOOP( "DockWidgetManager", "Project Preview" ),
462 463
                                  Qt::AllDockWidgetAreas,
                                  QDockWidget::AllDockWidgetFeatures,
464
                                  Qt::TopDockWidgetArea );
465
    KeyboardShortcutHelper* renderShortcut = new KeyboardShortcutHelper( "keyboard/renderpreview", this );
466
    connect( renderShortcut, SIGNAL( activated() ), m_projectPreview, SLOT( on_pushButtonPlay_clicked() ) );
467

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

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

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

511

512 513
//Private slots definition

514
void
515
MainWindow::on_actionQuit_triggered()
Ludovic Fauvet's avatar
Ludovic Fauvet committed
516 517 518
{
    QApplication::quit();
}
519

520
void
521
MainWindow::on_actionPreferences_triggered()
522
{
523
   m_globalPreferences->show();
524
}
Ludovic Fauvet's avatar
Ludovic Fauvet committed
525

526
void
527
MainWindow::on_actionAbout_triggered()
Ludovic Fauvet's avatar
Ludovic Fauvet committed
528
{
529
    About::getInstance()->exec();
Ludovic Fauvet's avatar
Ludovic Fauvet committed
530
}
531

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

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

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

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

581
        renderVideo( outputFileName, width, height, fps, vbitrate, abitrate );
582
    }
583 584
}

585
void
586 587 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
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...
    }
}

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

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

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

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

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

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

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

673
void
674
MainWindow::on_actionBypass_effects_engine_toggled(bool)
675
{
676 677 678 679 680 681 682
//    EffectsEngine*  ee;
//
//    ee = MainWorkflow::getInstance()->getEffectsEngine();
//    if (toggled)
//        ee->enable();
//    else
//       ee->disable();
683 684
    return ;
}
685

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

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

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

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

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

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

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

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

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

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

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

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

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

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