diff --git a/Configuration.cpp b/Configuration.cpp index 7dd86ed83..616db6725 100644 --- a/Configuration.cpp +++ b/Configuration.cpp @@ -344,7 +344,8 @@ public: using FrequencyDelta = Radio::FrequencyDelta; using port_type = Configuration::port_type; - explicit impl (Configuration * self, QSettings * settings, QWidget * parent); + explicit impl (Configuration * self, QDir const& temp_directory, + QSettings * settings, QWidget * parent); ~impl (); bool have_rig (); @@ -564,8 +565,9 @@ private: // delegate to implementation class -Configuration::Configuration (QSettings * settings, QWidget * parent) - : m_ {this, settings, parent} +Configuration::Configuration (QDir const& temp_directory, + QSettings * settings, QWidget * parent) + : m_ {this, temp_directory, settings, parent} { } @@ -734,13 +736,15 @@ void Configuration::sync_transceiver (bool force_signal, bool enforce_mode_and_s } } -Configuration::impl::impl (Configuration * self, QSettings * settings, QWidget * parent) +Configuration::impl::impl (Configuration * self, QDir const& temp_directory, + QSettings * settings, QWidget * parent) : QDialog {parent} , self_ {self} , ui_ {new Ui::configuration_dialog} , settings_ {settings} , doc_dir_ {QApplication::applicationDirPath ()} , data_dir_ {QApplication::applicationDirPath ()} + , temp_dir_ {temp_directory} , frequencies_ {&bands_} , next_frequencies_ {&bands_} , stations_ {&bands_} @@ -805,39 +809,6 @@ Configuration::impl::impl (Configuration * self, QSettings * settings, QWidget * data_dir_.cd (WSJT_DATA_DESTINATION); #endif - { - // Create a temporary directory in a suitable location - QString temp_location {QStandardPaths::writableLocation (QStandardPaths::TempLocation)}; - if (!temp_location.isEmpty ()) - { - temp_dir_.setPath (temp_location); - } - - bool ok {false}; - QString unique_directory {QApplication::applicationName ()}; - do - { - if (!temp_dir_.mkpath (unique_directory) - || !temp_dir_.cd (unique_directory)) - { - QMessageBox::critical (this, "WSJT-X", tr ("Create temporary directory error: ") + temp_dir_.absolutePath ()); - throw std::runtime_error {"Failed to create a temporary directory"}; - } - if (!temp_dir_.isReadable () || !(ok = QTemporaryFile {temp_dir_.absoluteFilePath ("test")}.open ())) - { - if (QMessageBox::Cancel == QMessageBox::critical (this, "WSJT-X", - tr ("Create temporary directory error:\n%1\n" - "Another application may be locking the directory").arg (temp_dir_.absolutePath ()), - QMessageBox::Retry | QMessageBox::Cancel)) - { - throw std::runtime_error {"Failed to create a usable temporary directory"}; - } - temp_dir_.cdUp (); // revert to parent as this one is no good - } - } - while (!ok); - } - { // Find a suitable data file location QDir data_dir {QStandardPaths::writableLocation (QStandardPaths::DataLocation)}; @@ -1034,7 +1005,6 @@ Configuration::impl::~impl () transceiver_thread_->quit (); transceiver_thread_->wait (); write_settings (); - temp_dir_.removeRecursively (); // clean up temp files } void Configuration::impl::initialize_models () diff --git a/Configuration.hpp b/Configuration.hpp index 25efa8f29..4c0f99c44 100644 --- a/Configuration.hpp +++ b/Configuration.hpp @@ -68,7 +68,8 @@ public: enum Type2MsgGen {type_2_msg_1_full, type_2_msg_3_full, type_2_msg_5_only}; Q_ENUM (Type2MsgGen) - explicit Configuration (QSettings * settings, QWidget * parent = nullptr); + explicit Configuration (QDir const& temp_directory, QSettings * settings, + QWidget * parent = nullptr); ~Configuration (); int exec (); diff --git a/main.cpp b/main.cpp index d010036c3..9eb610389 100644 --- a/main.cpp +++ b/main.cpp @@ -158,11 +158,15 @@ int main(int argc, char *argv[]) multiple = true; } + // find the temporary files path + QDir temp_dir {QStandardPaths::writableLocation (QStandardPaths::TempLocation)}; + Q_ASSERT (temp_dir.exists ()); // sanity check + // disallow multiple instances with same instance key - QLockFile instance_lock {QDir {QStandardPaths::writableLocation (QStandardPaths::TempLocation)}.absoluteFilePath (a.applicationName () + ".lock")}; + QLockFile instance_lock {temp_dir.absoluteFilePath (a.applicationName () + ".lock")}; instance_lock.setStaleLockTime (0); - auto ok = false; - while (!(ok = instance_lock.tryLock ())) + bool lock_ok {false}; + while (!(lock_ok = instance_lock.tryLock ())) { if (QLockFile::LockFailedError == instance_lock.error ()) { @@ -187,14 +191,42 @@ int main(int argc, char *argv[]) } #endif - MultiSettings multi_settings; - #if WSJT_QDEBUG_TO_FILE // Open a trace file - TraceFile trace_file {QDir {QStandardPaths::writableLocation (QStandardPaths::TempLocation)}.absoluteFilePath (a.applicationName () + "_trace.log")}; + TraceFile trace_file {temp_dir.absoluteFilePath (a.applicationName () + "_trace.log")}; qDebug () << program_title (revision ()) + " - Program startup"; #endif + // Create a unique writeable temporary directory in a suitable location + bool temp_ok {false}; + QString unique_directory {QApplication::applicationName ()}; + do + { + if (!temp_dir.mkpath (unique_directory) + || !temp_dir.cd (unique_directory)) + { + QMessageBox::critical (nullptr, + "WSJT-X", + QObject::tr ("Create temporary directory error: ") + temp_dir.absolutePath ()); + throw std::runtime_error {"Failed to create a temporary directory"}; + } + if (!temp_dir.isReadable () || !(temp_ok = QTemporaryFile {temp_dir.absoluteFilePath ("test")}.open ())) + { + if (QMessageBox::Cancel == QMessageBox::critical (nullptr, + "WSJT-X", + QObject::tr ("Create temporary directory error:\n%1\n" + "Another application may be locking the directory").arg (temp_dir.absolutePath ()), + QMessageBox::Retry | QMessageBox::Cancel)) + { + throw std::runtime_error {"Failed to create a usable temporary directory"}; + } + temp_dir.cdUp (); // revert to parent as this one is no good + } + } + while (!temp_ok); + + MultiSettings multi_settings; + int result; do { @@ -251,12 +283,13 @@ int main(int argc, char *argv[]) } // run the application UI - MainWindow w(multiple, &multi_settings, &mem_jt9, downSampleFactor, new QNetworkAccessManager {&a}); + MainWindow w(temp_dir, multiple, &multi_settings, &mem_jt9, downSampleFactor, new QNetworkAccessManager {&a}); w.show(); QObject::connect (&a, SIGNAL (lastWindowClosed()), &a, SLOT (quit())); result = a.exec(); } while (!result && !multi_settings.exit ()); + temp_dir.removeRecursively (); // clean up temp files return result; } catch (std::exception const& e) diff --git a/mainwindow.cpp b/mainwindow.cpp index b60acdec7..4b9b88aec 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -138,8 +138,8 @@ namespace } //--------------------------------------------------- MainWindow constructor -MainWindow::MainWindow(bool multiple, MultiSettings * multi_settings, - QSharedMemory *shdmem, +MainWindow::MainWindow(QDir const& temp_directory, bool multiple, + MultiSettings * multi_settings, QSharedMemory *shdmem, unsigned downSampleFactor, QNetworkAccessManager * network_manager, QWidget *parent) : QMainWindow(parent), @@ -149,7 +149,7 @@ MainWindow::MainWindow(bool multiple, MultiSettings * multi_settings, m_multi_settings {multi_settings}, m_settings {multi_settings->settings ()}, ui(new Ui::MainWindow), - m_config {m_settings, this}, + m_config {temp_directory, m_settings, this}, m_WSPR_band_hopping {m_settings, &m_config, this}, m_WSPR_tx_next {false}, m_wideGraph (new WideGraph(m_settings)), diff --git a/mainwindow.h b/mainwindow.h index 82714c0fc..ffb425fc7 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -82,10 +82,10 @@ public: using FrequencyDelta = Radio::FrequencyDelta; using Mode = Modes::Mode; - // Multiple instances: call MainWindow() with *thekey - explicit MainWindow(bool multiple, MultiSettings *, QSharedMemory *shdmem, - unsigned downSampleFactor, QNetworkAccessManager * network_manager, - QWidget *parent = 0); + explicit MainWindow(QDir const& temp_directory, bool multiple, MultiSettings *, + QSharedMemory *shdmem, unsigned downSampleFactor, + QNetworkAccessManager * network_manager, + QWidget *parent = nullptr); ~MainWindow(); public slots: