Further work on moving to players list model
authorunc0rr
Sun, 07 Oct 2012 00:12:46 +0400
changeset 7725 4ad05a478c6c
parent 7724 36c539c9cfb1
child 7726 1137406bce12
Further work on moving to players list model
QTfrontend/model/playerslistmodel.cpp
QTfrontend/model/playerslistmodel.h
QTfrontend/net/newnetclient.cpp
QTfrontend/res/css/qt.css
QTfrontend/ui/widget/chatwidget.cpp
QTfrontend/ui/widget/chatwidget.h
--- a/QTfrontend/model/playerslistmodel.cpp	Sat Oct 06 23:36:43 2012 +0400
+++ b/QTfrontend/model/playerslistmodel.cpp	Sun Oct 07 00:12:46 2012 +0400
@@ -1,14 +1,190 @@
+#include <QModelIndexList>
+#include <QModelIndex>
+#include <QPainter>
+
 #include "playerslistmodel.h"
 
 PlayersListModel::PlayersListModel(QObject *parent) :
-    QStringListModel(parent)
+    QAbstractListModel(parent)
 {
 
 }
 
+
+int PlayersListModel::rowCount(const QModelIndex &parent) const
+{
+    if(parent.isValid())
+        return 0;
+    else
+        return m_data.size();
+}
+
+
+QVariant PlayersListModel::data(const QModelIndex &index, int role) const
+{
+    if(!index.isValid())
+        return QVariant(QVariant::Invalid);
+
+    return m_data.at(index.row()).value(role);
+}
+
+
+bool PlayersListModel::setData(const QModelIndex &index, const QVariant &value, int role)
+{
+    if(!index.isValid() || index.row() < 0 || index.row() >= rowCount() || index.column() != 0)
+        return false;
+
+    m_data[index.row()].insert(role, value);
+
+    emit dataChanged(index, index);
+
+    return true;
+}
+
+
+bool PlayersListModel::insertRow(int row, const QModelIndex &parent)
+{
+    return insertRows(row, 1, parent);
+}
+
+
+bool PlayersListModel::insertRows(int row, int count, const QModelIndex &parent)
+{
+    if(parent.isValid() || row > rowCount() || row < 0 || count < 1)
+        return false;
+
+    beginInsertRows(parent, row, row + count - 1);
+
+    for(int i = 0; i < count; ++i)
+        m_data.insert(row, DataEntry());
+
+    endInsertRows();
+
+    return true;
+}
+
+
+bool PlayersListModel::removeRows(int row, int count, const QModelIndex &parent)
+{
+    if(parent.isValid() || row + count > rowCount() || row < 0 || count < 1)
+        return false;
+
+    beginRemoveRows(parent, row, row + count - 1);
+
+    for(int i = 0; i < count; ++i)
+        m_data.removeAt(row);
+
+    endRemoveRows();
+
+    return true;
+}
+
+
 void PlayersListModel::addPlayer(const QString & nickname)
 {
-    insertRows(rowCount(), 1);
+    insertRow(rowCount());
 
     setData(index(rowCount() - 1), nickname);
+
+    updateIcon(index(rowCount() - 1));
 }
+
+
+void PlayersListModel::removePlayer(const QString & nickname)
+{
+    QModelIndexList mil = match(index(0, 0), Qt::DisplayRole, nickname);
+
+    if(mil.size())
+        removeRow(mil[0].row());
+}
+
+
+void PlayersListModel::setFlag(const QString &nickname, StateFlag flagType, bool isSet)
+{
+    QModelIndexList mil = match(index(0), Qt::DisplayRole, nickname);
+
+    if(mil.size())
+    {
+        setData(mil[0], flagType, isSet);
+        updateIcon(mil[0]);
+    }
+}
+
+
+void PlayersListModel::updateIcon(const QModelIndex & index)
+{
+    quint32 iconNum = 0;
+
+    QList<bool> flags;
+    flags
+        << index.data(Ready).toBool()
+        << index.data(ServerAdmin).toBool()
+        << index.data(RoomAdmin).toBool()
+        << index.data(Registered).toBool()
+        << index.data(Friend).toBool()
+        << index.data(Ignore).toBool()
+        ;
+
+    for(int i = flags.size() - 1; i >= 0; --i)
+        if(flags[i])
+            iconNum |= 1 << i;
+
+    if(m_icons().contains(iconNum))
+    {
+        setData(index, m_icons().value(iconNum), Qt::DecorationRole);
+        qDebug("cached");
+    }
+    else
+    {
+        QPixmap result(24, 16);
+        result.fill(Qt::transparent);
+
+        QPainter painter(&result);
+
+        if(index.data(Ready).toBool())
+            painter.drawPixmap(0, 0, 16, 16, QPixmap(":/res/chat/lamp.png"));
+
+        QString mainIconName(":/res/chat/");
+
+        if(index.data(RoomAdmin).toBool())
+            mainIconName += "roomadmin";
+        else if(index.data(ServerAdmin).toBool())
+            mainIconName += "serveradmin";
+        else
+            mainIconName += "hedgehog";
+
+        if(!index.data(Registered).toBool())
+            mainIconName += "_gray";
+
+        painter.drawPixmap(8, 0, 16, 16, QPixmap(mainIconName + ".png"));
+
+        if(index.data(Ignore).toBool())
+            painter.drawPixmap(8, 0, 16, 16, QPixmap(":/res/chat/ignore.png"));
+        else
+        if(index.data(Friend).toBool())
+            painter.drawPixmap(8, 0, 16, 16, QPixmap(":/res/chat/friend.png"));
+
+        painter.end();
+
+        QIcon icon(result);
+
+        setData(index, icon, Qt::DecorationRole);
+        m_icons().insert(iconNum, icon);
+    }
+
+    if(index.data(Ignore).toBool())
+        setData(index, Qt::gray, Qt::ForegroundRole);
+    else
+    if(index.data(Friend).toBool())
+        setData(index, Qt::green, Qt::ForegroundRole);
+    else
+        setData(index, QBrush(QColor(0xff, 0xcc, 0x00)), Qt::ForegroundRole);
+}
+
+
+QHash<quint32, QIcon> & PlayersListModel::m_icons()
+{
+    static QHash<quint32, QIcon> iconsCache;
+
+    return iconsCache;
+}
--- a/QTfrontend/model/playerslistmodel.h	Sat Oct 06 23:36:43 2012 +0400
+++ b/QTfrontend/model/playerslistmodel.h	Sun Oct 07 00:12:46 2012 +0400
@@ -1,19 +1,46 @@
 #ifndef PLAYERSLISTMODEL_H
 #define PLAYERSLISTMODEL_H
 
-#include <QStringListModel>
+#include <QAbstractListModel>
+#include <QHash>
+#include <QIcon>
+#include <QModelIndex>
 
-class PlayersListModel : public QStringListModel
+class PlayersListModel : public QAbstractListModel
 {
     Q_OBJECT
+
 public:
+    enum StateFlag {
+        Ready       = Qt::UserRole,
+        ServerAdmin = Qt::UserRole + 1,
+        RoomAdmin   = Qt::UserRole + 2,
+        Registered  = Qt::UserRole + 3,
+        Friend      = Qt::UserRole + 4,
+        Ignore      = Qt::UserRole + 5
+    };
+
     explicit PlayersListModel(QObject *parent = 0);
 
-signals:
-    
+    int rowCount(const QModelIndex &parent = QModelIndex()) const;
+
+    QVariant data(const QModelIndex &index, int role) const;
+    bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::DisplayRole);
+
+    bool insertRow(int row, const QModelIndex &parent = QModelIndex());
+    bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex());
+    bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex());
+
 public slots:
     void addPlayer(const QString & nickname);
-    
+    void removePlayer(const QString & nickname);
+    void setFlag(const QString & nickname, StateFlag flagType, bool isSet);
+
+private:
+    QHash<quint32, QIcon> & m_icons();
+    typedef QHash<int, QVariant> DataEntry;
+    QList<DataEntry> m_data;
+    void updateIcon(const QModelIndex & index);
 };
 
 #endif // PLAYERSLISTMODEL_H
--- a/QTfrontend/net/newnetclient.cpp	Sat Oct 06 23:36:43 2012 +0400
+++ b/QTfrontend/net/newnetclient.cpp	Sun Oct 07 00:12:46 2012 +0400
@@ -496,6 +496,9 @@
             emit chatStringLobby(tr("%1 *** %2 has left").arg('\x03').arg(lst[1]));
         else
             emit chatStringLobby(lst[1], tr("%1 *** %2 has left (%3)").arg('\x03').arg("|nick|", lst[2]));
+
+        m_lobbyPlayersModel->removePlayer(lst[1]);
+
         return;
     }
 
--- a/QTfrontend/res/css/qt.css	Sat Oct 06 23:36:43 2012 +0400
+++ b/QTfrontend/res/css/qt.css	Sun Oct 07 00:12:46 2012 +0400
@@ -32,7 +32,7 @@
 
 a { color:#c8c8ff; }
 
-QLineEdit, QListWidget, QTableView, QTextBrowser, QSpinBox, QComboBox,
+QLineEdit, QListWidget, QListView, QTableView, QTextBrowser, QSpinBox, QComboBox,
 QComboBox QAbstractItemView, QPlainTextEdit, QMenu::item {
 background-color: rgba(13, 5, 68, 70%);
 }
@@ -41,7 +41,7 @@
 border: solid; border-width: 3px; border-color: #ffcc00;
 }
 
-QPushButton, QListWidget, QTableView, QLineEdit, QHeaderView,
+QPushButton, QListWidget, QListView, QTableView, QLineEdit, QHeaderView,
 QTextBrowser, QSpinBox, QToolBox, QComboBox, QPlainTextEdit,
 QComboBox QAbstractItemView, IconedGroupBox,
 .QGroupBox, GameCFGWidget, TeamSelWidget, SelWeaponWidget,
@@ -51,17 +51,17 @@
 border-color: #ffcc00;
 }
 
-QPushButton:hover, QLineEdit:hover, QListWidget:hover,
+QPushButton:hover, QLineEdit:hover, QListWidget:hover, QListView:hover,
 QSpinBox:hover, QToolBox:hover, QComboBox:hover {
 border-color: yellow;
 }
 
-QLineEdit, QListWidget,QTableView, QTextBrowser,
+QLineEdit, QListWidget, QListView, QTableView, QTextBrowser,
 QSpinBox, QToolBox, QPlainTextEdit {
 border-radius: 10px;
 }
 
-QLineEdit, QLabel, QHeaderView, QListWidget, QTableView,
+QLineEdit, QLabel, QHeaderView, QListWidget, QListView, QTableView,
 QSpinBox, QToolBox::tab, QComboBox, QComboBox QAbstractItemView,
 IconedGroupBox, .QGroupBox, GameCFGWidget, TeamSelWidget,
 SelWeaponWidget, QCheckBox, QRadioButton, QPushButton, QPlainTextEdit {
--- a/QTfrontend/ui/widget/chatwidget.cpp	Sat Oct 06 23:36:43 2012 +0400
+++ b/QTfrontend/ui/widget/chatwidget.cpp	Sun Oct 07 00:12:46 2012 +0400
@@ -357,9 +357,10 @@
 
     chatNicks = new QListView(this);
     chatNicks->setIconSize(QSize(24, 16));
+    chatNicks->setSelectionMode(QAbstractItemView::SingleSelection);
+    chatNicks->setEditTriggers(QAbstractItemView::NoEditTriggers);
     chatNicks->setMinimumHeight(10);
     chatNicks->setMinimumWidth(10);
-    //chatNicks->setSortingEnabled(true);
     chatNicks->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
     chatNicks->setContextMenuPolicy(Qt::ActionsContextMenu);
     connect(chatNicks, SIGNAL(itemDoubleClicked(QListWidgetItem *)),
@@ -1106,7 +1107,7 @@
 }
 
 
-void HWChatWidget::setUsersModel(QAbstractListModel * model)
+void HWChatWidget::setUsersModel(QAbstractItemModel *model)
 {
     chatNicks->setModel(model);
     chatNicks->setModelColumn(0);
--- a/QTfrontend/ui/widget/chatwidget.h	Sat Oct 06 23:36:43 2012 +0400
+++ b/QTfrontend/ui/widget/chatwidget.h	Sun Oct 07 00:12:46 2012 +0400
@@ -37,7 +37,7 @@
 class QLineEdit;
 class QListView;
 class QSettings;
-class QAbstractListModel;
+class QAbstractItemModel;
 
 /// Class for custom nickname sorting
 class ListWidgetNickItem : public QListWidgetItem
@@ -87,7 +87,7 @@
         void displayNotice(const QString & message);
         void displayWarning(const QString & message);
         void setUser(const QString & nickname);
-        void setUsersModel(QAbstractListModel * model);
+        void setUsersModel(QAbstractItemModel * model);
 
     protected:
         virtual void dragEnterEvent(QDragEnterEvent * event);