Files
lmms/src/gui/MainWindow.cpp
Tobias Doerffel 0ff1f91c1b Mixer: renamed class and file name
The mixer class is now named "Mixer" and accessible via engine::mixer().
2014-01-08 22:35:14 +01:00

1080 lines
26 KiB
C++

/*
* main_window.cpp - implementation of LMMS-main-window
*
* Copyright (c) 2004-2013 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
* 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 (see COPYING); if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
*/
#include <QtXml/QDomElement>
#include <QtCore/QUrl>
#include <QtGui/QApplication>
#include <QtGui/QCloseEvent>
#include <QtGui/QDesktopServices>
#include <QtGui/QFileDialog>
#include <QtGui/QMdiArea>
#include <QtGui/QMdiSubWindow>
#include <QtGui/QMenuBar>
#include <QtGui/QMessageBox>
#include <QtGui/QSplitter>
#include "lmmsversion.h"
#include "MainWindow.h"
#include "bb_editor.h"
#include "song_editor.h"
#include "song.h"
#include "piano_roll.h"
#include "embed.h"
#include "engine.h"
#include "FxMixerView.h"
#include "InstrumentTrack.h"
#include "PianoView.h"
#include "about_dialog.h"
#include "ControllerRackView.h"
#include "file_browser.h"
#include "plugin_browser.h"
#include "SideBar.h"
#include "config_mgr.h"
#include "Mixer.h"
#include "PluginView.h"
#include "project_notes.h"
#include "setup_dialog.h"
#include "AudioDummy.h"
#include "ToolPlugin.h"
#include "tool_button.h"
#include "ProjectJournal.h"
#include "AutomationEditor.h"
#include "templates.h"
MainWindow::MainWindow( void ) :
m_workspace( NULL ),
m_templatesMenu( NULL ),
m_recentlyOpenedProjectsMenu( NULL ),
m_toolsMenu( NULL ),
m_autoSaveTimer( this )
{
setAttribute( Qt::WA_DeleteOnClose );
QWidget * main_widget = new QWidget( this );
QVBoxLayout * vbox = new QVBoxLayout( main_widget );
vbox->setSpacing( 0 );
vbox->setMargin( 0 );
QWidget * w = new QWidget( main_widget );
QHBoxLayout * hbox = new QHBoxLayout( w );
hbox->setSpacing( 0 );
hbox->setMargin( 0 );
SideBar * sideBar = new SideBar( Qt::Vertical, w );
QSplitter * splitter = new QSplitter( Qt::Horizontal, w );
splitter->setChildrenCollapsible( FALSE );
QString wdir = configManager::inst()->workingDir();
sideBar->appendTab( new pluginBrowser( splitter ) );
sideBar->appendTab( new fileBrowser(
configManager::inst()->userProjectsDir() + "*" +
configManager::inst()->factoryProjectsDir(),
"*.mmp *.mmpz *.xml *.mid *.flp",
tr( "My projects" ),
embed::getIconPixmap( "project_file" ),
splitter ) );
sideBar->appendTab( new fileBrowser(
configManager::inst()->userSamplesDir() + "*" +
configManager::inst()->factorySamplesDir(),
"*", tr( "My samples" ),
embed::getIconPixmap( "sample_file" ),
splitter ) );
sideBar->appendTab( new fileBrowser(
configManager::inst()->userPresetsDir() + "*" +
configManager::inst()->factoryPresetsDir(),
"*.xpf *.cs.xml *.xiz",
tr( "My presets" ),
embed::getIconPixmap( "preset_file" ),
splitter ) );
sideBar->appendTab( new fileBrowser( QDir::homePath(), "*",
tr( "My home" ),
embed::getIconPixmap( "home" ),
splitter ) );
QFileInfoList drives = QDir::drives();
QStringList root_paths;
foreach( const QFileInfo & drive, drives )
{
root_paths += drive.absolutePath();
}
sideBar->appendTab( new fileBrowser( root_paths.join( "*" ), "*",
#ifdef LMMS_BUILD_WIN32
tr( "My computer" ),
#else
tr( "Root directory" ),
#endif
embed::getIconPixmap( "computer" ),
splitter,
#ifdef LMMS_BUILD_WIN32
true
#else
false
#endif
) );
m_workspace = new QMdiArea( splitter );
// Load background
QString bgArtwork = configManager::inst()->backgroundArtwork();
QImage bgImage;
if( !bgArtwork.isEmpty() )
{
bgImage = QImage( bgArtwork );
}
if( !bgImage.isNull() )
{
m_workspace->setBackground( bgImage );
}
else
{
m_workspace->setBackground( Qt::NoBrush );
}
m_workspace->setOption( QMdiArea::DontMaximizeSubWindowOnActivation );
m_workspace->setHorizontalScrollBarPolicy( Qt::ScrollBarAsNeeded );
m_workspace->setVerticalScrollBarPolicy( Qt::ScrollBarAsNeeded );
hbox->addWidget( sideBar );
hbox->addWidget( splitter );
// create global-toolbar at the top of our window
m_toolBar = new QWidget( main_widget );
m_toolBar->setObjectName( "mainToolbar" );
m_toolBar->setFixedHeight( 64 );
m_toolBar->move( 0, 0 );
// add layout for organizing quite complex toolbar-layouting
m_toolBarLayout = new QGridLayout( m_toolBar/*, 2, 1*/ );
m_toolBarLayout->setMargin( 0 );
m_toolBarLayout->setSpacing( 0 );
vbox->addWidget( m_toolBar );
vbox->addWidget( w );
setCentralWidget( main_widget );
m_updateTimer.start( 1000 / 20, this ); // 20 fps
if( configManager::inst()->value( "ui", "enableautosave" ).toInt() )
{
// connect auto save
connect(&m_autoSaveTimer, SIGNAL(timeout()), this, SLOT(autoSave()));
m_autoSaveTimer.start(1000 * 60); // 1 minute
}
}
MainWindow::~MainWindow()
{
for( QList<PluginView *>::iterator it = m_tools.begin();
it != m_tools.end(); ++it )
{
Model * m = ( *it )->model();
delete *it;
delete m;
}
// TODO: Close tools
// destroy engine which will do further cleanups etc.
engine::destroy();
}
void MainWindow::finalize( void )
{
resetWindowTitle();
setWindowIcon( embed::getIconPixmap( "icon" ) );
// project-popup-menu
QMenu * project_menu = new QMenu( this );
menuBar()->addMenu( project_menu )->setText( tr( "&Project" ) );
project_menu->addAction( embed::getIconPixmap( "project_new" ),
tr( "&New" ),
this, SLOT( createNewProject() ),
Qt::CTRL + Qt::Key_N );
project_menu->addAction( embed::getIconPixmap( "project_open" ),
tr( "&Open..." ),
this, SLOT( openProject() ),
Qt::CTRL + Qt::Key_O );
m_recentlyOpenedProjectsMenu = project_menu->addMenu(
embed::getIconPixmap( "project_open_recent" ),
tr( "Recently opened projects" ) );
connect( m_recentlyOpenedProjectsMenu, SIGNAL( aboutToShow() ),
this, SLOT( updateRecentlyOpenedProjectsMenu() ) );
connect( m_recentlyOpenedProjectsMenu, SIGNAL( triggered( QAction * ) ),
this, SLOT( openRecentlyOpenedProject( QAction * ) ) );
project_menu->addAction( embed::getIconPixmap( "project_save" ),
tr( "&Save" ),
this, SLOT( saveProject() ),
Qt::CTRL + Qt::Key_S );
project_menu->addAction( embed::getIconPixmap( "project_saveas" ),
tr( "Save &As..." ),
this, SLOT( saveProjectAs() ),
Qt::CTRL + Qt::SHIFT + Qt::Key_S );
project_menu->addSeparator();
project_menu->addAction( embed::getIconPixmap( "project_import" ),
tr( "Import..." ),
engine::getSong(),
SLOT( importProject() ) );
project_menu->addAction( embed::getIconPixmap( "project_export" ),
tr( "E&xport..." ),
engine::getSong(),
SLOT( exportProject() ),
Qt::CTRL + Qt::Key_E );
project_menu->addAction( embed::getIconPixmap( "project_export" ),
tr( "E&xport tracks..." ),
engine::getSong(),
SLOT( exportProjectTracks() ),
Qt::CTRL + Qt::SHIFT + Qt::Key_E );
project_menu->addSeparator();
project_menu->addAction( embed::getIconPixmap( "exit" ), tr( "&Quit" ),
qApp, SLOT( closeAllWindows() ),
Qt::CTRL + Qt::Key_Q );
QMenu * edit_menu = new QMenu( this );
menuBar()->addMenu( edit_menu )->setText( tr( "&Edit" ) );
edit_menu->addAction( embed::getIconPixmap( "edit_undo" ),
tr( "Undo" ),
this, SLOT( undo() ),
Qt::CTRL + Qt::Key_Z );
edit_menu->addAction( embed::getIconPixmap( "edit_redo" ),
tr( "Redo" ),
this, SLOT( redo() ),
Qt::CTRL + Qt::Key_R );
edit_menu->addSeparator();
edit_menu->addAction( embed::getIconPixmap( "setup_general" ),
tr( "Settings" ),
this, SLOT( showSettingsDialog() ) );
m_toolsMenu = new QMenu( this );
Plugin::DescriptorList pluginDescriptors;
Plugin::getDescriptorsOfAvailPlugins( pluginDescriptors );
for( Plugin::DescriptorList::ConstIterator it = pluginDescriptors.begin();
it != pluginDescriptors.end(); ++it )
{
if( it->type == Plugin::Tool )
{
m_toolsMenu->addAction( it->logo->pixmap(),
it->displayName );
m_tools.push_back( ToolPlugin::instantiate( it->name,
/*this*/NULL )->createView( this ) );
}
}
if( !m_toolsMenu->isEmpty() )
{
menuBar()->addMenu( m_toolsMenu )->setText( tr( "&Tools" ) );
connect( m_toolsMenu, SIGNAL( triggered( QAction * ) ),
this, SLOT( showTool( QAction * ) ) );
}
// help-popup-menu
QMenu * help_menu = new QMenu( this );
menuBar()->addMenu( help_menu )->setText( tr( "&Help" ) );
// May use offline help
if( TRUE )
{
help_menu->addAction( embed::getIconPixmap( "help" ),
tr( "Online help" ),
this, SLOT( browseHelp() ) );
}
else
{
help_menu->addAction( embed::getIconPixmap( "help" ),
tr( "Help" ),
this, SLOT( help() ) );
}
help_menu->addAction( embed::getIconPixmap( "whatsthis" ),
tr( "What's this?" ),
this, SLOT( enterWhatsThisMode() ) );
help_menu->addSeparator();
help_menu->addAction( embed::getIconPixmap( "icon" ), tr( "About" ),
this, SLOT( aboutLMMS() ) );
// create tool-buttons
toolButton * project_new = new toolButton(
embed::getIconPixmap( "project_new" ),
tr( "Create new project" ),
this, SLOT( createNewProject() ),
m_toolBar );
toolButton * project_new_from_template = new toolButton(
embed::getIconPixmap( "project_new_from_template" ),
tr( "Create new project from template" ),
this, SLOT( emptySlot() ),
m_toolBar );
m_templatesMenu = new QMenu( project_new_from_template );
connect( m_templatesMenu, SIGNAL( aboutToShow() ),
this, SLOT( fillTemplatesMenu() ) );
connect( m_templatesMenu, SIGNAL( triggered( QAction * ) ),
this, SLOT( createNewProjectFromTemplate( QAction * ) ) );
project_new_from_template->setMenu( m_templatesMenu );
project_new_from_template->setPopupMode( toolButton::InstantPopup );
toolButton * project_open = new toolButton(
embed::getIconPixmap( "project_open" ),
tr( "Open existing project" ),
this, SLOT( openProject() ),
m_toolBar );
toolButton * project_open_recent = new toolButton(
embed::getIconPixmap( "project_open_recent" ),
tr( "Recently opened project" ),
this, SLOT( emptySlot() ), m_toolBar );
project_open_recent->setMenu( m_recentlyOpenedProjectsMenu );
project_open_recent->setPopupMode( toolButton::InstantPopup );
toolButton * project_save = new toolButton(
embed::getIconPixmap( "project_save" ),
tr( "Save current project" ),
this, SLOT( saveProject() ),
m_toolBar );
toolButton * project_export = new toolButton(
embed::getIconPixmap( "project_export" ),
tr( "Export current project" ),
engine::getSong(),
SLOT( exportProject() ),
m_toolBar );
m_toolBarLayout->setColumnMinimumWidth( 0, 5 );
m_toolBarLayout->addWidget( project_new, 0, 1 );
m_toolBarLayout->addWidget( project_new_from_template, 0, 2 );
m_toolBarLayout->addWidget( project_open, 0, 3 );
m_toolBarLayout->addWidget( project_open_recent, 0, 4 );
m_toolBarLayout->addWidget( project_save, 0, 5 );
m_toolBarLayout->addWidget( project_export, 0, 6 );
// window-toolbar
toolButton * song_editor_window = new toolButton(
embed::getIconPixmap( "songeditor" ),
tr( "Show/hide Song-Editor" ) + " (F5)",
this, SLOT( toggleSongEditorWin() ),
m_toolBar );
song_editor_window->setShortcut( Qt::Key_F5 );
song_editor_window->setWhatsThis(
tr( "By pressing this button, you can show or hide the "
"Song-Editor. With the help of the Song-Editor you can "
"edit song-playlist and specify when which track "
"should be played. "
"You can also insert and move samples (e.g. "
"rap samples) directly into the playlist." ) );
toolButton * bb_editor_window = new toolButton(
embed::getIconPixmap( "bb_track" ),
tr( "Show/hide Beat+Bassline Editor" ) +
" (F6)",
this, SLOT( toggleBBEditorWin() ),
m_toolBar );
bb_editor_window->setShortcut( Qt::Key_F6 );
bb_editor_window->setWhatsThis(
tr( "By pressing this button, you can show or hide the "
"Beat+Bassline Editor. The Beat+Bassline Editor is "
"needed for creating beats, and for opening, adding, and "
"removing channels, and for cutting, copying and pasting "
"beat and bassline-patterns, and for other things like "
"that." ) );
toolButton * piano_roll_window = new toolButton(
embed::getIconPixmap( "piano" ),
tr( "Show/hide Piano-Roll" ) +
" (F7)",
this, SLOT( togglePianoRollWin() ),
m_toolBar );
piano_roll_window->setShortcut( Qt::Key_F7 );
piano_roll_window->setWhatsThis(
tr( "Click here to show or hide the "
"Piano-Roll. With the help of the Piano-Roll "
"you can edit melodies in an easy way."
) );
toolButton * automation_editor_window = new toolButton(
embed::getIconPixmap( "automation" ),
tr( "Show/hide Automation Editor" ) +
" (F8)",
this,
SLOT( toggleAutomationEditorWin() ),
m_toolBar );
automation_editor_window->setShortcut( Qt::Key_F8 );
automation_editor_window->setWhatsThis(
tr( "Click here to show or hide the "
"Automation Editor. With the help of the "
"Automation Editor you can edit dynamic values "
"in an easy way."
) );
toolButton * fx_mixer_window = new toolButton(
embed::getIconPixmap( "fx_mixer" ),
tr( "Show/hide FX Mixer" ) + " (F9)",
this, SLOT( toggleFxMixerWin() ),
m_toolBar );
fx_mixer_window->setShortcut( Qt::Key_F9 );
fx_mixer_window->setWhatsThis(
tr( "Click here to show or hide the "
"FX Mixer. The FX Mixer is a very powerful tool "
"for managing effects for your song. You can insert "
"effects into different effect-channels." ) );
toolButton * project_notes_window = new toolButton(
embed::getIconPixmap( "project_notes" ),
tr( "Show/hide project notes" ) +
" (F10)",
this, SLOT( toggleProjectNotesWin() ),
m_toolBar );
project_notes_window->setShortcut( Qt::Key_F10 );
project_notes_window->setWhatsThis(
tr( "Click here to show or hide the "
"project notes window. In this window you can put "
"down your project notes.") );
toolButton * controllers_window = new toolButton(
embed::getIconPixmap( "controller" ),
tr( "Show/hide controller rack" ) +
" (F11)",
this, SLOT( toggleControllerRack() ),
m_toolBar );
controllers_window->setShortcut( Qt::Key_F11 );
m_toolBarLayout->addWidget( song_editor_window, 1, 1 );
m_toolBarLayout->addWidget( bb_editor_window, 1, 2 );
m_toolBarLayout->addWidget( piano_roll_window, 1, 3 );
m_toolBarLayout->addWidget( automation_editor_window, 1, 4 );
m_toolBarLayout->addWidget( fx_mixer_window, 1, 5 );
m_toolBarLayout->addWidget( project_notes_window, 1, 6 );
m_toolBarLayout->addWidget( controllers_window, 1, 7 );
m_toolBarLayout->setColumnStretch( 100, 1 );
// setup-dialog opened before?
if( !configManager::inst()->value( "app", "configured" ).toInt() )
{
configManager::inst()->setValue( "app", "configured", "1" );
// no, so show it that user can setup everything
setupDialog sd;
sd.exec();
}
// look whether mixer could use a audio-interface beside AudioDummy
else if( engine::mixer()->audioDevName() == AudioDummy::name() )
{
// no, so we offer setup-dialog with audio-settings...
setupDialog sd( setupDialog::AudioSettings );
sd.exec();
}
}
int MainWindow::addWidgetToToolBar( QWidget * _w, int _row, int _col )
{
int col = ( _col == -1 ) ? m_toolBarLayout->columnCount() + 7 : _col;
if( _w->height() > 32 || _row == -1 )
{
m_toolBarLayout->addWidget( _w, 0, col, 2, 1 );
}
else
{
m_toolBarLayout->addWidget( _w, _row, col );
}
return( col );
}
void MainWindow::addSpacingToToolBar( int _size )
{
m_toolBarLayout->setColumnMinimumWidth( m_toolBarLayout->columnCount() +
7, _size );
}
void MainWindow::resetWindowTitle( void )
{
QString title = "";
if( engine::getSong()->projectFileName() != "" )
{
title = QFileInfo( engine::getSong()->projectFileName()
).completeBaseName();
}
if( title == "" )
{
title = tr( "Untitled" );
}
if( engine::getSong()->isModified() )
{
title += '*';
}
setWindowTitle( title + " - " + tr( "LMMS %1" ).arg( LMMS_VERSION ) );
}
bool MainWindow::mayChangeProject( void )
{
engine::getSong()->stop();
if( !engine::getSong()->isModified() )
{
return( TRUE );
}
QMessageBox mb( tr( "Project not saved" ),
tr( "The current project was modified since "
"last saving. Do you want to save it "
"now?" ),
QMessageBox::Question,
QMessageBox::Save,
QMessageBox::Discard,
QMessageBox::Cancel,
this );
int answer = mb.exec();
if( answer == QMessageBox::Save )
{
return( saveProject() );
}
else if( answer == QMessageBox::Discard )
{
return( TRUE );
}
return( FALSE );
}
void MainWindow::clearKeyModifiers( void )
{
m_keyMods.m_ctrl = FALSE;
m_keyMods.m_shift = FALSE;
m_keyMods.m_alt = FALSE;
}
void MainWindow::saveWidgetState( QWidget * _w, QDomElement & _de )
{
if( _w->parentWidget() != NULL &&
_w->parentWidget()->inherits( "QMdiSubWindow" ) )
{
_w = _w->parentWidget();
}
_de.setAttribute( "x", _w->x() );
_de.setAttribute( "y", _w->y() );
_de.setAttribute( "visible", _w->isVisible() );
_de.setAttribute( "minimized", _w->isMinimized() );
_de.setAttribute( "maximized", _w->isMaximized() );
_de.setAttribute( "width", _w->width() );
_de.setAttribute( "height", _w->height() );
}
void MainWindow::restoreWidgetState( QWidget * _w, const QDomElement & _de )
{
QRect r( qMax( 0, _de.attribute( "x" ).toInt() ),
qMax( 0, _de.attribute( "y" ).toInt() ),
qMax( 100, _de.attribute( "width" ).toInt() ),
qMax( 100, _de.attribute( "height" ).toInt() ) );
if( _de.hasAttribute( "visible" ) && !r.isNull() )
{
if ( _w->parentWidget() != NULL &&
_w->parentWidget()->inherits( "QMdiSubWindow" ) )
{
_w = _w->parentWidget();
}
_w->resize( r.size() );
_w->move( r.topLeft() );
_w->setVisible( _de.attribute( "visible" ).toInt() );
_w->setWindowState( _de.attribute( "minimized" ).toInt() ?
( _w->windowState() | Qt::WindowMinimized ) :
( _w->windowState() & ~Qt::WindowMinimized ) );
_w->setWindowState( _de.attribute( "maximized" ).toInt() ?
( _w->windowState() | Qt::WindowMaximized ) :
( _w->windowState() & ~Qt::WindowMaximized ) );
}
}
void MainWindow::createNewProject( void )
{
if( mayChangeProject() )
{
engine::getSong()->createNewProject();
}
}
void MainWindow::createNewProjectFromTemplate( QAction * _idx )
{
if( m_templatesMenu != NULL && mayChangeProject() )
{
QString dir_base = m_templatesMenu->actions().indexOf( _idx )
>= m_custom_templates_count ?
configManager::inst()->factoryProjectsDir() :
configManager::inst()->userProjectsDir();
engine::getSong()->createNewProjectFromTemplate(
dir_base + "templates/" + _idx->text() + ".mpt" );
}
}
void MainWindow::openProject( void )
{
if( mayChangeProject() )
{
QFileDialog ofd( this, tr( "Open project" ), "",
tr( "MultiMedia Project (*.mmp *.mmpz *.xml)" ) );
#if QT_VERSION >= 0x040806
ofd.setOption( QFileDialog::DontUseCustomDirectoryIcons );
#endif
ofd.setDirectory( configManager::inst()->userProjectsDir() );
ofd.setFileMode( QFileDialog::ExistingFiles );
if( ofd.exec () == QDialog::Accepted &&
!ofd.selectedFiles().isEmpty() )
{
setCursor( Qt::WaitCursor );
engine::getSong()->loadProject(
ofd.selectedFiles()[0] );
setCursor( Qt::ArrowCursor );
}
}
}
void MainWindow::updateRecentlyOpenedProjectsMenu( void )
{
m_recentlyOpenedProjectsMenu->clear();
QStringList rup = configManager::inst()->recentlyOpenedProjects();
for( QStringList::iterator it = rup.begin(); it != rup.end(); ++it )
{
m_recentlyOpenedProjectsMenu->addAction(
embed::getIconPixmap( "project_file" ), *it );
}
}
void MainWindow::openRecentlyOpenedProject( QAction * _action )
{
const QString & f = _action->text();
setCursor( Qt::WaitCursor );
engine::getSong()->loadProject( f );
configManager::inst()->addRecentlyOpenedProject( f );
setCursor( Qt::ArrowCursor );
}
bool MainWindow::saveProject( void )
{
if( engine::getSong()->projectFileName() == "" )
{
return( saveProjectAs() );
}
else
{
engine::getSong()->guiSaveProject();
}
return( TRUE );
}
bool MainWindow::saveProjectAs( void )
{
QFileDialog sfd( this, tr( "Save project" ), "",
tr( "MultiMedia Project (*.mmp *.mmpz);;"
"MultiMedia Project Template (*.mpt)" ) );
#if QT_VERSION >= 0x040806
sfd.setOption( QFileDialog::DontUseCustomDirectoryIcons );
#endif
sfd.setAcceptMode( QFileDialog::AcceptSave );
sfd.setFileMode( QFileDialog::AnyFile );
QString f = engine::getSong()->projectFileName();
if( f != "" )
{
sfd.setDirectory( QFileInfo( f ).absolutePath() );
sfd.selectFile( QFileInfo( f ).fileName() );
}
else
{
sfd.setDirectory( configManager::inst()->userProjectsDir() );
}
if( sfd.exec () == QFileDialog::Accepted &&
!sfd.selectedFiles().isEmpty() && sfd.selectedFiles()[0] != "" )
{
engine::getSong()->guiSaveProjectAs(
sfd.selectedFiles()[0] );
return( TRUE );
}
return( FALSE );
}
void MainWindow::showSettingsDialog( void )
{
setupDialog sd;
sd.exec();
}
void MainWindow::aboutLMMS( void )
{
aboutDialog().exec();
}
void MainWindow::help( void )
{
QMessageBox::information( this, tr( "Help not available" ),
tr( "Currently there's no help "
"available in LMMS.\n"
"Please visit "
"http://lmms.sf.net/wiki "
"for documentation on LMMS." ),
QMessageBox::Ok );
}
void MainWindow::toggleWindow( QWidget *window, bool forceShow )
{
QWidget *parent = window->parentWidget();
if( forceShow ||
m_workspace->activeSubWindow() != parent ||
parent->isHidden() )
{
parent->show();
window->show();
window->setFocus();
}
else
{
parent->hide();
}
// Workaround for Qt Bug #260116
m_workspace->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
m_workspace->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
m_workspace->setHorizontalScrollBarPolicy( Qt::ScrollBarAsNeeded );
m_workspace->setVerticalScrollBarPolicy( Qt::ScrollBarAsNeeded );
}
void MainWindow::toggleBBEditorWin( bool forceShow )
{
toggleWindow( engine::getBBEditor(), forceShow );
}
void MainWindow::toggleSongEditorWin( void )
{
toggleWindow( engine::getSongEditor() );
}
void MainWindow::toggleProjectNotesWin( void )
{
toggleWindow( engine::getProjectNotes() );
}
void MainWindow::togglePianoRollWin( void )
{
toggleWindow( engine::getPianoRoll() );
}
void MainWindow::toggleAutomationEditorWin( void )
{
toggleWindow( engine::automationEditor() );
}
void MainWindow::toggleFxMixerWin( void )
{
toggleWindow( engine::fxMixerView() );
}
void MainWindow::toggleControllerRack( void )
{
toggleWindow( engine::getControllerRackView() );
}
void MainWindow::undo( void )
{
engine::projectJournal()->undo();
}
void MainWindow::redo( void )
{
engine::projectJournal()->redo();
}
void MainWindow::closeEvent( QCloseEvent * _ce )
{
if( mayChangeProject() )
{
// delete recovery file
QDir working(configManager::inst()->workingDir());
working.remove("recover.mmp");
_ce->accept();
}
else
{
_ce->ignore();
}
}
void MainWindow::focusOutEvent( QFocusEvent * _fe )
{
// when loosing focus we do not receive key-(release!)-events anymore,
// so we might miss release-events of one the modifiers we're watching!
clearKeyModifiers();
QMainWindow::leaveEvent( _fe );
}
void MainWindow::keyPressEvent( QKeyEvent * _ke )
{
switch( _ke->key() )
{
case Qt::Key_Control: m_keyMods.m_ctrl = TRUE; break;
case Qt::Key_Shift: m_keyMods.m_shift = TRUE; break;
case Qt::Key_Alt: m_keyMods.m_alt = TRUE; break;
default:
{
InstrumentTrackWindow * w =
InstrumentTrackView::topLevelInstrumentTrackWindow();
if( w )
{
w->pianoView()->keyPressEvent( _ke );
}
if( !_ke->isAccepted() )
{
QMainWindow::keyPressEvent( _ke );
}
}
}
}
void MainWindow::keyReleaseEvent( QKeyEvent * _ke )
{
switch( _ke->key() )
{
case Qt::Key_Control: m_keyMods.m_ctrl = FALSE; break;
case Qt::Key_Shift: m_keyMods.m_shift = FALSE; break;
case Qt::Key_Alt: m_keyMods.m_alt = FALSE; break;
default:
if( InstrumentTrackView::topLevelInstrumentTrackWindow() )
{
InstrumentTrackView::topLevelInstrumentTrackWindow()->
pianoView()->keyReleaseEvent( _ke );
}
if( !_ke->isAccepted() )
{
QMainWindow::keyReleaseEvent( _ke );
}
}
}
void MainWindow::timerEvent( QTimerEvent * _te)
{
emit periodicUpdate();
}
void MainWindow::fillTemplatesMenu( void )
{
m_templatesMenu->clear();
QDir user_d( configManager::inst()->userProjectsDir() + "templates" );
QStringList templates = user_d.entryList( QStringList( "*.mpt" ),
QDir::Files | QDir::Readable );
m_custom_templates_count = templates.count();
for( QStringList::iterator it = templates.begin();
it != templates.end(); ++it )
{
m_templatesMenu->addAction(
embed::getIconPixmap( "project_file" ),
( *it ).left( ( *it ).length() - 4 ) );
}
QDir d( configManager::inst()->factoryProjectsDir() + "templates" );
templates = d.entryList( QStringList( "*.mpt" ),
QDir::Files | QDir::Readable );
if( m_custom_templates_count > 0 && !templates.isEmpty() )
{
m_templatesMenu->addSeparator();
}
for( QStringList::iterator it = templates.begin();
it != templates.end(); ++it )
{
m_templatesMenu->addAction(
embed::getIconPixmap( "project_file" ),
( *it ).left( ( *it ).length() - 4 ) );
}
}
void MainWindow::showTool( QAction * _idx )
{
PluginView * p = m_tools[m_toolsMenu->actions().indexOf( _idx )];
p->show();
p->parentWidget()->show();
p->setFocus();
}
void MainWindow::browseHelp( void )
{
// file:// alternative for offline help
QString url = "http://lmms.sf.net/wiki/index.php?title=Main_Page";
QDesktopServices::openUrl( url );
// TODO: Handle error
}
void MainWindow::autoSave()
{
if( !( engine::getSong()->isPlaying() ||
engine::getSong()->isExporting() ) )
{
QDir work(configManager::inst()->workingDir());
engine::getSong()->saveProjectFile(work.absoluteFilePath("recover.mmp"));
}
else
{
// try again in 10 seconds
QTimer::singleShot( 10*1000, this, SLOT( autoSave() ) );
}
}
#include "moc_MainWindow.cxx"