From d884f849d60db44f05a6a6b22f4ffcf520900389 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Sun, 25 Aug 2013 01:32:42 +0200 Subject: All kinds of incremental improvements Redone the instance action toolbar: * Removed all the dead actions * Change icon and Rename are now morphed into a header * Added button for opening the config folder Implemented support for loose files and folders as legacy jar mods Added texture pack support --- depends/quazip/JlCompress.cpp | 32 ++-- depends/quazip/JlCompress.h | 16 +- gui/LegacyModEditDialog.cpp | 60 +++++++- gui/LegacyModEditDialog.h | 1 + gui/LegacyModEditDialog.ui | 4 +- gui/mainwindow.cpp | 179 +++++++++++++--------- gui/mainwindow.h | 17 +-- gui/mainwindow.ui | 68 +++++---- logic/BaseInstance.h | 8 + logic/LegacyInstance.cpp | 36 +++++ logic/LegacyInstance.h | 6 + logic/LegacyInstance_p.h | 1 + logic/LegacyUpdate.cpp | 51 ++++--- logic/ModList.cpp | 342 +++++------------------------------------- logic/ModList.h | 10 +- logic/NostalgiaInstance.cpp | 6 + logic/NostalgiaInstance.h | 1 + logic/OneSixInstance.cpp | 19 +++ logic/OneSixInstance.h | 5 + 19 files changed, 399 insertions(+), 463 deletions(-) diff --git a/depends/quazip/JlCompress.cpp b/depends/quazip/JlCompress.cpp index 19bf6246..a6cf0eaf 100644 --- a/depends/quazip/JlCompress.cpp +++ b/depends/quazip/JlCompress.cpp @@ -75,17 +75,18 @@ bool JlCompress::compressFile(QuaZip* zip, QString fileName, QString fileDest) { * dunque gli errori di compressione di una sotto cartella sono gli stessi di questa * funzione. */ -bool JlCompress::compressSubDir(QuaZip* zip, QString dir, QString origDir, bool recursive) { +bool JlCompress::compressSubDir( QuaZip* parentZip, QString dir, QString parentDir, bool recursive, QSet& added ) +{ // zip: oggetto dove aggiungere il file // dir: cartella reale corrente // origDir: cartella reale originale // (path(dir)-path(origDir)) = path interno all'oggetto zip // Controllo l'apertura dello zip - if (!zip) return false; - if (zip->getMode()!=QuaZip::mdCreate && - zip->getMode()!=QuaZip::mdAppend && - zip->getMode()!=QuaZip::mdAdd) return false; + if (!parentZip ) return false; + if ( parentZip->getMode()!=QuaZip::mdCreate && + parentZip->getMode()!=QuaZip::mdAppend && + parentZip->getMode()!=QuaZip::mdAdd) return false; // Controllo la cartella QDir directory(dir); @@ -95,24 +96,28 @@ bool JlCompress::compressSubDir(QuaZip* zip, QString dir, QString origDir, bool if (recursive) { // Per ogni sotto cartella QFileInfoList files = directory.entryInfoList(QDir::AllDirs|QDir::NoDotAndDotDot); - Q_FOREACH (QFileInfo file, files) { + Q_FOREACH (QFileInfo file, files) + { // Comprimo la sotto cartella - if(!compressSubDir(zip,file.absoluteFilePath(),origDir,recursive)) return false; + if(!compressSubDir( parentZip,file.absoluteFilePath(),parentDir,recursive,added)) return false; } } // Per ogni file nella cartella QFileInfoList files = directory.entryInfoList(QDir::Files); - QDir origDirectory(origDir); - Q_FOREACH (QFileInfo file, files) { + QDir origDirectory( parentDir ); + Q_FOREACH (QFileInfo file, files) + { // Se non e un file o e il file compresso che sto creando - if(!file.isFile()||file.absoluteFilePath()==zip->getZipName()) continue; + if(!file.isFile()||file.absoluteFilePath()==parentZip->getZipName()) continue; // Creo il nome relativo da usare all'interno del file compresso QString filename = origDirectory.relativeFilePath(file.absoluteFilePath()); // Comprimo il file - if (!compressFile(zip,file.absoluteFilePath(),filename)) return false; + if (!compressFile( parentZip,file.absoluteFilePath(),filename)) + return false; + added.insert(filename); } return true; @@ -290,9 +295,10 @@ bool JlCompress::compressDir(QString fileCompressed, QString dir, bool recursive QFile::remove(fileCompressed); return false; } - + QSet added; // Aggiungo i file e le sotto cartelle - if (!compressSubDir(&zip,dir,dir,recursive)) { + if (!compressSubDir(&zip,dir,dir,recursive, added)) + { QFile::remove(fileCompressed); return false; } diff --git a/depends/quazip/JlCompress.h b/depends/quazip/JlCompress.h index 9679de7c..3ee8c25a 100644 --- a/depends/quazip/JlCompress.h +++ b/depends/quazip/JlCompress.h @@ -16,6 +16,13 @@ */ class QUAZIP_EXPORT JlCompress { private: + /// Remove some files. + /** + \param listFile The list of files to remove. + \return true if success, false otherwise. + */ + static bool removeFile(QStringList listFile); +public: /// Compress a single file. /** \param zip Opened zip to compress the file to. @@ -34,7 +41,7 @@ private: files. \return true if success, false otherwise. */ - static bool compressSubDir(QuaZip* parentZip, QString dir, QString parentDir, bool recursive = true); + static bool compressSubDir( QuaZip* parentZip, QString dir, QString parentDir, bool recursive, QSet< QString >& added ); /// Extract a single file. /** \param zip The opened zip archive to extract from. @@ -43,14 +50,7 @@ private: \return true if success, false otherwise. */ static bool extractFile(QuaZip* zip, QString fileName, QString fileDest); - /// Remove some files. - /** - \param listFile The list of files to remove. - \return true if success, false otherwise. - */ - static bool removeFile(QStringList listFile); -public: /// copy data from inFile to outFile static bool copyData(QIODevice &inFile, QIODevice &outFile); /// Compress a single file. diff --git a/gui/LegacyModEditDialog.cpp b/gui/LegacyModEditDialog.cpp index 218e0979..ea5aa941 100644 --- a/gui/LegacyModEditDialog.cpp +++ b/gui/LegacyModEditDialog.cpp @@ -35,18 +35,29 @@ LegacyModEditDialog::LegacyModEditDialog( LegacyInstance* inst, QWidget* parent m_mods = m_inst->loaderModList(); m_coremods = m_inst->coreModList(); m_jarmods = m_inst->jarModList(); + m_texturepacks = m_inst->texturePackList(); ui->jarModsTreeView->setModel(m_jarmods.data()); ui->coreModsTreeView->setModel(m_coremods.data()); ui->mlModTreeView->setModel(m_mods.data()); + ui->texPackTreeView->setModel(m_texturepacks.data()); ui->jarModsTreeView->installEventFilter( this ); ui->coreModsTreeView->installEventFilter( this ); ui->mlModTreeView->installEventFilter( this ); + ui->texPackTreeView->installEventFilter( this ); + m_mods->startWatching(); + m_coremods->startWatching(); + m_jarmods->startWatching(); + m_texturepacks->startWatching(); } LegacyModEditDialog::~LegacyModEditDialog() { + m_mods->stopWatching(); + m_coremods->stopWatching(); + m_jarmods->stopWatching(); + m_texturepacks->stopWatching(); delete ui; } @@ -116,6 +127,22 @@ bool LegacyModEditDialog::loaderListFilter ( QKeyEvent* keyEvent ) return QDialog::eventFilter( ui->mlModTreeView, keyEvent ); } +bool LegacyModEditDialog::texturePackListFilter ( QKeyEvent* keyEvent ) +{ + switch(keyEvent->key()) + { + case Qt::Key_Delete: + on_rmTexPackBtn_clicked(); + return true; + case Qt::Key_Plus: + on_addTexPackBtn_clicked(); + return true; + default: + break; + } + return QDialog::eventFilter( ui->texPackTreeView, keyEvent ); +} + bool LegacyModEditDialog::eventFilter ( QObject* obj, QEvent* ev ) { @@ -130,6 +157,8 @@ bool LegacyModEditDialog::eventFilter ( QObject* obj, QEvent* ev ) return coreListFilter(keyEvent); if(obj == ui->mlModTreeView) return loaderListFilter(keyEvent); + if(obj == ui->texPackTreeView) + return loaderListFilter(keyEvent); return QDialog::eventFilter( obj, ev ); } @@ -139,7 +168,9 @@ void LegacyModEditDialog::on_addCoreBtn_clicked() QStringList fileNames = QFileDialog::getOpenFileNames(this, "Select Core Mods"); for(auto filename:fileNames) { + m_coremods->stopWatching(); m_coremods->installMod(QFileInfo(filename)); + m_coremods->startWatching(); } } void LegacyModEditDialog::on_addForgeBtn_clicked() @@ -151,7 +182,9 @@ void LegacyModEditDialog::on_addJarBtn_clicked() QStringList fileNames = QFileDialog::getOpenFileNames(this, "Select Jar Mods"); for(auto filename:fileNames) { + m_jarmods->stopWatching(); m_jarmods->installMod(QFileInfo(filename)); + m_jarmods->startWatching(); } } void LegacyModEditDialog::on_addModBtn_clicked() @@ -159,12 +192,20 @@ void LegacyModEditDialog::on_addModBtn_clicked() QStringList fileNames = QFileDialog::getOpenFileNames(this, "Select Loader Mods"); for(auto filename:fileNames) { + m_mods->stopWatching(); m_mods->installMod(QFileInfo(filename)); + m_mods->startWatching(); } } void LegacyModEditDialog::on_addTexPackBtn_clicked() { - + QStringList fileNames = QFileDialog::getOpenFileNames(this, "Select Texture Packs"); + for(auto filename:fileNames) + { + m_texturepacks->stopWatching(); + m_texturepacks->installMod(QFileInfo(filename)); + m_texturepacks->startWatching(); + } } bool lastfirst (QModelIndexList & list, int & first, int & last) @@ -209,7 +250,9 @@ void LegacyModEditDialog::on_rmCoreBtn_clicked() if(!lastfirst(list, first, last)) return; + m_coremods->stopWatching(); m_coremods->deleteMods(first, last); + m_coremods->startWatching(); } void LegacyModEditDialog::on_rmJarBtn_clicked() { @@ -218,7 +261,9 @@ void LegacyModEditDialog::on_rmJarBtn_clicked() if(!lastfirst(list, first, last)) return; + m_jarmods->stopWatching(); m_jarmods->deleteMods(first, last); + m_jarmods->startWatching(); } void LegacyModEditDialog::on_rmModBtn_clicked() { @@ -227,11 +272,20 @@ void LegacyModEditDialog::on_rmModBtn_clicked() if(!lastfirst(list, first, last)) return; + m_mods->stopWatching(); m_mods->deleteMods(first, last); + m_mods->startWatching(); } void LegacyModEditDialog::on_rmTexPackBtn_clicked() { - + int first, last; + auto list = ui->texPackTreeView->selectionModel()->selectedRows(); + + if(!lastfirst(list, first, last)) + return; + m_texturepacks->stopWatching(); + m_texturepacks->deleteMods(first, last); + m_texturepacks->startWatching(); } void LegacyModEditDialog::on_viewCoreBtn_clicked() { @@ -243,7 +297,7 @@ void LegacyModEditDialog::on_viewModBtn_clicked() } void LegacyModEditDialog::on_viewTexPackBtn_clicked() { - //openDirInDefaultProgram(m_inst->mlModsDir(), true); + openDirInDefaultProgram(m_inst->texturePackDir(), true); } diff --git a/gui/LegacyModEditDialog.h b/gui/LegacyModEditDialog.h index 536d402a..bc9ebac0 100644 --- a/gui/LegacyModEditDialog.h +++ b/gui/LegacyModEditDialog.h @@ -56,6 +56,7 @@ protected: bool jarListFilter( QKeyEvent* ev ); bool coreListFilter( QKeyEvent* ev ); bool loaderListFilter( QKeyEvent* ev ); + bool texturePackListFilter( QKeyEvent* ev ); private: Ui::LegacyModEditDialog *ui; QSharedPointer m_mods; diff --git a/gui/LegacyModEditDialog.ui b/gui/LegacyModEditDialog.ui index c219e7c2..bff2bfbe 100644 --- a/gui/LegacyModEditDialog.ui +++ b/gui/LegacyModEditDialog.ui @@ -17,7 +17,7 @@ - 0 + 1 @@ -261,7 +261,7 @@ - QDialogButtonBox::Close|QDialogButtonBox::Reset + QDialogButtonBox::Close diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index 97e60658..b562769e 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -28,6 +28,8 @@ #include #include #include +#include +#include #include "osutils.h" #include "userutils.h" @@ -58,6 +60,8 @@ #include "logic/OneSixUpdate.h" #include "logic/lists/MinecraftVersionList.h" #include "logic/lists/LwjglVersionList.h" +#include +#include #include "instancemodel.h" #include "instancedelegate.h" @@ -69,10 +73,13 @@ MainWindow::MainWindow ( QWidget *parent ) : instList ( globalSettings->get ( "InstanceDir" ).toString() ) { ui->setupUi ( this ); - + + // Set the selected instance to null + m_selectedInstance = nullptr; // Set active instance to null. - m_activeInst = NULL; - + m_activeInst = nullptr; + // the rename label is inside the rename tool button + renameLabel = nullptr; // Create the widget view = new KCategorizedView ( ui->centralWidget ); drawer = new KCategoryDrawer ( view ); @@ -118,12 +125,14 @@ MainWindow::MainWindow ( QWidget *parent ) : // restoreGeometry(settings->getConfig().value("MainWindowGeometry", saveGeometry()).toByteArray()); // restoreState(settings->getConfig().value("MainWindowState", saveState()).toByteArray()); view->setModel ( proxymodel ); - connect(view, SIGNAL(doubleClicked(const QModelIndex &)), - this, SLOT(instanceActivated(const QModelIndex &))); - - connect(view, SIGNAL(clicked(const QModelIndex &)), - this, SLOT(instanceChanged(const QModelIndex &))); - + connect(view, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(instanceActivated(const QModelIndex &))); + auto selectionmodel = view->selectionModel(); + connect( + selectionmodel, + SIGNAL(currentChanged(const QModelIndex &,const QModelIndex &)), + this, + SLOT(instanceChanged(const QModelIndex &,const QModelIndex &)) + ); // Load the instances. FIXME: this is not the place I'd say. instList.loadList(); @@ -242,31 +251,32 @@ void MainWindow::on_actionAddInstance_triggered() void MainWindow::on_actionChangeInstIcon_triggered() { - BaseInstance* inst = selectedInstance(); - if(!inst) + if(!m_selectedInstance) return; IconPickerDialog dlg(this); - dlg.exec(selectedInstance()->iconKey()); + dlg.exec(m_selectedInstance->iconKey()); if(dlg.result() == QDialog::Accepted) { - selectedInstance()->setIconKey(dlg.selectedIconKey); + m_selectedInstance->setIconKey(dlg.selectedIconKey); + IconList * iconListModel = IconList::instance(); + auto ico =iconListModel->getIcon(dlg.selectedIconKey); + ui->actionChangeInstIcon->setIcon(ico); } } void MainWindow::on_actionChangeInstGroup_triggered() { - BaseInstance* inst = selectedInstance(); - if(!inst) + if(!m_selectedInstance) return; bool ok = false; - QString name ( inst->group() ); + QString name ( m_selectedInstance->group() ); name = QInputDialog::getText ( this, tr ( "Group name" ), tr ( "Enter a new group name." ), QLineEdit::Normal, name, &ok ); if(ok) - inst->setGroup(name); + m_selectedInstance->setGroup(name); } @@ -286,6 +296,16 @@ void MainWindow::on_actionViewCentralModsFolder_triggered() openDirInDefaultProgram ( globalSettings->get ( "CentralModsDir" ).toString() , true); } +void MainWindow::on_actionConfig_Folder_triggered() +{ + if(m_selectedInstance) + { + QString str = m_selectedInstance->instanceConfigFolder(); + openDirInDefaultProgram ( QDir(str).absolutePath() ); + } +} + + void MainWindow::on_actionCheckUpdate_triggered() { @@ -322,14 +342,13 @@ void MainWindow::on_mainToolBar_visibilityChanged ( bool ) void MainWindow::on_actionDeleteInstance_triggered() { - BaseInstance* inst = selectedInstance(); - if (inst) + if (m_selectedInstance) { int response = QMessageBox::question(this, "CAREFUL", - QString("This is permanent! Are you sure?\nAbout to delete: ") + inst->name()); + QString("This is permanent! Are you sure?\nAbout to delete: ") + m_selectedInstance->name()); if (response == QMessageBox::Yes) { - QDir(inst->instanceRoot()).removeRecursively(); + QDir(m_selectedInstance->instanceRoot()).removeRecursively(); instList.loadList(); } } @@ -337,38 +356,38 @@ void MainWindow::on_actionDeleteInstance_triggered() void MainWindow::on_actionRenameInstance_triggered() { - BaseInstance* inst = selectedInstance(); - if(inst) + if(m_selectedInstance) { bool ok = false; - QString name ( inst->name() ); + QString name ( m_selectedInstance->name() ); name = QInputDialog::getText ( this, tr ( "Instance name" ), tr ( "Enter a new instance name." ), QLineEdit::Normal, name, &ok ); if (name.length() > 0) { if(ok && name.length() && name.length() <= 25) - inst->setName(name); + m_selectedInstance->setName(name); + //ui->actionRenameInstance->setText(name); + setRenameText(name); } + } } void MainWindow::on_actionViewSelectedInstFolder_triggered() { - BaseInstance* inst = selectedInstance(); - if(inst) + if(m_selectedInstance) { - QString str = inst->instanceRoot(); + QString str = m_selectedInstance->instanceRoot(); openDirInDefaultProgram ( QDir(str).absolutePath() ); } } void MainWindow::on_actionEditInstMods_triggered() { - BaseInstance* inst = selectedInstance(); - if (inst) + if (m_selectedInstance) { - auto dialog = inst->createModEditDialog(this); + auto dialog = m_selectedInstance->createModEditDialog(this); if(dialog) dialog->exec(); dialog->deleteLater(); @@ -394,30 +413,9 @@ void MainWindow::on_instanceView_customContextMenuRequested ( const QPoint &pos instContextMenu->exec ( view->mapToGlobal ( pos ) ); } -BaseInstance* MainWindow::selectedInstance() -{ - QAbstractItemView * iv = view; - auto smodel = iv->selectionModel(); - QModelIndex mindex; - if(smodel->hasSelection()) - { - auto rows = smodel->selectedRows(); - mindex = rows.at(0); - } - - if(mindex.isValid()) - { - return (BaseInstance *) mindex.data(InstanceModel::InstancePointerRole).value(); - } - else - return nullptr; -} - - void MainWindow::on_actionLaunchInstance_triggered() { - BaseInstance* inst = selectedInstance(); - if(inst) + if(m_selectedInstance) { doLogin(); } @@ -425,7 +423,7 @@ void MainWindow::on_actionLaunchInstance_triggered() void MainWindow::doLogin(const QString& errorMsg) { - if (!selectedInstance()) + if (!m_selectedInstance) return; LoginDialog* loginDlg = new LoginDialog(this, errorMsg); @@ -438,7 +436,7 @@ void MainWindow::doLogin(const QString& errorMsg) LoginTask* loginTask = new LoginTask(uInfo, tDialog); connect(loginTask, SIGNAL(succeeded()),SLOT(onLoginComplete()), Qt::QueuedConnection); connect(loginTask, SIGNAL(failed(QString)), SLOT(doLogin(QString)), Qt::QueuedConnection); - m_activeInst = selectedInstance(); + m_activeInst = m_selectedInstance; tDialog->exec(loginTask); } } @@ -534,27 +532,24 @@ void MainWindow::on_actionChangeInstMCVersion_triggered() if (view->selectionModel()->selectedIndexes().count() < 1) return; - BaseInstance *inst = selectedInstance(); - - VersionSelectDialog vselect(inst->versionList(), this); + VersionSelectDialog vselect(m_selectedInstance->versionList(), this); if (vselect.exec() && vselect.selectedVersion()) { - inst->setIntendedVersionId(vselect.selectedVersion()->descriptor); + m_selectedInstance->setIntendedVersionId(vselect.selectedVersion()->descriptor); } } void MainWindow::on_actionChangeInstLWJGLVersion_triggered() { - BaseInstance *inst = selectedInstance(); - - if (!inst) + if (!m_selectedInstance) return; LWJGLSelectDialog lselect(this); lselect.exec(); if (lselect.result() == QDialog::Accepted) { - + LegacyInstance * linst = (LegacyInstance *) m_selectedInstance; + linst->setLWJGLVersion(lselect.selectedVersion()); } } @@ -563,14 +558,60 @@ void MainWindow::on_actionInstanceSettings_triggered() if (view->selectionModel()->selectedIndexes().count() < 1) return; - BaseInstance *inst = selectedInstance(); - SettingsObject *s; - s = &inst->settings(); - InstanceSettings settings(s, this); + InstanceSettings settings(&m_selectedInstance->settings(), this); settings.setWindowTitle(QString("Instance settings")); settings.exec(); } -void MainWindow::instanceChanged(QModelIndex idx) { - ui->instanceToolBar->setEnabled(idx.isValid()); +void MainWindow::setRenameText ( QString text ) +{ + ui->actionRenameInstance->setText(text); + // FIXME: too much bullshit. + /* + QToolButton * toolbtn = (QToolButton *) ui->instanceToolBar->widgetForAction(ui->actionRenameInstance); + QLayout *layout = toolbtn->layout(); + if(!layout) + { + layout = new QHBoxLayout(); + renameLabel = new QLabel(); + renameLabel->setWordWrap(true); + renameLabel->setAlignment(Qt::AlignCenter); + layout->addWidget(renameLabel); + toolbtn->setText(" "); + toolbtn->setLayout(layout); + toolbtn->setMinimumWidth(120); + toolbtn->setMinimumHeight(renameLabel->minsize().height()); + } + if(renameLabel) + renameLabel->setText(text); + */ +} + + +void MainWindow::instanceChanged( const QModelIndex& current, const QModelIndex& previous ) +{ + QString iconKey = "infinity"; + + if(current.isValid() && nullptr != (m_selectedInstance = (BaseInstance *) current.data(InstanceModel::InstancePointerRole).value())) + { + ui->instanceToolBar->setEnabled(true); + iconKey = m_selectedInstance->iconKey(); + //ui->actionRenameInstance->setText(m_selectedInstance->name()); + setRenameText(m_selectedInstance->name()); + ui->actionChangeInstLWJGLVersion->setEnabled(m_selectedInstance->menuActionEnabled("actionChangeInstLWJGLVersion")); + ui->actionEditInstMods->setEnabled(m_selectedInstance->menuActionEnabled("actionEditInstMods")); + statusBar()->clearMessage(); + statusBar()->showMessage(m_selectedInstance->getStatusbarDescription()); + } + else + { + statusBar()->clearMessage(); + ui->instanceToolBar->setEnabled(false); + //ui->actionRenameInstance->setText("Rename Instance"); + setRenameText("Rename Instance"); + } + + IconList * iconListModel = IconList::instance(); + auto ico =iconListModel->getIcon(iconKey); + ui->actionChangeInstIcon->setIcon(ico); } diff --git a/gui/mainwindow.h b/gui/mainwindow.h index 79716e5e..597cc750 100644 --- a/gui/mainwindow.h +++ b/gui/mainwindow.h @@ -22,6 +22,7 @@ #include "logic/tasks/LoginTask.h" #include "logic/BaseInstance.h" +class QLabel; class InstanceModel; class InstanceProxyModel; class KCategorizedView; @@ -39,11 +40,6 @@ class MainWindow : public QMainWindow { Q_OBJECT - /*! - * The currently selected instance. - */ - Q_PROPERTY(BaseInstance* selectedInstance READ selectedInstance STORED false) - public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); @@ -54,8 +50,6 @@ public: void openWebPage(QUrl url); - BaseInstance *selectedInstance(); - private slots: void on_actionAbout_triggered(); @@ -67,6 +61,8 @@ private slots: void on_actionViewInstanceFolder_triggered(); + void on_actionConfig_Folder_triggered(); + void on_actionViewSelectedInstFolder_triggered(); void on_actionRefresh_triggered(); @@ -116,7 +112,7 @@ private slots: public slots: void instanceActivated ( QModelIndex ); - void instanceChanged ( QModelIndex ); + void instanceChanged (const QModelIndex & current,const QModelIndex & previous); void startTask(Task *task); @@ -124,7 +120,7 @@ public slots: protected: bool eventFilter(QObject *obj, QEvent *ev); - + void setRenameText(QString text); private: Ui::MainWindow *ui; KCategoryDrawer * drawer; @@ -135,6 +131,9 @@ private: MinecraftProcess *proc; ConsoleWindow *console; OneSixAssets *assets_downloader; + QLabel * renameLabel; + + BaseInstance *m_selectedInstance; // A pointer to the instance we are actively doing stuff with. // This is set when the user launches an instance and is used to refer to that diff --git a/gui/mainwindow.ui b/gui/mainwindow.ui index 893062a5..60e0f70b 100644 --- a/gui/mainwindow.ui +++ b/gui/mainwindow.ui @@ -45,6 +45,12 @@ Qt::TopToolBarArea + + Qt::ToolButtonIconOnly + + + false + TopToolBarArea @@ -74,6 +80,15 @@ Qt::LeftToolBarArea|Qt::RightToolBarArea + + + 80 + 80 + + + + Qt::ToolButtonIconOnly + false @@ -83,22 +98,19 @@ false + + + - - - - - - - - - + - + + + @@ -256,7 +268,7 @@ - Rename + Instance Name Rename the selected instance. @@ -280,6 +292,10 @@ true + + + :/icons/instances/infinity:/icons/instances/infinity + Change Icon @@ -291,9 +307,6 @@ - - false - Edit Notes @@ -385,26 +398,9 @@ Change the version of LWJGL for the selected instance to use. - - - false - - - false - - - Rebuild Jar - - - Reinstall the mods for the selected instance. - - - Reinstall the mods for the selected instance. - - - View Folder + Instance Folder Open the selected instance's root folder in a file browser. @@ -424,6 +420,14 @@ Delete the selected instance. + + + Config Folder + + + Open the instance's config folder + + diff --git a/logic/BaseInstance.h b/logic/BaseInstance.h index 48481e26..13ed169f 100644 --- a/logic/BaseInstance.h +++ b/logic/BaseInstance.h @@ -149,6 +149,14 @@ public: /// create a mod edit dialog for the instance virtual QDialog * createModEditDialog ( QWidget* parent ) = 0; + + /// is a particular action enabled with this instance selected? + virtual bool menuActionEnabled(QString action_name) const = 0; + + virtual QString getStatusbarDescription() = 0; + + /// FIXME: this really should be elsewhere... + virtual QString instanceConfigFolder() const = 0; signals: /*! * \brief Signal emitted when properties relevant to the instance view change diff --git a/logic/LegacyInstance.cpp b/logic/LegacyInstance.cpp index 9e191740..dce1d2f3 100644 --- a/logic/LegacyInstance.cpp +++ b/logic/LegacyInstance.cpp @@ -127,6 +127,19 @@ QSharedPointer< ModList > LegacyInstance::loaderModList() return d->loader_mod_list; } +QSharedPointer< ModList > LegacyInstance::texturePackList() +{ + I_D(LegacyInstance); + if(!d->texture_pack_list) + { + d->texture_pack_list.reset(new ModList(texturePackDir())); + } + else + d->texture_pack_list->update(); + return d->texture_pack_list; +} + + QDialog * LegacyInstance::createModEditDialog ( QWidget* parent ) { return new LegacyModEditDialog(this, parent); @@ -168,6 +181,10 @@ QString LegacyInstance::resourceDir() const { return PathCombine(minecraftRoot(), "resources"); } +QString LegacyInstance::texturePackDir() const +{ + return PathCombine(minecraftRoot(), "texturepacks"); +} QString LegacyInstance::runnableJar() const { @@ -178,6 +195,13 @@ QString LegacyInstance::modListFile() const { return PathCombine(instanceRoot(), "modlist"); } + +QString LegacyInstance::instanceConfigFolder() const +{ + return PathCombine(minecraftRoot(), "config"); +} + + /* bool LegacyInstance::shouldUpdateCurrentVersion() const { @@ -285,3 +309,15 @@ QString LegacyInstance::defaultCustomBaseJar() const return PathCombine(binDir(), "mcbackup.jar"); } +bool LegacyInstance::menuActionEnabled ( QString action_name ) const +{ + return true; +} + +QString LegacyInstance::getStatusbarDescription() +{ + if(shouldUpdate()) + return "Legacy : " + currentVersionId() + " -> " + intendedVersionId(); + else + return "Legacy : " + currentVersionId(); +} diff --git a/logic/LegacyInstance.h b/logic/LegacyInstance.h index 46c531d9..97502945 100644 --- a/logic/LegacyInstance.h +++ b/logic/LegacyInstance.h @@ -22,14 +22,17 @@ public: QSharedPointer jarModList(); QSharedPointer coreModList(); QSharedPointer loaderModList(); + QSharedPointer texturePackList(); ////// Directories ////// QString savesDir() const; + QString texturePackDir() const; QString jarModsDir() const; QString binDir() const; QString mlModsDir() const; QString coreModsDir() const; QString resourceDir() const; + virtual QString instanceConfigFolder() const; /*! * Whether or not the instance's minecraft.jar needs to be rebuilt. @@ -61,6 +64,9 @@ public: virtual QString defaultBaseJar() const; virtual QString defaultCustomBaseJar() const; + bool menuActionEnabled ( QString action_name ) const; + virtual QString getStatusbarDescription(); + protected slots: virtual void jarModsChanged(); }; \ No newline at end of file diff --git a/logic/LegacyInstance_p.h b/logic/LegacyInstance_p.h index a1d195b4..d1f417fe 100644 --- a/logic/LegacyInstance_p.h +++ b/logic/LegacyInstance_p.h @@ -12,4 +12,5 @@ struct LegacyInstancePrivate: public BaseInstancePrivate QSharedPointer jar_mod_list; QSharedPointer core_mod_list; QSharedPointer loader_mod_list; + QSharedPointer texture_pack_list; }; \ No newline at end of file diff --git a/logic/LegacyUpdate.cpp b/logic/LegacyUpdate.cpp index 9644cb80..0dc8ee72 100644 --- a/logic/LegacyUpdate.cpp +++ b/logic/LegacyUpdate.cpp @@ -271,7 +271,15 @@ bool LegacyUpdate::MergeZipFiles( QuaZip* into, QFileInfo from, QSet< QString >& { return false; } - if(!zipOutFile.open(QIODevice::WriteOnly, QuaZipNewInfo(fileInsideMod.getActualFileName()))) + /* + QuaZipFileInfo old_info; + fileInsideMod.getFileInfo(&old_info); + */ + QuaZipNewInfo info_out(fileInsideMod.getActualFileName()); + /* + info_out.externalAttr = old_info.externalAttr; + */ + if(!zipOutFile.open(QIODevice::WriteOnly, info_out)) { fileInsideMod.close(); return false; @@ -369,31 +377,32 @@ void LegacyUpdate::ModTheJar() } else if (mod.type() == Mod::MOD_SINGLEFILE) { - zipOut.close(); - QFile::remove(runnableJar.filePath()); - emitFailed("Loose files are NOT supported as jar mods."); - return; - /* - wxFileName destFileName = modFileName; - destFileName.MakeRelativeTo(m_inst->GetInstModsDir().GetFullPath()); - wxString destFile = destFileName.GetFullPath(); - - if (addedFiles.count(destFile) == 0) + auto filename = mod.filename(); + if(!JlCompress::compressFile(&zipOut, filename.absoluteFilePath(), filename.fileName())) { - wxFFileInputStream input(modFileName.GetFullPath()); - zipOut.PutNextEntry(destFile); - zipOut.Write(input); - - addedFiles.insert(destFile); + zipOut.close(); + QFile::remove(runnableJar.filePath()); + emitFailed("Failed to add " + filename.fileName() + " to the jar"); + return; } - */ + addedFiles.insert(filename.fileName()); + qDebug() << "Adding file " << filename.fileName() << " from " << filename.absoluteFilePath(); } else if (mod.type() == Mod::MOD_FOLDER) { - zipOut.close(); - QFile::remove(runnableJar.filePath()); - emitFailed("Folders are NOT supported as jar mods."); - return; + auto filename = mod.filename(); + QString what_to_zip = filename.absoluteFilePath(); + QDir dir(what_to_zip); + dir.cdUp(); + QString parent_dir = dir.absolutePath(); + if(!JlCompress::compressSubDir(&zipOut, what_to_zip, parent_dir, true, addedFiles)) + { + zipOut.close(); + QFile::remove(runnableJar.filePath()); + emitFailed("Failed to add " + filename.fileName() + " to the jar"); + return; + } + qDebug() << "Adding folder " << filename.fileName() << " from " << filename.absoluteFilePath(); } } diff --git a/logic/ModList.cpp b/logic/ModList.cpp index c3f3ced3..84511e4c 100644 --- a/logic/ModList.cpp +++ b/logic/ModList.cpp @@ -21,6 +21,7 @@ #include #include #include +#include ModList::ModList ( const QString& dir, const QString& list_file ) : QAbstractListModel(), m_dir(dir), m_list_file(list_file) @@ -28,9 +29,31 @@ ModList::ModList ( const QString& dir, const QString& list_file ) m_dir.setFilter(QDir::Readable | QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs | QDir::NoSymLinks); m_dir.setSorting(QDir::Name); m_list_id = QUuid::createUuid().toString(); + m_watcher = new QFileSystemWatcher(this); + is_watching = false; + connect(m_watcher,SIGNAL(directoryChanged(QString)), this, SLOT(directoryChanged(QString))); update(); } +void ModList::startWatching() +{ + is_watching = m_watcher->addPath(m_dir.absolutePath()); + if(is_watching) + qDebug() << "Started watching " << m_dir.absolutePath(); + else + qDebug() << "Failed to start watching " << m_dir.absolutePath(); +} + +void ModList::stopWatching() +{ + is_watching = !m_watcher->removePath(m_dir.absolutePath()); + if(!is_watching) + qDebug() << "Stopped watching " << m_dir.absolutePath(); + else + qDebug() << "Failed to stop watching " << m_dir.absolutePath(); +} + + bool ModList::update() { if (!isValid()) @@ -88,6 +111,12 @@ bool ModList::update() return true; } +void ModList::directoryChanged ( QString path ) +{ + update(); +} + + QStringList ModList::readListFile() { QStringList stringList; @@ -333,11 +362,11 @@ QVariant ModList::headerData ( int section, Qt::Orientation orientation, int rol switch (section) { case 0: - return QString("Mod Name"); + return QString("Name"); case 1: - return QString("Mod Version"); + return QString("Version"); case 2: - return QString("MC Version"); + return QString("Minecraft"); } } @@ -412,6 +441,9 @@ bool ModList::dropMimeData ( const QMimeData* data, Qt::DropAction action, int r // files dropped from outside? if(data->hasUrls()) { + bool was_watching = is_watching; + if(was_watching) + stopWatching(); auto urls = data->urls(); for(auto url: urls) { @@ -422,6 +454,8 @@ bool ModList::dropMimeData ( const QMimeData* data, Qt::DropAction action, int r installMod(filename, row); qDebug() << "installing: " << filename; } + if(was_watching) + startWatching(); return true; } else if(data->hasText()) @@ -446,305 +480,3 @@ bool ModList::dropMimeData ( const QMimeData* data, Qt::DropAction action, int r return false; } - -/* -ModList::ModList(const QString &dir) - : modsFolder(dir) -{ - -} - -bool ModList::update(bool quickLoad) -{ - bool listChanged = false; - - // Check for mods in the list whose files do not exist and remove them from the list. - // If doing a quickLoad, erase the whole list. - for (size_t i = 0; i < size(); i++) - { - if (quickLoad || !at(i).GetFileName().FileExists()) - { - erase(begin() + i); - i--; - listChanged = true; - } - } - - // Add any mods in the mods folder that aren't already in the list. - if (LoadModListFromDir(QString(), quickLoad)) - listChanged = true; - - return listChanged; -} - -bool ModList::LoadModListFromDir(const QString& loadFrom, bool quickLoad) -{ - QString dir(loadFrom.isEmpty() ? modsFolder : loadFrom); - - QDir modDir(dir); - if (!modDir.exists()) - return false; - - bool listChanged = false; - - auto list = modDir.entryInfoList(QDir::Readable|QDir::NoDotAndDotDot, QDir::Name); - for(auto currentFile: list) - { - if (currentFile.isFile()) - { - if (quickLoad || FindByFilename(currentFile.absoluteFilePath()) == nullptr) - { - Mod mod(currentFile.absoluteFilePath()); - push_back(mod); - listChanged = true; - } - } - else if (currentFile.isDir()) - { - if (LoadModListFromDir(currentFile.absoluteFilePath())) - listChanged = true; - } - } - - return listChanged; -} - -Mod *ModList::FindByFilename(const QString& filename) -{ - // Search the list for a mod with the given filename. - for (auto iter = begin(); iter != end(); ++iter) - { - if (iter->GetFileName() == QFileInfo(filename)) - return &(*iter); - } - - // If nothing is found, return nullptr. - return nullptr; -} - -int ModList::FindIndexByFilename(const QString& filename) -{ - // Search the list for a mod with the given filename. - int i = 0; - for (auto iter = begin(); iter != end(); ++iter, i++) - { - if (iter->GetFileName() == QFileInfo(filename)) - return i; - } - - // If nothing is found, return nullptr. - return -1; -} - -Mod* ModList::FindByID(const QString& modID, const QString& modVersion) -{ - // Search the list for a mod that matches - for (auto iter = begin(); iter != end(); ++iter) - { - QString ID = iter->GetModID(); - QString version = iter->GetModVersion(); - if ( ID == modID && version == modVersion) - return &(*iter); - } - - // If nothing is found, return nullptr. - return nullptr; -} - -void ModList::LoadFromFile(const QString& file) -{ - if (!wxFileExists(file)) - return; - - wxFFileInputStream inputStream(file); - wxArrayString modListFile = ReadAllLines(inputStream); - - for (wxArrayString::iterator iter = modListFile.begin(); iter != modListFile.end(); iter++) - { - // Normalize the path to the instMods dir. - wxFileName modFile(*iter); - modFile.Normalize(wxPATH_NORM_ALL, modsFolder); - modFile.MakeRelativeTo(); - // if the file is gone, do not load it - if(!modFile.Exists()) - { - continue; - } - - if (FindByFilename(modFile.GetFullPath()) == nullptr) - { - push_back(Mod(modFile)); - } - } -} - -void ModList::SaveToFile(const QString& file) -{ - QString text; - for (iterator iter = begin(); iter != end(); ++iter) - { - wxFileName modFile = iter->GetFileName(); - modFile.MakeRelativeTo(modsFolder); - text.append(modFile.GetFullPath()); - text.append("\n"); - } - - wxTempFileOutputStream out(file); - WriteAllText(out, text); - out.Commit(); -} - -bool ModList::InsertMod(size_t index, const QString &filename, const QString& saveToFile) -{ - QFileInfo source(filename); - QFileInfo dest(PathCombine(modsFolder, source.fileName())); - - if (source != dest) - { - QFile::copy(source.absoluteFilePath(), dest.absoluteFilePath()); - } - - int oldIndex = FindIndexByFilename(dest.absoluteFilePath()); - - if (oldIndex != -1) - { - erase(begin() + oldIndex); - } - - if (index >= size()) - push_back(Mod(dest)); - else - insert(begin() + index, Mod(dest)); - - if (!saveToFile.isEmpty()) - SaveToFile(saveToFile); - - return true; -} - -bool ModList::DeleteMod(size_t index, const QString& saveToFile) -{ - Mod *mod = &at(index); - if(mod->GetModType() == Mod::MOD_FOLDER) - { - QDir dir(mod->GetFileName().absoluteFilePath()); - if(dir.removeRecursively()) - { - erase(begin() + index); - - if (!saveToFile.isEmpty()) - SaveToFile(saveToFile); - - return true; - } - else - { - // wxLogError(_("Failed to delete mod.")); - } - } - else if (QFile(mod->GetFileName().absoluteFilePath()).remove()) - { - erase(begin() + index); - - if (!saveToFile.isEmpty()) - SaveToFile(saveToFile); - - return true; - } - else - { - // wxLogError(_("Failed to delete mod.")); - } - return false; -} - -bool JarModList::InsertMod(size_t index, const QString &filename, const QString& saveToFile) -{ - QString saveFile = saveToFile; - if (saveToFile.isEmpty()) - saveFile = m_inst->GetModListFile().GetFullPath(); - - if (ModList::InsertMod(index, filename, saveFile)) - { - m_inst->setLWJGLVersion(true); - return true; - } - return false; -} - -bool JarModList::DeleteMod(size_t index, const QString& saveToFile) -{ - QString saveFile = saveToFile; - if (saveToFile.IsEmpty()) - saveFile = m_inst->GetModListFile().GetFullPath(); - - if (ModList::DeleteMod(index, saveFile)) - { - m_inst->SetNeedsRebuild(); - return true; - } - return false; -} - -bool JarModList::UpdateModList(bool quickLoad) -{ - if (ModList::UpdateModList(quickLoad)) - { - m_inst->SetNeedsRebuild(); - return true; - } - return false; -} - -bool FolderModList::LoadModListFromDir(const QString& loadFrom, bool quickLoad) -{ - QString dir(loadFrom.IsEmpty() ? modsFolder : loadFrom); - - if (!wxDirExists(dir)) - return false; - - bool listChanged = false; - wxDir modDir(dir); - - if (!modDir.IsOpened()) - { - wxLogError(_("Failed to open directory: ") + dir); - return false; - } - - QString currentFile; - if (modDir.GetFirst(¤tFile)) - { - do - { - wxFileName modFile(Path::Combine(dir, currentFile)); - - if (wxFileExists(modFile.GetFullPath()) || wxDirExists(modFile.GetFullPath())) - { - if (quickLoad || FindByFilename(modFile.GetFullPath()) == nullptr) - { - Mod mod(modFile.GetFullPath()); - push_back(mod); - listChanged = true; - } - } - } while (modDir.GetNext(¤tFile)); - } - - return listChanged; -} - -bool ModNameSort (const Mod & i,const Mod & j) -{ - if(i.GetModType() == j.GetModType()) - return (i.GetName().toLower() < j.GetName().toLower()); - return (i.GetModType() < j.GetModType()); -} - -bool FolderModList::UpdateModList ( bool quickLoad ) -{ - bool changed = ModList::UpdateModList(quickLoad); - std::sort(begin(),end(),ModNameSort); - return changed; -} -*/ diff --git a/logic/ModList.h b/logic/ModList.h index 61f3d596..5395e9ae 100644 --- a/logic/ModList.h +++ b/logic/ModList.h @@ -15,9 +15,10 @@ class BaseInstance; #include #include #include - #include "Mod.h" +class QFileSystemWatcher; + /** * A legacy mod list. * Backed by a folder. @@ -86,6 +87,9 @@ public: /// what drop actions do we support? virtual Qt::DropActions supportedDropActions() const; + void startWatching(); + void stopWatching(); + virtual bool isValid(); QDir dir() @@ -95,10 +99,14 @@ public: private: QStringList readListFile(); bool saveListFile(); +private slots: + void directoryChanged(QString path); signals: void changed(); protected: + QFileSystemWatcher * m_watcher; + bool is_watching; QDir m_dir; QString m_list_file; QString m_list_id; diff --git a/logic/NostalgiaInstance.cpp b/logic/NostalgiaInstance.cpp index 0a7f3c5a..039cd9ce 100644 --- a/logic/NostalgiaInstance.cpp +++ b/logic/NostalgiaInstance.cpp @@ -6,6 +6,12 @@ NostalgiaInstance::NostalgiaInstance ( const QString& rootDir, SettingsObject* s } +QString NostalgiaInstance::getStatusbarDescription() +{ + return "Nostalgia : " + intendedVersionId(); +} + + /* ADD MORE IF REQUIRED diff --git a/logic/NostalgiaInstance.h b/logic/NostalgiaInstance.h index b8858218..f2df1828 100644 --- a/logic/NostalgiaInstance.h +++ b/logic/NostalgiaInstance.h @@ -7,4 +7,5 @@ class NostalgiaInstance : public OneSixInstance Q_OBJECT public: explicit NostalgiaInstance(const QString &rootDir, SettingsObject * settings, QObject *parent = 0); + virtual QString getStatusbarDescription(); }; diff --git a/logic/OneSixInstance.cpp b/logic/OneSixInstance.cpp index 2eca7cd7..4cbf17b2 100644 --- a/logic/OneSixInstance.cpp +++ b/logic/OneSixInstance.cpp @@ -226,3 +226,22 @@ QString OneSixInstance::defaultCustomBaseJar() const { return PathCombine(instanceRoot(), "custom.jar"); } + +bool OneSixInstance::menuActionEnabled ( QString action_name ) const +{ + if(action_name == "actionChangeInstLWJGLVersion") + return false; + if(action_name == "actionEditInstMods") + return false; + return true; +} + +QString OneSixInstance::getStatusbarDescription() +{ + return "One Six : " + intendedVersionId(); +} + +QString OneSixInstance::instanceConfigFolder() const +{ + return PathCombine(minecraftRoot(), "config"); +} diff --git a/logic/OneSixInstance.h b/logic/OneSixInstance.h index 654b91dc..7c28b4cc 100644 --- a/logic/OneSixInstance.h +++ b/logic/OneSixInstance.h @@ -32,6 +32,11 @@ public: virtual QString defaultBaseJar() const; virtual QString defaultCustomBaseJar() const; + + virtual bool menuActionEnabled ( QString action_name ) const; + virtual QString getStatusbarDescription(); + virtual QString instanceConfigFolder() const; + private: QStringList processMinecraftArgs( QString user, QString session ); }; \ No newline at end of file -- cgit v1.2.3