summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOrochimarufan <orochimarufan.x3@gmail.com>2013-03-22 14:01:54 +0100
committerOrochimarufan <orochimarufan.x3@gmail.com>2013-03-22 14:01:54 +0100
commitcd1fdbbbc2953c5e34d8c0ae6861bec4a7f6532e (patch)
treea4148d6bb1704e635807c37b36013e9a33820a80
parentf4c9cb8c1d395422b7e4f1c27ac92b6df08a39bb (diff)
parente4806ab08d0293d395c1718ab16d28ba2ae9d0ed (diff)
downloadMultiMC-cd1fdbbbc2953c5e34d8c0ae6861bec4a7f6532e.tar
MultiMC-cd1fdbbbc2953c5e34d8c0ae6861bec4a7f6532e.tar.gz
MultiMC-cd1fdbbbc2953c5e34d8c0ae6861bec4a7f6532e.tar.lz
MultiMC-cd1fdbbbc2953c5e34d8c0ae6861bec4a7f6532e.tar.xz
MultiMC-cd1fdbbbc2953c5e34d8c0ae6861bec4a7f6532e.zip
Merge branch 'master' of http://github.com/peterix/MultiMC5
Conflicts: CMakeLists.txt main.cpp
-rw-r--r--CMakeLists.txt3
-rw-r--r--gui/iconcache.cpp127
-rw-r--r--gui/iconcache.h43
-rw-r--r--gui/instancedelegate.cpp12
-rw-r--r--gui/instancemodel.cpp43
-rw-r--r--gui/instancemodel.h7
-rw-r--r--gui/mainwindow.cpp65
-rw-r--r--gui/mainwindow.h7
-rw-r--r--libmultimc/include/instance.h34
-rw-r--r--libmultimc/include/instancelist.h44
-rw-r--r--libmultimc/src/instancelist.cpp160
-rw-r--r--libutil/CMakeLists.txt3
-rw-r--r--main.cpp16
-rw-r--r--multimc.qrc3
-rw-r--r--resources/catbgrnd2.pngbin0 -> 78285 bytes
-rw-r--r--resources/icons/instances/skeleton.svg40
16 files changed, 523 insertions, 84 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6f0204c3..742f47f6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -31,7 +31,6 @@ ENDIF()
# First, include header overrides
include_directories(hacks)
-
######## 3rd Party Libs ########
# Find the required Qt parts
@@ -173,6 +172,7 @@ gui/aboutdialog.h
gui/consolewindow.h
gui/instancemodel.h
gui/instancedelegate.h
+gui/iconcache.h
multimc_pragma.h
@@ -201,6 +201,7 @@ gui/aboutdialog.cpp
gui/consolewindow.cpp
gui/instancemodel.cpp
gui/instancedelegate.cpp
+gui/iconcache.cpp
java/javautils.cpp
java/annotations.cpp
diff --git a/gui/iconcache.cpp b/gui/iconcache.cpp
new file mode 100644
index 00000000..520a7839
--- /dev/null
+++ b/gui/iconcache.cpp
@@ -0,0 +1,127 @@
+#include "iconcache.h"
+#include <QMap>
+#include <QWebView>
+#include <QWebFrame>
+#include <QEventLoop>
+#include <QWebElement>
+
+IconCache* IconCache::m_Instance = 0;
+QMutex IconCache::mutex;
+#define MAX_SIZE 1024
+
+class Private : public QWebView
+{
+ Q_OBJECT
+
+public:
+ QString name;
+ QSize size;
+ QMap<QString, QIcon> icons;
+
+public:
+ Private()
+ {
+ connect(this, SIGNAL(loadFinished(bool)), this, SLOT(svgLoaded(bool)));
+ setFixedSize(MAX_SIZE, MAX_SIZE);
+
+ QPalette pal = palette();
+ pal.setColor(QPalette::Base, Qt::transparent);
+ setPalette(pal);
+ setAttribute(Qt::WA_OpaquePaintEvent, false);
+ size = QSize(128,128);
+ }
+ void renderSVGIcon(QString name);
+
+signals:
+ void svgRendered();
+
+private slots:
+ void svgLoaded(bool ok);
+};
+
+void Private::svgLoaded(bool ok)
+{
+ if (!ok)
+ {
+ emit svgRendered();
+ return;
+ }
+ // check for SVG root tag
+ QString root = page()->currentFrame()->documentElement().tagName();
+ if (root.compare("svg", Qt::CaseInsensitive) != 0)
+ {
+ emit svgRendered();
+ return;
+ }
+
+ // get the size of the svg image, check if it's valid
+ auto elem = page()->currentFrame()->documentElement();
+ double width = elem.attribute("width").toDouble();
+ double height = elem.attribute("height").toDouble();
+ if (width == 0.0 || height == 0.0 || width == MAX_SIZE || height == MAX_SIZE)
+ {
+ emit svgRendered();
+ return;
+ }
+
+ // create the target surface
+ QSize t = size.isValid() ? size : QSize(width, height);
+ QImage img(t, QImage::Format_ARGB32_Premultiplied);
+ img.fill(Qt::transparent);
+
+ // prepare the painter, scale to required size
+ QPainter p(&img);
+ if(size.isValid())
+ {
+ p.scale(size.width() / width, size.height() / height);
+ }
+
+ // the best quality
+ p.setRenderHint(QPainter::Antialiasing);
+ p.setRenderHint(QPainter::TextAntialiasing);
+ p.setRenderHint(QPainter::SmoothPixmapTransform);
+
+ page()->mainFrame()->render(&p,QWebFrame::ContentsLayer);
+ p.end();
+
+ icons[name] = QIcon(QPixmap::fromImage(img));
+ emit svgRendered();
+}
+
+void Private::renderSVGIcon ( QString name )
+{
+ // use event loop to wait for signal
+ QEventLoop loop;
+ this->name = name;
+ QString prefix = "qrc:/icons/instances/";
+ QObject::connect(this, SIGNAL(svgRendered()), &loop, SLOT(quit()));
+ load(QUrl(prefix + name));
+ loop.exec();
+}
+
+IconCache::IconCache():d(new Private())
+{
+}
+
+QIcon IconCache::getIcon ( QString name )
+{
+ if(name == "default")
+ name = "infinity";
+ {
+ auto iter = d->icons.find(name);
+ if(iter != d->icons.end())
+ return *iter;
+ }
+ d->renderSVGIcon(name);
+ auto iter = d->icons.find(name);
+ if(iter != d->icons.end())
+ return *iter;
+
+ // Fallback for icons that don't exist.
+ QString path = ":/icons/instances/infinity";
+ //path += name;
+ d->icons[name] = QIcon(path);
+ return d->icons[name];
+}
+
+#include "iconcache.moc" \ No newline at end of file
diff --git a/gui/iconcache.h b/gui/iconcache.h
new file mode 100644
index 00000000..5c5e4142
--- /dev/null
+++ b/gui/iconcache.h
@@ -0,0 +1,43 @@
+#pragma once
+
+#include <QMutex>
+#include <QtGui/QIcon>
+
+class Private;
+
+class IconCache
+{
+public:
+ static IconCache* instance()
+ {
+ if (!m_Instance)
+ {
+ mutex.lock();
+ if (!m_Instance)
+ m_Instance = new IconCache;
+ mutex.unlock();
+ }
+ return m_Instance;
+ }
+
+ static void drop()
+ {
+ mutex.lock();
+ delete m_Instance;
+ m_Instance = 0;
+ mutex.unlock();
+ }
+
+ QIcon getIcon(QString name);
+
+private:
+ IconCache();
+ // hide copy constructor
+ IconCache(const IconCache &);
+ // hide assign op
+ IconCache& operator=(const IconCache &);
+ static IconCache* m_Instance;
+ static QMutex mutex;
+ Private* d;
+};
+ \ No newline at end of file
diff --git a/gui/instancedelegate.cpp b/gui/instancedelegate.cpp
index dac2dacb..86b7d399 100644
--- a/gui/instancedelegate.cpp
+++ b/gui/instancedelegate.cpp
@@ -33,9 +33,15 @@ ListViewDelegate::ListViewDelegate ( QObject* parent ) : QStyledItemDelegate ( p
void drawSelectionRect(QPainter *painter, const QStyleOptionViewItemV4 &option, const QRect &rect)
{
- if (!(option.state & QStyle::State_Selected))
- return;
- painter->fillRect ( rect, option.palette.brush ( QPalette::Highlight ) );
+ if ((option.state & QStyle::State_Selected))
+ painter->fillRect ( rect, option.palette.brush ( QPalette::Highlight ) );
+ else
+ {
+ QColor backgroundColor = option.palette.color(QPalette::Background);
+ backgroundColor.setAlpha(160);
+ painter->fillRect ( rect, QBrush(backgroundColor) );
+ }
+
}
void drawFocusRect(QPainter *painter, const QStyleOptionViewItemV4 &option, const QRect &rect)
diff --git a/gui/instancemodel.cpp b/gui/instancemodel.cpp
index 73d0dbc1..8db985e8 100644
--- a/gui/instancemodel.cpp
+++ b/gui/instancemodel.cpp
@@ -1,13 +1,38 @@
#include "instancemodel.h"
#include <instance.h>
#include <QIcon>
+#include "iconcache.h"
InstanceModel::InstanceModel ( const InstanceList& instances, QObject *parent )
: QAbstractListModel ( parent ), m_instances ( &instances )
{
- cachedIcon = QIcon(":/icons/multimc/scalable/apps/multimc.svg");
+ currentInstancesNumber = m_instances->count();
+ connect(m_instances,SIGNAL(instanceAdded(int)),this,SLOT(onInstanceAdded(int)));
+ connect(m_instances,SIGNAL(instanceChanged(int)),this,SLOT(onInstanceChanged(int)));
+ connect(m_instances,SIGNAL(invalidated()),this,SLOT(onInvalidated()));
}
+void InstanceModel::onInstanceAdded ( int index )
+{
+ beginInsertRows(QModelIndex(), index, index);
+ currentInstancesNumber ++;
+ endInsertRows();
+}
+
+void InstanceModel::onInstanceChanged ( int index )
+{
+ QModelIndex mx = InstanceModel::index(index);
+ dataChanged(mx,mx);
+}
+
+void InstanceModel::onInvalidated()
+{
+ beginResetModel();
+ currentInstancesNumber = m_instances->count();
+ endResetModel();
+}
+
+
int InstanceModel::rowCount ( const QModelIndex& parent ) const
{
Q_UNUSED ( parent );
@@ -17,7 +42,7 @@ int InstanceModel::rowCount ( const QModelIndex& parent ) const
QModelIndex InstanceModel::index ( int row, int column, const QModelIndex& parent ) const
{
Q_UNUSED ( parent );
- if ( row < 0 || row >= m_instances->count() )
+ if ( row < 0 || row >= currentInstancesNumber )
return QModelIndex();
return createIndex ( row, column, ( void* ) m_instances->at ( row ).data() );
}
@@ -46,14 +71,22 @@ QVariant InstanceModel::data ( const QModelIndex& index, int role ) const
}
case Qt::DecorationRole:
{
- // FIXME: replace with an icon cache
- return cachedIcon;
+ IconCache * ic = IconCache::instance();
+ // FIXME: replace with an icon cache/renderer
+ /*
+ QString path = ":/icons/instances/";
+ path += pdata->iconKey();
+ QIcon icon(path);
+ */
+ QString key = pdata->iconKey();
+ return ic->getIcon(key);
+ //else return QIcon(":/icons/multimc/scalable/apps/multimc.svg");
}
// for now.
case KCategorizedSortFilterProxyModel::CategorySortRole:
case KCategorizedSortFilterProxyModel::CategoryDisplayRole:
{
- return "IT'S A GROUP";
+ return pdata->group();
}
default:
break;
diff --git a/gui/instancemodel.h b/gui/instancemodel.h
index 995c51ec..208ee68e 100644
--- a/gui/instancemodel.h
+++ b/gui/instancemodel.h
@@ -22,9 +22,14 @@ public:
QVariant data ( const QModelIndex& index, int role ) const;
Qt::ItemFlags flags ( const QModelIndex& index ) const;
+public slots:
+ void onInstanceAdded(int index);
+ void onInstanceChanged(int index);
+ void onInvalidated();
+
private:
const InstanceList* m_instances;
- QIcon cachedIcon;
+ int currentInstancesNumber;
};
class InstanceProxyModel : public KCategorizedSortFilterProxyModel
diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp
index e691c8c4..5a915e8c 100644
--- a/gui/mainwindow.cpp
+++ b/gui/mainwindow.cpp
@@ -64,11 +64,25 @@ MainWindow::MainWindow ( QWidget *parent ) :
{
ui->setupUi ( this );
// Create the widget
- instList.loadList();
-
view = new KCategorizedView ( ui->centralWidget );
drawer = new KCategoryDrawer ( view );
-
+ /*
+ QPalette pal = view->palette();
+ pal.setBrush(QPalette::Base, QBrush(QPixmap(QString::fromUtf8(":/backgrounds/kitteh"))));
+ view->setPalette(pal);
+ */
+
+ view->setStyleSheet(
+ "QListView\
+ {\
+ background-image: url(:/backgrounds/kitteh);\
+ background-attachment: fixed;\
+ background-clip: padding;\
+ background-position: top right;\
+ background-repeat: none;\
+ background-color:palette(base);\
+ }");
+
view->setSelectionMode ( QAbstractItemView::SingleSelection );
//view->setSpacing( KDialog::spacingHint() );
view->setCategoryDrawer ( drawer );
@@ -100,7 +114,14 @@ MainWindow::MainWindow ( QWidget *parent ) :
view->setModel ( proxymodel );
connect(view, SIGNAL(doubleClicked(const QModelIndex &)),
this, SLOT(instanceActivated(const QModelIndex &)));
-
+
+ // Load the instances.
+ instList.loadList();
+ // just a test
+ /*
+ instList.at(0)->setGroup("TEST GROUP");
+ instList.at(0)->setName("TEST ITEM");
+ */
}
MainWindow::~MainWindow()
@@ -125,6 +146,18 @@ void MainWindow::on_actionAddInstance_triggered()
newInstDlg->exec();
}
+void MainWindow::on_actionChangeInstGroup_triggered()
+{
+ Instance* inst = selectedInstance();
+ if(inst)
+ {
+ QString name ( inst->group() );
+ name = QInputDialog::getText ( this, tr ( "Group name" ), tr ( "Enter a new group name." ), QLineEdit::Normal, name );
+ inst->setGroup(name);
+ }
+}
+
+
void MainWindow::on_actionViewInstanceFolder_triggered()
{
openInDefaultProgram ( globalSettings->get ( "InstanceDir" ).toString() );
@@ -195,13 +228,31 @@ void MainWindow::on_instanceView_customContextMenuRequested ( const QPoint &pos
instContextMenu->exec ( view->mapToGlobal ( pos ) );
}
+Instance* 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 (Instance *) mindex.data(InstanceModel::InstancePointerRole).value<void *>();
+ }
+ else
+ return nullptr;
+}
+
void MainWindow::on_actionLaunchInstance_triggered()
{
- QModelIndex index = view->currentIndex();
- if(index.isValid())
+ Instance* inst = selectedInstance();
+ if(inst)
{
- Instance * inst = (Instance *) index.data(InstanceModel::InstancePointerRole).value<void *>();
doLogin(inst->id());
}
}
diff --git a/gui/mainwindow.h b/gui/mainwindow.h
index c2dedf74..5d990639 100644
--- a/gui/mainwindow.h
+++ b/gui/mainwindow.h
@@ -44,14 +44,19 @@ public:
// Browser Dialog
void openWebPage(QUrl url);
+
+private:
+ Instance *selectedInstance();
private slots:
void on_actionAbout_triggered();
void on_actionAddInstance_triggered();
- void on_actionViewInstanceFolder_triggered();
+ void on_actionChangeInstGroup_triggered();
+ void on_actionViewInstanceFolder_triggered();
+
void on_actionRefresh_triggered();
void on_actionViewCentralModsFolder_triggered();
diff --git a/libmultimc/include/instance.h b/libmultimc/include/instance.h
index c41e6718..258a0dab 100644
--- a/libmultimc/include/instance.h
+++ b/libmultimc/include/instance.h
@@ -65,6 +65,9 @@ class LIBMULTIMC_EXPORT Instance : public QObject
//! The instance's notes.
Q_PROPERTY(QString notes READ notes WRITE setNotes)
+ //! The instance's group.
+ Q_PROPERTY(QString group READ group WRITE setGroup)
+
/*!
* Whether or not the instance's minecraft.jar needs to be rebuilt.
* If this is true, when the instance launches, its jar mods will be
@@ -173,14 +176,29 @@ public:
//// General Info ////
virtual QString name() { return settings().get("name").toString(); }
- virtual void setName(QString val) { settings().set("name", val); }
+ virtual void setName(QString val)
+ {
+ settings().set("name", val);
+ emit propertiesChanged(this);
+ }
virtual QString iconKey() const { return settings().get("iconKey").toString(); }
- virtual void setIconKey(QString val) { settings().set("iconKey", val); }
+ virtual void setIconKey(QString val)
+ {
+ settings().set("iconKey", val);
+ emit propertiesChanged(this);
+ }
virtual QString notes() const { return settings().get("notes").toString(); }
virtual void setNotes(QString val) { settings().set("notes", val); }
+ virtual QString group() const { return m_group; }
+ virtual void setGroup(QString val)
+ {
+ m_group = val;
+ emit propertiesChanged(this);
+ }
+
virtual bool shouldRebuild() const { return settings().get("NeedsRebuild").toBool(); }
virtual void setShouldRebuild(bool val) { settings().set("NeedsRebuild", val); }
@@ -202,7 +220,10 @@ public:
virtual qint64 lastLaunch() { return settings().get("lastLaunchTime").value<qint64>(); }
virtual void setLastLaunch(qint64 val = QDateTime::currentMSecsSinceEpoch())
- { settings().set("lastLaunchTime", val); }
+ {
+ settings().set("lastLaunchTime", val);
+ emit propertiesChanged(this);
+ }
////// Directories //////
@@ -277,8 +298,15 @@ public:
*/
virtual SettingsObject &settings() const;
+signals:
+ /*!
+ * \brief Signal emitted when properties relevant to the instance view change
+ */
+ void propertiesChanged(Instance * inst);
+
private:
QString m_rootDir;
+ QString m_group;
SettingsObject *m_settings;
};
diff --git a/libmultimc/include/instancelist.h b/libmultimc/include/instancelist.h
index d4e7556a..a0d8788a 100644
--- a/libmultimc/include/instancelist.h
+++ b/libmultimc/include/instancelist.h
@@ -17,16 +17,14 @@
#define INSTANCELIST_H
#include <QObject>
-
#include <QSharedPointer>
-#include "siglist.h"
-
+#include "instance.h"
#include "libmmc_config.h"
class Instance;
-class LIBMULTIMC_EXPORT InstanceList : public QObject, public SigList< QSharedPointer<Instance> >
+class LIBMULTIMC_EXPORT InstanceList : public QObject
{
Q_OBJECT
public:
@@ -46,14 +44,46 @@ public:
QString instDir() const { return m_instDir; }
/*!
- * \brief Loads the instance list.
+ * \brief Loads the instance list. Triggers notifications.
*/
InstListError loadList();
- DEFINE_SIGLIST_SIGNALS(QSharedPointer<Instance>);
- SETUP_SIGLIST_SIGNALS(QSharedPointer<Instance>);
+ /*!
+ * \brief Get the instance at index
+ */
+ InstancePtr at(int i) const
+ {
+ return m_instances.at(i);
+ };
+
+ /*!
+ * \brief Get the count of loaded instances
+ */
+ int count() const
+ {
+ return m_instances.count();
+ };
+
+ /// Clear all instances. Triggers notifications.
+ void clear();
+
+ /// Add an instance. Triggers notifications, returns the new index
+ int add(InstancePtr t);
+
+ /// Get an instance by ID
+ InstancePtr getInstanceById (QString id);
+
+signals:
+ void instanceAdded(int index);
+ void instanceChanged(int index);
+ void invalidated();
+
+private slots:
+ void propertiesChanged(Instance * inst);
+
protected:
QString m_instDir;
+ QList< InstancePtr > m_instances;
};
#endif // INSTANCELIST_H
diff --git a/libmultimc/src/instancelist.cpp b/libmultimc/src/instancelist.cpp
index 78650634..f9c525d0 100644
--- a/libmultimc/src/instancelist.cpp
+++ b/libmultimc/src/instancelist.cpp
@@ -15,17 +15,21 @@
#include "include/instancelist.h"
-#include "siglist_impl.h"
-
#include <QDir>
#include <QFile>
#include <QDirIterator>
+#include <QThread>
+#include <QTextStream>
+#include <QJsonDocument>
+#include <QJsonObject>
+#include <QJsonArray>
#include "include/instance.h"
#include "include/instanceloader.h"
#include "pathutils.h"
+const static int GROUP_FILE_FORMAT_VERSION = 1;
InstanceList::InstanceList(const QString &instDir, QObject *parent) :
QObject(parent), m_instDir("instances")
@@ -38,6 +42,104 @@ InstanceList::InstListError InstanceList::loadList()
QDir dir(m_instDir);
QDirIterator iter(dir);
+ QString groupFileName = m_instDir + "/instgroups.json";
+ // temporary map from instance ID to group name
+ QMap<QString, QString> groupMap;
+
+ // HACK: this is really an if. breaks after one iteration.
+ while (QFileInfo(groupFileName).exists())
+ {
+ QFile groupFile(groupFileName);
+
+ if (!groupFile.open(QIODevice::ReadOnly))
+ {
+ // An error occurred. Ignore it.
+ qDebug("Failed to read instance group file.");
+ break;
+ }
+
+ QTextStream in(&groupFile);
+ QString jsonStr = in.readAll();
+ groupFile.close();
+
+ QJsonParseError error;
+ QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonStr.toUtf8(), &error);
+
+ if (error.error != QJsonParseError::NoError)
+ {
+ qWarning(QString("Failed to parse instance group file: %1 at offset %2").
+ arg(error.errorString(), QString::number(error.offset)).toUtf8());
+ break;
+ }
+
+ if (!jsonDoc.isObject())
+ {
+ qWarning("Invalid group file. Root entry should be an object.");
+ break;
+ }
+
+ QJsonObject rootObj = jsonDoc.object();
+
+ // Make sure the format version matches.
+ if (rootObj.value("formatVersion").toVariant().toInt() == GROUP_FILE_FORMAT_VERSION)
+ {
+ // Get the group list.
+ if (!rootObj.value("groups").isObject())
+ {
+ qWarning("Invalid group list JSON: 'groups' should be an object.");
+ break;
+ }
+
+ // Iterate through the list.
+ QJsonObject groupList = rootObj.value("groups").toObject();
+
+ for (QJsonObject::iterator iter = groupList.begin();
+ iter != groupList.end(); iter++)
+ {
+ QString groupName = iter.key();
+
+ // If not an object, complain and skip to the next one.
+ if (!iter.value().isObject())
+ {
+ qWarning(QString("Group '%1' in the group list should "
+ "be an object.").arg(groupName).toUtf8());
+ continue;
+ }
+
+ QJsonObject groupObj = iter.value().toObject();
+ /*
+ // Create the group object.
+ InstanceGroup *group = new InstanceGroup(groupName, this);
+ groups.push_back(group);
+
+ // If 'hidden' isn't a bool value, just assume it's false.
+ if (groupObj.value("hidden").isBool() && groupObj.value("hidden").toBool())
+ {
+ group->setHidden(groupObj.value("hidden").toBool());
+ }
+ */
+
+ if (!groupObj.value("instances").isArray())
+ {
+ qWarning(QString("Group '%1' in the group list is invalid. "
+ "It should contain an array "
+ "called 'instances'.").arg(groupName).toUtf8());
+ continue;
+ }
+
+ // Iterate through the list of instances in the group.
+ QJsonArray instancesArray = groupObj.value("instances").toArray();
+
+ for (QJsonArray::iterator iter2 = instancesArray.begin();
+ iter2 != instancesArray.end(); iter2++)
+ {
+ groupMap[(*iter2).toString()] = groupName;
+ }
+ }
+ }
+ break;
+ }
+ m_instances.clear();
while (iter.hasNext())
{
QString subDir = iter.next();
@@ -75,13 +177,61 @@ InstanceList::InstListError InstanceList::loadList()
else
{
QSharedPointer<Instance> inst(instPtr);
-
+ auto iter = groupMap.find(inst->id());
+ if(iter != groupMap.end())
+ {
+ inst->setGroup((*iter));
+ }
qDebug(QString("Loaded instance %1").arg(inst->name()).toUtf8());
inst->setParent(this);
- append(QSharedPointer<Instance>(inst));
+ m_instances.append(inst);
+ connect(instPtr, SIGNAL(propertiesChanged(Instance*)),this, SLOT(propertiesChanged(Instance*)));
}
}
}
-
+ emit invalidated();
return NoError;
}
+
+/// Clear all instances. Triggers notifications.
+void InstanceList::clear()
+{
+ m_instances.clear();
+ emit invalidated();
+};
+
+/// Add an instance. Triggers notifications, returns the new index
+int InstanceList::add(InstancePtr t)
+{
+ m_instances.append(t);
+ emit instanceAdded(count() - 1);
+ return count() - 1;
+}
+
+InstancePtr InstanceList::getInstanceById(QString instId)
+{
+ QListIterator<InstancePtr> iter(m_instances);
+ InstancePtr inst;
+ while(iter.hasNext())
+ {
+ inst = iter.next();
+ if (inst->id() == instId)
+ break;
+ }
+ if (inst->id() != instId)
+ return InstancePtr();
+ else
+ return iter.peekPrevious();
+}
+
+void InstanceList::propertiesChanged(Instance * inst)
+{
+ for(int i = 0; i < m_instances.count(); i++)
+ {
+ if(inst == m_instances[i].data())
+ {
+ emit instanceChanged(i);
+ break;
+ }
+ }
+} \ No newline at end of file
diff --git a/libutil/CMakeLists.txt b/libutil/CMakeLists.txt
index 5b2c3837..11b21426 100644
--- a/libutil/CMakeLists.txt
+++ b/libutil/CMakeLists.txt
@@ -31,9 +31,6 @@ include/pathutils.h
include/osutils.h
include/userutils.h
include/cmdutils.h
-
-include/siglist.h
-include/siglist_impl.h
)
SET(LIBUTIL_SOURCES
diff --git a/main.cpp b/main.cpp
index 31d5277e..7c82d6d8 100644
--- a/main.cpp
+++ b/main.cpp
@@ -57,20 +57,6 @@ public:
this->instId = instId;
}
-private:
- InstancePtr findInstance(QString instId)
- {
- QListIterator<InstancePtr> iter(instances);
- InstancePtr inst;
- while(iter.hasNext())
- {
- inst = iter.next();
- if (inst->id() == instId)
- return inst;
- }
- return InstancePtr();
- }
-
private slots:
void onTerminated()
{
@@ -114,7 +100,7 @@ public:
instances.loadList();
std::cout << "Launching Instance '" << qPrintable(instId) << "'" << std::endl;
- instance = findInstance(instId);
+ instance = instances.getInstanceById(instId);
if (instance.isNull())
{
std::cout << "Could not find instance requested. note that you have to specify the ID, not the NAME" << std::endl;
diff --git a/multimc.qrc b/multimc.qrc
index cfcc9829..acd9efd2 100644
--- a/multimc.qrc
+++ b/multimc.qrc
@@ -34,4 +34,7 @@
<file alias="scalable/apps/multimc.svg">resources/icons/multimc.svg</file>
<file alias="index.theme">resources/XdgIcon.theme</file>
</qresource>
+ <qresource prefix="/backgrounds">
+ <file alias="kitteh">resources/catbgrnd2.png</file>
+ </qresource>
</RCC>
diff --git a/resources/catbgrnd2.png b/resources/catbgrnd2.png
new file mode 100644
index 00000000..2b949e0b
--- /dev/null
+++ b/resources/catbgrnd2.png
Binary files differ
diff --git a/resources/icons/instances/skeleton.svg b/resources/icons/instances/skeleton.svg
index b2da5a46..5d55f272 100644
--- a/resources/icons/instances/skeleton.svg
+++ b/resources/icons/instances/skeleton.svg
@@ -13,7 +13,7 @@
height="32"
id="svg2"
version="1.1"
- inkscape:version="0.48.3.1 r9886"
+ inkscape:version="0.48.4 r9939"
sodipodi:docname="skeleton.svg"
inkscape:export-filename="/home/peterix/projects/MultiMC4/src/resources/insticons/skeleton128.png"
inkscape:export-xdpi="360"
@@ -23,19 +23,6 @@
<filter
color-interpolation-filters="sRGB"
inkscape:collect="always"
- id="filter5719"
- x="-0.18000001"
- width="1.36"
- y="-0.36000001"
- height="1.72">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.15"
- id="feGaussianBlur5721" />
- </filter>
- <filter
- color-interpolation-filters="sRGB"
- inkscape:collect="always"
id="filter5723"
x="-0.20999999"
width="1.42"
@@ -49,19 +36,6 @@
<filter
color-interpolation-filters="sRGB"
inkscape:collect="always"
- id="filter5711"
- x="-0.1728"
- width="1.3456"
- y="-0.34560001"
- height="1.6912">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.144"
- id="feGaussianBlur5713" />
- </filter>
- <filter
- color-interpolation-filters="sRGB"
- inkscape:collect="always"
id="filter5727"
x="-0.20999999"
width="1.42"
@@ -103,12 +77,12 @@
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="11.313708"
- inkscape:cx="17.044214"
- inkscape:cy="19.500236"
+ inkscape:cx="-18.309169"
+ inkscape:cy="22.958832"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
- inkscape:window-width="1607"
+ inkscape:window-width="1614"
inkscape:window-height="1030"
inkscape:window-x="1676"
inkscape:window-y="-3"
@@ -129,7 +103,7 @@
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
+ <dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
@@ -612,7 +586,7 @@
x="7.9999995"
y="1036.3622" />
<rect
- style="fill:#00ffff;fill-opacity:1;stroke:none;filter:url(#filter5711)"
+ style="fill:#00ffff;fill-opacity:1;stroke:none;"
id="rect4084-3"
width="2"
height="1"
@@ -626,7 +600,7 @@
x="20"
y="1036.3622" />
<rect
- style="fill:#00ffff;fill-opacity:1;stroke:none;filter:url(#filter5719)"
+ style="fill:#00ffff;fill-opacity:1;stroke:none;"
id="rect4086-7"
width="2"
height="1"