MainWindow.cpp 14.9 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
    // Mouse (default) tool
    QToolButton* mouseTool = new QToolButton( this );
174
    mouseTool->setAutoRaise( true );
175 176 177 178 179 180
    mouseTool->setCheckable( true );
    mouseTool->setIcon( QIcon( ":/images/mouse" ) );
    m_ui.statusbar->addPermanentWidget( mouseTool );

    // Cut/Split tool
    QToolButton* splitTool = new QToolButton( this );
181
    splitTool->setAutoRaise( true );
182 183 184 185 186 187 188 189 190 191 192
    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 );

193 194 195 196 197 198
    //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() ) );

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

    // Zoom slider
215 216 217 218 219 220 221 222 223
    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
224
    m_zoomSlider->setInvertedAppearance( true );
225
    m_ui.statusbar->addPermanentWidget( m_zoomSlider );
226

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

235
void MainWindow::initializeDockWidgets( void )
236
{
237 238
    WorkflowRenderer*    workflowRenderer = new WorkflowRenderer();
    m_timeline = new Timeline( workflowRenderer, this );
239 240 241
    m_timeline->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
    m_timeline->show();
    setCentralWidget( m_timeline );
242

243 244
    DockWidgetManager *dockManager = DockWidgetManager::instance();

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

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

263
    dockManager->addDockedWidget( UndoStack::getInstance( this ),
264 265 266 267
                                  tr( "History" ),
                                  Qt::AllDockWidgetAreas,
                                  QDockWidget::AllDockWidgetFeatures,
                                  Qt::LeftDockWidgetArea );
268
    setupLibrary();
269 270
}

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

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

307

308 309
//Private slots definition

Ludovic Fauvet's avatar
Ludovic Fauvet committed
310 311 312 313
void MainWindow::on_actionQuit_triggered()
{
    QApplication::quit();
}
314 315 316

void MainWindow::on_actionPreferences_triggered()
{
317
   m_globalPreferences->show();
318
}
Ludovic Fauvet's avatar
Ludovic Fauvet committed
319 320 321 322 323

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

325
void MainWindow::on_actionTranscode_triggered()
326
{
327 328
    QMessageBox::information( this, tr( "Sorry" ),
                              tr( "This feature is currently disabled." ) );
329
    //Transcode::instance( this )->exec();
330
}
331

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

353 354 355 356
void MainWindow::on_actionNew_Project_triggered()
{
    //TODO : clear the library, the timeline, and show the configuration box
    //of the newly created project
357

358
    m_pWizard->restart();
359
    m_pWizard->show();
360 361
}

362
void    MainWindow::on_actionHelp_triggered()
363 364
{
    QDesktopServices::openUrl( QUrl( "http://vlmc.org" ) );
365 366
}

367 368
void    MainWindow::on_actionImport_triggered()
{
Thomas Boquet's avatar
Thomas Boquet committed
369 370
    //Import* import = new Import( );
    //import->exec();
371 372
}

373
void    MainWindow::zoomIn()
Ludovic Fauvet's avatar
Ludovic Fauvet committed
374 375 376 377
{
    m_zoomSlider->setValue( m_zoomSlider->value() - 1 );
}

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

383
void    MainWindow::on_actionFullscreen_triggered( bool checked )
Ludovic Fauvet's avatar
Ludovic Fauvet committed
384 385 386 387 388 389
{
    if ( checked )
        showFullScreen();
    else
        showNormal();
}
390

391
void    MainWindow::registerWidgetInWindowMenu( QDockWidget* widget )
392
{
393
    m_ui.menuWindow->addAction( widget->toggleViewAction() );
394
}
395

396
void    MainWindow::toolButtonClicked( int id )
397 398 399
{
    emit toolChanged( (ToolButtons)id );
}
400

401 402 403 404 405 406 407 408 409 410 411
void MainWindow::on_actionBypass_effects_engine_toggled(bool toggled)
{
    EffectsEngine*  ee;

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

413 414
void MainWindow::on_actionProject_Preferences_triggered()
{
415
  m_projectPreferences->show( "project" );
416
}
417

418 419 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
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();
}
446 447 448 449

void    MainWindow::projectChanged( const QString& projectName, bool savedStatus )
{
    QString title = tr( "VideoLAN Movie Creator" );
450
    title += " - ";
451 452 453 454 455
    title += projectName;
    if ( savedStatus == false )
        title += " *";
    setWindowTitle( title );
}