From 88f585c5520332c31cf34bfae03d6c60f9391eee Mon Sep 17 00:00:00 2001 From: Johannes Sauer Date: Sun, 18 Apr 2021 20:24:37 +0200 Subject: [PATCH 1/7] working on support for autosave with multiple instances --- YUViewLib/src/common/YUViewInstanceInfo.cpp | 304 ++++++++++++++++++ YUViewLib/src/common/YUViewInstanceInfo.h | 51 +++ YUViewLib/src/ui/mainwindow.cpp | 9 +- YUViewLib/src/ui/mainwindow.h | 2 + .../src/ui/widgets/PlaylistTreeWidget.cpp | 165 ++++++++-- YUViewLib/src/ui/widgets/PlaylistTreeWidget.h | 12 +- 6 files changed, 520 insertions(+), 23 deletions(-) create mode 100644 YUViewLib/src/common/YUViewInstanceInfo.cpp create mode 100644 YUViewLib/src/common/YUViewInstanceInfo.h diff --git a/YUViewLib/src/common/YUViewInstanceInfo.cpp b/YUViewLib/src/common/YUViewInstanceInfo.cpp new file mode 100644 index 000000000..ae83a4791 --- /dev/null +++ b/YUViewLib/src/common/YUViewInstanceInfo.cpp @@ -0,0 +1,304 @@ +#include "YUViewInstanceInfo.h" +#include +#include +#include + + +const QString YUViewInstanceInfo::instanceInfoKey = QString("YUViewInstances"); + +void YUViewInstanceInfo::initializeAsNewInstance() +{ + QSettings settings; + uuid = QUuid::createUuid(); + pid = QCoreApplication::applicationPid(); + // append instance to recorded ones + QList listOfQSettingInstances = YUViewInstanceInfo::getYUViewInstancesInQSettings(); + listOfQSettingInstances.append(QVariant::fromValue(*this)); + listOfQSettingInstances.append(QVariant::fromValue(*this)); + listOfQSettingInstances.append(QVariant::fromValue(*this)); + settings.setValue(instanceInfoKey, listOfQSettingInstances); + settings.sync(); + // debug + QList test = YUViewInstanceInfo::getYUViewInstancesInQSettings(); + YUViewInstanceInfo tmp = test.at(0).value(); + int a = 42; + a++; +} + +void YUViewInstanceInfo::autoSavePlaylist(const QByteArray &newCompressedPlaylist) +{ + QSettings settings; + // set new playlist + this->compressedPlaylist = newCompressedPlaylist; + + // change the one stored + QList listOfQSettingInstances = YUViewInstanceInfo::getYUViewInstancesInQSettings(); + QVariant thisInstance = QVariant::fromValue(*this); + QMutableListIterator it(listOfQSettingInstances); + while (it.hasNext()) + { + YUViewInstanceInfo otherInstance = it.next().value(); + if(this->uuid == otherInstance.uuid && + this->pid == otherInstance.pid ) + { + // already had a instance, replace its playlist + it.setValue(thisInstance); + settings.setValue(instanceInfoKey, listOfQSettingInstances); + settings.sync(); + return; + } + } + + // no instance yet, save new one + // should never be reached, as we create the instance in initializeAsNewInstance, + // thus there always should be one + listOfQSettingInstances.append(thisInstance); + settings.setValue(instanceInfoKey, listOfQSettingInstances); + return; +} + +//void YUViewInstanceInfo::loadAutosavedPlaylist() +//{ +// QSettings settings; + +// for( auto instance : crashedInstances) +// { +// // take the first in the list +// QString playlist_name = "Autosaveplaylist-" + instance; +// if (settings.contains(playlist_name)) +// { +// QByteArray compressedPlaylist = settings.value(playlist_name).toByteArray(); +// QByteArray uncompressedPlaylist = qUncompress(compressedPlaylist); +// loadPlaylistFromByteArray(uncompressedPlaylist, QDir::current().absolutePath()); +// dropAutosavedPlaylist(instance); +// break; +// } + +// } +//} + +void YUViewInstanceInfo::dropAutosavedPlaylist() +{ + // replace saved on with emtpy playlist + this->autoSavePlaylist(QByteArray()); +} + +void YUViewInstanceInfo::removeInstanceFromQSettings() +{ + QSettings settings; + + // find and remove current instance from stored ones + QList listOfQSettingInstances = YUViewInstanceInfo::getYUViewInstancesInQSettings(); + QVariant thisInstance = QVariant::fromValue(*this); + QMutableListIterator it(listOfQSettingInstances); + while (it.hasNext()) + { + YUViewInstanceInfo otherInstance = it.next().value(); + if(this->uuid == otherInstance.uuid && + this->pid == otherInstance.pid ) + { + // found it, now remove it + it.remove(); + settings.setValue(instanceInfoKey, listOfQSettingInstances); + return; + } + } +} + +YUViewInstanceInfo YUViewInstanceInfo::getAutosavedPlaylist() +{ + QSettings settings; + QList listOfPids = YUViewInstanceInfo::getRunningYUViewInstances(); + QList listOfQSettingInstances = YUViewInstanceInfo::getYUViewInstancesInQSettings(); + + YUViewInstanceInfo candidateForRestore; + QMutableListIterator it(listOfQSettingInstances); + while (it.hasNext()) + { + YUViewInstanceInfo instanceInSettings = it.next().value(); + bool still_running = false; + // get known instances, if instance no longer runs, remove it from QSettings + for( auto pid_running : listOfPids ) + { + if( pid_running == instanceInSettings.pid ) still_running = true; + } + if(!still_running) + { + // found an instance which is no longer running: candidate for restore + candidateForRestore = instanceInSettings; + it.remove(); + } + } + + return candidateForRestore; +} + +void YUViewInstanceInfo::cleanupRecordedInstances() +{ + QSettings settings; + QList listOfPids = YUViewInstanceInfo::getRunningYUViewInstances(); + QList listOfQSettingInstances = YUViewInstanceInfo::getYUViewInstancesInQSettings(); + + QMutableListIterator it(listOfQSettingInstances); + while (it.hasNext()) + { + YUViewInstanceInfo instanceInSettings = it.next().value(); + bool still_running = false; + // get known instances, if instance no longer runs, remove it from QSettings + for( auto pid_running : listOfPids ) + { + if( pid_running == instanceInSettings.pid ) still_running = true; + } + if(!still_running) + { + // can remove this one + it.remove(); + } + } + + settings.setValue(instanceInfoKey, listOfQSettingInstances); +} + +bool YUViewInstanceInfo::isValid() +{ + return !uuid.isNull(); +} + +QList YUViewInstanceInfo::getRunningYUViewInstances() +{ + + QList listOfPids; + + // code for getting process ids adopted from https://www.qtcentre.org/threads/44489-Get-Process-ID-for-a-running-application + // also mentions checking /proc. However there is no proc on macos, while pgrep should be available. + +#if defined(Q_OS_WIN) + // Get the list of process identifiers. + DWORD aProcesses[1024], cbNeeded, cProcesses; + unsigned int i; + + if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded)) + { + return 0; + } + + // Calculate how many process identifiers were returned. + cProcesses = cbNeeded / sizeof(DWORD); + + // Search for a matching name for each process + for (i = 0; i < cProcesses; i++) + { + if (aProcesses[i] != 0) + { + char szProcessName[MAX_PATH] = {0}; + + DWORD processID = aProcesses[i]; + + // Get a handle to the process. + HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | + PROCESS_VM_READ, + FALSE, processID); + + // Get the process name + if (NULL != hProcess) + { + HMODULE hMod; + DWORD cbNeeded; + + if (EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded)) + { + GetModuleBaseNameA(hProcess, hMod, szProcessName, sizeof(szProcessName)/sizeof(char)); + } + + // Release the handle to the process. + CloseHandle(hProcess); + + if (*szProcessName != 0 && strcmp(processName, szProcessName) == 0) + { + listOfPids.append(QString::number(processID)); + } + } + } + } + + return listOfPids.count(); + +#else + + // Run pgrep, which looks through the currently running processses and lists the process IDs + // which match the selection criteria to stdout. + QProcess process; + process.start("pgrep", QStringList() << "YUView"); + process.waitForReadyRead(); + + QByteArray bytes = process.readAllStandardOutput(); + + process.terminate(); + process.waitForFinished(); + process.kill(); + + // Output is something like "2472\n2323" for multiple instances + if (bytes.isEmpty()) + return QList(); + + // Remove trailing CR + if (bytes.endsWith("\n")) + bytes.resize(bytes.size() - 1); + + QStringList strListOfPids = QString(bytes).split("\n"); + for( auto strPid : strListOfPids ) + { + listOfPids.append(strPid.toLongLong()); + } +#endif + + return listOfPids; +} + +QList YUViewInstanceInfo::getYUViewInstancesInQSettings() +{ + QSettings settings; + QList instancesInQSettings; + if (settings.contains(instanceInfoKey)) + { + instancesInQSettings = settings.value(instanceInfoKey).toList(); + } + return instancesInQSettings; +} + +//const QString YUViewInstanceInfo::getKeyOfInstance() +//{ +// return this->uuid.toString() + ";" + QString::number(this->pid); +//} + +//YUViewInstanceInfo YUViewInstanceInfo::fromQList(const QList list) +//{ +// YUViewInstanceInfo instanceInfo; +// instanceInfo.uuid = list.at(0).toUuid(); +// instanceInfo.pid = list.at(1).toLongLong(); +// instanceInfo.compressedPlaylist = list.at(2).toByteArray(); +// return instanceInfo; +//} + +//QList YUViewInstanceInfo::toQList() +//{ +// QList list; +// list.append(this->uuid); +// list.append(this->pid); +// list.append(this->compressedPlaylist); +// return list; +//} + +QByteArray YUViewInstanceInfo::getCompressedPlaylist() const +{ + return compressedPlaylist; +} + +//void YUViewInstanceInfo::keyToUuidAndPid(const QString key, QUuid &uuid, qint64 &pid) +//{ +// QStringList instance_uuid_and_pid = key.split(';'); +// uuid = QUuid(instance_uuid_and_pid.at(0)); +// QString instance_pid_str = instance_uuid_and_pid.at(1); +// pid = instance_pid_str.toLongLong(); +//} + diff --git a/YUViewLib/src/common/YUViewInstanceInfo.h b/YUViewLib/src/common/YUViewInstanceInfo.h new file mode 100644 index 000000000..e2e7e9043 --- /dev/null +++ b/YUViewLib/src/common/YUViewInstanceInfo.h @@ -0,0 +1,51 @@ +#ifndef YUVIEWINSTANCEINFO_H +#define YUVIEWINSTANCEINFO_H + +#include +#include +#include +#include + +class YUViewInstanceInfo +{ +public: + YUViewInstanceInfo() = default; + ~YUViewInstanceInfo() = default; + YUViewInstanceInfo(const YUViewInstanceInfo &) = default; + YUViewInstanceInfo &operator=(const YUViewInstanceInfo &) = default; + +// YUViewInstanceInfo(const QString &body, const QStringList &headers); + + void initializeAsNewInstance(); + void autoSavePlaylist(const QByteArray &newCompressedPlaylist); +// void loadAutosavedPlaylist(); + void dropAutosavedPlaylist(); + void removeInstanceFromQSettings(); + YUViewInstanceInfo getAutosavedPlaylist(); + void cleanupRecordedInstances(); + bool isValid(); + + QByteArray getCompressedPlaylist() const; + +private: + static QList getRunningYUViewInstances(); + static QList getYUViewInstancesInQSettings(); +// const QString getKeyOfInstance(); +// static YUViewInstanceInfo fromQList(const QList list); +// QList toQList(); + + qint64 pid; + QUuid uuid; + QByteArray compressedPlaylist; + +// static void keyToUuidAndPid( const QString key, QUuid &uuid, qint64 &pid); + static const QString instanceInfoKey; // key used for QSettings +}; + + + +Q_DECLARE_METATYPE(YUViewInstanceInfo); + + + +#endif // YUVIEWINSTANCEINFO_H diff --git a/YUViewLib/src/ui/mainwindow.cpp b/YUViewLib/src/ui/mainwindow.cpp index c373caf91..1bc978c9e 100644 --- a/YUViewLib/src/ui/mainwindow.cpp +++ b/YUViewLib/src/ui/mainwindow.cpp @@ -197,7 +197,12 @@ MainWindow::MainWindow(bool useAlternativeSources, QWidget *parent) : QMainWindo // Give the playlist a pointer to the state handler so it can save the states ti playlist ui.playlistTreeWidget->setViewStateHandler(&stateHandler); - if (ui.playlistTreeWidget->isAutosaveAvailable()) + instance_uuid = QUuid::createUuid(); + instance_pid = QCoreApplication::applicationPid(); + + QStringList crashedInstances; + YUViewInstanceInfo autosaveCandidateInstance = ui.playlistTreeWidget->getInstanceInfo().getAutosavedPlaylist(); + if( autosaveCandidateInstance.isValid()) { QMessageBox::StandardButton resBtn = QMessageBox::question(this, @@ -208,7 +213,7 @@ MainWindow::MainWindow(bool useAlternativeSources, QWidget *parent) : QMainWindo QMessageBox::Yes | QMessageBox::No, QMessageBox::No); if (resBtn == QMessageBox::Yes) - ui.playlistTreeWidget->loadAutosavedPlaylist(); + ui.playlistTreeWidget->loadAutosavedPlaylist(autosaveCandidateInstance); else ui.playlistTreeWidget->dropAutosavedPlaylist(); } diff --git a/YUViewLib/src/ui/mainwindow.h b/YUViewLib/src/ui/mainwindow.h index 296a7c8c0..31d1a04e0 100644 --- a/YUViewLib/src/ui/mainwindow.h +++ b/YUViewLib/src/ui/mainwindow.h @@ -127,4 +127,6 @@ private slots: SeparateWindow separateViewWindow; bool showNormalMaximized; // When going to full screen: Was this windows maximized? bool panelsVisible[5] {false}; // Which panels are visible when going to full-screen mode? + QUuid instance_uuid; + qint64 instance_pid; }; diff --git a/YUViewLib/src/ui/widgets/PlaylistTreeWidget.cpp b/YUViewLib/src/ui/widgets/PlaylistTreeWidget.cpp index 0d5055c80..aab089137 100644 --- a/YUViewLib/src/ui/widgets/PlaylistTreeWidget.cpp +++ b/YUViewLib/src/ui/widgets/PlaylistTreeWidget.cpp @@ -46,6 +46,8 @@ #include #include #include +#include +#include #include "playlistitem/playlistItemContainer.h" #include "playlistitem/playlistItemDifference.h" @@ -143,10 +145,11 @@ PlaylistTreeWidget::PlaylistTreeWidget(QWidget *parent) : QTreeWidget(parent) header()->setSectionResizeMode(1, QHeaderView::Fixed); header()->setSectionResizeMode(0, QHeaderView::Stretch); + instanceInfo.initializeAsNewInstance(); + // This does not work here. Don't know why. Setting it every time a new item is added, however, // works. // header()->resizeSection(1, 10); - connect(this, &PlaylistTreeWidget::itemSelectionChanged, this, @@ -158,9 +161,7 @@ PlaylistTreeWidget::~PlaylistTreeWidget() { // This is a conventional quit. Remove the automatically saved playlist. autosaveTimer.stop(); - QSettings settings; - if (settings.contains("Autosaveplaylist")) - settings.remove("Autosaveplaylist"); + instanceInfo.removeInstanceFromQSettings(); } playlistItem *PlaylistTreeWidget::getDropTarget(const QPoint &pos) const @@ -1015,29 +1016,153 @@ void PlaylistTreeWidget::updateSettings() } } -bool PlaylistTreeWidget::isAutosaveAvailable() +bool PlaylistTreeWidget::isAutosaveAvailable(QUuid current_instance_uuid, qint64 current_instance_pid, QStringList &crashedInstances) { QSettings settings; - return settings.contains("Autosaveplaylist"); + + // code for getting process ids adopted from https://www.qtcentre.org/threads/44489-Get-Process-ID-for-a-running-application + // also mentions checking /proc. However there is no proc on macos, while pgrep should be available. + +// unsigned int System::getProcessIdsByProcessName(const char* processName, + QStringList listOfPids; +// { +// // Clear content of returned list of PIDS +// listOfPids.clear(); + +#if defined(Q_OS_WIN) + // Get the list of process identifiers. + DWORD aProcesses[1024], cbNeeded, cProcesses; + unsigned int i; + + if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded)) + { + return 0; + } + + // Calculate how many process identifiers were returned. + cProcesses = cbNeeded / sizeof(DWORD); + + // Search for a matching name for each process + for (i = 0; i < cProcesses; i++) + { + if (aProcesses[i] != 0) + { + char szProcessName[MAX_PATH] = {0}; + + DWORD processID = aProcesses[i]; + + // Get a handle to the process. + HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | + PROCESS_VM_READ, + FALSE, processID); + + // Get the process name + if (NULL != hProcess) + { + HMODULE hMod; + DWORD cbNeeded; + + if (EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded)) + { + GetModuleBaseNameA(hProcess, hMod, szProcessName, sizeof(szProcessName)/sizeof(char)); + } + + // Release the handle to the process. + CloseHandle(hProcess); + + if (*szProcessName != 0 && strcmp(processName, szProcessName) == 0) + { + listOfPids.append(QString::number(processID)); + } + } + } + } + + return listOfPids.count(); + +#else + + // Run pgrep, which looks through the currently running processses and lists the process IDs + // which match the selection criteria to stdout. + QProcess process; + process.start("pgrep", QStringList() << "YUView"); + process.waitForReadyRead(); + + QByteArray bytes = process.readAllStandardOutput(); + + process.terminate(); + process.waitForFinished(); + process.kill(); + + // Output is something like "2472\n2323" for multiple instances + if (bytes.isEmpty()) + return 0; + + // Remove trailing CR + if (bytes.endsWith("\n")) + bytes.resize(bytes.size() - 1); + + listOfPids = QString(bytes).split("\n"); +// return listOfPids.count(); + +#endif + + +#ifdef Q_OS_LINUX + +// sfsd +#endif +#ifdef Q_OS_MAC + // todo +#endif +#ifdef Q_OS_WIN32 + // todo +#endif + + if (settings.contains("YUView-instances")) + { + QStringList runningInstances = settings.value("YUView-instances").toStringList(); + for (auto instance : runningInstances) + { + QStringList instance_uuid_and_pid = instance.split(';'); + QUuid instance_uuid = QUuid(instance.at(0)); + QString instance_pid_str = instance.at(1); + qint64 instance_pid = instance_pid_str.toLongLong(); + + if ( instance_pid == current_instance_pid && instance_uuid != current_instance_uuid ) + { + // seems we found a crashed instance and our newly launched instance happens to have gotten the same pid + crashedInstances << instance; + } + + if(!listOfPids.contains(instance_pid_str)) + { + // pid in list from settings which is not present on the system. must be a crashed instance + crashedInstances << instance; + } + } + } + + + return crashedInstances.length() > 0; } -void PlaylistTreeWidget::loadAutosavedPlaylist() +void PlaylistTreeWidget::loadAutosavedPlaylist(const YUViewInstanceInfo &crashedInstance) { QSettings settings; - if (!settings.contains("Autosaveplaylist")) - return; - - QByteArray compressedPlaylist = settings.value("Autosaveplaylist").toByteArray(); + QByteArray compressedPlaylist= crashedInstance.getCompressedPlaylist(); QByteArray uncompressedPlaylist = qUncompress(compressedPlaylist); loadPlaylistFromByteArray(uncompressedPlaylist, QDir::current().absolutePath()); - - dropAutosavedPlaylist(); } void PlaylistTreeWidget::dropAutosavedPlaylist() { - QSettings settings; - settings.remove("Autosaveplaylist"); +// QSettings settings; +// QString playlist_name = "Autosaveplaylist-" + crashedInstance; +// settings.remove(crashedInstance); +// settings.remove(playlist_name); + + instanceInfo.cleanupRecordedInstances(); } void PlaylistTreeWidget::cloneSelectedItem() @@ -1077,17 +1202,21 @@ void PlaylistTreeWidget::autoSavePlaylist() if (topLevelItemCount() == 0) { // Empty playlist - if (settings.contains("Autosaveplaylist")) - settings.remove("Autosaveplaylist"); + instanceInfo.dropAutosavedPlaylist(); } else { QString playlistAsString = getPlaylistString(QDir::current()); QByteArray compressedPlaylist = qCompress(playlistAsString.toLatin1()); - settings.setValue("Autosaveplaylist", compressedPlaylist); + instanceInfo.autoSavePlaylist(compressedPlaylist); } } +YUViewInstanceInfo PlaylistTreeWidget::getInstanceInfo() const +{ + return instanceInfo; +} + void PlaylistTreeWidget::startAutosaveTimer() { autosaveTimer.setTimerType(Qt::VeryCoarseTimer); diff --git a/YUViewLib/src/ui/widgets/PlaylistTreeWidget.h b/YUViewLib/src/ui/widgets/PlaylistTreeWidget.h index 14d1234ab..7320fc889 100644 --- a/YUViewLib/src/ui/widgets/PlaylistTreeWidget.h +++ b/YUViewLib/src/ui/widgets/PlaylistTreeWidget.h @@ -40,6 +40,7 @@ #include "playlistitem/playlistItem.h" #include "common/typedef.h" #include "ui/ViewStateHandler.h" +#include "common/YUViewInstanceInfo.h" class QDomElement; @@ -87,15 +88,18 @@ class PlaylistTreeWidget : public QTreeWidget // Update the caching status of all items void updateCachingStatus() { emit dataChanged(QModelIndex(), QModelIndex()); }; - bool isAutosaveAvailable(); - void loadAutosavedPlaylist(); + bool isAutosaveAvailable(QUuid current_instance_uuid, qint64 current_instance_pid, QStringList &crashedInstances); + void loadAutosavedPlaylist(const YUViewInstanceInfo &crashedInstance); void dropAutosavedPlaylist(); + void dropAutosavedPlaylists(QStringList &crashedInstances); void startAutosaveTimer(); + YUViewInstanceInfo getInstanceInfo() const; + public slots: void savePlaylistToFile(); - // Slots for going to the next item. WrapAround = if the current item is the last one in the list, + // Slots for going to the next item. WrapAround = if the current item is the last one in the list, // goto the first item in the list. Return if there is a next item. // callByPlayback is true if this call is caused by the playback function going to the next item. void onSelectNextItem(bool) { this->selectNextItem(false, false); } @@ -206,4 +210,6 @@ protected slots: void autoSavePlaylist(); QTimer autosaveTimer; + + YUViewInstanceInfo instanceInfo; }; From d76c98c9141fb34781fb7eab411ca29a3734fa1b Mon Sep 17 00:00:00 2001 From: Johannes Sauer Date: Wed, 21 Apr 2021 15:40:13 +0200 Subject: [PATCH 2/7] fixed compile error due to missing include. could not find std::logic_error --- YUViewLib/src/common/EnumMapper.h | 1 + 1 file changed, 1 insertion(+) diff --git a/YUViewLib/src/common/EnumMapper.h b/YUViewLib/src/common/EnumMapper.h index c58c3f4ce..4992a0081 100644 --- a/YUViewLib/src/common/EnumMapper.h +++ b/YUViewLib/src/common/EnumMapper.h @@ -36,6 +36,7 @@ #include #include #include +#include /* This class implement mapping of "enum class" values to and from names (string). */ From e9a2c9dd0de0b7bb0fa9635f8d9ec27a28413ec7 Mon Sep 17 00:00:00 2001 From: Johannes Sauer Date: Wed, 21 Apr 2021 15:40:58 +0200 Subject: [PATCH 3/7] fixed conversion to absolute path for loading playlist on Linux --- YUViewLib/src/playlistitem/playlistItemCompressedVideo.cpp | 3 ++- YUViewLib/src/playlistitem/playlistItemImageFile.cpp | 3 ++- YUViewLib/src/playlistitem/playlistItemRawFile.cpp | 3 ++- YUViewLib/src/playlistitem/playlistItemStatisticsFile.cpp | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/YUViewLib/src/playlistitem/playlistItemCompressedVideo.cpp b/YUViewLib/src/playlistitem/playlistItemCompressedVideo.cpp index bc2d3ea30..77ad489da 100644 --- a/YUViewLib/src/playlistitem/playlistItemCompressedVideo.cpp +++ b/YUViewLib/src/playlistitem/playlistItemCompressedVideo.cpp @@ -395,7 +395,8 @@ playlistItemCompressedVideo::newPlaylistItemCompressedVideo(const YUViewDomEleme const QString &playlistFilePath) { // Parse the DOM element. It should have all values of a playlistItemRawCodedVideo - auto absolutePath = root.findChildValue("absolutePath"); + QUrl absoluteUrl = root.findChildValue("absolutePath"); + auto absolutePath = absoluteUrl.toLocalFile(); auto relativePath = root.findChildValue("relativePath"); int displaySignal = root.findChildValue("displayComponent").toInt(); diff --git a/YUViewLib/src/playlistitem/playlistItemImageFile.cpp b/YUViewLib/src/playlistitem/playlistItemImageFile.cpp index 6fd6476d8..fa64c7241 100644 --- a/YUViewLib/src/playlistitem/playlistItemImageFile.cpp +++ b/YUViewLib/src/playlistitem/playlistItemImageFile.cpp @@ -109,7 +109,8 @@ playlistItemImageFile::newplaylistItemImageFile(const YUViewDomElement &root, const QString & playlistFilePath) { // Parse the DOM element. It should have all values of a playlistItemImageFile - QString absolutePath = root.findChildValue("absolutePath"); + QUrl absoluteUrl = root.findChildValue("absolutePath"); + auto absolutePath = absoluteUrl.toLocalFile(); QString relativePath = root.findChildValue("relativePath"); // check if file with absolute path exists, otherwise check relative path diff --git a/YUViewLib/src/playlistitem/playlistItemRawFile.cpp b/YUViewLib/src/playlistitem/playlistItemRawFile.cpp index b48adf277..c68c2d3ad 100644 --- a/YUViewLib/src/playlistitem/playlistItemRawFile.cpp +++ b/YUViewLib/src/playlistitem/playlistItemRawFile.cpp @@ -469,7 +469,8 @@ playlistItemRawFile *playlistItemRawFile::newplaylistItemRawFile(const YUViewDom const QString &playlistFilePath) { // Parse the DOM element. It should have all values of a playlistItemRawFile - auto absolutePath = root.findChildValue("absolutePath"); + QUrl absoluteUrl = root.findChildValue("absolutePath"); + auto absolutePath = absoluteUrl.toLocalFile(); auto relativePath = root.findChildValue("relativePath"); auto type = root.findChildValue("type"); diff --git a/YUViewLib/src/playlistitem/playlistItemStatisticsFile.cpp b/YUViewLib/src/playlistitem/playlistItemStatisticsFile.cpp index a0298a7d2..19da98b17 100644 --- a/YUViewLib/src/playlistitem/playlistItemStatisticsFile.cpp +++ b/YUViewLib/src/playlistitem/playlistItemStatisticsFile.cpp @@ -104,7 +104,8 @@ playlistItemStatisticsFile *playlistItemStatisticsFile::newplaylistItemStatistic const YUViewDomElement &root, const QString &playlistFilePath, OpenMode openMode) { // Parse the DOM element. It should have all values of a playlistItemStatisticsFile - auto absolutePath = root.findChildValue("absolutePath"); + QUrl absoluteUrl = root.findChildValue("absolutePath"); + auto absolutePath = absoluteUrl.toLocalFile(); auto relativePath = root.findChildValue("relativePath"); // check if file with absolute path exists, otherwise check relative path From fb5ae064e2cf425267ad30a04b869de215b36e5e Mon Sep 17 00:00:00 2001 From: Johannes Sauer Date: Wed, 21 Apr 2021 20:27:52 +0200 Subject: [PATCH 4/7] implemented QDataStream operators for YUViewInstanceInfo. Basic restore works now (one crashed instance) --- YUViewApp/src/yuviewapp.cpp | 7 +- YUViewLib/src/common/YUViewInstanceInfo.cpp | 108 ++++++++++++------ YUViewLib/src/common/YUViewInstanceInfo.h | 11 +- .../src/ui/widgets/PlaylistTreeWidget.cpp | 5 - 4 files changed, 88 insertions(+), 43 deletions(-) diff --git a/YUViewApp/src/yuviewapp.cpp b/YUViewApp/src/yuviewapp.cpp index 2eaf6e697..1a2473a92 100644 --- a/YUViewApp/src/yuviewapp.cpp +++ b/YUViewApp/src/yuviewapp.cpp @@ -34,6 +34,7 @@ #include "common/typedef.h" #include "ui/YUViewApplication.h" +#include "common/YUViewInstanceInfo.h" int main(int argc, char *argv[]) { @@ -45,7 +46,11 @@ int main(int argc, char *argv[]) QCoreApplication::setAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents,false); qRegisterMetaType("recacheIndicator"); - + qRegisterMetaType("YUViewInstanceInfo"); + qRegisterMetaType("YUViewInstanceInfoList"); + qRegisterMetaTypeStreamOperators("YUViewInstanceInfo"); + qRegisterMetaTypeStreamOperators("YUViewInstanceInfoList"); + YUViewApplication app(argc, argv); return app.returnCode; diff --git a/YUViewLib/src/common/YUViewInstanceInfo.cpp b/YUViewLib/src/common/YUViewInstanceInfo.cpp index ae83a4791..a08fe614b 100644 --- a/YUViewLib/src/common/YUViewInstanceInfo.cpp +++ b/YUViewLib/src/common/YUViewInstanceInfo.cpp @@ -6,23 +6,64 @@ const QString YUViewInstanceInfo::instanceInfoKey = QString("YUViewInstances"); + +QDataStream& operator<<(QDataStream &ds, const YUViewInstanceInfo &inObj) +{ + ds << inObj.uuid; + // conversion to string should not be necessary. + // but without I get ambiguous overload for operator + ds << QString::number(inObj.pid); + ds << inObj.compressedPlaylist; + return ds; +} + +QDataStream& operator>>(QDataStream &ds, YUViewInstanceInfo &outObj) +{ + ds >> outObj.uuid; + QString tmp; + ds >> tmp; + outObj.pid = tmp.toLongLong(); + ds >> outObj.compressedPlaylist; + return ds; +} + +QDataStream& operator<<(QDataStream &ds, const YUViewInstanceInfoList &inObj) +{ + const qint64 list_length = inObj.length(); + // conversion to string should not be necessary. + // but without I get ambiguous overload for operator + ds << QString::number(list_length); + for( auto instance : inObj ) + { + ds << instance; + } + return ds; +} + +QDataStream& operator>>(QDataStream &ds, YUViewInstanceInfoList &outObj) +{ + outObj.clear(); + QString tmp; + ds >> tmp; + const qint64 list_length = tmp.toLongLong(); + for(unsigned i = 0; i> tmp; + outObj.push_back(tmp); + } + return ds; +} + void YUViewInstanceInfo::initializeAsNewInstance() { QSettings settings; uuid = QUuid::createUuid(); pid = QCoreApplication::applicationPid(); // append instance to recorded ones - QList listOfQSettingInstances = YUViewInstanceInfo::getYUViewInstancesInQSettings(); - listOfQSettingInstances.append(QVariant::fromValue(*this)); - listOfQSettingInstances.append(QVariant::fromValue(*this)); - listOfQSettingInstances.append(QVariant::fromValue(*this)); - settings.setValue(instanceInfoKey, listOfQSettingInstances); - settings.sync(); - // debug - QList test = YUViewInstanceInfo::getYUViewInstancesInQSettings(); - YUViewInstanceInfo tmp = test.at(0).value(); - int a = 42; - a++; + YUViewInstanceInfoList listOfQSettingInstances = YUViewInstanceInfo::getYUViewInstancesInQSettings(); + listOfQSettingInstances.append(*this); + settings.setValue(instanceInfoKey, QVariant::fromValue(listOfQSettingInstances)); } void YUViewInstanceInfo::autoSavePlaylist(const QByteArray &newCompressedPlaylist) @@ -32,19 +73,17 @@ void YUViewInstanceInfo::autoSavePlaylist(const QByteArray &newCompressedPlaylis this->compressedPlaylist = newCompressedPlaylist; // change the one stored - QList listOfQSettingInstances = YUViewInstanceInfo::getYUViewInstancesInQSettings(); - QVariant thisInstance = QVariant::fromValue(*this); - QMutableListIterator it(listOfQSettingInstances); + YUViewInstanceInfoList listOfQSettingInstances = YUViewInstanceInfo::getYUViewInstancesInQSettings(); + QMutableListIterator it(listOfQSettingInstances); while (it.hasNext()) { - YUViewInstanceInfo otherInstance = it.next().value(); + YUViewInstanceInfo otherInstance = it.next(); if(this->uuid == otherInstance.uuid && this->pid == otherInstance.pid ) { // already had a instance, replace its playlist - it.setValue(thisInstance); - settings.setValue(instanceInfoKey, listOfQSettingInstances); - settings.sync(); + it.setValue(*this); + settings.setValue(instanceInfoKey, QVariant::fromValue(listOfQSettingInstances)); return; } } @@ -52,8 +91,8 @@ void YUViewInstanceInfo::autoSavePlaylist(const QByteArray &newCompressedPlaylis // no instance yet, save new one // should never be reached, as we create the instance in initializeAsNewInstance, // thus there always should be one - listOfQSettingInstances.append(thisInstance); - settings.setValue(instanceInfoKey, listOfQSettingInstances); + listOfQSettingInstances.append(*this); + settings.setValue(instanceInfoKey, QVariant::fromValue(listOfQSettingInstances)); return; } @@ -88,18 +127,17 @@ void YUViewInstanceInfo::removeInstanceFromQSettings() QSettings settings; // find and remove current instance from stored ones - QList listOfQSettingInstances = YUViewInstanceInfo::getYUViewInstancesInQSettings(); - QVariant thisInstance = QVariant::fromValue(*this); - QMutableListIterator it(listOfQSettingInstances); + YUViewInstanceInfoList listOfQSettingInstances = YUViewInstanceInfo::getYUViewInstancesInQSettings(); + QMutableListIterator it(listOfQSettingInstances); while (it.hasNext()) { - YUViewInstanceInfo otherInstance = it.next().value(); + YUViewInstanceInfo otherInstance = it.next(); if(this->uuid == otherInstance.uuid && this->pid == otherInstance.pid ) { // found it, now remove it it.remove(); - settings.setValue(instanceInfoKey, listOfQSettingInstances); + settings.setValue(instanceInfoKey, QVariant::fromValue(listOfQSettingInstances)); return; } } @@ -109,13 +147,13 @@ YUViewInstanceInfo YUViewInstanceInfo::getAutosavedPlaylist() { QSettings settings; QList listOfPids = YUViewInstanceInfo::getRunningYUViewInstances(); - QList listOfQSettingInstances = YUViewInstanceInfo::getYUViewInstancesInQSettings(); + YUViewInstanceInfoList listOfQSettingInstances = YUViewInstanceInfo::getYUViewInstancesInQSettings(); YUViewInstanceInfo candidateForRestore; - QMutableListIterator it(listOfQSettingInstances); + QMutableListIterator it(listOfQSettingInstances); while (it.hasNext()) { - YUViewInstanceInfo instanceInSettings = it.next().value(); + YUViewInstanceInfo instanceInSettings = it.next(); bool still_running = false; // get known instances, if instance no longer runs, remove it from QSettings for( auto pid_running : listOfPids ) @@ -137,12 +175,12 @@ void YUViewInstanceInfo::cleanupRecordedInstances() { QSettings settings; QList listOfPids = YUViewInstanceInfo::getRunningYUViewInstances(); - QList listOfQSettingInstances = YUViewInstanceInfo::getYUViewInstancesInQSettings(); + YUViewInstanceInfoList listOfQSettingInstances = YUViewInstanceInfo::getYUViewInstancesInQSettings(); - QMutableListIterator it(listOfQSettingInstances); + QMutableListIterator it(listOfQSettingInstances); while (it.hasNext()) { - YUViewInstanceInfo instanceInSettings = it.next().value(); + YUViewInstanceInfo instanceInSettings = it.next(); bool still_running = false; // get known instances, if instance no longer runs, remove it from QSettings for( auto pid_running : listOfPids ) @@ -156,7 +194,7 @@ void YUViewInstanceInfo::cleanupRecordedInstances() } } - settings.setValue(instanceInfoKey, listOfQSettingInstances); + settings.setValue(instanceInfoKey, QVariant::fromValue(listOfQSettingInstances)); } bool YUViewInstanceInfo::isValid() @@ -255,13 +293,13 @@ QList YUViewInstanceInfo::getRunningYUViewInstances() return listOfPids; } -QList YUViewInstanceInfo::getYUViewInstancesInQSettings() +YUViewInstanceInfoList YUViewInstanceInfo::getYUViewInstancesInQSettings() { QSettings settings; - QList instancesInQSettings; + YUViewInstanceInfoList instancesInQSettings; if (settings.contains(instanceInfoKey)) { - instancesInQSettings = settings.value(instanceInfoKey).toList(); + instancesInQSettings = settings.value(instanceInfoKey).value(); } return instancesInQSettings; } diff --git a/YUViewLib/src/common/YUViewInstanceInfo.h b/YUViewLib/src/common/YUViewInstanceInfo.h index e2e7e9043..8e31c464c 100644 --- a/YUViewLib/src/common/YUViewInstanceInfo.h +++ b/YUViewLib/src/common/YUViewInstanceInfo.h @@ -27,9 +27,11 @@ class YUViewInstanceInfo QByteArray getCompressedPlaylist() const; + friend QDataStream& (operator<<) (QDataStream &ds, const YUViewInstanceInfo &inObj); + friend QDataStream& (operator>>) (QDataStream &ds, YUViewInstanceInfo &outObj); private: static QList getRunningYUViewInstances(); - static QList getYUViewInstancesInQSettings(); + static QList getYUViewInstancesInQSettings(); // const QString getKeyOfInstance(); // static YUViewInstanceInfo fromQList(const QList list); // QList toQList(); @@ -42,10 +44,15 @@ class YUViewInstanceInfo static const QString instanceInfoKey; // key used for QSettings }; +typedef QList YUViewInstanceInfoList; +QDataStream& operator<<(QDataStream &ds, const YUViewInstanceInfo &inObj); +QDataStream& operator>>(QDataStream &ds, YUViewInstanceInfo &outObj); +QDataStream& operator<<(QDataStream &ds, const YUViewInstanceInfoList &inObj); +QDataStream& operator>>(QDataStream &ds, YUViewInstanceInfoList &outObj); Q_DECLARE_METATYPE(YUViewInstanceInfo); - +Q_DECLARE_METATYPE(YUViewInstanceInfoList); #endif // YUVIEWINSTANCEINFO_H diff --git a/YUViewLib/src/ui/widgets/PlaylistTreeWidget.cpp b/YUViewLib/src/ui/widgets/PlaylistTreeWidget.cpp index a2419c906..a089e7924 100644 --- a/YUViewLib/src/ui/widgets/PlaylistTreeWidget.cpp +++ b/YUViewLib/src/ui/widgets/PlaylistTreeWidget.cpp @@ -1153,11 +1153,6 @@ void PlaylistTreeWidget::loadAutosavedPlaylist(const YUViewInstanceInfo &crashed void PlaylistTreeWidget::dropAutosavedPlaylist() { -// QSettings settings; -// QString playlist_name = "Autosaveplaylist-" + crashedInstance; -// settings.remove(crashedInstance); -// settings.remove(playlist_name); - instanceInfo.cleanupRecordedInstances(); } From 62a2c4aa93e986a2fcb540aa89dfa014d5be8032 Mon Sep 17 00:00:00 2001 From: Johannes Sauer Date: Wed, 21 Apr 2021 20:43:08 +0200 Subject: [PATCH 5/7] remove oboslete code --- .../src/ui/widgets/PlaylistTreeWidget.cpp | 131 ------------------ YUViewLib/src/ui/widgets/PlaylistTreeWidget.h | 1 - 2 files changed, 132 deletions(-) diff --git a/YUViewLib/src/ui/widgets/PlaylistTreeWidget.cpp b/YUViewLib/src/ui/widgets/PlaylistTreeWidget.cpp index a089e7924..cd78feae9 100644 --- a/YUViewLib/src/ui/widgets/PlaylistTreeWidget.cpp +++ b/YUViewLib/src/ui/widgets/PlaylistTreeWidget.cpp @@ -1012,137 +1012,6 @@ void PlaylistTreeWidget::updateSettings() } } -bool PlaylistTreeWidget::isAutosaveAvailable(QUuid current_instance_uuid, qint64 current_instance_pid, QStringList &crashedInstances) -{ - QSettings settings; - - // code for getting process ids adopted from https://www.qtcentre.org/threads/44489-Get-Process-ID-for-a-running-application - // also mentions checking /proc. However there is no proc on macos, while pgrep should be available. - -// unsigned int System::getProcessIdsByProcessName(const char* processName, - QStringList listOfPids; -// { -// // Clear content of returned list of PIDS -// listOfPids.clear(); - -#if defined(Q_OS_WIN) - // Get the list of process identifiers. - DWORD aProcesses[1024], cbNeeded, cProcesses; - unsigned int i; - - if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded)) - { - return 0; - } - - // Calculate how many process identifiers were returned. - cProcesses = cbNeeded / sizeof(DWORD); - - // Search for a matching name for each process - for (i = 0; i < cProcesses; i++) - { - if (aProcesses[i] != 0) - { - char szProcessName[MAX_PATH] = {0}; - - DWORD processID = aProcesses[i]; - - // Get a handle to the process. - HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | - PROCESS_VM_READ, - FALSE, processID); - - // Get the process name - if (NULL != hProcess) - { - HMODULE hMod; - DWORD cbNeeded; - - if (EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded)) - { - GetModuleBaseNameA(hProcess, hMod, szProcessName, sizeof(szProcessName)/sizeof(char)); - } - - // Release the handle to the process. - CloseHandle(hProcess); - - if (*szProcessName != 0 && strcmp(processName, szProcessName) == 0) - { - listOfPids.append(QString::number(processID)); - } - } - } - } - - return listOfPids.count(); - -#else - - // Run pgrep, which looks through the currently running processses and lists the process IDs - // which match the selection criteria to stdout. - QProcess process; - process.start("pgrep", QStringList() << "YUView"); - process.waitForReadyRead(); - - QByteArray bytes = process.readAllStandardOutput(); - - process.terminate(); - process.waitForFinished(); - process.kill(); - - // Output is something like "2472\n2323" for multiple instances - if (bytes.isEmpty()) - return 0; - - // Remove trailing CR - if (bytes.endsWith("\n")) - bytes.resize(bytes.size() - 1); - - listOfPids = QString(bytes).split("\n"); -// return listOfPids.count(); - -#endif - - -#ifdef Q_OS_LINUX - -// sfsd -#endif -#ifdef Q_OS_MAC - // todo -#endif -#ifdef Q_OS_WIN32 - // todo -#endif - - if (settings.contains("YUView-instances")) - { - QStringList runningInstances = settings.value("YUView-instances").toStringList(); - for (auto instance : runningInstances) - { - QStringList instance_uuid_and_pid = instance.split(';'); - QUuid instance_uuid = QUuid(instance.at(0)); - QString instance_pid_str = instance.at(1); - qint64 instance_pid = instance_pid_str.toLongLong(); - - if ( instance_pid == current_instance_pid && instance_uuid != current_instance_uuid ) - { - // seems we found a crashed instance and our newly launched instance happens to have gotten the same pid - crashedInstances << instance; - } - - if(!listOfPids.contains(instance_pid_str)) - { - // pid in list from settings which is not present on the system. must be a crashed instance - crashedInstances << instance; - } - } - } - - - return crashedInstances.length() > 0; -} - void PlaylistTreeWidget::loadAutosavedPlaylist(const YUViewInstanceInfo &crashedInstance) { QSettings settings; diff --git a/YUViewLib/src/ui/widgets/PlaylistTreeWidget.h b/YUViewLib/src/ui/widgets/PlaylistTreeWidget.h index f0bed7f96..b4d17a7c7 100644 --- a/YUViewLib/src/ui/widgets/PlaylistTreeWidget.h +++ b/YUViewLib/src/ui/widgets/PlaylistTreeWidget.h @@ -88,7 +88,6 @@ class PlaylistTreeWidget : public QTreeWidget // Update the caching status of all items void updateCachingStatus() { emit dataChanged(QModelIndex(), QModelIndex()); }; - bool isAutosaveAvailable(QUuid current_instance_uuid, qint64 current_instance_pid, QStringList &crashedInstances); void loadAutosavedPlaylist(const YUViewInstanceInfo &crashedInstance); void dropAutosavedPlaylist(); void dropAutosavedPlaylists(QStringList &crashedInstances); From df3093b73c6cfd40b0cae867b971eae998d27561 Mon Sep 17 00:00:00 2001 From: Johannes Sauer Date: Wed, 21 Apr 2021 20:43:19 +0200 Subject: [PATCH 6/7] fixed: playlist could be restored, but the record was still kept in the Qsettings for the crashed instance --- YUViewLib/src/common/YUViewInstanceInfo.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/YUViewLib/src/common/YUViewInstanceInfo.cpp b/YUViewLib/src/common/YUViewInstanceInfo.cpp index a08fe614b..f3a3a32ce 100644 --- a/YUViewLib/src/common/YUViewInstanceInfo.cpp +++ b/YUViewLib/src/common/YUViewInstanceInfo.cpp @@ -165,6 +165,8 @@ YUViewInstanceInfo YUViewInstanceInfo::getAutosavedPlaylist() // found an instance which is no longer running: candidate for restore candidateForRestore = instanceInSettings; it.remove(); + settings.setValue(instanceInfoKey, QVariant::fromValue(listOfQSettingInstances)); + break; // keep playlist from potential other crashed instances for other new instances } } From 30d1626a9eac2f071050aaeae1f257d4cabcb81c Mon Sep 17 00:00:00 2001 From: Johannes Sauer Date: Wed, 21 Apr 2021 21:15:05 +0200 Subject: [PATCH 7/7] cleanup --- YUViewLib/src/common/YUViewInstanceInfo.cpp | 50 ------------------- YUViewLib/src/common/YUViewInstanceInfo.h | 14 ++---- YUViewLib/src/ui/mainwindow.cpp | 7 ++- YUViewLib/src/ui/mainwindow.h | 2 - .../src/ui/widgets/PlaylistTreeWidget.cpp | 1 + YUViewLib/src/ui/widgets/PlaylistTreeWidget.h | 1 - 6 files changed, 8 insertions(+), 67 deletions(-) diff --git a/YUViewLib/src/common/YUViewInstanceInfo.cpp b/YUViewLib/src/common/YUViewInstanceInfo.cpp index f3a3a32ce..a9f58099d 100644 --- a/YUViewLib/src/common/YUViewInstanceInfo.cpp +++ b/YUViewLib/src/common/YUViewInstanceInfo.cpp @@ -96,26 +96,6 @@ void YUViewInstanceInfo::autoSavePlaylist(const QByteArray &newCompressedPlaylis return; } -//void YUViewInstanceInfo::loadAutosavedPlaylist() -//{ -// QSettings settings; - -// for( auto instance : crashedInstances) -// { -// // take the first in the list -// QString playlist_name = "Autosaveplaylist-" + instance; -// if (settings.contains(playlist_name)) -// { -// QByteArray compressedPlaylist = settings.value(playlist_name).toByteArray(); -// QByteArray uncompressedPlaylist = qUncompress(compressedPlaylist); -// loadPlaylistFromByteArray(uncompressedPlaylist, QDir::current().absolutePath()); -// dropAutosavedPlaylist(instance); -// break; -// } - -// } -//} - void YUViewInstanceInfo::dropAutosavedPlaylist() { // replace saved on with emtpy playlist @@ -306,39 +286,9 @@ YUViewInstanceInfoList YUViewInstanceInfo::getYUViewInstancesInQSettings() return instancesInQSettings; } -//const QString YUViewInstanceInfo::getKeyOfInstance() -//{ -// return this->uuid.toString() + ";" + QString::number(this->pid); -//} - -//YUViewInstanceInfo YUViewInstanceInfo::fromQList(const QList list) -//{ -// YUViewInstanceInfo instanceInfo; -// instanceInfo.uuid = list.at(0).toUuid(); -// instanceInfo.pid = list.at(1).toLongLong(); -// instanceInfo.compressedPlaylist = list.at(2).toByteArray(); -// return instanceInfo; -//} - -//QList YUViewInstanceInfo::toQList() -//{ -// QList list; -// list.append(this->uuid); -// list.append(this->pid); -// list.append(this->compressedPlaylist); -// return list; -//} - QByteArray YUViewInstanceInfo::getCompressedPlaylist() const { return compressedPlaylist; } -//void YUViewInstanceInfo::keyToUuidAndPid(const QString key, QUuid &uuid, qint64 &pid) -//{ -// QStringList instance_uuid_and_pid = key.split(';'); -// uuid = QUuid(instance_uuid_and_pid.at(0)); -// QString instance_pid_str = instance_uuid_and_pid.at(1); -// pid = instance_pid_str.toLongLong(); -//} diff --git a/YUViewLib/src/common/YUViewInstanceInfo.h b/YUViewLib/src/common/YUViewInstanceInfo.h index 8e31c464c..0f7cdf40f 100644 --- a/YUViewLib/src/common/YUViewInstanceInfo.h +++ b/YUViewLib/src/common/YUViewInstanceInfo.h @@ -6,6 +6,9 @@ #include #include +class YUViewInstanceInfo; +typedef QList YUViewInstanceInfoList; + class YUViewInstanceInfo { public: @@ -14,11 +17,8 @@ class YUViewInstanceInfo YUViewInstanceInfo(const YUViewInstanceInfo &) = default; YUViewInstanceInfo &operator=(const YUViewInstanceInfo &) = default; -// YUViewInstanceInfo(const QString &body, const QStringList &headers); - void initializeAsNewInstance(); void autoSavePlaylist(const QByteArray &newCompressedPlaylist); -// void loadAutosavedPlaylist(); void dropAutosavedPlaylist(); void removeInstanceFromQSettings(); YUViewInstanceInfo getAutosavedPlaylist(); @@ -31,21 +31,15 @@ class YUViewInstanceInfo friend QDataStream& (operator>>) (QDataStream &ds, YUViewInstanceInfo &outObj); private: static QList getRunningYUViewInstances(); - static QList getYUViewInstancesInQSettings(); -// const QString getKeyOfInstance(); -// static YUViewInstanceInfo fromQList(const QList list); -// QList toQList(); + static YUViewInstanceInfoList getYUViewInstancesInQSettings(); qint64 pid; QUuid uuid; QByteArray compressedPlaylist; -// static void keyToUuidAndPid( const QString key, QUuid &uuid, qint64 &pid); static const QString instanceInfoKey; // key used for QSettings }; -typedef QList YUViewInstanceInfoList; - QDataStream& operator<<(QDataStream &ds, const YUViewInstanceInfo &inObj); QDataStream& operator>>(QDataStream &ds, YUViewInstanceInfo &outObj); QDataStream& operator<<(QDataStream &ds, const YUViewInstanceInfoList &inObj); diff --git a/YUViewLib/src/ui/mainwindow.cpp b/YUViewLib/src/ui/mainwindow.cpp index 1bc978c9e..0ad1857ca 100644 --- a/YUViewLib/src/ui/mainwindow.cpp +++ b/YUViewLib/src/ui/mainwindow.cpp @@ -197,9 +197,6 @@ MainWindow::MainWindow(bool useAlternativeSources, QWidget *parent) : QMainWindo // Give the playlist a pointer to the state handler so it can save the states ti playlist ui.playlistTreeWidget->setViewStateHandler(&stateHandler); - instance_uuid = QUuid::createUuid(); - instance_pid = QCoreApplication::applicationPid(); - QStringList crashedInstances; YUViewInstanceInfo autosaveCandidateInstance = ui.playlistTreeWidget->getInstanceInfo().getAutosavedPlaylist(); if( autosaveCandidateInstance.isValid()) @@ -209,7 +206,9 @@ MainWindow::MainWindow(bool useAlternativeSources, QWidget *parent) : QMainWindo "Restore Playlist", tr("It looks like YUView crashed the last time you used it. We are " "sorry about that. However, we have an autosave of the playlist " - "you were working with. Do you want to resotre this playlist?\n"), + "you were working with. Do you want to restore this playlist? If" + " you had more than one YUView instance, opening more instances " + "will allow you to restore other playlists as well.\n"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No); if (resBtn == QMessageBox::Yes) diff --git a/YUViewLib/src/ui/mainwindow.h b/YUViewLib/src/ui/mainwindow.h index 31d1a04e0..296a7c8c0 100644 --- a/YUViewLib/src/ui/mainwindow.h +++ b/YUViewLib/src/ui/mainwindow.h @@ -127,6 +127,4 @@ private slots: SeparateWindow separateViewWindow; bool showNormalMaximized; // When going to full screen: Was this windows maximized? bool panelsVisible[5] {false}; // Which panels are visible when going to full-screen mode? - QUuid instance_uuid; - qint64 instance_pid; }; diff --git a/YUViewLib/src/ui/widgets/PlaylistTreeWidget.cpp b/YUViewLib/src/ui/widgets/PlaylistTreeWidget.cpp index cd78feae9..da730b574 100644 --- a/YUViewLib/src/ui/widgets/PlaylistTreeWidget.cpp +++ b/YUViewLib/src/ui/widgets/PlaylistTreeWidget.cpp @@ -155,6 +155,7 @@ PlaylistTreeWidget::PlaylistTreeWidget(QWidget *parent) : QTreeWidget(parent) // This does not work here. Don't know why. Setting it every time a new item is added, however, // works. // header()->resizeSection(1, 10); + connect(this, &PlaylistTreeWidget::itemSelectionChanged, this, diff --git a/YUViewLib/src/ui/widgets/PlaylistTreeWidget.h b/YUViewLib/src/ui/widgets/PlaylistTreeWidget.h index b4d17a7c7..ee87faaaa 100644 --- a/YUViewLib/src/ui/widgets/PlaylistTreeWidget.h +++ b/YUViewLib/src/ui/widgets/PlaylistTreeWidget.h @@ -90,7 +90,6 @@ class PlaylistTreeWidget : public QTreeWidget void loadAutosavedPlaylist(const YUViewInstanceInfo &crashedInstance); void dropAutosavedPlaylist(); - void dropAutosavedPlaylists(QStringList &crashedInstances); void startAutosaveTimer(); YUViewInstanceInfo getInstanceInfo() const;