mirror of
https://github.com/LMMS/lmms.git
synced 2026-01-28 00:08:15 -05:00
Recovery file fixes
This commit is contained in:
@@ -81,6 +81,29 @@ public:
|
||||
///
|
||||
bool mayChangeProject(bool stopPlayback);
|
||||
|
||||
void autoSaveTimerStart()
|
||||
{
|
||||
m_autoSaveTimer.start( 1000 * 60 ); // 1 minute
|
||||
}
|
||||
|
||||
enum SessionState
|
||||
{
|
||||
Normal,
|
||||
Recover,
|
||||
Limited,
|
||||
};
|
||||
|
||||
void setSession( SessionState session )
|
||||
{
|
||||
m_session = session;
|
||||
}
|
||||
|
||||
SessionState getSession()
|
||||
{
|
||||
return m_session;
|
||||
}
|
||||
|
||||
void sessionCleanup();
|
||||
|
||||
void clearKeyModifiers();
|
||||
|
||||
@@ -131,6 +154,8 @@ public slots:
|
||||
void undo();
|
||||
void redo();
|
||||
|
||||
void autoSave();
|
||||
void runAutoSave();
|
||||
|
||||
protected:
|
||||
virtual void closeEvent( QCloseEvent * _ce );
|
||||
@@ -150,7 +175,6 @@ private:
|
||||
void toggleWindow( QWidget *window, bool forceShow = false );
|
||||
void refocus();
|
||||
|
||||
|
||||
QMdiArea * m_workspace;
|
||||
|
||||
QWidget * m_toolBar;
|
||||
@@ -187,6 +211,8 @@ private:
|
||||
|
||||
ToolButton * m_metronomeToggle;
|
||||
|
||||
SessionState m_session;
|
||||
|
||||
private slots:
|
||||
void browseHelp();
|
||||
void fillTemplatesMenu();
|
||||
@@ -198,8 +224,6 @@ private slots:
|
||||
void onToggleMetronome();
|
||||
|
||||
|
||||
void autoSave();
|
||||
|
||||
signals:
|
||||
void periodicUpdate();
|
||||
void initProgress(const QString &msg);
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <QTranslator>
|
||||
#include <QApplication>
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#include <QTextStream>
|
||||
|
||||
#ifdef LMMS_BUILD_WIN32
|
||||
@@ -61,6 +62,7 @@
|
||||
#include "MemoryManager.h"
|
||||
#include "ConfigManager.h"
|
||||
#include "NotePlayHandle.h"
|
||||
#include "embed.h"
|
||||
#include "Engine.h"
|
||||
#include "GuiApplication.h"
|
||||
#include "ImportFilter.h"
|
||||
@@ -644,13 +646,102 @@ int main( int argc, char * * argv )
|
||||
// recover a file?
|
||||
QString recoveryFile = ConfigManager::inst()->recoveryFile();
|
||||
|
||||
if( QFileInfo(recoveryFile).exists() &&
|
||||
QMessageBox::question( gui->mainWindow(), MainWindow::tr( "Project recovery" ),
|
||||
MainWindow::tr( "It looks like the last session did not end properly. "
|
||||
"Do you want to recover the project of this session?" ),
|
||||
QMessageBox::Yes | QMessageBox::No ) == QMessageBox::Yes )
|
||||
bool recoveryFilePresent = QFileInfo( recoveryFile ).exists() &&
|
||||
QFileInfo( recoveryFile ).isFile();
|
||||
bool autoSaveEnabled =
|
||||
ConfigManager::inst()->value( "ui", "enableautosave" ).toInt();
|
||||
if( recoveryFilePresent )
|
||||
{
|
||||
fileToLoad = recoveryFile;
|
||||
QMessageBox mb;
|
||||
mb.setWindowTitle( MainWindow::tr( "Project recovery" ) );
|
||||
mb.setText( QString(
|
||||
"<html>"
|
||||
"<p style=\"margin-left:6\">%1</p>"
|
||||
"<table cellpadding=\"3\">"
|
||||
" <tr>"
|
||||
" <td><b>%2</b></td>"
|
||||
" <td>%3</td>"
|
||||
" </tr>"
|
||||
" <tr>"
|
||||
" <td><b>%4</b></td>"
|
||||
" <td>%5</td>"
|
||||
" </tr>"
|
||||
" <tr>"
|
||||
" <td><b>%6</b></td>"
|
||||
" <td>%7</td>"
|
||||
" </tr>"
|
||||
" <tr>"
|
||||
" <td><b>%8</b></td>"
|
||||
" <td>%9</td>"
|
||||
" </tr>"
|
||||
"</table>"
|
||||
"</html>" ).arg(
|
||||
MainWindow::tr( "There is a recovery file present. "
|
||||
"It looks like the last session did not end "
|
||||
"properly or another instance of LMMS is "
|
||||
"already running. Do you want to recover the "
|
||||
"project of this session?" ),
|
||||
MainWindow::tr( "Recover" ),
|
||||
MainWindow::tr( "Recover the file. Please don't run "
|
||||
"multiple instances of LMMS when you do this." ),
|
||||
MainWindow::tr( "Ignore" ),
|
||||
MainWindow::tr( "Launch LMMS as usual but with "
|
||||
"automatic backup disabled to prevent the "
|
||||
"present recover file from being overwritten." ),
|
||||
MainWindow::tr( "Discard" ),
|
||||
MainWindow::tr( "Launch a default session and delete "
|
||||
"the restored files. This is not reversible." ),
|
||||
MainWindow::tr( "Quit" ),
|
||||
MainWindow::tr( "Shut down LMMS with no further action." )
|
||||
) );
|
||||
|
||||
mb.setIcon( QMessageBox::Warning );
|
||||
mb.setWindowIcon( embed::getIconPixmap( "icon" ) );
|
||||
|
||||
mb.setStandardButtons( QMessageBox::Ok |
|
||||
QMessageBox::Discard );
|
||||
|
||||
mb.setButtonText( QMessageBox::Ok,
|
||||
MainWindow::tr( "Recover" ) );
|
||||
|
||||
QAbstractButton * recover;
|
||||
QAbstractButton * discard;
|
||||
QPushButton * ignore;
|
||||
QPushButton * exit;
|
||||
|
||||
recover = mb.QMessageBox::button( QMessageBox::Ok );
|
||||
discard = mb.QMessageBox::button( QMessageBox::Discard );
|
||||
ignore = mb.addButton( MainWindow::tr( "Ignore" ),
|
||||
QMessageBox::NoRole );
|
||||
ignore->setIcon( embed::getIconPixmap( "no_entry" ) );
|
||||
exit = mb.addButton( MainWindow::tr( "Exit" ),
|
||||
QMessageBox::RejectRole );
|
||||
exit->setIcon( embed::getIconPixmap( "exit" ) );
|
||||
|
||||
mb.setDefaultButton( QMessageBox::Ok );
|
||||
mb.setEscapeButton( exit );
|
||||
|
||||
mb.exec();
|
||||
if( mb.clickedButton() == discard )
|
||||
{
|
||||
gui->mainWindow()->sessionCleanup();
|
||||
}
|
||||
else if( mb.clickedButton() == recover ) // ::Recover
|
||||
{
|
||||
fileToLoad = recoveryFile;
|
||||
gui->mainWindow()->setSession( MainWindow::SessionState::Recover );
|
||||
}
|
||||
else if( mb.clickedButton() == ignore )
|
||||
{
|
||||
if( autoSaveEnabled )
|
||||
{
|
||||
gui->mainWindow()->setSession( MainWindow::SessionState::Limited );
|
||||
}
|
||||
}
|
||||
else // Exit
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// we try to load given file
|
||||
@@ -689,10 +780,13 @@ int main( int argc, char * * argv )
|
||||
{
|
||||
|
||||
// If enabled, open last project if there is one. Else, create
|
||||
// a new one.
|
||||
// a new one. Also skip recently opened file if limited session to
|
||||
// lower the chance of opening an already opened file.
|
||||
if( ConfigManager::inst()->
|
||||
value( "app", "openlastproject" ).toInt() &&
|
||||
!ConfigManager::inst()->recentlyOpenedProjects().isEmpty() )
|
||||
!ConfigManager::inst()->recentlyOpenedProjects().isEmpty() &&
|
||||
gui->mainWindow()->getSession()
|
||||
!= MainWindow::SessionState::Limited )
|
||||
{
|
||||
QString f = ConfigManager::inst()->
|
||||
recentlyOpenedProjects().first();
|
||||
@@ -720,6 +814,15 @@ int main( int argc, char * * argv )
|
||||
gui->mainWindow()->showMaximized();
|
||||
}
|
||||
}
|
||||
// Finally we start the auto save timer and also trigger the
|
||||
// autosave one time as recover.mmp is a signal to possible other
|
||||
// instances of LMMS.
|
||||
if( autoSaveEnabled &&
|
||||
gui->mainWindow()->getSession() != MainWindow::SessionState::Limited )
|
||||
{
|
||||
gui->mainWindow()->runAutoSave();
|
||||
gui->mainWindow()->autoSaveTimerStart();
|
||||
}
|
||||
}
|
||||
|
||||
const int ret = app->exec();
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <QCloseEvent>
|
||||
#include <QDesktopServices>
|
||||
#include <QDomElement>
|
||||
#include <QFileInfo>
|
||||
#include <QMdiArea>
|
||||
#include <QMdiSubWindow>
|
||||
#include <QMenuBar>
|
||||
@@ -79,7 +80,8 @@ MainWindow::MainWindow() :
|
||||
m_toolsMenu( NULL ),
|
||||
m_autoSaveTimer( this ),
|
||||
m_viewMenu( NULL ),
|
||||
m_metronomeToggle( 0 )
|
||||
m_metronomeToggle( 0 ),
|
||||
m_session( Normal )
|
||||
{
|
||||
setAttribute( Qt::WA_DeleteOnClose );
|
||||
|
||||
@@ -201,7 +203,10 @@ MainWindow::MainWindow() :
|
||||
{
|
||||
// connect auto save
|
||||
connect(&m_autoSaveTimer, SIGNAL(timeout()), this, SLOT(autoSave()));
|
||||
m_autoSaveTimer.start(1000 * 60); // 1 minute
|
||||
// The auto save function mustn't run until there is a project
|
||||
// to save or it will run over recover.mmp if you hesitate at the
|
||||
// recover messagebox for a minute. It is now started in main.
|
||||
// See autoSaveTimerStart() in MainWindow.h
|
||||
}
|
||||
|
||||
connect( Engine::getSong(), SIGNAL( playbackStateChanged() ),
|
||||
@@ -650,6 +655,14 @@ void MainWindow::resetWindowTitle()
|
||||
{
|
||||
title += '*';
|
||||
}
|
||||
if( getSession() == Recover )
|
||||
{
|
||||
title += " - " + tr( "Recover session. Please save your work!" );
|
||||
}
|
||||
if( getSession() == Limited )
|
||||
{
|
||||
title += " - " + tr( "Automatic backup disabled. Remember to save your work!" );
|
||||
}
|
||||
setWindowTitle( title + " - " + tr( "LMMS %1" ).arg( LMMS_VERSION ) );
|
||||
}
|
||||
|
||||
@@ -659,17 +672,31 @@ void MainWindow::resetWindowTitle()
|
||||
bool MainWindow::mayChangeProject(bool stopPlayback)
|
||||
{
|
||||
if( stopPlayback )
|
||||
{
|
||||
Engine::getSong()->stop();
|
||||
}
|
||||
|
||||
if( !Engine::getSong()->isModified() )
|
||||
if( !Engine::getSong()->isModified() && getSession() != Recover )
|
||||
{
|
||||
return( true );
|
||||
}
|
||||
|
||||
QMessageBox mb( tr( "Project not saved" ),
|
||||
tr( "The current project was modified since "
|
||||
// Separate message strings for modified and recovered files
|
||||
QString messageTitleRecovered = tr( "Recovered project not saved" );
|
||||
QString messageRecovered = tr( "This project was recovered from the "
|
||||
"previous session. It is currently "
|
||||
"unsaved and will be lost if you don't "
|
||||
"save it. Do you want to save it now?" );
|
||||
|
||||
QString messageTitleUnsaved = tr( "Project not saved" );
|
||||
QString messageUnsaved = tr( "The current project was modified since "
|
||||
"last saving. Do you want to save it "
|
||||
"now?" ),
|
||||
"now?" );
|
||||
|
||||
QMessageBox mb( ( getSession() == Recover ?
|
||||
messageTitleRecovered : messageTitleUnsaved ),
|
||||
( getSession() == Recover ?
|
||||
messageRecovered : messageUnsaved ),
|
||||
QMessageBox::Question,
|
||||
QMessageBox::Save,
|
||||
QMessageBox::Discard,
|
||||
@@ -683,6 +710,10 @@ bool MainWindow::mayChangeProject(bool stopPlayback)
|
||||
}
|
||||
else if( answer == QMessageBox::Discard )
|
||||
{
|
||||
if( getSession() == Recover )
|
||||
{
|
||||
sessionCleanup();
|
||||
}
|
||||
return( true );
|
||||
}
|
||||
|
||||
@@ -789,6 +820,7 @@ void MainWindow::createNewProject()
|
||||
{
|
||||
Engine::getSong()->createNewProject();
|
||||
}
|
||||
runAutoSave();
|
||||
}
|
||||
|
||||
|
||||
@@ -807,6 +839,7 @@ void MainWindow::createNewProjectFromTemplate( QAction * _idx )
|
||||
Engine::getSong()->createNewProjectFromTemplate(
|
||||
dirBase + _idx->text() + ".mpt" );
|
||||
}
|
||||
runAutoSave();
|
||||
}
|
||||
|
||||
|
||||
@@ -831,6 +864,7 @@ void MainWindow::openProject()
|
||||
setCursor( Qt::ArrowCursor );
|
||||
}
|
||||
}
|
||||
runAutoSave();
|
||||
}
|
||||
|
||||
|
||||
@@ -874,6 +908,7 @@ void MainWindow::openRecentlyOpenedProject( QAction * _action )
|
||||
ConfigManager::inst()->addRecentlyOpenedProject( f );
|
||||
setCursor( Qt::ArrowCursor );
|
||||
}
|
||||
runAutoSave();
|
||||
}
|
||||
|
||||
|
||||
@@ -888,6 +923,10 @@ bool MainWindow::saveProject()
|
||||
else
|
||||
{
|
||||
Engine::getSong()->guiSaveProject();
|
||||
if( getSession() == Recover )
|
||||
{
|
||||
sessionCleanup();
|
||||
}
|
||||
}
|
||||
return( true );
|
||||
}
|
||||
@@ -919,8 +958,11 @@ bool MainWindow::saveProjectAs()
|
||||
{
|
||||
fname += ".mpt";
|
||||
}
|
||||
Engine::getSong()->guiSaveProjectAs(
|
||||
fname );
|
||||
Engine::getSong()->guiSaveProjectAs( fname );
|
||||
if( getSession() == Recover )
|
||||
{
|
||||
sessionCleanup();
|
||||
}
|
||||
return( true );
|
||||
}
|
||||
return( false );
|
||||
@@ -1189,6 +1231,8 @@ void MainWindow::updateViewMenu()
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void MainWindow::updateConfig( QAction * _who )
|
||||
{
|
||||
QString tag = _who->data().toString();
|
||||
@@ -1306,8 +1350,12 @@ void MainWindow::closeEvent( QCloseEvent * _ce )
|
||||
if( mayChangeProject(true) )
|
||||
{
|
||||
// delete recovery file
|
||||
QFile::remove(ConfigManager::inst()->recoveryFile());
|
||||
_ce->accept();
|
||||
if( ConfigManager::inst()->value( "ui", "enableautosave" ).toInt()
|
||||
&& getSession() != Limited )
|
||||
{
|
||||
sessionCleanup();
|
||||
_ce->accept();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1318,6 +1366,16 @@ void MainWindow::closeEvent( QCloseEvent * _ce )
|
||||
|
||||
|
||||
|
||||
void MainWindow::sessionCleanup()
|
||||
{
|
||||
// delete recover session files
|
||||
QFile::remove( ConfigManager::inst()->recoveryFile() );
|
||||
setSession( Normal );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void MainWindow::focusOutEvent( QFocusEvent * _fe )
|
||||
{
|
||||
// when loosing focus we do not receive key-(release!)-events anymore,
|
||||
@@ -1459,3 +1517,15 @@ void MainWindow::autoSave()
|
||||
QTimer::singleShot( 10*1000, this, SLOT( autoSave() ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// For the occasional auto save action that isn't run
|
||||
// from the timer where we need to do extra tests.
|
||||
void MainWindow::runAutoSave()
|
||||
{
|
||||
if( ConfigManager::inst()->value( "ui", "enableautosave" ).toInt() &&
|
||||
getSession() != Limited )
|
||||
{
|
||||
autoSave();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user