28#include <QActionGroup>
31#include <QDialogButtonBox>
33#include <QFileSystemWatcher>
34#include <QInputDialog>
43 , m_firstBackupSession(
DataPaths::currentProfilePath() +
QL1S(
"/session.dat.old"))
44 , m_secondBackupSession(
DataPaths::currentProfilePath() +
QL1S(
"/session.dat.old1"))
47 connect(sessionFilesWatcher, &QFileSystemWatcher::directoryChanged,
this, &SessionManager::sessionsDirectoryChanged);
53void SessionManager::aboutToShowSessionsMenu()
55 auto* menu = qobject_cast<QMenu*>(sender());
58 auto *group =
new QActionGroup(menu);
60 const auto sessions = sessionMetaData(
false);
62 QAction* action = menu->addAction(metaData.name);
63 action->setCheckable(
true);
64 action->setChecked(metaData.isActive);
65 group->addAction(action);
66 connect(action, &QAction::triggered,
this, [=]() {
67 switchToSession(metaData.filePath);
72void SessionManager::sessionsDirectoryChanged()
74 m_sessionsMetaDataList.clear();
77void SessionManager::openSession(QString sessionFilePath, SessionManager::SessionFlags flags)
79 if (sessionFilePath.isEmpty()) {
80 auto* action = qobject_cast<QAction*>(sender());
84 sessionFilePath = action->data().toString();
87 if (isActive(sessionFilePath)) {
108 m_lastActiveSessionPath = QFileInfo(sessionFilePath).canonicalFilePath();
109 m_sessionsMetaDataList.clear();
113 mApp->openSession(window, sessionData);
116void SessionManager::renameSession(QString sessionFilePath, SessionManager::SessionFlags flags)
118 if (sessionFilePath.isEmpty()) {
119 auto* action = qobject_cast<QAction*>(sender());
123 sessionFilePath = action->data().toString();
127 const QString suggestedName = QFileInfo(sessionFilePath).completeBaseName() + (flags.testFlag(
CloneSession) ? tr(
"_cloned") : tr(
"_renamed"));
128 QString newName = QInputDialog::getText(
mApp->activeWindow(), (flags.testFlag(
CloneSession) ? tr(
"Clone Session") : tr(
"Rename Session")),
129 tr(
"Please enter a new name:"), QLineEdit::Normal,
136 if (QFile::exists(newSessionPath)) {
137 QMessageBox::information(
mApp->activeWindow(), tr(
"Error!"), tr(
"The session file \"%1\" exists. Please enter another name.").arg(newName));
138 renameSession(sessionFilePath, flags);
143 if (!QFile::copy(sessionFilePath, newSessionPath)) {
144 QMessageBox::information(
mApp->activeWindow(), tr(
"Error!"), tr(
"An error occurred when cloning session file."));
148 if (!QFile::rename(sessionFilePath, newSessionPath)) {
149 QMessageBox::information(
mApp->activeWindow(), tr(
"Error!"), tr(
"An error occurred when renaming session file."));
152 if (isActive(sessionFilePath)) {
153 m_lastActiveSessionPath = newSessionPath;
154 m_sessionsMetaDataList.clear();
159void SessionManager::saveSession()
162 QString sessionName = QInputDialog::getText(
mApp->activeWindow(), tr(
"Save Session"),
163 tr(
"Please enter a name to save session:"), QLineEdit::Normal,
164 tr(
"Saved Session (%1)").arg(QDateTime::currentDateTime().toString(
QSL(
"dd MMM yyyy HH-mm-ss"))), &ok);
170 if (QFile::exists(filePath)) {
171 QMessageBox::information(
mApp->activeWindow(), tr(
"Error!"), tr(
"The session file \"%1\" exists. Please enter another name.").arg(sessionName));
179void SessionManager::replaceSession(
const QString &filePath)
181 QMessageBox::StandardButton result = QMessageBox::information(
mApp->activeWindow(), tr(
"Restore Backup"), tr(
"Are you sure you want to replace current session?"),
182 QMessageBox::Yes | QMessageBox::No);
183 if (result == QMessageBox::Yes) {
188void SessionManager::switchToSession(
const QString &filePath)
193void SessionManager::cloneSession(
const QString &filePath)
198void SessionManager::deleteSession(
const QString &filePath)
200 QMessageBox::StandardButton result = QMessageBox::information(
mApp->activeWindow(), tr(
"Delete Session"), tr(
"Are you sure you want to delete session '%1'?")
201 .arg(QFileInfo(filePath).completeBaseName()), QMessageBox::Yes | QMessageBox::No);
202 if (result == QMessageBox::Yes) {
203 QFile::remove(filePath);
207void SessionManager::newSession()
210 QString sessionName = QInputDialog::getText(
mApp->activeWindow(), tr(
"New Session"),
211 tr(
"Please enter a name to create new session:"), QLineEdit::Normal,
212 tr(
"New Session (%1)").arg(QDateTime::currentDateTime().toString(
QSL(
"dd MMM yyyy HH-mm-ss"))), &ok);
218 if (QFile::exists(filePath)) {
219 QMessageBox::information(
mApp->activeWindow(), tr(
"Error!"), tr(
"The session file \"%1\" exists. Please enter another name.").arg(sessionName));
232 m_lastActiveSessionPath = filePath;
236QList<SessionManager::SessionMetaData> SessionManager::sessionMetaData(
bool withBackups)
238 fillSessionsMetaDataListIfNeeded();
240 auto out = m_sessionsMetaDataList;
242 if (withBackups && QFile::exists(m_firstBackupSession)) {
243 SessionMetaData data;
244 data.name = tr(
"Backup 1");
245 data.filePath = m_firstBackupSession;
246 data.isBackup =
true;
249 if (withBackups && QFile::exists(m_secondBackupSession)) {
250 SessionMetaData data;
251 data.name = tr(
"Backup 2");
252 data.filePath = m_secondBackupSession;
253 data.isBackup =
true;
260bool SessionManager::isActive(
const QString &filePath)
const
262 return QFileInfo(filePath) == QFileInfo(m_lastActiveSessionPath);
265bool SessionManager::isActive(
const QFileInfo &fileInfo)
const
267 return fileInfo == QFileInfo(m_lastActiveSessionPath);
270void SessionManager::fillSessionsMetaDataListIfNeeded()
272 if (!m_sessionsMetaDataList.isEmpty())
277 const QFileInfoList sessionFiles = QFileInfoList() << QFileInfo(
defaultSessionPath()) << dir.entryInfoList({
QSL(
"*.*")}, QDir::Files, QDir::Time);
279 QStringList fileNames;
281 for (
int i = 0;
i < sessionFiles.size(); ++
i) {
282 const QFileInfo &fileInfo = sessionFiles.at(
i);
287 SessionMetaData metaData;
288 metaData.name = fileInfo.completeBaseName();
291 metaData.name = tr(
"Default Session");
292 metaData.isDefault =
true;
293 }
else if (fileNames.contains(fileInfo.completeBaseName())) {
294 metaData.name = fileInfo.fileName();
296 metaData.name = fileInfo.completeBaseName();
299 if (isActive(fileInfo)) {
300 metaData.isActive =
true;
303 fileNames << metaData.name;
304 metaData.filePath = fileInfo.canonicalFilePath();
306 m_sessionsMetaDataList << metaData;
319 if (QDir::isRelativePath(m_lastActiveSessionPath)) {
320 m_lastActiveSessionPath = sessionsDir.absoluteFilePath(m_lastActiveSessionPath);
334 settings.
setValue(
QSL(
"lastActiveSessionPath"), sessionsDir.relativeFilePath(m_lastActiveSessionPath));
345 return m_lastActiveSessionPath;
350 if (!QFile::exists(m_lastActiveSessionPath)) {
354 if (QFile::exists(m_firstBackupSession)) {
355 QFile::remove(m_secondBackupSession);
356 QFile::copy(m_firstBackupSession, m_secondBackupSession);
359 QFile::remove(m_firstBackupSession);
360 QFile::copy(m_lastActiveSessionPath, m_firstBackupSession);
365 QSaveFile file(filePath);
366 if (!file.open(QIODevice::WriteOnly) || file.write(
mApp->saveState()) == -1) {
367 qWarning() <<
"Error! can not write the current session file: " << filePath << file.errorString();
381 if (
mApp->isPrivate() ||
mApp->windowCount() == 0) {
391 fillSessionsMetaDataListIfNeeded();
393 QDialog dialog(
mApp->getWindow(), Qt::WindowStaysOnTopHint);
394 QLabel label(tr(
"Please select the startup session:"), &dialog);
395 QComboBox comboBox(&dialog);
396 QDialogButtonBox buttonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, &dialog);
397 connect(&buttonBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept);
398 connect(&buttonBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject);
401 layout.addWidget(&label);
402 layout.addWidget(&comboBox);
403 layout.addWidget(&buttonBox);
404 dialog.setLayout(&layout);
406 const QFileInfo lastActiveSessionFileInfo(m_lastActiveSessionPath);
409 if (QFileInfo(metaData.filePath) != lastActiveSessionFileInfo) {
410 comboBox.addItem(metaData.name, metaData.filePath);
413 comboBox.insertItem(0, tr(
"%1 (last session)").arg(metaData.name), metaData.filePath);
417 comboBox.setCurrentIndex(0);
419 if (dialog.exec() == QDialog::Accepted) {
420 m_lastActiveSessionPath = comboBox.currentData().toString();
423 return m_lastActiveSessionPath;
static QString path(Path type)
static QString currentProfilePath()
static bool validateFile(const QString &file)
static void createFromFile(const QString &file, RestoreData &data)
friend class SessionManagerDialog
static QString defaultSessionPath()
void backupSavedSessions()
void sessionsMetaDataChanged()
void openSessionManagerDialog()
QString askSessionFromUser()
void autoSaveLastSession()
QString lastActiveSessionPath() const
void writeCurrentSession(const QString &filePath)
SessionManager(QObject *parent=nullptr)
void beginGroup(const QString &prefix)
QVariant value(const QString &key, const QVariant &defaultValue=QVariant())
void setValue(const QString &key, const QVariant &defaultValue=QVariant())