mirror of
https://gitlab.com/pholy/OSCAR-code.git
synced 2025-04-05 02:30:44 +00:00
Added profile lockfile ability to help protect against multiple profile instances
This commit is contained in:
parent
083a667527
commit
87d848ff14
@ -15,6 +15,8 @@
|
||||
#include <QMessageBox>
|
||||
#include <QDebug>
|
||||
#include <QProcess>
|
||||
#include <QByteArray>
|
||||
#include <QHostInfo>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
||||
@ -64,6 +66,10 @@ Profile::Profile(QString path)
|
||||
|
||||
Profile::~Profile()
|
||||
{
|
||||
QString lockfile=p_path+"/lockfile";
|
||||
QFile file(lockfile);
|
||||
file.remove();
|
||||
|
||||
if (m_opened) {
|
||||
delete user;
|
||||
delete doctor;
|
||||
@ -87,6 +93,27 @@ bool Profile::Save(QString filename)
|
||||
} else return false;
|
||||
}
|
||||
|
||||
bool Profile::removeLock()
|
||||
{
|
||||
QString filename=p_path+"/lockfile";
|
||||
QFile file(filename);
|
||||
return file.remove();
|
||||
}
|
||||
|
||||
QString Profile::checkLock()
|
||||
{
|
||||
|
||||
QString filename=p_path+"/lockfile";
|
||||
QFile file(filename);
|
||||
|
||||
if (!file.exists())
|
||||
return QString();
|
||||
|
||||
file.open(QFile::ReadOnly);
|
||||
QString lockhost = file.readLine(1024).trimmed();
|
||||
return lockhost;
|
||||
}
|
||||
|
||||
bool Profile::Open(QString filename)
|
||||
{
|
||||
if (filename.isEmpty()) {
|
||||
@ -98,6 +125,14 @@ bool Profile::Open(QString filename)
|
||||
}
|
||||
bool b = Preferences::Open(filename);
|
||||
|
||||
QString lockfile=p_path+"/lockfile";
|
||||
QFile file(lockfile);
|
||||
file.open(QFile::WriteOnly);
|
||||
QByteArray ba;
|
||||
ba.append(QHostInfo::localHostName());
|
||||
file.write(ba);
|
||||
file.close();
|
||||
|
||||
m_opened=true;
|
||||
doctor = new DoctorInfo(this);
|
||||
user = new UserInfo(this);
|
||||
|
@ -54,6 +54,12 @@ class Profile : public Preferences
|
||||
//! \brief Open profile, parse profile.xml file, and initialize helper classes
|
||||
virtual bool Open(QString filename = "");
|
||||
|
||||
//! \brief Returns hostname that locked profile, or empty string if unlocked
|
||||
QString checkLock();
|
||||
|
||||
//! \brief Removes a lockfile
|
||||
bool removeLock();
|
||||
|
||||
//! \brief Save Profile object (This is an extension to Preference::Save(..))
|
||||
virtual bool Save(QString filename = "");
|
||||
|
||||
|
@ -302,6 +302,29 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
#endif
|
||||
|
||||
on_homeButton_clicked();
|
||||
|
||||
qsrand(QDateTime::currentDateTime().toTime_t());
|
||||
|
||||
// Translators, these are only temporary messages, don't bother unless you really want to..
|
||||
|
||||
warnmsg.push_back(tr("<b>Warning:</b> This pre-release build is meant for beta testers only. Please do <b>NOT</b> share outside the SleepyHead Testing Forum."));
|
||||
warnmsg.push_back(tr("Please report bugs for this build to the SleepyHead Testing Forum, but first, check the release thread to ensure you are running the latest version."));
|
||||
warnmsg.push_back(tr("When reporting bugs, please make sure to supply the SleepyHead version number, operating system details and CPAP machine model."));
|
||||
warnmsg.push_back(tr("<b>Warning:</b> This reports this software generates are not fit for compliance or medical diagnostic purposes."));
|
||||
warnmsg.push_back(tr(""));
|
||||
warnmsg.push_back(tr("These messages are only a temporary feature. Some people thought they were an error."));
|
||||
|
||||
wtimer.setParent(this);
|
||||
warnidx = 0;
|
||||
wtimer.singleShot(0, this, SLOT(on_changeWarningMessage()));
|
||||
}
|
||||
|
||||
void MainWindow::on_changeWarningMessage()
|
||||
{
|
||||
int i=warnidx++ % warnmsg.size();
|
||||
QString warning = "<html><head/><body><p>"+warnmsg[i]+"</p></body></html>";
|
||||
ui->warningLabel->setText(warning);
|
||||
wtimer.singleShot(10000, this, SLOT(on_changeWarningMessage()));
|
||||
}
|
||||
|
||||
void MainWindow::closeEvent(QCloseEvent * event)
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkReply>
|
||||
#include <QSystemTrayIcon>
|
||||
#include <QTimer>
|
||||
|
||||
#include "daily.h"
|
||||
#include "overview.h"
|
||||
@ -310,6 +311,8 @@ class MainWindow : public QMainWindow
|
||||
|
||||
void on_importButton_clicked();
|
||||
|
||||
void on_changeWarningMessage();
|
||||
|
||||
private:
|
||||
void importCPAPBackups();
|
||||
void finishCPAPImport();
|
||||
@ -335,6 +338,10 @@ private:
|
||||
|
||||
//! \brief Destroy ALL the CPAP data for the selected machine
|
||||
void purgeMachine(Machine *);
|
||||
|
||||
int warnidx;
|
||||
QStringList warnmsg;
|
||||
QTimer wtimer;
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <QVBoxLayout>
|
||||
#include <QCryptographicHash>
|
||||
#include <QMessageBox>
|
||||
#include <QHostInfo>
|
||||
#include <QTimer>
|
||||
#include <QFontMetrics>
|
||||
#include <QDir>
|
||||
@ -49,17 +50,23 @@ ProfileSelect::ProfileSelect(QWidget *parent) :
|
||||
p != Profiles::profiles.end(); p++) {
|
||||
name = p.key();
|
||||
|
||||
QStandardItem *item = new QStandardItem(name);
|
||||
QRect rect = fm.boundingRect(name);
|
||||
if (rect.width() > w) w = rect.width();
|
||||
|
||||
if (PREF.contains(STR_GEN_Profile) && (name == PREF[STR_GEN_Profile].toString())) {
|
||||
sel = i;
|
||||
}
|
||||
|
||||
item->setData(p.key());
|
||||
QStandardItem *item = new QStandardItem(name);
|
||||
|
||||
item->setData(p.key(), Qt::UserRole+2);
|
||||
item->setEditable(false);
|
||||
|
||||
if (!(*p)->checkLock().isEmpty()) {
|
||||
item->setForeground(QBrush(Qt::red));
|
||||
item->setText(name+" (open)");
|
||||
}
|
||||
|
||||
QRect rect = fm.boundingRect(name);
|
||||
if (rect.width() > w) w = rect.width();
|
||||
|
||||
// Profile fonts arern't loaded yet.. Using generic font.
|
||||
item->setFont(font);
|
||||
model->appendRow(item);
|
||||
@ -122,10 +129,13 @@ void ProfileSelect::earlyExit()
|
||||
}
|
||||
void ProfileSelect::editProfile()
|
||||
{
|
||||
QString name = ui->listView->currentIndex().data().toString();
|
||||
QString name = ui->listView->currentIndex().data(Qt::UserRole+2).toString();
|
||||
Profile *profile = Profiles::Get(name);
|
||||
|
||||
if (!profile) { return; }
|
||||
if (!profile->isOpen()) {
|
||||
profile->Open();
|
||||
}
|
||||
|
||||
bool reallyEdit = false;
|
||||
|
||||
@ -173,7 +183,7 @@ void ProfileSelect::editProfile()
|
||||
}
|
||||
void ProfileSelect::deleteProfile()
|
||||
{
|
||||
QString name = ui->listView->currentIndex().data().toString();
|
||||
QString name = ui->listView->currentIndex().data(Qt::UserRole+2).toString();
|
||||
|
||||
QDialog confirmdlg;
|
||||
QVBoxLayout layout(&confirmdlg);
|
||||
@ -292,11 +302,38 @@ void ProfileSelect::on_newProfileButton_clicked()
|
||||
//! \brief Process the selected login, requesting passwords if required.
|
||||
void ProfileSelect::on_listView_activated(const QModelIndex &index)
|
||||
{
|
||||
QString name = index.data().toString();
|
||||
QString name = index.data(Qt::UserRole+2).toString();
|
||||
Profile *profile = Profiles::profiles[name];
|
||||
|
||||
if (!profile) { return; }
|
||||
if (!profile->isOpen()) {
|
||||
QString lockhost = profile->checkLock();
|
||||
|
||||
if (!lockhost.isEmpty()) {
|
||||
if (lockhost.compare(QHostInfo::localHostName()) == 0) {
|
||||
// Localhost has it locked..
|
||||
if (QMessageBox::warning(nullptr, STR_MessageBox_Warning,
|
||||
QObject::tr("There is a lockfile already present for profile '%1'.").arg(name)+"\n\n"+
|
||||
QObject::tr("You can only work with one instance of an individual SleepyHead profile at a time.")+"\n\n"+
|
||||
QObject::tr("Please close any other instances of SleepyHead running with this profile before proceeding.")+"\n\n"+
|
||||
QObject::tr("If no other instances of SleepyHead are running, (eg, it crashed last time!), it is safe to ignore this message."),
|
||||
QMessageBox::Cancel |QMessageBox::Ok, QMessageBox::Cancel) == QMessageBox::Cancel) {
|
||||
return;
|
||||
}
|
||||
|
||||
} else {
|
||||
if (QMessageBox::warning(nullptr, STR_MessageBox_Warning,
|
||||
QObject::tr("There is a lockfile already present for this profile '%1', claimed on '%2'.").arg(name).arg(lockhost)+"\n\n"+
|
||||
QObject::tr("You can only work with one instance of an individual SleepyHead profile at a time.")+"\n\n"+
|
||||
QObject::tr("If you are using cloud storage, make sure SleepyHead is closed and syncing has completed first on the other computer before proceeding."),
|
||||
QMessageBox::Cancel |QMessageBox::Ok, QMessageBox::Cancel) == QMessageBox::Cancel) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
profile->removeLock();
|
||||
}
|
||||
|
||||
profile->Open();
|
||||
// Do this in case user renames the directory (otherwise it won't load)
|
||||
// Essentially makes the folder name the user name, but whatever..
|
||||
|
Loading…
Reference in New Issue
Block a user