aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt14
-rw-r--r--asset_test.cpp170
-rw-r--r--backend/CMakeLists.txt2
-rw-r--r--backend/IconListModel.cpp163
-rw-r--r--backend/IconListModel.h33
-rw-r--r--gui/IconPickerDialog.cpp88
-rw-r--r--gui/IconPickerDialog.h26
-rw-r--r--gui/IconPickerDialog.ui67
-rw-r--r--gui/iconcache.cpp127
-rw-r--r--gui/iconcache.h43
-rw-r--r--gui/instancemodel.cpp5
-rw-r--r--gui/mainwindow.cpp59
-rw-r--r--gui/mainwindow.h2
-rw-r--r--gui/mainwindow.ui20
-rw-r--r--gui/newinstancedialog.cpp31
-rw-r--r--gui/newinstancedialog.h3
-rw-r--r--main.cpp3
-rw-r--r--multimc.qrc83
-rw-r--r--resources/icons/instances/brick.pngbin0 -> 713 bytes
-rw-r--r--resources/icons/instances/chicken.pngbin0 -> 1181 bytes
-rw-r--r--resources/icons/instances/chicken128.pngbin0 -> 6369 bytes
-rw-r--r--resources/icons/instances/creeper.pngbin0 -> 1524 bytes
-rw-r--r--resources/icons/instances/creeper128.pngbin0 -> 9046 bytes
-rw-r--r--resources/icons/instances/derp.pngbin0 -> 5225 bytes
-rw-r--r--resources/icons/instances/diamond.pngbin0 -> 708 bytes
-rw-r--r--resources/icons/instances/dirt.pngbin0 -> 482 bytes
-rw-r--r--resources/icons/instances/enderman.pngbin0 -> 2429 bytes
-rw-r--r--resources/icons/instances/enderpearl.pngbin0 -> 2120 bytes
-rw-r--r--resources/icons/instances/enderpearl128.pngbin0 -> 21425 bytes
-rw-r--r--resources/icons/instances/ftb_glow.pngbin0 -> 1747 bytes
-rw-r--r--resources/icons/instances/ftb_glow128.pngbin0 -> 12708 bytes
-rw-r--r--resources/icons/instances/ftb_logo.pngbin0 -> 1607 bytes
-rw-r--r--resources/icons/instances/ftb_logo128.pngbin0 -> 7883 bytes
-rw-r--r--resources/icons/instances/gear.pngbin0 -> 2414 bytes
-rw-r--r--resources/icons/instances/gear128.pngbin0 -> 18321 bytes
-rw-r--r--resources/icons/instances/gold.pngbin0 -> 978 bytes
-rw-r--r--resources/icons/instances/grass.pngbin0 -> 618 bytes
-rw-r--r--resources/icons/instances/herobrine.pngbin0 -> 1034 bytes
-rw-r--r--resources/icons/instances/herobrine128.pngbin0 -> 4937 bytes
-rw-r--r--resources/icons/instances/infinity.pngbin0 -> 1714 bytes
-rw-r--r--resources/icons/instances/infinity128.pngbin0 -> 9237 bytes
-rw-r--r--resources/icons/instances/iron.pngbin0 -> 532 bytes
-rw-r--r--resources/icons/instances/magitech.pngbin0 -> 2646 bytes
-rw-r--r--resources/icons/instances/magitech128.pngbin0 -> 23097 bytes
-rw-r--r--resources/icons/instances/meat.pngbin0 -> 1514 bytes
-rw-r--r--resources/icons/instances/meat128.pngbin0 -> 10583 bytes
-rw-r--r--resources/icons/instances/netherstar.pngbin0 -> 1942 bytes
-rw-r--r--resources/icons/instances/netherstar128.pngbin0 -> 14062 bytes
-rw-r--r--resources/icons/instances/planks.pngbin0 -> 461 bytes
-rw-r--r--resources/icons/instances/skeleton.pngbin0 -> 696 bytes
-rw-r--r--resources/icons/instances/skeleton128.pngbin0 -> 3673 bytes
-rw-r--r--resources/icons/instances/squarecreeper.pngbin0 -> 1623 bytes
-rw-r--r--resources/icons/instances/squarecreeper128.pngbin0 -> 9136 bytes
-rw-r--r--resources/icons/instances/steve.pngbin0 -> 969 bytes
-rw-r--r--resources/icons/instances/steve128.pngbin0 -> 4312 bytes
-rw-r--r--resources/icons/instances/stone.pngbin0 -> 438 bytes
-rw-r--r--resources/icons/instances/tnt.pngbin0 -> 378 bytes
-rw-r--r--resources/icons/instances_svg/clucker.svg (renamed from resources/icons/instances/clucker.svg)0
-rw-r--r--resources/icons/instances_svg/creeper.svg (renamed from resources/icons/instances/creeper.svg)0
-rw-r--r--resources/icons/instances_svg/enderpearl.svg (renamed from resources/icons/instances/enderpearl.svg)0
-rw-r--r--resources/icons/instances_svg/ftb-glow.svg (renamed from resources/icons/instances/ftb-glow.svg)0
-rw-r--r--resources/icons/instances_svg/ftb-logo.svg (renamed from resources/icons/instances/ftb-logo.svg)0
-rw-r--r--resources/icons/instances_svg/gear.svg (renamed from resources/icons/instances/gear.svg)0
-rw-r--r--resources/icons/instances_svg/herobrine.svg (renamed from resources/icons/instances/herobrine.svg)0
-rw-r--r--resources/icons/instances_svg/magitech.svg (renamed from resources/icons/instances/magitech.svg)0
-rw-r--r--resources/icons/instances_svg/meat.svg (renamed from resources/icons/instances/meat.svg)0
-rw-r--r--resources/icons/instances_svg/netherstar.svg (renamed from resources/icons/instances/netherstar.svg)0
-rw-r--r--resources/icons/instances_svg/pskeleton.svg581
-rw-r--r--resources/icons/instances_svg/skeleton.svg (renamed from resources/icons/instances/skeleton.svg)0
-rw-r--r--resources/icons/instances_svg/squarecreeper.svg (renamed from resources/icons/instances/squarecreeper.svg)0
-rw-r--r--resources/icons/instances_svg/steve.svg (renamed from resources/icons/instances/steve.svg)0
-rw-r--r--resources/icons/toolbar/NewsIcon.pngbin0 -> 1173 bytes
-rw-r--r--resources/icons/toolbar/ReportBug.pngbin0 -> 1180 bytes
-rw-r--r--resources/icons/toolbar_svg/bug.svg (renamed from resources/icons/toolbar/bug.svg)0
-rw-r--r--resources/icons/toolbar_svg/news.svg (renamed from resources/icons/toolbar/news.svg)0
75 files changed, 1097 insertions, 423 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e858d888..d907e152 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -176,8 +176,8 @@ gui/instancemodel.h
gui/instancedelegate.h
gui/versionselectdialog.h
gui/lwjglselectdialog.h
-gui/iconcache.h
gui/instancesettings.h
+gui/IconPickerDialog.h
java/annotations.h
java/classfile.h
@@ -209,8 +209,8 @@ gui/instancemodel.cpp
gui/instancedelegate.cpp
gui/versionselectdialog.cpp
gui/lwjglselectdialog.cpp
-gui/iconcache.cpp
gui/instancesettings.cpp
+gui/IconPickerDialog.cpp
java/javautils.cpp
java/annotations.cpp
@@ -232,6 +232,7 @@ gui/consolewindow.ui
gui/versionselectdialog.ui
gui/lwjglselectdialog.ui
gui/instancesettings.ui
+gui/IconPickerDialog.ui
)
@@ -284,15 +285,6 @@ IF(BUILD_KEYRING_TEST)
TARGET_LINK_LIBRARIES(Test libUtil libSettings)
ENDIF()
-option(BUILD_ASSET_TEST "Build the asset sync test binary" OFF)
-IF(BUILD_ASSET_TEST)
- # test.cpp
- ADD_EXECUTABLE(AssetTest asset_test.cpp)
- QT5_USE_MODULES(AssetTest Core Network)
- TARGET_LINK_LIBRARIES(AssetTest libUtil backend libSettings)
-ENDIF()
-
-
################################ INSTALLATION AND PACKAGING ################################
# use QtCreator's QTDIR var
IF(DEFINED ENV{QTDIR})
diff --git a/asset_test.cpp b/asset_test.cpp
deleted file mode 100644
index 90da314f..00000000
--- a/asset_test.cpp
+++ /dev/null
@@ -1,170 +0,0 @@
-#include <QString>
-#include <QDebug>
-#include <QtXml/QtXml>
-
-#include "dlqueue.h"
-
-inline QDomElement getDomElementByTagName(QDomElement parent, QString tagname)
-{
- QDomNodeList elementList = parent.elementsByTagName(tagname);
- if (elementList.count())
- return elementList.at(0).toElement();
- else
- return QDomElement();
-}
-
-class ThreadedDeleter : public QThread
-{
- Q_OBJECT
-public:
- void run()
- {
- QDirIterator iter(m_base, QDirIterator::Subdirectories);
- QStringList nuke_list;
- int base_length = m_base.length();
- while (iter.hasNext())
- {
- QString filename = iter.next();
- QFileInfo current(filename);
- // we keep the dirs... whatever
- if(current.isDir())
- continue;
- QString trimmedf = filename;
- trimmedf.remove(0, base_length + 1);
- if(m_whitelist.contains(trimmedf))
- {
- //qDebug() << trimmedf << " gets to live";
- }
- else
- {
- // DO NOT TOLERATE JUNK
- //qDebug() << trimmedf << " dies";
- QFile f (filename);
- f.remove();
- }
- }
- };
- QString m_base;
- QStringList m_whitelist;
-};
-
-class NukeAndPaveJob: public Job
-{
- Q_OBJECT
-public:
-
- explicit NukeAndPaveJob(QString base, QStringList whitelist)
- :Job()
- {
- QDir dir(base);
- deleterThread.m_base = dir.absolutePath();
- deleterThread.m_whitelist = whitelist;
- };
-public slots:
- virtual void start()
- {
- connect(&deleterThread, SIGNAL(finished()), SLOT(threadFinished()));
- deleterThread.start();
- };
- void threadFinished()
- {
- emit finish();
- }
-private:
- ThreadedDeleter deleterThread;
-};
-
-class DlMachine : public QObject
-{
- Q_OBJECT
-public slots:
- void filesFinished()
- {
- qApp->quit();
- }
-
- void fetchFinished()
- {
- QString prefix("http://s3.amazonaws.com/Minecraft.Resources/");
- QString fprefix("assets/");
- QStringList nuke_whitelist;
-
- JobPtr firstJob = index_job->getFirstJob();
- auto DlJob = firstJob.dynamicCast<DownloadJob>();
- QByteArray ba = DlJob->m_data;
-
- QString xmlErrorMsg;
- QDomDocument doc;
- if (!doc.setContent(ba, false, &xmlErrorMsg))
- {
- qDebug() << "Failed to process s3.amazonaws.com/Minecraft.Resources. XML error:" <<
- xmlErrorMsg << ba;
- }
- //QRegExp etag_match(".*([a-f0-9]{32}).*");
- QDomNodeList contents = doc.elementsByTagName("Contents");
-
- JobList *job = new JobList();
- connect(job, SIGNAL(finished()), SLOT(filesFinished()));
-
- for (int i = 0; i < contents.length(); i++)
- {
- QDomElement element = contents.at(i).toElement();
-
- if (element.isNull())
- continue;
-
- QDomElement keyElement = getDomElementByTagName(element, "Key");
- QDomElement lastmodElement = getDomElementByTagName(element, "LastModified");
- QDomElement etagElement = getDomElementByTagName(element, "ETag");
- QDomElement sizeElement = getDomElementByTagName(element, "Size");
-
- if (keyElement.isNull() || lastmodElement.isNull() || etagElement.isNull() || sizeElement.isNull())
- continue;
-
- QString keyStr = keyElement.text();
- QString lastModStr = lastmodElement.text();
- QString etagStr = etagElement.text();
- QString sizeStr = sizeElement.text();
-
- //Filter folder keys
- if (sizeStr == "0")
- continue;
-
- QString trimmedEtag = etagStr.remove('"');
- job->add(DownloadJob::create(QUrl(prefix + keyStr),fprefix + keyStr, trimmedEtag));
- nuke_whitelist.append(keyStr);
- }
- job->add(JobPtr(new NukeAndPaveJob(fprefix, nuke_whitelist)));
- files_job.reset(job);
- dl.enqueue(files_job);
- }
- void fetchStarted()
- {
- qDebug() << "Started downloading!";
- }
-public:
- void start()
- {
- JobList *job = new JobList();
- job->add(DownloadJob::create(QUrl("http://s3.amazonaws.com/Minecraft.Resources/")));
- connect(job, SIGNAL(finished()), SLOT(fetchFinished()));
- connect(job, SIGNAL(started()), SLOT(fetchStarted()));
- index_job.reset(job);
- dl.enqueue(index_job);
- }
- JobListQueue dl;
- JobListPtr index_job;
- JobListPtr files_job;
-};
-
-int main(int argc, char *argv[])
-{
- QCoreApplication app(argc, argv);
-
- DlMachine dl;
- dl.start();
-
- return app.exec();
-}
-
-#include "asset_test.moc"
diff --git a/backend/CMakeLists.txt b/backend/CMakeLists.txt
index ea19fbbf..0d0df5e5 100644
--- a/backend/CMakeLists.txt
+++ b/backend/CMakeLists.txt
@@ -52,6 +52,7 @@ lists/InstanceList.h
lists/InstVersionList.h
lists/MinecraftVersionList.h
lists/LwjglVersionList.h
+IconListModel.h
# Tasks
tasks/Task.h
@@ -87,6 +88,7 @@ lists/InstanceList.cpp
lists/InstVersionList.cpp
lists/MinecraftVersionList.cpp
lists/LwjglVersionList.cpp
+IconListModel.cpp
# Tasks
tasks/Task.cpp
diff --git a/backend/IconListModel.cpp b/backend/IconListModel.cpp
new file mode 100644
index 00000000..2d2fb6cf
--- /dev/null
+++ b/backend/IconListModel.cpp
@@ -0,0 +1,163 @@
+#include "IconListModel.h"
+#include <pathutils.h>
+#include <QMap>
+#include <QEventLoop>
+#include <QDir>
+
+#define MAX_SIZE 1024
+IconList* IconList::m_Instance = 0;
+QMutex IconList::mutex;
+
+struct entry
+{
+ QString key;
+ QString name;
+ QIcon icon;
+ bool is_builtin;
+};
+
+class Private : public QObject
+{
+ Q_OBJECT
+public:
+ QMap<QString, int> index;
+ QVector<entry> icons;
+ Private()
+ {
+ }
+};
+
+
+IconList::IconList() : QAbstractListModel(), d(new Private())
+{
+ QDir instance_icons(":/icons/instances/");
+ auto file_info_list = instance_icons.entryInfoList(QDir::Files, QDir::Name);
+ for(auto file_info: file_info_list)
+ {
+ QString key = file_info.baseName();
+ addIcon(key, key, file_info.absoluteFilePath(), true);
+ }
+
+ // FIXME: get from settings
+ ensurePathExists("icons/");
+ QDir user_icons("icons/");
+ file_info_list = user_icons.entryInfoList(QDir::Files, QDir::Name);
+ for(auto file_info: file_info_list)
+ {
+ QString filename = file_info.absoluteFilePath();
+ QString key = file_info.baseName();
+ addIcon(key, key, filename);
+ }
+}
+
+IconList::~IconList()
+{
+ delete d;
+ d = nullptr;
+}
+
+QVariant IconList::data ( const QModelIndex& index, int role ) const
+{
+ if(!index.isValid())
+ return QVariant();
+
+ int row = index.row();
+
+ if(row < 0 || row >= d->icons.size())
+ return QVariant();
+
+ switch(role)
+ {
+ case Qt::DecorationRole:
+ return d->icons[row].icon;
+ case Qt::DisplayRole:
+ return d->icons[row].name;
+ case Qt::UserRole:
+ return d->icons[row].key;
+ default:
+ return QVariant();
+ }
+}
+
+int IconList::rowCount ( const QModelIndex& parent ) const
+{
+ return d->icons.size();
+}
+
+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;
+
+ QIcon icon(path);
+ if(icon.isNull()) return false;
+
+ // replace the icon
+ d->icons[*iter] = {key, name, icon, is_builtin};
+ return true;
+ }
+ else
+ {
+ QIcon icon(path);
+ if(icon.isNull()) return false;
+
+ // add a new icon
+ d->icons.push_back({key, name, icon, is_builtin});
+ d->index[key] = d->icons.size() - 1;
+ return true;
+ }
+}
+
+
+QIcon IconList::getIcon ( QString key )
+{
+ int icon_index = getIconIndex(key);
+
+ if(icon_index != -1)
+ return d->icons[icon_index].icon;
+
+ // Fallback for icons that don't exist.
+ icon_index = getIconIndex("infinity");
+
+ if(icon_index != -1)
+ return d->icons[icon_index].icon;
+ return QIcon();
+}
+
+int IconList::getIconIndex ( QString key )
+{
+ if(key == "default")
+ key = "infinity";
+
+ auto iter = d->index.find(key);
+ if(iter != d->index.end())
+ return *iter;
+
+
+ return -1;
+}
+
+
+void IconList::drop()
+{
+ mutex.lock();
+ delete m_Instance;
+ m_Instance = 0;
+ mutex.unlock();
+}
+
+IconList* IconList::instance()
+{
+ if ( !m_Instance )
+ {
+ mutex.lock();
+ if ( !m_Instance )
+ m_Instance = new IconList;
+ mutex.unlock();
+ }
+ return m_Instance;
+}
+
+#include "IconListModel.moc" \ No newline at end of file
diff --git a/backend/IconListModel.h b/backend/IconListModel.h
new file mode 100644
index 00000000..31b05e64
--- /dev/null
+++ b/backend/IconListModel.h
@@ -0,0 +1,33 @@
+#pragma once
+
+#include <QMutex>
+#include <QAbstractListModel>
+#include <QtGui/QIcon>
+
+class Private;
+
+class IconList : public QAbstractListModel
+{
+public:
+ static IconList* instance();
+ static void drop();
+ QIcon getIcon ( QString key );
+ int getIconIndex ( QString key );
+
+ virtual QVariant data ( const QModelIndex& index, int role = Qt::DisplayRole ) const;
+ virtual int rowCount ( const QModelIndex& parent = QModelIndex() ) const;
+
+ bool addIcon(QString key, QString name, QString path, bool is_builtin = false);
+
+
+private:
+ virtual ~IconList();
+ IconList();
+ // hide copy constructor
+ IconList ( const IconList & ) = delete;
+ // hide assign op
+ IconList& operator= ( const IconList & ) = delete;
+ static IconList* m_Instance;
+ static QMutex mutex;
+ Private* d;
+};
diff --git a/gui/IconPickerDialog.cpp b/gui/IconPickerDialog.cpp
new file mode 100644
index 00000000..27e7f3b6
--- /dev/null
+++ b/gui/IconPickerDialog.cpp
@@ -0,0 +1,88 @@
+#include "IconPickerDialog.h"
+#include "instancedelegate.h"
+#include "ui_IconPickerDialog.h"
+#include <IconListModel.h>
+
+IconPickerDialog::IconPickerDialog(QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::IconPickerDialog)
+{
+ ui->setupUi(this);
+ auto contentsWidget = ui->iconView;
+ contentsWidget->setViewMode(QListView::IconMode);
+ contentsWidget->setFlow(QListView::LeftToRight);
+ contentsWidget->setIconSize(QSize(48, 48));
+ contentsWidget->setMovement(QListView::Static);
+ contentsWidget->setResizeMode(QListView::Adjust);
+ contentsWidget->setSelectionMode(QAbstractItemView::SingleSelection);
+ contentsWidget->setSpacing(5);
+ contentsWidget->setWordWrap(false);
+ contentsWidget->setWrapping(true);
+ contentsWidget->setUniformItemSizes(true);
+ contentsWidget->setTextElideMode(Qt::ElideRight);
+ contentsWidget->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
+ contentsWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
+ contentsWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ contentsWidget->setItemDelegate(new ListViewDelegate());
+
+ IconList * list = IconList::instance();
+ contentsWidget->setModel(list);
+
+ connect
+ (
+ contentsWidget,
+ SIGNAL(doubleClicked(QModelIndex)),
+ SLOT(activated(QModelIndex))
+ );
+
+ connect
+ (
+ contentsWidget->selectionModel(),
+ SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
+ SLOT(selectionChanged(QItemSelection,QItemSelection))
+ );
+}
+
+void IconPickerDialog::activated ( QModelIndex index )
+{
+ selectedIconKey = index.data(Qt::UserRole).toString();
+ accept();
+}
+
+
+void IconPickerDialog::selectionChanged ( QItemSelection selected, QItemSelection deselected )
+{
+ if(selected.empty())
+ return;
+
+ QString key = selected.first().indexes().first().data(Qt::UserRole).toString();
+ if(!key.isEmpty())
+ selectedIconKey = key;
+}
+
+int IconPickerDialog::exec ( QString selection )
+{
+ IconList * list = IconList::instance();
+ auto contentsWidget = ui->iconView;
+ selectedIconKey = selection;
+
+
+ int index_nr = list->getIconIndex(selection);
+ auto model_index = list->index(index_nr);
+ contentsWidget->selectionModel()->select(model_index, QItemSelectionModel::Current | QItemSelectionModel::Select);
+
+ QMetaObject::invokeMethod(this, "delayed_scroll", Qt::QueuedConnection, Q_ARG(QModelIndex,model_index));
+ return QDialog::exec();
+}
+
+void IconPickerDialog::delayed_scroll ( QModelIndex model_index )
+{
+ auto contentsWidget = ui->iconView;
+ contentsWidget->scrollTo(model_index);
+}
+
+
+IconPickerDialog::~IconPickerDialog()
+{
+ delete ui;
+}
diff --git a/gui/IconPickerDialog.h b/gui/IconPickerDialog.h
new file mode 100644
index 00000000..c55f6ff2
--- /dev/null
+++ b/gui/IconPickerDialog.h
@@ -0,0 +1,26 @@
+#pragma once
+#include <QDialog>
+#include <QItemSelection>
+
+namespace Ui {
+class IconPickerDialog;
+}
+
+class IconPickerDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit IconPickerDialog(QWidget *parent = 0);
+ ~IconPickerDialog();
+ int exec(QString selection);
+ QString selectedIconKey;
+
+private:
+ Ui::IconPickerDialog *ui;
+
+private slots:
+ void selectionChanged ( QItemSelection,QItemSelection );
+ void activated ( QModelIndex );
+ void delayed_scroll ( QModelIndex );
+};
diff --git a/gui/IconPickerDialog.ui b/gui/IconPickerDialog.ui
new file mode 100644
index 00000000..c548edfb
--- /dev/null
+++ b/gui/IconPickerDialog.ui
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>IconPickerDialog</class>
+ <widget class="QDialog" name="IconPickerDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>676</width>
+ <height>555</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Pick icon</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QListView" name="iconView"/>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>IconPickerDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ &l