2017-04-07 10:02:27 +02:00
/* ============================================================
2017-08-25 17:11:29 +02:00
* Falkon - Qt web browser
2018-01-02 12:56:10 +01:00
* Copyright ( C ) 2017 Razi Alavizadeh < s . r . alavizadeh @ gmail . com >
* Copyright ( C ) 2018 David Rosca < nowrep @ gmail . com >
2017-04-07 10:02:27 +02:00
*
* 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 3 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 , see < http : //www.gnu.org/licenses/>.
* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
# include "browserwindow.h"
# include "datapaths.h"
# include "mainapplication.h"
# include "restoremanager.h"
# include "sessionmanager.h"
2017-06-08 14:12:54 +02:00
# include "sessionmanagerdialog.h"
2017-04-07 10:02:27 +02:00
# include "settings.h"
# include <QAction>
# include <QComboBox>
# include <QDateTime>
# include <QDialogButtonBox>
# include <QDir>
# include <QFileSystemWatcher>
# include <QInputDialog>
# include <QLabel>
# include <QMenu>
# include <QMessageBox>
# include <QVBoxLayout>
2017-06-08 10:04:45 +02:00
# include <QSaveFile>
2017-04-07 10:02:27 +02:00
SessionManager : : SessionManager ( QObject * parent )
: QObject ( parent )
, m_firstBackupSession ( DataPaths : : currentProfilePath ( ) + QL1S ( " /session.dat.old " ) )
, m_secondBackupSession ( DataPaths : : currentProfilePath ( ) + QL1S ( " /session.dat.old1 " ) )
{
QFileSystemWatcher * sessionFilesWatcher = new QFileSystemWatcher ( { DataPaths : : path ( DataPaths : : Sessions ) } , this ) ;
connect ( sessionFilesWatcher , SIGNAL ( directoryChanged ( QString ) ) , this , SLOT ( sessionsDirectoryChanged ( ) ) ) ;
2017-06-08 14:12:54 +02:00
connect ( sessionFilesWatcher , & QFileSystemWatcher : : directoryChanged , this , & SessionManager : : sessionsMetaDataChanged ) ;
2017-04-07 10:02:27 +02:00
loadSettings ( ) ;
}
void SessionManager : : aboutToShowSessionsMenu ( )
{
QMenu * menu = qobject_cast < QMenu * > ( sender ( ) ) ;
menu - > clear ( ) ;
2017-06-08 14:12:54 +02:00
QActionGroup * group = new QActionGroup ( menu ) ;
const auto sessions = sessionMetaData ( /*withBackups*/ false ) ;
for ( const SessionManager : : SessionMetaData & metaData : sessions ) {
QAction * action = menu - > addAction ( metaData . name ) ;
action - > setCheckable ( true ) ;
action - > setChecked ( metaData . isActive ) ;
group - > addAction ( action ) ;
connect ( action , & QAction : : triggered , this , [ = ] ( ) {
switchToSession ( metaData . filePath ) ;
} ) ;
2017-04-07 10:02:27 +02:00
}
}
void SessionManager : : sessionsDirectoryChanged ( )
{
m_sessionsMetaDataList . clear ( ) ;
}
2017-06-08 14:56:52 +02:00
void SessionManager : : openSession ( QString sessionFilePath , SessionFlags flags )
2017-04-07 10:02:27 +02:00
{
if ( sessionFilePath . isEmpty ( ) ) {
QAction * action = qobject_cast < QAction * > ( sender ( ) ) ;
if ( ! action )
return ;
sessionFilePath = action - > data ( ) . toString ( ) ;
}
2017-06-08 14:12:54 +02:00
if ( isActive ( sessionFilePath ) ) {
return ;
}
2018-01-02 12:56:10 +01:00
RestoreData sessionData ;
2017-04-07 10:02:27 +02:00
RestoreManager : : createFromFile ( sessionFilePath , sessionData ) ;
2018-01-03 11:39:49 +01:00
if ( ! sessionData . isValid ( ) )
2017-04-07 10:02:27 +02:00
return ;
BrowserWindow * window = mApp - > getWindow ( ) ;
2017-06-08 14:56:52 +02:00
if ( flags . testFlag ( SwitchSession ) ) {
2017-04-07 10:02:27 +02:00
writeCurrentSession ( m_lastActiveSessionPath ) ;
window = mApp - > createWindow ( Qz : : BW_OtherRestoredWindow ) ;
for ( BrowserWindow * win : mApp - > windows ( ) ) {
if ( win ! = window )
win - > close ( ) ;
}
2017-06-08 14:56:52 +02:00
if ( ! flags . testFlag ( ReplaceSession ) ) {
m_lastActiveSessionPath = QFileInfo ( sessionFilePath ) . canonicalFilePath ( ) ;
m_sessionsMetaDataList . clear ( ) ;
}
2017-04-07 10:02:27 +02:00
}
mApp - > openSession ( window , sessionData ) ;
}
2017-06-08 14:56:52 +02:00
void SessionManager : : renameSession ( QString sessionFilePath , SessionFlags flags )
2017-04-07 10:02:27 +02:00
{
if ( sessionFilePath . isEmpty ( ) ) {
QAction * action = qobject_cast < QAction * > ( sender ( ) ) ;
if ( ! action )
return ;
sessionFilePath = action - > data ( ) . toString ( ) ;
}
bool ok ;
2017-06-08 14:56:52 +02:00
const QString suggestedName = QFileInfo ( sessionFilePath ) . baseName ( ) + ( flags . testFlag ( CloneSession ) ? tr ( " _cloned " ) : tr ( " _renamed " ) ) ;
QString newName = QInputDialog : : getText ( mApp - > activeWindow ( ) , ( flags . testFlag ( CloneSession ) ? tr ( " Clone Session " ) : tr ( " Rename Session " ) ) ,
2017-04-07 10:02:27 +02:00
tr ( " Please enter a new name: " ) , QLineEdit : : Normal ,
suggestedName , & ok ) ;
if ( ! ok )
return ;
const QString newSessionPath = QString ( " %1/%2.dat " ) . arg ( DataPaths : : path ( DataPaths : : Sessions ) ) . arg ( newName ) ;
if ( QFile : : exists ( newSessionPath ) ) {
QMessageBox : : information ( mApp - > activeWindow ( ) , tr ( " Error! " ) , tr ( " The session file \" %1 \" exists. Please enter another name. " ) . arg ( newName ) ) ;
2017-06-08 14:56:52 +02:00
renameSession ( sessionFilePath , flags ) ;
2017-04-07 10:02:27 +02:00
return ;
}
2017-06-08 14:56:52 +02:00
if ( flags . testFlag ( CloneSession ) ) {
2017-04-07 10:02:27 +02:00
if ( ! QFile : : copy ( sessionFilePath , newSessionPath ) ) {
QMessageBox : : information ( mApp - > activeWindow ( ) , tr ( " Error! " ) , tr ( " An error occurred when cloning session file. " ) ) ;
return ;
}
2017-06-08 14:12:54 +02:00
} else {
if ( ! QFile : : rename ( sessionFilePath , newSessionPath ) ) {
QMessageBox : : information ( mApp - > activeWindow ( ) , tr ( " Error! " ) , tr ( " An error occurred when renaming session file. " ) ) ;
return ;
}
if ( isActive ( sessionFilePath ) ) {
m_lastActiveSessionPath = newSessionPath ;
m_sessionsMetaDataList . clear ( ) ;
}
2017-04-07 10:02:27 +02:00
}
}
void SessionManager : : saveSession ( )
{
bool ok ;
QString sessionName = QInputDialog : : getText ( mApp - > activeWindow ( ) , tr ( " Save Session " ) ,
tr ( " Please enter a name to save session: " ) , QLineEdit : : Normal ,
tr ( " Saved Session (%1) " ) . arg ( QDateTime : : currentDateTime ( ) . toString ( " dd MMM yyyy HH-mm-ss " ) ) , & ok ) ;
if ( ! ok )
return ;
const QString filePath = QString ( " %1/%2.dat " ) . arg ( DataPaths : : path ( DataPaths : : Sessions ) ) . arg ( sessionName ) ;
if ( QFile : : exists ( filePath ) ) {
QMessageBox : : information ( mApp - > activeWindow ( ) , tr ( " Error! " ) , tr ( " The session file \" %1 \" exists. Please enter another name. " ) . arg ( sessionName ) ) ;
saveSession ( ) ;
return ;
}
writeCurrentSession ( filePath ) ;
}
2017-06-08 14:56:52 +02:00
void SessionManager : : replaceSession ( const QString & filePath )
{
QMessageBox : : StandardButton result = QMessageBox : : information ( mApp - > activeWindow ( ) , tr ( " Restore Backup " ) , tr ( " Are you sure you want to replace current session? " ) ,
QMessageBox : : Yes | QMessageBox : : No ) ;
if ( result = = QMessageBox : : Yes ) {
openSession ( filePath , ReplaceSession ) ;
}
}
2017-06-08 14:12:54 +02:00
void SessionManager : : switchToSession ( const QString & filePath )
{
2017-06-08 14:56:52 +02:00
openSession ( filePath , SwitchSession ) ;
2017-06-08 14:12:54 +02:00
}
void SessionManager : : cloneSession ( const QString & filePath )
{
2017-06-08 14:56:52 +02:00
renameSession ( filePath , CloneSession ) ;
2017-06-08 14:12:54 +02:00
}
void SessionManager : : deleteSession ( const QString & filePath )
{
2017-06-08 14:59:40 +02:00
QMessageBox : : StandardButton result = QMessageBox : : information ( mApp - > activeWindow ( ) , tr ( " Delete Session " ) , tr ( " Are you sure you want to delete session '%1'? " )
. arg ( QFileInfo ( filePath ) . baseName ( ) ) , QMessageBox : : Yes | QMessageBox : : No ) ;
2017-06-08 14:12:54 +02:00
if ( result = = QMessageBox : : Yes ) {
QFile : : remove ( filePath ) ;
}
}
2017-04-07 10:02:27 +02:00
void SessionManager : : newSession ( )
{
bool ok ;
QString sessionName = QInputDialog : : getText ( mApp - > activeWindow ( ) , tr ( " New Session " ) ,
tr ( " Please enter a name to create new session: " ) , QLineEdit : : Normal ,
tr ( " New Session (%1) " ) . arg ( QDateTime : : currentDateTime ( ) . toString ( " dd MMM yyyy HH-mm-ss " ) ) , & ok ) ;
if ( ! ok )
return ;
const QString filePath = QString ( " %1/%2.dat " ) . arg ( DataPaths : : path ( DataPaths : : Sessions ) ) . arg ( sessionName ) ;
if ( QFile : : exists ( filePath ) ) {
QMessageBox : : information ( mApp - > activeWindow ( ) , tr ( " Error! " ) , tr ( " The session file \" %1 \" exists. Please enter another name. " ) . arg ( sessionName ) ) ;
newSession ( ) ;
return ;
}
writeCurrentSession ( m_lastActiveSessionPath ) ;
BrowserWindow * window = mApp - > createWindow ( Qz : : BW_NewWindow ) ;
for ( BrowserWindow * win : mApp - > windows ( ) ) {
if ( win ! = window )
win - > close ( ) ;
}
m_lastActiveSessionPath = filePath ;
autoSaveLastSession ( ) ;
}
2017-06-08 14:12:54 +02:00
QList < SessionManager : : SessionMetaData > SessionManager : : sessionMetaData ( bool withBackups )
{
fillSessionsMetaDataListIfNeeded ( ) ;
auto out = m_sessionsMetaDataList ;
if ( withBackups & & QFile : : exists ( m_firstBackupSession ) ) {
SessionMetaData data ;
2017-06-08 14:56:52 +02:00
data . name = tr ( " Backup 1 " ) ;
2017-06-08 14:12:54 +02:00
data . filePath = m_firstBackupSession ;
data . isBackup = true ;
out . append ( data ) ;
}
if ( withBackups & & QFile : : exists ( m_secondBackupSession ) ) {
SessionMetaData data ;
2017-06-08 14:56:52 +02:00
data . name = tr ( " Backup 2 " ) ;
2017-06-08 14:12:54 +02:00
data . filePath = m_secondBackupSession ;
data . isBackup = true ;
out . append ( data ) ;
}
return out ;
}
bool SessionManager : : isActive ( const QString & filePath ) const
{
return QFileInfo ( filePath ) = = QFileInfo ( m_lastActiveSessionPath ) ;
}
bool SessionManager : : isActive ( const QFileInfo & fileInfo ) const
{
return fileInfo = = QFileInfo ( m_lastActiveSessionPath ) ;
}
2017-04-07 10:02:27 +02:00
void SessionManager : : fillSessionsMetaDataListIfNeeded ( )
{
if ( ! m_sessionsMetaDataList . isEmpty ( ) )
return ;
QDir dir ( DataPaths : : path ( DataPaths : : Sessions ) ) ;
const QFileInfoList sessionFiles = QFileInfoList ( ) < < QFileInfo ( defaultSessionPath ( ) ) < < dir . entryInfoList ( { QSL ( " *.* " ) } , QDir : : Files , QDir : : Time ) ;
QStringList fileNames ;
for ( int i = 0 ; i < sessionFiles . size ( ) ; + + i ) {
const QFileInfo & fileInfo = sessionFiles . at ( i ) ;
2018-01-03 11:06:21 +01:00
if ( ! RestoreManager : : validateFile ( fileInfo . absoluteFilePath ( ) ) )
2017-04-07 10:02:27 +02:00
continue ;
SessionMetaData metaData ;
metaData . name = fileInfo . baseName ( ) ;
2017-06-08 14:12:54 +02:00
if ( fileInfo = = QFileInfo ( defaultSessionPath ( ) ) ) {
2017-04-07 10:02:27 +02:00
metaData . name = tr ( " Default Session " ) ;
2017-06-08 14:12:54 +02:00
metaData . isDefault = true ;
} else if ( fileNames . contains ( fileInfo . baseName ( ) ) ) {
2017-04-07 10:02:27 +02:00
metaData . name = fileInfo . fileName ( ) ;
2017-06-08 14:12:54 +02:00
} else {
2017-04-07 10:02:27 +02:00
metaData . name = fileInfo . baseName ( ) ;
2017-06-08 14:12:54 +02:00
}
if ( isActive ( fileInfo ) ) {
metaData . isActive = true ;
}
2017-04-07 10:02:27 +02:00
fileNames < < metaData . name ;
metaData . filePath = fileInfo . canonicalFilePath ( ) ;
m_sessionsMetaDataList < < metaData ;
}
}
void SessionManager : : loadSettings ( )
{
2018-01-02 20:56:08 +01:00
QDir sessionsDir ( DataPaths : : path ( DataPaths : : Sessions ) ) ;
2017-04-07 10:02:27 +02:00
Settings settings ;
settings . beginGroup ( " Web-Browser-Settings " ) ;
m_lastActiveSessionPath = settings . value ( " lastActiveSessionPath " , defaultSessionPath ( ) ) . toString ( ) ;
settings . endGroup ( ) ;
2018-01-02 20:56:08 +01:00
if ( QDir : : isRelativePath ( m_lastActiveSessionPath ) ) {
m_lastActiveSessionPath = sessionsDir . absoluteFilePath ( m_lastActiveSessionPath ) ;
}
2018-01-03 11:06:21 +01:00
// Fallback to default session
if ( ! RestoreManager : : validateFile ( m_lastActiveSessionPath ) )
2017-04-07 10:02:27 +02:00
m_lastActiveSessionPath = defaultSessionPath ( ) ;
}
void SessionManager : : saveSettings ( )
{
2018-01-02 20:56:08 +01:00
QDir sessionsDir ( DataPaths : : path ( DataPaths : : Sessions ) ) ;
2017-04-07 10:02:27 +02:00
Settings settings ;
settings . beginGroup ( " Web-Browser-Settings " ) ;
2018-01-02 20:56:08 +01:00
settings . setValue ( " lastActiveSessionPath " , sessionsDir . relativeFilePath ( m_lastActiveSessionPath ) ) ;
2017-04-07 10:02:27 +02:00
settings . endGroup ( ) ;
}
QString SessionManager : : defaultSessionPath ( )
{
return DataPaths : : currentProfilePath ( ) + QL1S ( " /session.dat " ) ;
}
QString SessionManager : : lastActiveSessionPath ( ) const
{
return m_lastActiveSessionPath ;
}
void SessionManager : : backupSavedSessions ( )
{
if ( ! QFile : : exists ( m_lastActiveSessionPath ) ) {
return ;
}
if ( QFile : : exists ( m_firstBackupSession ) ) {
QFile : : remove ( m_secondBackupSession ) ;
QFile : : copy ( m_firstBackupSession , m_secondBackupSession ) ;
}
QFile : : remove ( m_firstBackupSession ) ;
QFile : : copy ( m_lastActiveSessionPath , m_firstBackupSession ) ;
}
void SessionManager : : writeCurrentSession ( const QString & filePath )
{
2017-06-08 10:04:45 +02:00
QSaveFile file ( filePath ) ;
2017-04-07 10:02:27 +02:00
if ( ! file . open ( QIODevice : : WriteOnly ) | | file . write ( mApp - > saveState ( ) ) = = - 1 ) {
qWarning ( ) < < " Error! can not write the current session file: " < < filePath < < file . errorString ( ) ;
return ;
}
2017-06-08 10:04:45 +02:00
file . commit ( ) ;
2017-04-07 10:02:27 +02:00
}
2017-06-08 14:12:54 +02:00
void SessionManager : : openSessionManagerDialog ( )
{
SessionManagerDialog * dialog = new SessionManagerDialog ( mApp - > getWindow ( ) ) ;
dialog - > open ( ) ;
}
2017-04-07 10:02:27 +02:00
void SessionManager : : autoSaveLastSession ( )
{
if ( mApp - > isPrivate ( ) | | mApp - > isRestoring ( ) | | mApp - > windowCount ( ) = = 0 | | mApp - > restoreManager ( ) ) {
return ;
}
saveSettings ( ) ;
writeCurrentSession ( m_lastActiveSessionPath ) ;
}
QString SessionManager : : askSessionFromUser ( )
{
fillSessionsMetaDataListIfNeeded ( ) ;
QDialog dialog ( mApp - > getWindow ( ) , Qt : : WindowStaysOnTopHint ) ;
QLabel label ( tr ( " Please select the startup session: " ) , & dialog ) ;
QComboBox comboBox ( & dialog ) ;
QDialogButtonBox buttonBox ( QDialogButtonBox : : Ok | QDialogButtonBox : : Cancel , & dialog ) ;
connect ( & buttonBox , & QDialogButtonBox : : accepted , & dialog , & QDialog : : accept ) ;
connect ( & buttonBox , & QDialogButtonBox : : rejected , & dialog , & QDialog : : reject ) ;
QVBoxLayout layout ;
layout . addWidget ( & label ) ;
layout . addWidget ( & comboBox ) ;
layout . addWidget ( & buttonBox ) ;
dialog . setLayout ( & layout ) ;
const QFileInfo lastActiveSessionFileInfo ( m_lastActiveSessionPath ) ;
for ( const SessionMetaData & metaData : m_sessionsMetaDataList ) {
if ( QFileInfo ( metaData . filePath ) ! = lastActiveSessionFileInfo ) {
comboBox . addItem ( metaData . name , metaData . filePath ) ;
}
else {
comboBox . insertItem ( 0 , tr ( " %1 (last session) " ) . arg ( metaData . name ) , metaData . filePath ) ;
}
}
comboBox . setCurrentIndex ( 0 ) ;
if ( dialog . exec ( ) = = QDialog : : Accepted ) {
m_lastActiveSessionPath = comboBox . currentData ( ) . toString ( ) ;
}
return m_lastActiveSessionPath ;
}