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

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

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

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

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

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

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

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

449 450
    m_clipPreview = new PreviewWidget( new ClipRenderer, this );
    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
    m_projectPreview = new PreviewWidget( m_renderer, this );
459
    dockManager->addDockedWidget( m_projectPreview,
460
                                  QT_TRANSLATE_NOOP( "DockWidgetManager", "Project Preview" ),
461 462
                                  Qt::AllDockWidgetAreas,
                                  QDockWidget::AllDockWidgetFeatures,
463
                                  Qt::TopDockWidgetArea );
464
    KeyboardShortcutHelper* renderShortcut = new KeyboardShortcutHelper( "keyboard/renderpreview", this );
465
    connect( renderShortcut, SIGNAL( activated() ), m_projectPreview, SLOT( on_pushButtonPlay_clicked() ) );
466

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

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

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

510

511 512
//Private slots definition

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

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

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

531
void
532
MainWindow::on_actionTranscode_triggered()
533
{
534 535
    QMessageBox::information( this, tr( "Sorry" ),
                              tr( "This feature is currently disabled." ) );
536
    //Transcode::instance( this )->exec();
537
}
538

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

550
void
551 552 553 554 555
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();
556

557 558 559 560 561 562 563 564 565 566
    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;
}

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

588
        renderVideo( outputFileName, width, height, fps, vbitrate, abitrate );
589
    }
590 591
}

592
void
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 629 630 631 632 633
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...
    }
}

634
void
635
MainWindow::on_actionNew_Project_triggered()
636
{
637
    m_pWizard->restart();
638
    m_pWizard->show();
639 640
}

641
void
642
MainWindow::on_actionHelp_triggered()
643 644
{
    QDesktopServices::openUrl( QUrl( "http://vlmc.org" ) );
645 646
}

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

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

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

668
void
669
MainWindow::registerWidgetInWindowMenu( QDockWidget* widget )
670
{
671
    m_ui.menuWindow->addAction( widget->toggleViewAction() );
672
}
673

674
void
675
MainWindow::toolButtonClicked( int id )
676 677 678
{
    emit toolChanged( (ToolButtons)id );
}
679

680
void
681
MainWindow::on_actionBypass_effects_engine_toggled(bool)
682
{
683 684 685 686 687 688 689
//    EffectsEngine*  ee;
//
//    ee = MainWorkflow::getInstance()->getEffectsEngine();
//    if (toggled)
//        ee->enable();
//    else
//       ee->disable();
690 691
    return ;
}
692

693
void
694
MainWindow::on_actionProject_Preferences_triggered()
695
{
696
  m_projectPreferences->show();
697
}
698

699
void
700
MainWindow::closeEvent( QCloseEvent* e )
701
{
702 703
    GUIProjectManager   *pm = GUIProjectManager::getInstance();
    if ( pm->askForSaveIfModified() )
704
        e->accept();
705 706
    else
        e->ignore();
707
}
708

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

720
void
721
MainWindow::on_actionClose_Project_triggered()
722
{
723
    GUIProjectManager::getInstance()->closeProject();
724 725
}

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

732
void
733
MainWindow::on_actionRedo_triggered()
734 735 736 737
{
    UndoStack::getInstance( this )->redo();
}

738
void
739
MainWindow::on_actionCrash_triggered()
740
{
741 742 743 744 745
    //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 );
746
}
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
747

748
bool
749
MainWindow::restoreSession()
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
750 751
{
    QSettings   s;
752
    bool        fileCreated = false;
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
753 754
    bool        ret = false;

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

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

783
void
784
MainWindow::on_actionImport_triggered()
785 786 787
{
    m_importController->exec();
}
788

789
void
790
MainWindow::canUndoChanged( bool canUndo )
791 792 793 794
{
    m_ui.actionUndo->setEnabled( canUndo );
}

795
void
796
MainWindow::canRedoChanged( bool canRedo )
797 798 799 800
{
    m_ui.actionRedo->setEnabled( canRedo );
}

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