MainWindow.cpp 17.1 KB
Newer Older
Ludovic Fauvet's avatar
Ludovic Fauvet committed
1
/*****************************************************************************
2
 * MainWindow.cpp: VLMC MainWindow
Ludovic Fauvet's avatar
Ludovic Fauvet committed
3
4
5
6
 *****************************************************************************
 * Copyright (C) 2008-2009 the VLMC team
 *
 * Authors: Ludovic Fauvet <etix@l0cal.com>
7
 *          Hugo Beauzee-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
25
26
#include <QLabel>
#include <QSizePolicy>
#include <QPalette>
Christophe Courtaut's avatar
Christophe Courtaut committed
27
#include <QDockWidget>
28
#include <QFileDialog>
29
#include <QSlider>
30
#include <QUndoView>
31
#include <QMessageBox>
32
33
#include <QDesktopServices>
#include <QUrl>
34
#include <QSettings>
35
#include <QStringList>
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
36

Ludovic Fauvet's avatar
Ludovic Fauvet committed
37
#include "MainWindow.h"
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
38
#include "Library.h"
39
#include "Timeline.h"
Ludovic Fauvet's avatar
Ludovic Fauvet committed
40
#include "About.h"
41
#include "WorkflowRenderer.h"
42
#include "ClipRenderer.h"
43
#include "UndoStack.h"
44
#include "ClipProperty.h"
45
#include "PreviewWidget.h"
46
47
#include "PreferenceWidget.h"
#include "ProjectPreferences.h"
48
#include "ProjectManager.h"
49
50
#include "AudioProjectPreferences.h"
#include "VideoProjectPreferences.h"
51
52
#include "VLMCSettingsDefault.h"
#include "ProjectSettingsDefault.h"
53
#include "VLMCPreferences.h"
54
#include "Import.h"
55
#include "MediaLibraryWidget.h"
56
#include "LanguagePreferences.h"
57
#include "ProjectManager.h"
58
#include "KeyboardShortcut.h"
59
60
#include "SettingValue.h"
#include "SettingsManager.h"
Ludovic Fauvet's avatar
Ludovic Fauvet committed
61
62

MainWindow::MainWindow( QWidget *parent ) :
63
    QMainWindow( parent ), m_renderer( NULL )
Ludovic Fauvet's avatar
Ludovic Fauvet committed
64
65
{
    m_ui.setupUi( this );
66

67
    qRegisterMetaType<MainWorkflow::TrackType>( "MainWorkflow::TrackType" );
68
    qRegisterMetaType<MainWorkflow::FrameChangedReason>( "MainWorkflow::FrameChangedReason" );
69
70
71
72

    // Settings
    VLMCSettingsDefault::load( "default" );
    VLMCSettingsDefault::load( "VLMC" );
73
    VLMCSettingsDefault::loadKeyboardShortcutDefaults();
74
75

    // GUI
76
    DockWidgetManager::instance( this )->setMainWindow( this );
77
    initializeDockWidgets();
78
    createStatusBar();
79
    createGlobalPreferences();
80
    createProjectPreferences();
81
    initializeMenuKeyboardShortcut();
82

83
84
85
86
87
    // Wizard
    m_pWizard = new ProjectWizard( this );
    m_pWizard->setModal( true );
    m_pWizard->show();

Ludovic Fauvet's avatar
Ludovic Fauvet committed
88
    // Translations
89
90
    connect( this, SIGNAL( translateDockWidgetTitle() ),
             DockWidgetManager::instance(), SLOT( transLateWidgetTitle() ) );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
91
92

    // Zoom
93
94
    connect( m_zoomSlider, SIGNAL( valueChanged( int ) ),
             m_timeline, SLOT( changeZoom( int ) ) );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
95
96
97
98
    connect( m_timeline->tracksView(), SIGNAL( zoomIn() ),
             this, SLOT( zoomIn() ) );
    connect( m_timeline->tracksView(), SIGNAL( zoomOut() ),
             this, SLOT( zoomOut() ) );
99
100
    connect( this, SIGNAL( toolChanged( ToolButtons ) ),
             m_timeline, SLOT( setTool( ToolButtons ) ) );
101

102
103
104
    connect( ProjectManager::getInstance(), SIGNAL( projectChanged( const QString&, bool ) ),
             this, SLOT( projectChanged( const QString&, bool ) ) );

105
106
107
108
109
    QSettings s;
    // Restore the geometry
    restoreGeometry( s.value( "MainWindowGeometry" ).toByteArray() );
    // Restore the layout
    restoreState( s.value( "MainWindowState" ).toByteArray() );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
110
111
}

112
113
MainWindow::~MainWindow()
{
114
115
116
117
118
119
120
    QSettings s;
    // Save the current geometry
    s.setValue( "MainWindowGeometry", saveGeometry() );
    // Save the current layout
    s.setValue( "MainWindowState", saveState() );
    s.sync();

121
122
    if ( m_renderer )
        delete m_renderer;
123
    LibVLCpp::Instance::destroyInstance();
124
125
}

Ludovic Fauvet's avatar
Ludovic Fauvet committed
126
127
128
129
130
131
void MainWindow::changeEvent( QEvent *e )
{
    switch ( e->type() )
    {
    case QEvent::LanguageChange:
        m_ui.retranslateUi( this );
132
        emit translateDockWidgetTitle();
Ludovic Fauvet's avatar
Ludovic Fauvet committed
133
134
135
136
137
138
        break;
    default:
        break;
    }
}

Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
139
140
141
void        MainWindow::setupLibrary()
{
    //GUI part :
142

143
    MediaLibraryWidget* mediaLibraryWidget = new MediaLibraryWidget( this );
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
144

145
146
147
148
    DockWidgetManager::instance()->addDockedWidget( mediaLibraryWidget,
                                                    tr( "Media Library" ),
                                                    Qt::AllDockWidgetAreas,
                                                    QDockWidget::AllDockWidgetFeatures,
149

150
                                                    Qt::LeftDockWidgetArea );
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
151
152
    connect( mediaLibraryWidget, SIGNAL( mediaSelected( Media* ) ),
             m_clipPreview->getGenericRenderer(), SLOT( setMedia( Media* ) ) );
153

154
155
    connect( Library::getInstance(), SIGNAL( mediaRemoved( const QUuid& ) ),
             m_clipPreview->getGenericRenderer(), SLOT( mediaUnloaded( QUuid ) ) );
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
156
157
}

158
159
void    MainWindow::on_actionSave_triggered()
{
160
    ProjectManager::getInstance()->saveProject();
161
162
}

Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
163
164
165
166
167
void    MainWindow::on_actionSave_As_triggered()
{
    ProjectManager::getInstance()->saveProject( true );
}

168
169
void    MainWindow::on_actionLoad_Project_triggered()
{
170
171
    ProjectManager* pm = ProjectManager::getInstance();
    pm->loadProject( pm->loadProjectFile() );
172
173
}

174
175
void MainWindow::createStatusBar()
{
176
177
    // Mouse (default) tool
    QToolButton* mouseTool = new QToolButton( this );
178
    mouseTool->setAutoRaise( true );
179
180
181
182
183
184
    mouseTool->setCheckable( true );
    mouseTool->setIcon( QIcon( ":/images/mouse" ) );
    m_ui.statusbar->addPermanentWidget( mouseTool );

    // Cut/Split tool
    QToolButton* splitTool = new QToolButton( this );
185
    splitTool->setAutoRaise( true );
186
187
188
189
190
191
192
193
194
195
196
    splitTool->setCheckable( true );
    splitTool->setIcon( QIcon( ":/images/editcut" ) );
    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 );

197
198
199
200
201
202
    //Shortcut part:
    KeyboardShortcutHelper* defaultModeShortcut = new KeyboardShortcutHelper( "Default mode", this );
    KeyboardShortcutHelper* cutModeShortcut = new KeyboardShortcutHelper( "Cut mode", this );
    connect( defaultModeShortcut, SIGNAL( activated() ), mouseTool, SLOT( click() ) );
    connect( cutModeShortcut, SIGNAL( activated() ), splitTool, SLOT( click() ) );

203
204
205
206
207
208
209
210
    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
211
212
213
214
215
216
    // Zoom Out
    QToolButton* zoomOutButton = new QToolButton( this );
    zoomOutButton->setIcon( QIcon( ":/images/zoomout" ) );
    m_ui.statusbar->addPermanentWidget( zoomOutButton );
    connect( zoomOutButton, SIGNAL( clicked() ),
             this, SLOT( zoomOut() ) );
217
218

    // Zoom slider
219
220
221
222
223
224
225
226
227
    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
228
    m_zoomSlider->setInvertedAppearance( true );
229
    m_ui.statusbar->addPermanentWidget( m_zoomSlider );
230

Ludovic Fauvet's avatar
Ludovic Fauvet committed
231
232
233
234
235
236
    // Zoom IN
    QToolButton* zoomInButton = new QToolButton( this );
    zoomInButton->setIcon( QIcon( ":/images/zoomin" ) );
    m_ui.statusbar->addPermanentWidget( zoomInButton );
    connect( zoomInButton, SIGNAL( clicked() ),
             this, SLOT( zoomIn() ) );
237
238
}

239
void MainWindow::initializeDockWidgets( void )
240
{
241
242
    WorkflowRenderer*    workflowRenderer = new WorkflowRenderer();
    m_timeline = new Timeline( workflowRenderer, this );
243
244
245
    m_timeline->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
    m_timeline->show();
    setCentralWidget( m_timeline );
246

247
248
    DockWidgetManager *dockManager = DockWidgetManager::instance();

249
250
    m_clipPreview = new PreviewWidget( new ClipRenderer, this );
    dockManager->addDockedWidget( m_clipPreview,
251
                                  tr( "Clip Preview" ),
geoff's avatar
geoff committed
252
253
254
                                  Qt::AllDockWidgetAreas,
                                  QDockWidget::AllDockWidgetFeatures,
                                  Qt::TopDockWidgetArea );
255
    KeyboardShortcutHelper* clipShortcut = new KeyboardShortcutHelper( "Launch media preview", this );
256
    connect( clipShortcut, SIGNAL( activated() ), m_clipPreview, SLOT( on_pushButtonPlay_clicked() ) );
257

258
    m_projectPreview = new PreviewWidget( workflowRenderer, this );
259
    dockManager->addDockedWidget( m_projectPreview,
260
261
262
                                  tr( "Project Preview" ),
                                  Qt::AllDockWidgetAreas,
                                  QDockWidget::AllDockWidgetFeatures,
263
                                  Qt::TopDockWidgetArea );
264
    KeyboardShortcutHelper* renderShortcut = new KeyboardShortcutHelper( "Start render preview", this );
265
    connect( renderShortcut, SIGNAL( activated() ), m_projectPreview, SLOT( on_pushButtonPlay_clicked() ) );
266

267
    dockManager->addDockedWidget( UndoStack::getInstance( this ),
268
269
270
271
                                  tr( "History" ),
                                  Qt::AllDockWidgetAreas,
                                  QDockWidget::AllDockWidgetFeatures,
                                  Qt::LeftDockWidgetArea );
272
    setupLibrary();
273
274
}

275
276
void        MainWindow::createGlobalPreferences()
{
277
    m_globalPreferences = new Settings( false, "VLMC", this );
278
    m_globalPreferences->addWidget("VLMC",
Ludovic Fauvet's avatar
Ludovic Fauvet committed
279
                                   new VLMCPreferences( m_globalPreferences ),
280
                                   QIcon( ":/images/images/vlmc.png" ),
281
                                   "VLMC settings");
282
283
    m_globalPreferences->addWidget("Language preferences",
                                   new LanguagePreferences( m_globalPreferences ),
284
                                   QIcon( ":/images/images/vlmc.png" ),
285
                                   "Langage settings");
286
287
288
289
    m_globalPreferences->addWidget( "Keyboard",
                                     new KeyboardShortcut( m_globalPreferences ),
                                     QIcon( ":/images/keyboard" ),
                                     tr( "Keyboard Settings" ) );
290
291
292
    m_globalPreferences->build();
}

293
294
void	    MainWindow::createProjectPreferences()
{
295
    m_projectPreferences = new Settings( false, "project", this );
296
297
    m_projectPreferences->addWidget("Project",
                                   new ProjectPreferences,
298
                                   QIcon( ":/images/images/vlmc.png" ),
299
300
                                   "Project settings" );
    m_projectPreferences->addWidget( "Video",
301
                                   new VideoProjectPreferences,
302
                                   QIcon( ":/images/images/video.png" ),
303
304
                                   "Video settings" );
    m_projectPreferences->addWidget( "Audio",
305
                                   new AudioProjectPreferences,
306
                                   QIcon( ":/images/images/audio.png" ),
307
                                   "Audio settings" );
308
309
310
    m_projectPreferences->build();
}

311

312
313
//Private slots definition

Ludovic Fauvet's avatar
Ludovic Fauvet committed
314
315
316
317
void MainWindow::on_actionQuit_triggered()
{
    QApplication::quit();
}
318
319
320

void MainWindow::on_actionPreferences_triggered()
{
321
   m_globalPreferences->show();
322
}
Ludovic Fauvet's avatar
Ludovic Fauvet committed
323
324
325
326
327

void MainWindow::on_actionAbout_triggered()
{
    About::instance()->exec();
}
328

329
void MainWindow::on_actionTranscode_triggered()
330
{
331
332
    QMessageBox::information( this, tr( "Sorry" ),
                              tr( "This feature is currently disabled." ) );
333
    //Transcode::instance( this )->exec();
334
}
335

336
337
void    MainWindow::on_actionRender_triggered()
{
338
    if ( MainWorkflow::getInstance()->getLengthFrame() <= 0 )
339
340
341
342
343
344
    {
        QMessageBox::warning( NULL, "VLMC Renderer", "There is nothing to render." );
        return ;
    }
    QString outputFileName =
            QFileDialog::getSaveFileName( NULL, "Enter the output file name",
345
                                          QDir::currentPath(), "Videos(*.avi *.mpg)" );
346
347
348
349
350
351
    if ( outputFileName.length() == 0 )
        return ;
    else
    {
        if ( m_renderer )
            delete m_renderer;
352
        m_renderer = new WorkflowFileRenderer( outputFileName );
353
354
355
356
        m_renderer->run();
    }
}

357
358
359
360
void MainWindow::on_actionNew_Project_triggered()
{
    //TODO : clear the library, the timeline, and show the configuration box
    //of the newly created project
361

362
    m_pWizard->restart();
363
    m_pWizard->show();
364
365
}

366
void    MainWindow::on_actionHelp_triggered()
367
368
{
    QDesktopServices::openUrl( QUrl( "http://vlmc.org" ) );
369
370
}

371
372
void    MainWindow::on_actionImport_triggered()
{
Thomas Boquet's avatar
Thomas Boquet committed
373
374
    //Import* import = new Import( );
    //import->exec();
375
376
}

377
void    MainWindow::zoomIn()
Ludovic Fauvet's avatar
Ludovic Fauvet committed
378
379
380
381
{
    m_zoomSlider->setValue( m_zoomSlider->value() - 1 );
}

382
void    MainWindow::zoomOut()
Ludovic Fauvet's avatar
Ludovic Fauvet committed
383
384
385
{
    m_zoomSlider->setValue( m_zoomSlider->value() + 1 );
}
Ludovic Fauvet's avatar
Ludovic Fauvet committed
386

387
void    MainWindow::on_actionFullscreen_triggered( bool checked )
Ludovic Fauvet's avatar
Ludovic Fauvet committed
388
389
390
391
392
393
{
    if ( checked )
        showFullScreen();
    else
        showNormal();
}
394

395
void    MainWindow::registerWidgetInWindowMenu( QDockWidget* widget )
396
{
397
    m_ui.menuWindow->addAction( widget->toggleViewAction() );
398
}
399

400
void    MainWindow::toolButtonClicked( int id )
401
402
403
{
    emit toolChanged( (ToolButtons)id );
}
404

405
406
407
408
409
410
411
412
413
414
415
void MainWindow::on_actionBypass_effects_engine_toggled(bool toggled)
{
    EffectsEngine*  ee;

    ee = MainWorkflow::getInstance()->getEffectsEngine();
    if (toggled)
        ee->enable();
    else
       ee->disable();
    return ;
}
416

417
418
void MainWindow::on_actionProject_Preferences_triggered()
{
419
  m_projectPreferences->show( "project" );
420
}
421

422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
void    MainWindow::closeEvent( QCloseEvent* e )
{
    if ( ProjectManager::getInstance()->needSave() == true )
    {
        QMessageBox msgBox;
        msgBox.setText( tr( "The project has been modified." ) );
        msgBox.setInformativeText( tr( "Do you want to save it ?" ) );
        msgBox.setStandardButtons( QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel );
        msgBox.setDefaultButton(QMessageBox::Save);
        int     ret = msgBox.exec();

        switch ( ret )
        {
            case QMessageBox::Save:
                ProjectManager::getInstance()->saveProject();
                break ;
            case QMessageBox::Discard:
                break ;
            case QMessageBox::Cancel:
            default:
                e->ignore();
                return ;
            e->accept();
        }
    }
    else
        e->accept();
}
450
451
452
453

void    MainWindow::projectChanged( const QString& projectName, bool savedStatus )
{
    QString title = tr( "VideoLAN Movie Creator" );
454
    title += " - ";
455
456
457
458
459
    title += projectName;
    if ( savedStatus == false )
        title += " *";
    setWindowTitle( title );
}
460

461
462
463
464
465
void    MainWindow::on_actionClose_Project_triggered()
{
    ProjectManager::getInstance()->closeProject();
}

466
#define INIT_SHORTCUT( instName, shortcutName, actionInstance )      \
467
468
            const SettingValue* instName = SettingsManager::getInstance()->getValue( "keyboard_shortcut", shortcutName );\
            KeyboardShortcutHelper* helper##instName = new KeyboardShortcutHelper( shortcutName, this, true ); \
469
470
            connect( helper##instName, SIGNAL( changed( const QString&, const QString&) ), this, SLOT( keyboardShortcutChanged(QString,QString)) ); \
            m_ui.actionInstance->setShortcut( instName->get().toString() );
471
472
473

void    MainWindow::initializeMenuKeyboardShortcut()
{
474
475
476
477
478
479
480
481
    INIT_SHORTCUT( help, "Help", actionHelp );
    INIT_SHORTCUT( quit, "Quit", actionQuit );
    INIT_SHORTCUT( preferences, "Preferences", actionPreferences );
    INIT_SHORTCUT( fullscreen, "Fullscreen", actionFullscreen );
    INIT_SHORTCUT( newProject, "New project", actionNew_Project );
    INIT_SHORTCUT( openProject, "Open project", actionLoad_Project );
    INIT_SHORTCUT( save, "Save", actionSave );
    INIT_SHORTCUT( saveAs, "Save as", actionSave_As );
482
483
}

484
485
#undef INIT_SHORTCUT

486
487
488
489
490
void    MainWindow::keyboardShortcutChanged( const QString& name, const QString& val )
{
    qDebug() << "shortcut" << name << "changed to" << val;
    if ( name == "Help" )
        m_ui.actionHelp->setShortcut( val );
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
    else if ( name == "Quit" )
        m_ui.actionQuit->setShortcut( val );
    else if ( name == "Preferences" )
        m_ui.actionPreferences->setShortcut( val );
    else if ( name == "Fullscreen" )
        m_ui.actionFullscreen->setShortcut( val );
    else if ( name == "New project" )
        m_ui.actionNew_Project->setShortcut( val );
    else if ( name == "Open project" )
        m_ui.actionLoad_Project->setShortcut( val );
    else if ( name == "Save" )
        m_ui.actionSave->setShortcut( val );
    else if ( name == "Save as" )
        m_ui.actionSave_As->setShortcut( val );
    else
        qWarning() << "Unknown shortcut:" << name;
507
}