MainWindow.cpp 14.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 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
 *****************************************************************************
 * Copyright (C) 2008-2009 the VLMC team
 *
 * Authors: Ludovic Fauvet <etix@l0cal.com>
 *
 * 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.
 *****************************************************************************/

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

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

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

64
    qRegisterMetaType<MainWorkflow::TrackType>( "MainWorkflow::TrackType" );
65
    qRegisterMetaType<MainWorkflow::FrameChangedReason>( "MainWorkflow::FrameChangedReason" );
66 67 68 69

    // Settings
    VLMCSettingsDefault::load( "default" );
    VLMCSettingsDefault::load( "VLMC" );
70
    VLMCSettingsDefault::loadKeyboardShortcutDefaults();
71 72

    // GUI
73
    DockWidgetManager::instance( this )->setMainWindow( this );
74
    initializeDockWidgets();
75
    createStatusBar();
76
    createGlobalPreferences();
77
    createProjectPreferences();
78

79 80 81 82 83
    // Wizard
    m_pWizard = new ProjectWizard( this );
    m_pWizard->setModal( true );
    m_pWizard->show();

Ludovic Fauvet's avatar
Ludovic Fauvet committed
84
    // Translations
85 86
    connect( this, SIGNAL( translateDockWidgetTitle() ),
             DockWidgetManager::instance(), SLOT( transLateWidgetTitle() ) );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
87 88

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

98 99 100
    connect( ProjectManager::getInstance(), SIGNAL( projectChanged( const QString&, bool ) ),
             this, SLOT( projectChanged( const QString&, bool ) ) );

101 102 103 104 105
    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
106 107
}

108 109
MainWindow::~MainWindow()
{
110 111 112 113 114 115 116
    QSettings s;
    // Save the current geometry
    s.setValue( "MainWindowGeometry", saveGeometry() );
    // Save the current layout
    s.setValue( "MainWindowState", saveState() );
    s.sync();

117 118
    if ( m_renderer )
        delete m_renderer;
119
    LibVLCpp::Instance::destroyInstance();
120 121
}

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

Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
135 136 137
void        MainWindow::setupLibrary()
{
    //GUI part :
138

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

141 142 143 144
    DockWidgetManager::instance()->addDockedWidget( mediaLibraryWidget,
                                                    tr( "Media Library" ),
                                                    Qt::AllDockWidgetAreas,
                                                    QDockWidget::AllDockWidgetFeatures,
145

146
                                                    Qt::LeftDockWidgetArea );
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
147 148
    connect( mediaLibraryWidget, SIGNAL( mediaSelected( Media* ) ),
             m_clipPreview->getGenericRenderer(), SLOT( setMedia( Media* ) ) );
149

150 151
    connect( Library::getInstance(), SIGNAL( mediaRemoved( const QUuid& ) ),
             m_clipPreview->getGenericRenderer(), SLOT( mediaUnloaded( QUuid ) ) );
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
152 153
}

154 155
void    MainWindow::on_actionSave_triggered()
{
156
    ProjectManager::getInstance()->saveProject();
157 158
}

Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
159 160 161 162 163
void    MainWindow::on_actionSave_As_triggered()
{
    ProjectManager::getInstance()->saveProject( true );
}

164 165
void    MainWindow::on_actionLoad_Project_triggered()
{
166 167
    ProjectManager* pm = ProjectManager::getInstance();
    pm->loadProject( pm->loadProjectFile() );
168 169
}

170 171
void MainWindow::createStatusBar()
{
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
    // Mouse (default) tool
    QToolButton* mouseTool = new QToolButton( this );
    mouseTool->setCheckable( true );
    mouseTool->setIcon( QIcon( ":/images/mouse" ) );
    m_ui.statusbar->addPermanentWidget( mouseTool );

    // Cut/Split tool
    QToolButton* splitTool = new QToolButton( this );
    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 );

    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
199 200 201 202 203 204
    // Zoom Out
    QToolButton* zoomOutButton = new QToolButton( this );
    zoomOutButton->setIcon( QIcon( ":/images/zoomout" ) );
    m_ui.statusbar->addPermanentWidget( zoomOutButton );
    connect( zoomOutButton, SIGNAL( clicked() ),
             this, SLOT( zoomOut() ) );
205 206

    // Zoom slider
207 208 209 210 211 212 213 214 215
    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
216
    m_zoomSlider->setInvertedAppearance( true );
217
    m_ui.statusbar->addPermanentWidget( m_zoomSlider );
218

Ludovic Fauvet's avatar
Ludovic Fauvet committed
219 220 221 222 223 224
    // Zoom IN
    QToolButton* zoomInButton = new QToolButton( this );
    zoomInButton->setIcon( QIcon( ":/images/zoomin" ) );
    m_ui.statusbar->addPermanentWidget( zoomInButton );
    connect( zoomInButton, SIGNAL( clicked() ),
             this, SLOT( zoomIn() ) );
225 226
}

227
void MainWindow::initializeDockWidgets( void )
228
{
229 230
    WorkflowRenderer*    workflowRenderer = new WorkflowRenderer();
    m_timeline = new Timeline( workflowRenderer, this );
231 232 233
    m_timeline->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
    m_timeline->show();
    setCentralWidget( m_timeline );
234

235 236
    DockWidgetManager *dockManager = DockWidgetManager::instance();

237 238
    m_clipPreview = new PreviewWidget( new ClipRenderer, this );
    dockManager->addDockedWidget( m_clipPreview,
239
                                  tr( "Clip Preview" ),
geoff's avatar
geoff committed
240 241 242
                                  Qt::AllDockWidgetAreas,
                                  QDockWidget::AllDockWidgetFeatures,
                                  Qt::TopDockWidgetArea );
243
    KeyboardShortcutHelper* clipShortcut = new KeyboardShortcutHelper( "Launch media preview", this );
244
    connect( clipShortcut, SIGNAL( activated() ), m_clipPreview, SLOT( on_pushButtonPlay_clicked() ) );
245

246
    m_projectPreview = new PreviewWidget( workflowRenderer, this );
247
    dockManager->addDockedWidget( m_projectPreview,
248 249 250
                                  tr( "Project Preview" ),
                                  Qt::AllDockWidgetAreas,
                                  QDockWidget::AllDockWidgetFeatures,
251
                                  Qt::TopDockWidgetArea );
252
    KeyboardShortcutHelper* renderShortcut = new KeyboardShortcutHelper( "Start render preview", this );
253
    connect( renderShortcut, SIGNAL( activated() ), m_projectPreview, SLOT( on_pushButtonPlay_clicked() ) );
254

255
    dockManager->addDockedWidget( UndoStack::getInstance( this ),
256 257 258 259
                                  tr( "History" ),
                                  Qt::AllDockWidgetAreas,
                                  QDockWidget::AllDockWidgetFeatures,
                                  Qt::LeftDockWidgetArea );
260
    setupLibrary();
261 262
}

263 264
void        MainWindow::createGlobalPreferences()
{
265
    m_globalPreferences = new Settings( false, "VLMC", this );
266
    m_globalPreferences->addWidget("VLMC",
Ludovic Fauvet's avatar
Ludovic Fauvet committed
267
                                   new VLMCPreferences( m_globalPreferences ),
268
                                   QIcon( ":/images/images/vlmc.png" ),
269
                                   "VLMC settings");
270 271
    m_globalPreferences->addWidget("Language preferences",
                                   new LanguagePreferences( m_globalPreferences ),
272
                                   QIcon( ":/images/images/vlmc.png" ),
273
                                   "Langage settings");
274 275 276 277
    m_globalPreferences->addWidget( "Keyboard",
                                     new KeyboardShortcut( m_globalPreferences ),
                                     QIcon( ":/images/keyboard" ),
                                     tr( "Keyboard Settings" ) );
278 279 280
    m_globalPreferences->build();
}

281 282
void	    MainWindow::createProjectPreferences()
{
283
    m_projectPreferences = new Settings( false, "project", this );
284 285
    m_projectPreferences->addWidget("Project",
                                   new ProjectPreferences,
286
                                   QIcon( ":/images/images/vlmc.png" ),
287 288
                                   "Project settings" );
    m_projectPreferences->addWidget( "Video",
289
                                   new VideoProjectPreferences,
290
                                   QIcon( ":/images/images/video.png" ),
291 292
                                   "Video settings" );
    m_projectPreferences->addWidget( "Audio",
293
                                   new AudioProjectPreferences,
294
                                   QIcon( ":/images/images/audio.png" ),
295
                                   "Audio settings" );
296 297 298
    m_projectPreferences->build();
}

299

300 301
//Private slots definition

Ludovic Fauvet's avatar
Ludovic Fauvet committed
302 303 304 305
void MainWindow::on_actionQuit_triggered()
{
    QApplication::quit();
}
306 307 308

void MainWindow::on_actionPreferences_triggered()
{
309
   m_globalPreferences->show();
310
}
Ludovic Fauvet's avatar
Ludovic Fauvet committed
311 312 313 314 315

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

317
void MainWindow::on_actionTranscode_triggered()
318
{
319 320
    QMessageBox::information( this, tr( "Sorry" ),
                              tr( "This feature is currently disabled." ) );
321
    //Transcode::instance( this )->exec();
322
}
323

324 325
void    MainWindow::on_actionRender_triggered()
{
326
    if ( MainWorkflow::getInstance()->getLengthFrame() <= 0 )
327 328 329 330 331 332
    {
        QMessageBox::warning( NULL, "VLMC Renderer", "There is nothing to render." );
        return ;
    }
    QString outputFileName =
            QFileDialog::getSaveFileName( NULL, "Enter the output file name",
333
                                          QDir::currentPath(), "Videos(*.avi *.mpg)" );
334 335 336 337 338 339
    if ( outputFileName.length() == 0 )
        return ;
    else
    {
        if ( m_renderer )
            delete m_renderer;
340
        m_renderer = new WorkflowFileRenderer( outputFileName );
341 342 343 344
        m_renderer->run();
    }
}

345 346 347 348
void MainWindow::on_actionNew_Project_triggered()
{
    //TODO : clear the library, the timeline, and show the configuration box
    //of the newly created project
349

350
    m_pWizard->restart();
351
    m_pWizard->show();
352 353
}

354
void    MainWindow::on_actionHelp_triggered()
355 356
{
    QDesktopServices::openUrl( QUrl( "http://vlmc.org" ) );
357 358
}

359 360
void    MainWindow::on_actionImport_triggered()
{
Thomas Boquet's avatar
Thomas Boquet committed
361 362
    //Import* import = new Import( );
    //import->exec();
363 364
}

365
void    MainWindow::zoomIn()
Ludovic Fauvet's avatar
Ludovic Fauvet committed
366 367 368 369
{
    m_zoomSlider->setValue( m_zoomSlider->value() - 1 );
}

370
void    MainWindow::zoomOut()
Ludovic Fauvet's avatar
Ludovic Fauvet committed
371 372 373
{
    m_zoomSlider->setValue( m_zoomSlider->value() + 1 );
}
Ludovic Fauvet's avatar
Ludovic Fauvet committed
374

375
void    MainWindow::on_actionFullscreen_triggered( bool checked )
Ludovic Fauvet's avatar
Ludovic Fauvet committed
376 377 378 379 380 381
{
    if ( checked )
        showFullScreen();
    else
        showNormal();
}
382

383
void    MainWindow::registerWidgetInWindowMenu( QDockWidget* widget )
384
{
385
    m_ui.menuWindow->addAction( widget->toggleViewAction() );
386
}
387

388
void    MainWindow::toolButtonClicked( int id )
389 390 391
{
    emit toolChanged( (ToolButtons)id );
}
392

393 394 395 396 397 398 399 400 401 402 403
void MainWindow::on_actionBypass_effects_engine_toggled(bool toggled)
{
    EffectsEngine*  ee;

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

405 406
void MainWindow::on_actionProject_Preferences_triggered()
{
407
  m_projectPreferences->show( "project" );
408
}
409

410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437
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();
}
438 439 440 441

void    MainWindow::projectChanged( const QString& projectName, bool savedStatus )
{
    QString title = tr( "VideoLAN Movie Creator" );
442
    title += " - ";
443 444 445 446 447
    title += projectName;
    if ( savedStatus == false )
        title += " *";
    setWindowTitle( title );
}