Add a new page that can show all sorts of logs
This commit is contained in:
		
				
					committed by
					
						 Petr Mrázek
						Petr Mrázek
					
				
			
			
				
	
			
			
			
						parent
						
							aba1f89e2a
						
					
				
				
					commit
					5c43842359
				
			| @@ -35,7 +35,7 @@ set(CMAKE_JAVA_TARGET_OUTPUT_DIR ${PROJECT_BINARY_DIR}/jars) | ||||
| ######## Set compiler flags ######## | ||||
| include(UseCXX11) | ||||
| include(Coverage) | ||||
| set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") | ||||
| set(CMAKE_CXX_FLAGS " -Wall ${CMAKE_CXX_FLAGS}") | ||||
| set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Werror=return-type") | ||||
|  | ||||
| ################################ 3rd Party Libs ################################ | ||||
| @@ -280,6 +280,10 @@ SET(MULTIMC_SOURCES | ||||
| 	logger/QsLogDest.cpp | ||||
| 	logger/QsLogDest.h | ||||
|  | ||||
| 	# GUI - general utilities | ||||
| 	gui/GuiUtil.h | ||||
| 	gui/GuiUtil.cpp | ||||
|  | ||||
| 	# GUI - windows | ||||
| 	gui/MainWindow.h | ||||
| 	gui/MainWindow.cpp | ||||
| @@ -287,6 +291,7 @@ SET(MULTIMC_SOURCES | ||||
| 	gui/ConsoleWindow.cpp | ||||
|  | ||||
| 	# GUI - page dialog pages | ||||
| 	gui/pages/BasePage.h | ||||
| 	gui/pages/VersionPage.cpp | ||||
| 	gui/pages/VersionPage.h | ||||
| 	gui/pages/TexturePackPage.h | ||||
| @@ -305,6 +310,8 @@ SET(MULTIMC_SOURCES | ||||
| 	gui/pages/InstanceSettingsPage.h | ||||
| 	gui/pages/ScreenshotsPage.cpp | ||||
| 	gui/pages/ScreenshotsPage.h | ||||
| 	gui/pages/OtherLogsPage.cpp | ||||
| 	gui/pages/OtherLogsPage.h | ||||
|  | ||||
| 	# GUI - dialogs | ||||
| 	gui/dialogs/AboutDialog.cpp | ||||
| @@ -512,6 +519,10 @@ SET(MULTIMC_SOURCES | ||||
| 	logic/minecraft/VersionPatch.h | ||||
| 	logic/minecraft/VersionSource.h | ||||
|  | ||||
| 	# A Recursive file system watcher | ||||
| 	logic/RecursiveFileSystemWatcher.h | ||||
| 	logic/RecursiveFileSystemWatcher.cpp | ||||
|  | ||||
| 	# Various base classes | ||||
| 	logic/BaseInstaller.h | ||||
| 	logic/BaseInstaller.cpp | ||||
| @@ -628,6 +639,7 @@ SET(MULTIMC_UIS | ||||
| 	gui/pages/InstanceSettingsPage.ui | ||||
| 	gui/pages/NotesPage.ui | ||||
| 	gui/pages/ScreenshotsPage.ui | ||||
| 	gui/pages/OtherLogsPage.ui | ||||
|  | ||||
| 	# Dialogs | ||||
| 	gui/dialogs/SettingsDialog.ui | ||||
|   | ||||
							
								
								
									
										38
									
								
								gui/GuiUtil.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								gui/GuiUtil.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | ||||
| #include "GuiUtil.h" | ||||
|  | ||||
| #include <QClipboard> | ||||
| #include <QDesktopServices> | ||||
| #include <QApplication> | ||||
|  | ||||
| #include "dialogs/ProgressDialog.h" | ||||
| #include "logic/net/PasteUpload.h" | ||||
| #include "dialogs/CustomMessageBox.h" | ||||
|  | ||||
| void GuiUtil::uploadPaste(const QString &text, QWidget *parentWidget) | ||||
| { | ||||
| 	ProgressDialog dialog(parentWidget); | ||||
| 	PasteUpload *paste = new PasteUpload(parentWidget, text); | ||||
| 	dialog.exec(paste); | ||||
| 	if (!paste->successful()) | ||||
| 	{ | ||||
| 		CustomMessageBox::selectable(parentWidget, "Upload failed", paste->failReason(), | ||||
| 									 QMessageBox::Critical)->exec(); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		const QString link = paste->pasteLink(); | ||||
| 		setClipboardText(link); | ||||
| 		QDesktopServices::openUrl(link); | ||||
| 		CustomMessageBox::selectable( | ||||
| 			parentWidget, QObject::tr("Upload finished"), | ||||
| 			QObject::tr("The <a href=\"%1\">link to the uploaded log</a> has been opened in the default " | ||||
| 			   "browser and placed in your clipboard.").arg(link), | ||||
| 			QMessageBox::Information)->exec(); | ||||
| 	} | ||||
| 	delete paste; | ||||
| } | ||||
|  | ||||
| void GuiUtil::setClipboardText(const QString &text) | ||||
| { | ||||
| 	QApplication::clipboard()->setText(text); | ||||
| } | ||||
							
								
								
									
										9
									
								
								gui/GuiUtil.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								gui/GuiUtil.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include <QWidget> | ||||
|  | ||||
| namespace GuiUtil | ||||
| { | ||||
| void uploadPaste(const QString &text, QWidget *parentWidget); | ||||
| void setClipboardText(const QString &text); | ||||
| } | ||||
| @@ -21,25 +21,27 @@ | ||||
| class BasePage | ||||
| { | ||||
| public: | ||||
| 	virtual ~BasePage(){}; | ||||
| 	virtual QString id() = 0; | ||||
| 	virtual QString displayName() = 0; | ||||
| 	virtual QIcon icon() = 0; | ||||
| 	virtual ~BasePage(){} | ||||
| 	virtual QString id() const = 0; | ||||
| 	virtual QString displayName() const = 0; | ||||
| 	virtual QIcon icon() const = 0; | ||||
| 	virtual bool apply() | ||||
| 	{ | ||||
| 		return true; | ||||
| 	} | ||||
| 	virtual bool shouldDisplay() | ||||
| 	virtual bool shouldDisplay() const | ||||
| 	{ | ||||
| 		return true; | ||||
| 	} | ||||
| 	virtual QString helpPage() | ||||
| 	virtual QString helpPage() const | ||||
| 	{ | ||||
| 		return QString(); | ||||
| 	} | ||||
| 	virtual void opened() | ||||
| 	{ | ||||
| 		 | ||||
| 	} | ||||
| 	virtual void closed() | ||||
| 	{ | ||||
| 	} | ||||
| 	int stackIndex = -1; | ||||
| 	int listIndex = -1; | ||||
|   | ||||
| @@ -8,17 +8,17 @@ | ||||
| #include <QMessageBox> | ||||
| #include "ui_InstanceSettingsPage.h" | ||||
|  | ||||
| QString InstanceSettingsPage::displayName() | ||||
| QString InstanceSettingsPage::displayName() const | ||||
| { | ||||
| 	return tr("Settings"); | ||||
| } | ||||
|  | ||||
| QIcon InstanceSettingsPage::icon() | ||||
| QIcon InstanceSettingsPage::icon() const | ||||
| { | ||||
| 	return QIcon::fromTheme("settings"); | ||||
| } | ||||
|  | ||||
| QString InstanceSettingsPage::id() | ||||
| QString InstanceSettingsPage::id() const | ||||
| { | ||||
| 	return "settings"; | ||||
| } | ||||
| @@ -31,7 +31,7 @@ InstanceSettingsPage::InstanceSettingsPage(BaseInstance *inst, QWidget *parent) | ||||
| 	loadSettings(); | ||||
| } | ||||
|  | ||||
| bool InstanceSettingsPage::shouldDisplay() | ||||
| bool InstanceSettingsPage::shouldDisplay() const | ||||
| { | ||||
| 	return !m_instance->isRunning(); | ||||
| } | ||||
|   | ||||
| @@ -34,12 +34,12 @@ class InstanceSettingsPage : public QWidget, public BasePage | ||||
| public: | ||||
| 	explicit InstanceSettingsPage(BaseInstance *inst, QWidget *parent = 0); | ||||
| 	virtual ~InstanceSettingsPage(); | ||||
| 	virtual QString displayName() override; | ||||
| 	virtual QIcon icon() override; | ||||
| 	virtual QString id() override; | ||||
| 	virtual QString displayName() const override; | ||||
| 	virtual QIcon icon() const override; | ||||
| 	virtual QString id() const override; | ||||
| 	virtual bool apply(); | ||||
| 	virtual QString helpPage() override { return "Instance-settings"; } | ||||
| 	virtual bool shouldDisplay(); | ||||
| 	virtual QString helpPage() const override { return "Instance-settings"; } | ||||
| 	virtual bool shouldDisplay() const; | ||||
| private slots: | ||||
| 	void on_javaDetectBtn_clicked(); | ||||
|  | ||||
|   | ||||
| @@ -49,22 +49,22 @@ LegacyJarModPage::~LegacyJarModPage() | ||||
| 	delete ui; | ||||
| } | ||||
|  | ||||
| QString LegacyJarModPage::displayName() | ||||
| QString LegacyJarModPage::displayName() const | ||||
| { | ||||
| 	return tr("Jar Mods"); | ||||
| } | ||||
|  | ||||
| bool LegacyJarModPage::shouldDisplay() | ||||
| bool LegacyJarModPage::shouldDisplay() const | ||||
| { | ||||
| 	return !m_inst->isRunning(); | ||||
| } | ||||
|  | ||||
| QIcon LegacyJarModPage::icon() | ||||
| QIcon LegacyJarModPage::icon() const | ||||
| { | ||||
| 	return QIcon::fromTheme("plugin-red"); | ||||
| } | ||||
|  | ||||
| QString LegacyJarModPage::id() | ||||
| QString LegacyJarModPage::id() const | ||||
| { | ||||
| 	return "jarmods"; | ||||
| } | ||||
|   | ||||
| @@ -34,11 +34,11 @@ public: | ||||
| 	explicit LegacyJarModPage(LegacyInstance *inst, QWidget *parent = 0); | ||||
| 	virtual ~LegacyJarModPage(); | ||||
|  | ||||
| 	virtual QString displayName(); | ||||
| 	virtual QIcon icon(); | ||||
| 	virtual QString id(); | ||||
| 	virtual QString helpPage() override { return "Legacy-jar-mods"; }; | ||||
| 	virtual bool shouldDisplay(); | ||||
| 	virtual QString displayName() const; | ||||
| 	virtual QIcon icon() const; | ||||
| 	virtual QString id() const; | ||||
| 	virtual QString helpPage() const override { return "Legacy-jar-mods"; } | ||||
| 	virtual bool shouldDisplay() const; | ||||
|  | ||||
| private | ||||
| slots: | ||||
|   | ||||
| @@ -2,17 +2,17 @@ | ||||
| #include <logic/LegacyInstance.h> | ||||
| #include "ui_LegacyUpgradePage.h" | ||||
|  | ||||
| QString LegacyUpgradePage::displayName() | ||||
| QString LegacyUpgradePage::displayName() const | ||||
| { | ||||
| 	return tr("Upgrade"); | ||||
| } | ||||
|  | ||||
| QIcon LegacyUpgradePage::icon() | ||||
| QIcon LegacyUpgradePage::icon() const | ||||
| { | ||||
| 	return QIcon::fromTheme("checkupdate"); | ||||
| } | ||||
|  | ||||
| QString LegacyUpgradePage::id() | ||||
| QString LegacyUpgradePage::id() const | ||||
| { | ||||
| 	return "upgrade"; | ||||
| } | ||||
| @@ -33,7 +33,7 @@ void LegacyUpgradePage::on_upgradeButton_clicked() | ||||
| 	// now what? | ||||
| } | ||||
|  | ||||
| bool LegacyUpgradePage::shouldDisplay() | ||||
| bool LegacyUpgradePage::shouldDisplay() const | ||||
| { | ||||
| 	return !m_inst->isRunning(); | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -33,11 +33,11 @@ class LegacyUpgradePage : public QWidget, public BasePage | ||||
| public: | ||||
| 	explicit LegacyUpgradePage(LegacyInstance *inst, QWidget *parent = 0); | ||||
| 	virtual ~LegacyUpgradePage(); | ||||
| 	virtual QString displayName() override; | ||||
| 	virtual QIcon icon() override; | ||||
| 	virtual QString id() override; | ||||
| 	virtual QString helpPage() override { return "Legacy-upgrade"; }; | ||||
| 	virtual bool shouldDisplay(); | ||||
| 	virtual QString displayName() const override; | ||||
| 	virtual QIcon icon() const override; | ||||
| 	virtual QString id() const override; | ||||
| 	virtual QString helpPage() const override { return "Legacy-upgrade"; } | ||||
| 	virtual bool shouldDisplay() const; | ||||
| private | ||||
| slots: | ||||
| 	void on_upgradeButton_clicked(); | ||||
|   | ||||
| @@ -1,25 +1,23 @@ | ||||
| #include "LogPage.h" | ||||
| #include <gui/dialogs/CustomMessageBox.h> | ||||
| #include <gui/dialogs/ProgressDialog.h> | ||||
| #include <logic/MinecraftProcess.h> | ||||
| #include <QtGui/QIcon> | ||||
| #include "ui_LogPage.h" | ||||
| #include "logic/net/PasteUpload.h" | ||||
| #include <QScrollBar> | ||||
| #include <QtGui/QClipboard> | ||||
| #include <QtGui/QDesktopServices> | ||||
|  | ||||
| QString LogPage::displayName() | ||||
| #include <QIcon> | ||||
| #include <QScrollBar> | ||||
|  | ||||
| #include "logic/MinecraftProcess.h" | ||||
| #include "gui/GuiUtil.h" | ||||
|  | ||||
| QString LogPage::displayName() const | ||||
| { | ||||
| 	return tr("Minecraft Log"); | ||||
| } | ||||
|  | ||||
| QIcon LogPage::icon() | ||||
| QIcon LogPage::icon() const | ||||
| { | ||||
| 	return QIcon::fromTheme("refresh"); | ||||
| } | ||||
|  | ||||
| QString LogPage::id() | ||||
| QString LogPage::id() const | ||||
| { | ||||
| 	return "console"; | ||||
| } | ||||
| @@ -42,42 +40,19 @@ bool LogPage::apply() | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| bool LogPage::shouldDisplay() | ||||
| bool LogPage::shouldDisplay() const | ||||
| { | ||||
| 	return m_process->instance()->isRunning(); | ||||
| } | ||||
|  | ||||
| void LogPage::on_btnPaste_clicked() | ||||
| { | ||||
| 	auto text = ui->text->toPlainText(); | ||||
| 	ProgressDialog dialog(this); | ||||
| 	PasteUpload *paste = new PasteUpload(this, text); | ||||
| 	dialog.exec(paste); | ||||
| 	if (!paste->successful()) | ||||
| 	{ | ||||
| 		CustomMessageBox::selectable(this, "Upload failed", paste->failReason(), | ||||
| 									 QMessageBox::Critical)->exec(); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		QString link = paste->pasteLink(); | ||||
| 		QClipboard *clipboard = QApplication::clipboard(); | ||||
| 		clipboard->setText(link); | ||||
| 		QDesktopServices::openUrl(link); | ||||
| 		CustomMessageBox::selectable( | ||||
| 			this, tr("Upload finished"), | ||||
| 		tr("The <a href=\"%1\">link to the uploaded log</a> has been opened in the default browser and placed in your clipboard.") | ||||
| 		.arg(link), | ||||
| 		QMessageBox::Information)->exec(); | ||||
| 	} | ||||
| 	delete paste; | ||||
| 	GuiUtil::uploadPaste(ui->text->toPlainText(), this); | ||||
| } | ||||
|  | ||||
| void LogPage::on_btnCopy_clicked() | ||||
| { | ||||
| 	auto text = ui->text->toPlainText(); | ||||
| 	QClipboard *clipboard = QApplication::clipboard(); | ||||
| 	clipboard->setText(text); | ||||
| 	GuiUtil::setClipboardText(ui->text->toPlainText()); | ||||
| } | ||||
|  | ||||
| void LogPage::on_btnClear_clicked() | ||||
|   | ||||
| @@ -36,12 +36,12 @@ class LogPage : public QWidget, public BasePage | ||||
| public: | ||||
| 	explicit LogPage(MinecraftProcess *proc, QWidget *parent = 0); | ||||
| 	virtual ~LogPage(); | ||||
| 	virtual QString displayName() override; | ||||
| 	virtual QIcon icon() override; | ||||
| 	virtual QString id() override; | ||||
| 	virtual QString displayName() const override; | ||||
| 	virtual QIcon icon() const override; | ||||
| 	virtual QString id() const override; | ||||
| 	virtual bool apply(); | ||||
| 	virtual QString helpPage() override { return "Minecraft-Log"; }; | ||||
| 	virtual bool shouldDisplay(); | ||||
| 	virtual QString helpPage() const override { return "Minecraft-Log"; } | ||||
| 	virtual bool shouldDisplay() const; | ||||
|  | ||||
| private: | ||||
| 	/** | ||||
|   | ||||
| @@ -33,17 +33,17 @@ | ||||
| #include "logic/Mod.h" | ||||
| #include <logic/VersionFilterData.h> | ||||
|  | ||||
| QString ModFolderPage::displayName() | ||||
| QString ModFolderPage::displayName() const | ||||
| { | ||||
| 	return m_displayName; | ||||
| } | ||||
|  | ||||
| QIcon ModFolderPage::icon() | ||||
| QIcon ModFolderPage::icon() const | ||||
| { | ||||
| 	return QIcon::fromTheme(m_iconName); | ||||
| } | ||||
|  | ||||
| QString ModFolderPage::id() | ||||
| QString ModFolderPage::id() const | ||||
| { | ||||
| 	return m_id; | ||||
| } | ||||
| @@ -80,14 +80,14 @@ ModFolderPage::~ModFolderPage() | ||||
| 	delete ui; | ||||
| } | ||||
|  | ||||
| bool ModFolderPage::shouldDisplay() | ||||
| bool ModFolderPage::shouldDisplay() const | ||||
| { | ||||
| 	if(m_inst) | ||||
| 		return !m_inst->isRunning(); | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| bool CoreModFolderPage::shouldDisplay() | ||||
| bool CoreModFolderPage::shouldDisplay() const | ||||
| { | ||||
| 	if (ModFolderPage::shouldDisplay()) | ||||
| 	{ | ||||
|   | ||||
| @@ -32,19 +32,26 @@ class ModFolderPage : public QWidget, public BasePage | ||||
| 	Q_OBJECT | ||||
|  | ||||
| public: | ||||
| 	explicit ModFolderPage(BaseInstance * inst, std::shared_ptr<ModList> mods, QString id, QString iconName, | ||||
| 						   QString displayName, QString helpPage = "" , QWidget *parent = 0); | ||||
| 	explicit ModFolderPage(BaseInstance *inst, std::shared_ptr<ModList> mods, QString id, | ||||
| 						   QString iconName, QString displayName, QString helpPage = "", | ||||
| 						   QWidget *parent = 0); | ||||
| 	virtual ~ModFolderPage(); | ||||
| 	virtual QString displayName() override; | ||||
| 	virtual QIcon icon() override; | ||||
| 	virtual QString id() override; | ||||
| 	virtual QString helpPage() override { return m_helpName; }; | ||||
| 	virtual bool shouldDisplay(); | ||||
| 	virtual QString displayName() const override; | ||||
| 	virtual QIcon icon() const override; | ||||
| 	virtual QString id() const override; | ||||
| 	virtual QString helpPage() const override | ||||
| 	{ | ||||
| 		return m_helpName; | ||||
| 	} | ||||
| 	virtual bool shouldDisplay() const; | ||||
|  | ||||
| protected: | ||||
| 	bool eventFilter(QObject *obj, QEvent *ev); | ||||
| 	bool modListFilter(QKeyEvent *ev); | ||||
|  | ||||
| protected: | ||||
| 	BaseInstance * m_inst; | ||||
| 	BaseInstance *m_inst; | ||||
|  | ||||
| private: | ||||
| 	Ui::ModFolderPage *ui; | ||||
| 	std::shared_ptr<ModList> m_mods; | ||||
| @@ -53,10 +60,12 @@ private: | ||||
| 	QString m_displayName; | ||||
| 	QString m_helpName; | ||||
|  | ||||
| public slots: | ||||
| public | ||||
| slots: | ||||
| 	void modCurrent(const QModelIndex ¤t, const QModelIndex &previous); | ||||
|  | ||||
| private slots: | ||||
| private | ||||
| slots: | ||||
| 	void on_addModBtn_clicked(); | ||||
| 	void on_rmModBtn_clicked(); | ||||
| 	void on_viewModBtn_clicked(); | ||||
| @@ -68,6 +77,8 @@ public: | ||||
| 	explicit CoreModFolderPage(BaseInstance *inst, std::shared_ptr<ModList> mods, QString id, | ||||
| 							   QString iconName, QString displayName, QString helpPage = "", | ||||
| 							   QWidget *parent = 0); | ||||
| 	virtual ~CoreModFolderPage(){}; | ||||
| 	virtual bool shouldDisplay(); | ||||
| 	virtual ~CoreModFolderPage() | ||||
| 	{ | ||||
| 	} | ||||
| 	virtual bool shouldDisplay() const; | ||||
| }; | ||||
|   | ||||
| @@ -1,17 +1,17 @@ | ||||
| #include "NotesPage.h" | ||||
| #include "ui_NotesPage.h" | ||||
|  | ||||
| QString NotesPage::displayName() | ||||
| QString NotesPage::displayName() const | ||||
| { | ||||
| 	return tr("Notes"); | ||||
| } | ||||
|  | ||||
| QIcon NotesPage::icon() | ||||
| QIcon NotesPage::icon() const | ||||
| { | ||||
| 	return QIcon::fromTheme("news"); | ||||
| } | ||||
|  | ||||
| QString NotesPage::id() | ||||
| QString NotesPage::id() const | ||||
| { | ||||
| 	return "notes"; | ||||
| } | ||||
|   | ||||
| @@ -33,11 +33,11 @@ class NotesPage : public QWidget, public BasePage | ||||
| public: | ||||
| 	explicit NotesPage(BaseInstance *inst, QWidget *parent = 0); | ||||
| 	virtual ~NotesPage(); | ||||
| 	virtual QString displayName() override; | ||||
| 	virtual QIcon icon() override; | ||||
| 	virtual QString id() override; | ||||
| 	virtual QString displayName() const override; | ||||
| 	virtual QIcon icon() const override; | ||||
| 	virtual QString id() const override; | ||||
| 	virtual bool apply(); | ||||
| 	virtual QString helpPage() override { return "Notes"; }; | ||||
| 	virtual QString helpPage() const override { return "Notes"; } | ||||
|  | ||||
| private: | ||||
| 	Ui::NotesPage *ui; | ||||
|   | ||||
							
								
								
									
										122
									
								
								gui/pages/OtherLogsPage.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										122
									
								
								gui/pages/OtherLogsPage.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,122 @@ | ||||
| #include "OtherLogsPage.h" | ||||
| #include "ui_OtherLogsPage.h" | ||||
|  | ||||
| #include <QFileDialog> | ||||
| #include <QMessageBox> | ||||
|  | ||||
| #include "gui/GuiUtil.h" | ||||
| #include "logic/RecursiveFileSystemWatcher.h" | ||||
| #include "logic/BaseInstance.h" | ||||
|  | ||||
| OtherLogsPage::OtherLogsPage(BaseInstance *instance, QWidget *parent) : | ||||
| 	QWidget(parent), | ||||
| 	ui(new Ui::OtherLogsPage), | ||||
| 	m_instance(instance), | ||||
| 	m_watcher(new RecursiveFileSystemWatcher(this)) | ||||
| { | ||||
| 	ui->setupUi(this); | ||||
| 	connect(m_watcher, &RecursiveFileSystemWatcher::filesChanged, [this]() | ||||
| 	{ | ||||
| 		ui->selectLogBox->clear(); | ||||
| 		ui->selectLogBox->addItems(m_watcher->files()); | ||||
| 		ui->selectLogBox->addItem(tr("&Other"), true); | ||||
| 		if (m_currentFile.isNull()) | ||||
| 		{ | ||||
| 			ui->selectLogBox->setCurrentIndex(-1); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			const int index = ui->selectLogBox->findText(m_currentFile); | ||||
| 			ui->selectLogBox->setCurrentIndex(-1); | ||||
| 		} | ||||
| 	}); | ||||
| } | ||||
|  | ||||
| OtherLogsPage::~OtherLogsPage() | ||||
| { | ||||
| 	delete ui; | ||||
| } | ||||
|  | ||||
| void OtherLogsPage::opened() | ||||
| { | ||||
| 	m_watcher->enable(); | ||||
| } | ||||
| void OtherLogsPage::closed() | ||||
| { | ||||
| 	m_watcher->disable(); | ||||
| } | ||||
|  | ||||
| void OtherLogsPage::on_selectLogBox_currentIndexChanged(const int index) | ||||
| { | ||||
| 	QString file; | ||||
| 	if (index != -1) | ||||
| 	{ | ||||
| 		if (ui->selectLogBox->itemData(index).isValid()) | ||||
| 		{ | ||||
| 			file = QFileDialog::getOpenFileName(this, tr("Open log file"), m_instance->minecraftRoot(), tr("*.log;;*.txt;;*")); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			file = ui->selectLogBox->itemText(index); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (file.isEmpty() || !QFile::exists(file)) | ||||
| 	{ | ||||
| 		m_currentFile = QString(); | ||||
| 		setControlsEnabled(false); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		m_currentFile = file; | ||||
| 		on_btnReload_clicked(); | ||||
| 		setControlsEnabled(true); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void OtherLogsPage::on_btnReload_clicked() | ||||
| { | ||||
| 	QFile file(m_currentFile); | ||||
| 	if (!file.open(QFile::ReadOnly)) | ||||
| 	{ | ||||
| 		setControlsEnabled(false); | ||||
| 		ui->btnReload->setEnabled(true); // allow reload | ||||
| 		m_currentFile = QString(); | ||||
| 		QMessageBox::critical(this, tr("Error"), tr("Unable to open %1 for reading: %2").arg(m_currentFile, file.errorString())); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		ui->text->setPlainText(QString::fromUtf8(file.readAll())); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void OtherLogsPage::on_btnPaste_clicked() | ||||
| { | ||||
| 	GuiUtil::uploadPaste(ui->text->toPlainText(), this); | ||||
| } | ||||
| void OtherLogsPage::on_btnCopy_clicked() | ||||
| { | ||||
| 	GuiUtil::setClipboardText(ui->text->toPlainText()); | ||||
| } | ||||
| void OtherLogsPage::on_btnDelete_clicked() | ||||
| { | ||||
| 	if (QMessageBox::question(this, tr("Delete"), tr("Do you really want to delete %1?").arg(m_currentFile), QMessageBox::Yes, QMessageBox::No) | ||||
| 			== QMessageBox::No) | ||||
| 	{ | ||||
| 		return; | ||||
| 	} | ||||
| 	QFile file(m_currentFile); | ||||
| 	if (!file.remove()) | ||||
| 	{ | ||||
| 		QMessageBox::critical(this, tr("Error"), tr("Unable to delete %1: %2").arg(m_currentFile, file.errorString())); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void OtherLogsPage::setControlsEnabled(const bool enabled) | ||||
| { | ||||
| 	ui->btnReload->setEnabled(enabled); | ||||
| 	ui->btnDelete->setEnabled(enabled); | ||||
| 	ui->btnCopy->setEnabled(enabled); | ||||
| 	ui->btnPaste->setEnabled(enabled); | ||||
| 	ui->text->setEnabled(enabled); | ||||
| } | ||||
							
								
								
									
										45
									
								
								gui/pages/OtherLogsPage.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								gui/pages/OtherLogsPage.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include <QWidget> | ||||
|  | ||||
| #include "BasePage.h" | ||||
|  | ||||
| namespace Ui { | ||||
| class OtherLogsPage; | ||||
| } | ||||
|  | ||||
| class RecursiveFileSystemWatcher; | ||||
|  | ||||
| class BaseInstance; | ||||
|  | ||||
| class OtherLogsPage : public QWidget, public BasePage | ||||
| { | ||||
| 	Q_OBJECT | ||||
|  | ||||
| public: | ||||
| 	explicit OtherLogsPage(BaseInstance *instance, QWidget *parent = 0); | ||||
| 	~OtherLogsPage(); | ||||
|  | ||||
| 	QString id() const override { return "logs"; } | ||||
| 	QString displayName() const override { return tr("Other logs"); } | ||||
| 	QIcon icon() const override  { return QIcon(); } // TODO | ||||
| 	QString helpPage() const override { return "Minecraft-Logs"; } | ||||
| 	void opened() override; | ||||
| 	void closed() override; | ||||
|  | ||||
| private | ||||
| slots: | ||||
| 	void on_selectLogBox_currentIndexChanged(const int index); | ||||
| 	void on_btnReload_clicked(); | ||||
| 	void on_btnPaste_clicked(); | ||||
| 	void on_btnCopy_clicked(); | ||||
| 	void on_btnDelete_clicked(); | ||||
|  | ||||
| private: | ||||
| 	Ui::OtherLogsPage *ui; | ||||
| 	BaseInstance *m_instance; | ||||
| 	RecursiveFileSystemWatcher *m_watcher; | ||||
| 	QString m_currentFile; | ||||
|  | ||||
| 	void setControlsEnabled(const bool enabled); | ||||
| }; | ||||
							
								
								
									
										107
									
								
								gui/pages/OtherLogsPage.ui
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								gui/pages/OtherLogsPage.ui
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,107 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <ui version="4.0"> | ||||
|  <class>OtherLogsPage</class> | ||||
|  <widget class="QWidget" name="OtherLogsPage"> | ||||
|   <property name="geometry"> | ||||
|    <rect> | ||||
|     <x>0</x> | ||||
|     <y>0</y> | ||||
|     <width>640</width> | ||||
|     <height>480</height> | ||||
|    </rect> | ||||
|   </property> | ||||
|   <property name="windowTitle"> | ||||
|    <string>Form</string> | ||||
|   </property> | ||||
|   <layout class="QHBoxLayout" name="horizontalLayout"> | ||||
|    <property name="leftMargin"> | ||||
|     <number>0</number> | ||||
|    </property> | ||||
|    <property name="topMargin"> | ||||
|     <number>0</number> | ||||
|    </property> | ||||
|    <property name="rightMargin"> | ||||
|     <number>0</number> | ||||
|    </property> | ||||
|    <property name="bottomMargin"> | ||||
|     <number>0</number> | ||||
|    </property> | ||||
|    <item> | ||||
|     <widget class="QPlainTextEdit" name="text"> | ||||
|      <property name="enabled"> | ||||
|       <bool>false</bool> | ||||
|      </property> | ||||
|      <property name="readOnly"> | ||||
|       <bool>true</bool> | ||||
|      </property> | ||||
|     </widget> | ||||
|    </item> | ||||
|    <item> | ||||
|     <layout class="QVBoxLayout" name="verticalLayout"> | ||||
|      <item> | ||||
|       <widget class="QComboBox" name="selectLogBox"/> | ||||
|      </item> | ||||
|      <item> | ||||
|       <widget class="QPushButton" name="btnReload"> | ||||
|        <property name="text"> | ||||
|         <string>Reload</string> | ||||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item> | ||||
|       <widget class="Line" name="line"> | ||||
|        <property name="orientation"> | ||||
|         <enum>Qt::Horizontal</enum> | ||||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item> | ||||
|       <widget class="QPushButton" name="btnPaste"> | ||||
|        <property name="toolTip"> | ||||
|         <string>Upload the log to paste.ee - it will stay online for a month</string> | ||||
|        </property> | ||||
|        <property name="text"> | ||||
|         <string>Upload Log</string> | ||||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item> | ||||
|       <widget class="QPushButton" name="btnCopy"> | ||||
|        <property name="toolTip"> | ||||
|         <string>Copy the whole log into the clipboard</string> | ||||
|        </property> | ||||
|        <property name="text"> | ||||
|         <string>&Copy Log</string> | ||||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item> | ||||
|       <widget class="QPushButton" name="btnDelete"> | ||||
|        <property name="toolTip"> | ||||
|         <string>Clear the log</string> | ||||
|        </property> | ||||
|        <property name="text"> | ||||
|         <string>Delete</string> | ||||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item> | ||||
|       <spacer name="verticalSpacer"> | ||||
|        <property name="orientation"> | ||||
|         <enum>Qt::Vertical</enum> | ||||
|        </property> | ||||
|        <property name="sizeHint" stdset="0"> | ||||
|         <size> | ||||
|          <width>20</width> | ||||
|          <height>40</height> | ||||
|         </size> | ||||
|        </property> | ||||
|       </spacer> | ||||
|      </item> | ||||
|     </layout> | ||||
|    </item> | ||||
|   </layout> | ||||
|  </widget> | ||||
|  <resources/> | ||||
|  <connections/> | ||||
| </ui> | ||||
| @@ -10,8 +10,8 @@ public: | ||||
| 	{ | ||||
| 	} | ||||
|  | ||||
| 	virtual ~ResourcePackPage() {}; | ||||
| 	virtual bool shouldDisplay() override | ||||
| 	virtual ~ResourcePackPage() {} | ||||
| 	virtual bool shouldDisplay() const override | ||||
| 	{ | ||||
| 		return !m_inst->traits().contains("no-texturepacks") && | ||||
| 			   !m_inst->traits().contains("texturepacks"); | ||||
|   | ||||
| @@ -221,17 +221,17 @@ public: | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| QString ScreenshotsPage::displayName() | ||||
| QString ScreenshotsPage::displayName() const | ||||
| { | ||||
| 	return tr("Screenshots"); | ||||
| } | ||||
|  | ||||
| QIcon ScreenshotsPage::icon() | ||||
| QIcon ScreenshotsPage::icon() const | ||||
| { | ||||
| 	return QIcon::fromTheme("screenshots"); | ||||
| } | ||||
|  | ||||
| QString ScreenshotsPage::id() | ||||
| QString ScreenshotsPage::id() const | ||||
| { | ||||
| 	return "screenshots"; | ||||
| } | ||||
|   | ||||
| @@ -47,10 +47,10 @@ public: | ||||
| 	}; | ||||
| 	 | ||||
| 	virtual bool eventFilter(QObject *, QEvent *); | ||||
| 	virtual QString displayName() override; | ||||
| 	virtual QIcon icon() override; | ||||
| 	virtual QString id() override; | ||||
| 	virtual QString helpPage() override { return "Screenshots-management"; }; | ||||
| 	virtual QString displayName() const override; | ||||
| 	virtual QIcon icon() const override; | ||||
| 	virtual QString id() const override; | ||||
| 	virtual QString helpPage() const override { return "Screenshots-management"; } | ||||
| private | ||||
| slots: | ||||
| 	void on_uploadBtn_clicked(); | ||||
|   | ||||
| @@ -9,8 +9,8 @@ public: | ||||
| 						tr("Texture packs"), "Texture-packs", parent) | ||||
| 	{ | ||||
| 	} | ||||
| 	virtual ~TexturePackPage() {}; | ||||
| 	virtual bool shouldDisplay() override | ||||
| 	virtual ~TexturePackPage() {} | ||||
| 	virtual bool shouldDisplay() const override | ||||
| 	{ | ||||
| 		return m_inst->traits().contains("texturepacks"); | ||||
| 	} | ||||
|   | ||||
| @@ -50,22 +50,22 @@ | ||||
| #include <QString> | ||||
| #include <QUrl> | ||||
|  | ||||
| QString VersionPage::displayName() | ||||
| QString VersionPage::displayName() const | ||||
| { | ||||
| 	return tr("Version"); | ||||
| } | ||||
|  | ||||
| QIcon VersionPage::icon() | ||||
| QIcon VersionPage::icon() const | ||||
| { | ||||
| 	return MMC->icons()->getIcon(m_inst->iconKey()); | ||||
| } | ||||
|  | ||||
| QString VersionPage::id() | ||||
| QString VersionPage::id() const | ||||
| { | ||||
| 	return "version"; | ||||
| } | ||||
|  | ||||
| bool VersionPage::shouldDisplay() | ||||
| bool VersionPage::shouldDisplay() const | ||||
| { | ||||
| 	return !m_inst->isRunning(); | ||||
| } | ||||
|   | ||||
| @@ -33,11 +33,11 @@ class VersionPage : public QWidget, public BasePage | ||||
| public: | ||||
| 	explicit VersionPage(OneSixInstance *inst, QWidget *parent = 0); | ||||
| 	virtual ~VersionPage(); | ||||
| 	virtual QString displayName() override; | ||||
| 	virtual QIcon icon() override; | ||||
| 	virtual QString id() override; | ||||
| 	virtual QString helpPage() override { return "Instance-version"; }; | ||||
| 	virtual bool shouldDisplay(); | ||||
| 	virtual QString displayName() const override; | ||||
| 	virtual QIcon icon() const override; | ||||
| 	virtual QString id() const override; | ||||
| 	virtual QString helpPage() const override { return "Instance-version"; } | ||||
| 	virtual bool shouldDisplay() const; | ||||
| private | ||||
| slots: | ||||
|  | ||||
|   | ||||
| @@ -45,14 +45,16 @@ protected: | ||||
| 		const QString pattern = filterRegExp().pattern(); | ||||
| 		const auto model = static_cast<PageModel *>(sourceModel()); | ||||
| 		const auto page = model->pages().at(sourceRow); | ||||
| 		if(!page->shouldDisplay()) | ||||
| 		if (!page->shouldDisplay()) | ||||
| 			return false; | ||||
| 		// Regular contents check, then check page-filter. | ||||
| 		return QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent); | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| PageContainer::PageContainer(BasePageProviderPtr pageProvider, QString defaultId, QWidget *parent) : QWidget(parent) | ||||
| PageContainer::PageContainer(BasePageProviderPtr pageProvider, QString defaultId, | ||||
| 							 QWidget *parent) | ||||
| 	: QWidget(parent) | ||||
| { | ||||
| 	createUI(); | ||||
| 	m_model = new PageModel(this); | ||||
| @@ -60,12 +62,12 @@ PageContainer::PageContainer(BasePageProviderPtr pageProvider, QString defaultId | ||||
| 	int firstIndex = -1; | ||||
| 	int counter = 0; | ||||
| 	auto pages = pageProvider->getPages(); | ||||
| 	for(auto page: pages) | ||||
| 	for (auto page : pages) | ||||
| 	{ | ||||
| 		page->stackIndex = m_pageStack->addWidget(dynamic_cast<QWidget *>(page)); | ||||
| 		page->listIndex = counter; | ||||
| 		counter++; | ||||
| 		if(firstIndex == -1) | ||||
| 		if (firstIndex == -1) | ||||
| 		{ | ||||
| 			firstIndex = page->stackIndex; | ||||
| 		} | ||||
| @@ -79,22 +81,22 @@ PageContainer::PageContainer(BasePageProviderPtr pageProvider, QString defaultId | ||||
| 	m_pageList->setSelectionMode(QAbstractItemView::SingleSelection); | ||||
| 	m_pageList->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); | ||||
| 	m_pageList->setModel(m_proxyModel); | ||||
|     connect(m_pageList->selectionModel(), SIGNAL(currentRowChanged(QModelIndex,QModelIndex)), | ||||
|             this, SLOT(currentChanged(QModelIndex))); | ||||
| 	connect(m_pageList->selectionModel(), SIGNAL(currentRowChanged(QModelIndex, QModelIndex)), | ||||
| 			this, SLOT(currentChanged(QModelIndex))); | ||||
| 	m_pageStack->setStackingMode(QStackedLayout::StackOne); | ||||
| 	m_pageList->setFocus(); | ||||
| 	// now find what we want to have selected... | ||||
| 	auto page = m_model->findPageEntryById(defaultId); | ||||
| 	QModelIndex index; | ||||
| 	if(page) | ||||
| 	if (page) | ||||
| 	{ | ||||
| 		index = m_proxyModel->mapFromSource(m_model->index(page->listIndex)); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		index = m_proxyModel->index(0,0); | ||||
| 		index = m_proxyModel->index(0, 0); | ||||
| 	} | ||||
| 	if(index.isValid()) | ||||
| 	if (index.isValid()) | ||||
| 		m_pageList->setCurrentIndex(index); | ||||
| } | ||||
|  | ||||
| @@ -104,7 +106,7 @@ void PageContainer::createUI() | ||||
| 	m_filter = new QLineEdit; | ||||
| 	m_pageList = new PageView; | ||||
| 	m_header = new QLabel(); | ||||
| 	m_iconHeader = new IconLabel(this, QIcon(), QSize(24,24)); | ||||
| 	m_iconHeader = new IconLabel(this, QIcon(), QSize(24, 24)); | ||||
|  | ||||
| 	QFont headerLabelFont = m_header->font(); | ||||
| 	headerLabelFont.setBold(true); | ||||
| @@ -143,10 +145,13 @@ void PageContainer::addButtons(QLayout *buttons) | ||||
| 	m_layout->addLayout(buttons, 2, 0, 1, 2); | ||||
| } | ||||
|  | ||||
|  | ||||
| void PageContainer::showPage(int row) | ||||
| { | ||||
| 	if(row != -1) | ||||
| 	if (m_currentPage) | ||||
| 	{ | ||||
| 		m_currentPage->closed(); | ||||
| 	} | ||||
| 	if (row != -1) | ||||
| 	{ | ||||
| 		m_currentPage = m_model->pages().at(row); | ||||
| 	} | ||||
| @@ -154,7 +159,7 @@ void PageContainer::showPage(int row) | ||||
| 	{ | ||||
| 		m_currentPage = nullptr; | ||||
| 	} | ||||
| 	if(m_currentPage) | ||||
| 	if (m_currentPage) | ||||
| 	{ | ||||
| 		m_pageStack->setCurrentIndex(m_currentPage->stackIndex); | ||||
| 		m_header->setText(m_currentPage->displayName()); | ||||
| @@ -171,10 +176,10 @@ void PageContainer::showPage(int row) | ||||
|  | ||||
| void PageContainer::help() | ||||
| { | ||||
| 	if(m_currentPage) | ||||
| 	if (m_currentPage) | ||||
| 	{ | ||||
| 		QString pageId = m_currentPage->helpPage(); | ||||
| 		if(pageId.isEmpty()) | ||||
| 		if (pageId.isEmpty()) | ||||
| 			return; | ||||
| 		QDesktopServices::openUrl(QUrl("https://github.com/MultiMC/MultiMC5/wiki/" + pageId)); | ||||
| 	} | ||||
| @@ -185,11 +190,11 @@ void PageContainer::currentChanged(const QModelIndex ¤t) | ||||
| 	showPage(current.isValid() ? m_proxyModel->mapToSource(current).row() : -1); | ||||
| } | ||||
|  | ||||
| bool PageContainer::requestClose(QCloseEvent * event) | ||||
| bool PageContainer::requestClose(QCloseEvent *event) | ||||
| { | ||||
| 	for(auto page: m_model->pages()) | ||||
| 	for (auto page : m_model->pages()) | ||||
| 	{ | ||||
| 		if(!page->apply()) | ||||
| 		if (!page->apply()) | ||||
| 			return false; | ||||
| 	} | ||||
| 	return true; | ||||
|   | ||||
| @@ -31,12 +31,13 @@ | ||||
| #include "logic/MinecraftProcess.h" | ||||
| #include "gui/pagedialog/PageDialog.h" | ||||
| #include "gui/pages/VersionPage.h" | ||||
| #include <gui/pages/ModFolderPage.h> | ||||
| #include <gui/pages/ResourcePackPage.h> | ||||
| #include <gui/pages/TexturePackPage.h> | ||||
| #include <gui/pages/InstanceSettingsPage.h> | ||||
| #include <gui/pages/NotesPage.h> | ||||
| #include <gui/pages/ScreenshotsPage.h> | ||||
| #include "gui/pages/ModFolderPage.h" | ||||
| #include "gui/pages/ResourcePackPage.h" | ||||
| #include "gui/pages/TexturePackPage.h" | ||||
| #include "gui/pages/InstanceSettingsPage.h" | ||||
| #include "gui/pages/NotesPage.h" | ||||
| #include "gui/pages/ScreenshotsPage.h" | ||||
| #include "gui/pages/OtherLogsPage.h" | ||||
|  | ||||
| OneSixInstance::OneSixInstance(const QString &rootDir, SettingsObject *settings, | ||||
| 							   QObject *parent) | ||||
| @@ -72,6 +73,7 @@ QList<BasePage *> OneSixInstance::getPages() | ||||
| 	values.append(new NotesPage(this)); | ||||
| 	values.append(new ScreenshotsPage(this)); | ||||
| 	values.append(new InstanceSettingsPage(this)); | ||||
| 	values.append(new OtherLogsPage(this)); | ||||
| 	return values; | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										97
									
								
								logic/RecursiveFileSystemWatcher.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								logic/RecursiveFileSystemWatcher.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,97 @@ | ||||
| #include "RecursiveFileSystemWatcher.h" | ||||
|  | ||||
| #include <QRegularExpression> | ||||
|  | ||||
| RecursiveFileSystemWatcher::RecursiveFileSystemWatcher(QObject *parent) | ||||
| 	: QObject(parent), | ||||
| 	  m_watcher(new QFileSystemWatcher(this)) | ||||
| { | ||||
| 	connect(m_watcher, &QFileSystemWatcher::fileChanged, this, &RecursiveFileSystemWatcher::fileChange); | ||||
| 	connect(m_watcher, &QFileSystemWatcher::directoryChanged, this, &RecursiveFileSystemWatcher::directoryChange); | ||||
| } | ||||
|  | ||||
| void RecursiveFileSystemWatcher::setRootDir(const QDir &root) | ||||
| { | ||||
| 	bool wasEnabled = m_isEnabled; | ||||
| 	disable(); | ||||
| 	m_root = root; | ||||
| 	setFiles(scanRecursive(m_root)); | ||||
| 	if (wasEnabled) | ||||
| 	{ | ||||
| 		enable(); | ||||
| 	} | ||||
| } | ||||
| void RecursiveFileSystemWatcher::setWatchFiles(const bool watchFiles) | ||||
| { | ||||
| 	bool wasEnabled = m_isEnabled; | ||||
| 	disable(); | ||||
| 	m_watchFiles = watchFiles; | ||||
| 	if (wasEnabled) | ||||
| 	{ | ||||
| 		enable(); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void RecursiveFileSystemWatcher::enable() | ||||
| { | ||||
| 	Q_ASSERT(m_root != QDir::root()); | ||||
| 	addFilesToWatcherRecursive(m_root); | ||||
| 	m_isEnabled = true; | ||||
| } | ||||
| void RecursiveFileSystemWatcher::disable() | ||||
| { | ||||
| 	m_isEnabled = false; | ||||
| 	m_watcher->removePaths(m_watcher->files()); | ||||
| 	m_watcher->removePaths(m_watcher->directories()); | ||||
| } | ||||
|  | ||||
| void RecursiveFileSystemWatcher::setFiles(const QStringList &files) | ||||
| { | ||||
| 	if (files != m_files) | ||||
| 	{ | ||||
| 		m_files = files; | ||||
| 		emit filesChanged(); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void RecursiveFileSystemWatcher::addFilesToWatcherRecursive(const QDir &dir) | ||||
| { | ||||
| 	m_watcher->addPath(dir.absolutePath()); | ||||
| 	for (const QFileInfo &info : dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot)) | ||||
| 	{ | ||||
| 		addFilesToWatcherRecursive(info.absoluteDir()); | ||||
| 	} | ||||
| 	if (m_watchFiles) | ||||
| 	{ | ||||
| 		for (const QFileInfo &info : dir.entryInfoList(QDir::Files)) | ||||
| 		{ | ||||
| 			m_watcher->addPath(info.absoluteFilePath()); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| QStringList RecursiveFileSystemWatcher::scanRecursive(const QDir &dir) | ||||
| { | ||||
| 	QStringList ret; | ||||
| 	QRegularExpression exp(m_exp); | ||||
| 	for (const QFileInfo &info : dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::Files)) | ||||
| 	{ | ||||
| 		if (info.isFile() && exp.match(info.absoluteFilePath()).hasMatch()) | ||||
| 		{ | ||||
| 			ret.append(info.absoluteFilePath()); | ||||
| 		} | ||||
| 		else if (info.isDir()) | ||||
| 		{ | ||||
| 			ret.append(scanRecursive(info.absoluteDir())); | ||||
| 		} | ||||
| 	} | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| void RecursiveFileSystemWatcher::fileChange(const QString &path) | ||||
| { | ||||
| 	emit fileChanged(path); | ||||
| } | ||||
| void RecursiveFileSystemWatcher::directoryChange(const QString &path) | ||||
| { | ||||
| 	setFiles(scanRecursive(m_root)); | ||||
| } | ||||
							
								
								
									
										51
									
								
								logic/RecursiveFileSystemWatcher.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								logic/RecursiveFileSystemWatcher.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,51 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include <QFileSystemWatcher> | ||||
| #include <QDir> | ||||
|  | ||||
| class RecursiveFileSystemWatcher : public QObject | ||||
| { | ||||
| 	Q_OBJECT | ||||
| public: | ||||
| 	RecursiveFileSystemWatcher(QObject *parent); | ||||
|  | ||||
| 	void setRootDir(const QDir &root); | ||||
| 	QDir rootDir() const { return m_root; } | ||||
|  | ||||
| 	// WARNING: setting this to true may be bad for performance | ||||
| 	void setWatchFiles(const bool watchFiles); | ||||
| 	bool watchFiles() const { return m_watchFiles; } | ||||
|  | ||||
| 	void setFileExpression(const QString &exp) { m_exp = exp; } | ||||
| 	QString fileExpression() const { return m_exp; } | ||||
|  | ||||
| 	QStringList files() const { return m_files; } | ||||
|  | ||||
| signals: | ||||
| 	void filesChanged(); | ||||
| 	void fileChanged(const QString &path); | ||||
|  | ||||
| public | ||||
| slots: | ||||
| 	void enable(); | ||||
| 	void disable(); | ||||
|  | ||||
| private: | ||||
| 	QDir m_root; | ||||
| 	bool m_watchFiles = false; | ||||
| 	bool m_isEnabled = false; | ||||
| 	QString m_exp; | ||||
|  | ||||
| 	QFileSystemWatcher *m_watcher; | ||||
|  | ||||
| 	QStringList m_files; | ||||
| 	void setFiles(const QStringList &scanRecursive); | ||||
|  | ||||
| 	void addFilesToWatcherRecursive(const QDir &dir); | ||||
| 	QStringList scanRecursive(const QDir &dir); | ||||
|  | ||||
| private | ||||
| slots: | ||||
| 	void fileChange(const QString &path); | ||||
| 	void directoryChange(const QString &path); | ||||
| }; | ||||
		Reference in New Issue
	
	Block a user