diff --git a/gui/IconPickerDialog.cpp b/gui/IconPickerDialog.cpp index d80673a8..d3a33e57 100644 --- a/gui/IconPickerDialog.cpp +++ b/gui/IconPickerDialog.cpp @@ -2,6 +2,9 @@ #include "instancedelegate.h" #include "ui_IconPickerDialog.h" #include "logic/IconListModel.h" +#include +#include +#include IconPickerDialog::IconPickerDialog(QWidget *parent) : QDialog(parent), @@ -25,9 +28,24 @@ IconPickerDialog::IconPickerDialog(QWidget *parent) : contentsWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); contentsWidget->setItemDelegate(new ListViewDelegate()); + //contentsWidget->setAcceptDrops(true); + contentsWidget->setDropIndicatorShown(true); + contentsWidget->viewport()->setAcceptDrops(true); + contentsWidget->setDragDropMode(QAbstractItemView::DropOnly); + contentsWidget->setDefaultDropAction(Qt::CopyAction); + + contentsWidget->installEventFilter(this); + IconList * list = IconList::instance(); contentsWidget->setModel(list); + auto buttonAdd = ui->buttonBox->addButton("Add Icon",QDialogButtonBox::ResetRole); + auto buttonRemove = ui->buttonBox->addButton("Remove Icon",QDialogButtonBox::ResetRole); + + + connect(buttonAdd,SIGNAL(clicked(bool)),SLOT(addNewIcon())); + connect(buttonRemove,SIGNAL(clicked(bool)),SLOT(removeSelectedIcon())); + connect ( contentsWidget, @@ -42,6 +60,43 @@ IconPickerDialog::IconPickerDialog(QWidget *parent) : SLOT(selectionChanged(QItemSelection,QItemSelection)) ); } +bool IconPickerDialog::eventFilter ( QObject* obj, QEvent* evt) +{ + if(obj != ui->iconView) + return QDialog::eventFilter(obj ,evt); + if (evt->type() != QEvent::KeyPress) + { + return QDialog::eventFilter(obj ,evt); + } + QKeyEvent *keyEvent = static_cast(evt); + IconList * list = IconList::instance(); + switch(keyEvent->key()) + { + case Qt::Key_Delete: + removeSelectedIcon(); + return true; + case Qt::Key_Plus: + addNewIcon(); + return true; + default: + break; + } + return QDialog::eventFilter(obj ,evt); +} + +void IconPickerDialog::addNewIcon() +{ + QStringList fileNames = QFileDialog::getOpenFileNames(this, "Select Icons", QString(), "Icons (*.png *.jpg *.jpeg)"); + IconList * list = IconList::instance(); + list->installIcons(fileNames); +} + +void IconPickerDialog::removeSelectedIcon() +{ + IconList * list = IconList::instance(); + list->deleteIcon(selectedIconKey); +} + void IconPickerDialog::activated ( QModelIndex index ) { diff --git a/gui/IconPickerDialog.h b/gui/IconPickerDialog.h index c55f6ff2..96fc61ff 100644 --- a/gui/IconPickerDialog.h +++ b/gui/IconPickerDialog.h @@ -15,7 +15,8 @@ public: ~IconPickerDialog(); int exec(QString selection); QString selectedIconKey; - +protected: + virtual bool eventFilter ( QObject* , QEvent* ); private: Ui::IconPickerDialog *ui; @@ -23,4 +24,6 @@ private slots: void selectionChanged ( QItemSelection,QItemSelection ); void activated ( QModelIndex ); void delayed_scroll ( QModelIndex ); + void addNewIcon(); + void removeSelectedIcon(); }; diff --git a/gui/aboutdialog.cpp b/gui/aboutdialog.cpp index 876f3044..873cc175 100644 --- a/gui/aboutdialog.cpp +++ b/gui/aboutdialog.cpp @@ -1,23 +1,24 @@ #include "aboutdialog.h" #include "ui_aboutdialog.h" +#include #include #include AboutDialog::AboutDialog(QWidget *parent) : - QDialog(parent), - ui(new Ui::AboutDialog) + QDialog(parent), + ui(new Ui::AboutDialog) { - ui->setupUi(this); + ui->setupUi(this); - ui->icon->setPixmap(QIcon(":/icons/multimc/scalable/apps/multimc.svg").pixmap(64)); + ui->icon->setPixmap(QIcon(":/icons/multimc/scalable/apps/multimc.svg").pixmap(64)); + ui->title->setText("MultiMC " + AppVersion::current.toString()); + connect(ui->closeButton, SIGNAL(clicked()), SLOT(close())); - connect(ui->closeButton, SIGNAL(clicked()), SLOT(close())); - - QApplication::instance()->connect(ui->aboutQt, SIGNAL(clicked()), SLOT(aboutQt())); + QApplication::instance()->connect(ui->aboutQt, SIGNAL(clicked()), SLOT(aboutQt())); } AboutDialog::~AboutDialog() { - delete ui; + delete ui; } diff --git a/gui/instancesettings.ui b/gui/instancesettings.ui index 4a8ae12c..49309f11 100644 --- a/gui/instancesettings.ui +++ b/gui/instancesettings.ui @@ -42,13 +42,6 @@ false - - - - Compatibility mode? - - - @@ -403,7 +396,6 @@ settingsTabs windowSizeGroupBox - compatModeCheckBox maximizedCheckBox windowWidthSpinBox windowHeightSpinBox diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index fbda2547..8b06d698 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -87,6 +87,7 @@ MainWindow::MainWindow ( QWidget *parent ) : // the rename label is inside the rename tool button renameButton = new LabeledToolButton(); renameButton->setText("Instance Name"); + renameButton->setToolTip(ui->actionRenameInstance->toolTip()); connect(renameButton, SIGNAL(clicked(bool)), SLOT(on_actionRenameInstance_triggered())); ui->instanceToolBar->insertWidget(ui->actionLaunchInstance, renameButton); ui->instanceToolBar->insertSeparator(ui->actionLaunchInstance); diff --git a/gui/settingsdialog.cpp b/gui/settingsdialog.cpp index 909706b6..52093039 100644 --- a/gui/settingsdialog.cpp +++ b/gui/settingsdialog.cpp @@ -43,12 +43,8 @@ void SettingsDialog::showEvent ( QShowEvent* ev ) void SettingsDialog::updateCheckboxStuff() { - ui->windowWidthSpinBox->setEnabled(!(ui->compatModeCheckBox->isChecked() || - ui->maximizedCheckBox->isChecked())); - ui->windowHeightSpinBox->setEnabled(!(ui->compatModeCheckBox->isChecked() || - ui->maximizedCheckBox->isChecked())); - - ui->maximizedCheckBox->setEnabled(!ui->compatModeCheckBox->isChecked()); + ui->windowWidthSpinBox->setEnabled(!ui->maximizedCheckBox->isChecked()); + ui->windowHeightSpinBox->setEnabled(! ui->maximizedCheckBox->isChecked()); } void SettingsDialog::on_instDirBrowseBtn_clicked() diff --git a/gui/settingsdialog.ui b/gui/settingsdialog.ui index 8b53b0f1..0d30e301 100644 --- a/gui/settingsdialog.ui +++ b/gui/settingsdialog.ui @@ -54,6 +54,9 @@ By last launched + + sortingModeGroup + @@ -61,6 +64,9 @@ By name + + sortingModeGroup + @@ -175,13 +181,6 @@ Window Size - - - - Compatibility mode? - - - @@ -504,4 +503,7 @@ + + + diff --git a/logic/IconListModel.cpp b/logic/IconListModel.cpp index b531df43..4a5795d6 100644 --- a/logic/IconListModel.cpp +++ b/logic/IconListModel.cpp @@ -3,7 +3,8 @@ #include #include #include - +#include +#include #define MAX_SIZE 1024 IconList* IconList::m_Instance = 0; QMutex IconList::mutex; @@ -14,6 +15,7 @@ struct entry QString name; QIcon icon; bool is_builtin; + QString filename; }; class Private : public QObject @@ -56,6 +58,61 @@ IconList::~IconList() d = nullptr; } +QStringList IconList::mimeTypes() const +{ + QStringList types; + types << "text/uri-list"; + return types; +} +Qt::DropActions IconList::supportedDropActions() const +{ + return Qt::CopyAction; +} + +bool IconList::dropMimeData ( const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent ) +{ + if (action == Qt::IgnoreAction) + return true; + // check if the action is supported + if (!data || !(action & supportedDropActions())) + return false; + + // files dropped from outside? + if(data->hasUrls()) + { + /* + bool was_watching = is_watching; + if(was_watching) + stopWatching(); + */ + auto urls = data->urls(); + QStringList iconFiles; + for(auto url: urls) + { + // only local files may be dropped... + if(!url.isLocalFile()) + continue; + iconFiles += url.toLocalFile(); + } + installIcons(iconFiles); + /* + if(was_watching) + startWatching(); + */ + return true; + } + return false; +} + +Qt::ItemFlags IconList::flags ( const QModelIndex& index ) const +{ + Qt::ItemFlags defaultFlags = QAbstractListModel::flags ( index ); + if (index.isValid()) + return Qt::ItemIsDropEnabled | defaultFlags; + else + return Qt::ItemIsDropEnabled | defaultFlags; +} + QVariant IconList::data ( const QModelIndex& index, int role ) const { if(!index.isValid()) @@ -84,18 +141,65 @@ int IconList::rowCount ( const QModelIndex& parent ) const return d->icons.size(); } +void IconList::installIcons ( QStringList iconFiles ) +{ + for(QString file: iconFiles) + { + QFileInfo fileinfo(file); + if(!fileinfo.isReadable() || !fileinfo.isFile()) + continue; + QString target = PathCombine("icons", fileinfo.fileName()); + + QString suffix = fileinfo.suffix(); + if(suffix != "jpeg" && suffix != "png" && suffix != "jpg") + continue; + + if(!QFile::copy(file, target)) + continue; + + QString key = fileinfo.baseName(); + addIcon(key, key, target); + } +} + +bool IconList::deleteIcon ( QString key ) +{ + int iconIdx = getIconIndex(key); + if(iconIdx == -1) + return false; + auto & iconEntry = d->icons[iconIdx]; + if(iconEntry.is_builtin) + return false; + if(QFile::remove(iconEntry.filename)) + { + beginRemoveRows(QModelIndex(), iconIdx, iconIdx); + d->icons.remove(iconIdx); + reindex(); + endRemoveRows(); + } + return true; +} + bool IconList::addIcon ( QString key, QString name, QString path, bool is_builtin ) { auto iter = d->index.find(key); if(iter != d->index.end()) { - if(d->icons[*iter].is_builtin) return false; + if(d->icons[*iter].is_builtin) + return false; QIcon icon(path); - if(icon.isNull()) return false; + if(icon.isNull()) + return false; + auto & oldOne = d->icons[*iter]; + + if(!QFile::remove(oldOne.filename)) + return false; + // replace the icon - d->icons[*iter] = {key, name, icon, is_builtin}; + oldOne = {key, name, icon, is_builtin, path}; + dataChanged(index(*iter),index(*iter)); return true; } else @@ -104,12 +208,25 @@ bool IconList::addIcon ( QString key, QString name, QString path, bool is_builti if(icon.isNull()) return false; // add a new icon - d->icons.push_back({key, name, icon, is_builtin}); + beginInsertRows(QModelIndex(), d->icons.size(),d->icons.size()); + d->icons.push_back({key, name, icon, is_builtin, path}); d->index[key] = d->icons.size() - 1; + endInsertRows(); return true; } } +void IconList::reindex() +{ + d->index.clear(); + int i = 0; + for(auto& iter: d->icons) + { + d->index[iter.key] = i; + i++; + } +} + QIcon IconList::getIcon ( QString key ) { diff --git a/logic/IconListModel.h b/logic/IconListModel.h index 31b05e64..907dfd81 100644 --- a/logic/IconListModel.h +++ b/logic/IconListModel.h @@ -18,7 +18,14 @@ public: virtual int rowCount ( const QModelIndex& parent = QModelIndex() ) const; bool addIcon(QString key, QString name, QString path, bool is_builtin = false); + bool deleteIcon(QString key); + virtual QStringList mimeTypes() const; + virtual Qt::DropActions supportedDropActions() const; + virtual bool dropMimeData ( const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent ); + virtual Qt::ItemFlags flags ( const QModelIndex& index ) const; + + void installIcons ( QStringList iconFiles ); private: virtual ~IconList(); @@ -27,6 +34,7 @@ private: IconList ( const IconList & ) = delete; // hide assign op IconList& operator= ( const IconList & ) = delete; + void reindex(); static IconList* m_Instance; static QMutex mutex; Private* d;