MainWindow.cpp 14.4 KB
Newer Older
Ludovic Fauvet's avatar
Ludovic Fauvet committed
1
/*****************************************************************************
2
 * MainWindow.cpp: VLMC MainWindow
Ludovic Fauvet's avatar
Ludovic Fauvet committed
3 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 70 71

    // Settings
    VLMCSettingsDefault::load( "default" );
    VLMCSettingsDefault::load( "VLMC" );

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

163 164
void    MainWindow::on_actionLoad_Project_triggered()
{
165
    ProjectManager::getInstance()->loadProject();
166 167
}

168 169
void MainWindow::createStatusBar()
{
170 171 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
    // 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
197 198 199 200 201 202
    // Zoom Out
    QToolButton* zoomOutButton = new QToolButton( this );
    zoomOutButton->setIcon( QIcon( ":/images/zoomout" ) );
    m_ui.statusbar->addPermanentWidget( zoomOutButton );
    connect( zoomOutButton, SIGNAL( clicked() ),
             this, SLOT( zoomOut() ) );
203 204

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

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

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

233 234
    DockWidgetManager *dockManager = DockWidgetManager::instance();

235 236
    m_clipPreview = new PreviewWidget( new ClipRenderer, this );
    dockManager->addDockedWidget( m_clipPreview,
237
                                  tr( "Clip Preview" ),
geoff's avatar
geoff committed
238 239 240
                                  Qt::AllDockWidgetAreas,
                                  QDockWidget::AllDockWidgetFeatures,
                                  Qt::TopDockWidgetArea );
241 242
    QShortcut*  clipShortcut = new QShortcut( QKeySequence( tr( "Ctrl+Return", "Start clip preview" ) ), this );
    connect( clipShortcut, SIGNAL( activated() ), m_clipPreview, SLOT( on_pushButtonPlay_clicked() ) );
243

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

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

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

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

297

298 299
//Private slots definition

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

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

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

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

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

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

348
    m_pWizard->show();
349 350
}

351
void    MainWindow::on_actionHelp_triggered()
352 353
{
    QDesktopServices::openUrl( QUrl( "http://vlmc.org" ) );
354 355
}

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

362
void    MainWindow::zoomIn()
Ludovic Fauvet's avatar
Ludovic Fauvet committed
363 364 365 366
{
    m_zoomSlider->setValue( m_zoomSlider->value() - 1 );
}

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

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

380
void    MainWindow::registerWidgetInWindowMenu( QDockWidget* widget )
381
{
382
    m_ui.menuWindow->addAction( widget->toggleViewAction() );
383
}
384

385
void    MainWindow::toolButtonClicked( int id )
386 387 388
{
    emit toolChanged( (ToolButtons)id );
}
389

390 391 392 393 394 395 396 397 398 399 400
void MainWindow::on_actionBypass_effects_engine_toggled(bool toggled)
{
    EffectsEngine*  ee;

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

402 403
void MainWindow::on_actionProject_Preferences_triggered()
{
404
  m_projectPreferences->show( "project" );
405
}
406

407 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
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();
}
435 436 437 438

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