From ef46d6e863819b3b3c9ce7aeacd4b493f3421eee Mon Sep 17 00:00:00 2001 From: Max-Wilhelm Bruker Date: Fri, 20 Nov 2009 15:22:56 +0100 Subject: [PATCH] deck list storage completed --- cockatrice/src/tab_deck_storage.cpp | 172 ++++++++++++++++++++--- cockatrice/src/tab_deck_storage.h | 11 +- common/protocol.cpp | 55 +++++--- common/protocol.h | 53 ++----- common/protocol_datastructures.h | 34 +++++ servatrice/src/serversocketinterface.cpp | 10 +- servatrice/src/serversocketinterface.h | 2 +- 7 files changed, 251 insertions(+), 86 deletions(-) diff --git a/cockatrice/src/tab_deck_storage.cpp b/cockatrice/src/tab_deck_storage.cpp index c9c49664..ee240781 100644 --- a/cockatrice/src/tab_deck_storage.cpp +++ b/cockatrice/src/tab_deck_storage.cpp @@ -95,35 +95,44 @@ void TabDeckStorage::refreshServerList() client->sendCommand(command); } -void TabDeckStorage::populateDeckList(Response_DeckList::Directory *folder, QTreeWidgetItem *parent) +void TabDeckStorage::addFileToTree(DeckList_File *file, QTreeWidgetItem *parent) +{ + QFileIconProvider fip; + QTreeWidgetItem *newDeck = new QTreeWidgetItem(TWIDeckType); + newDeck->setIcon(0, fip.icon(QFileIconProvider::File)); + newDeck->setData(0, Qt::DisplayRole, file->getName()); + newDeck->setData(1, Qt::DisplayRole, file->getId()); + newDeck->setTextAlignment(1, Qt::AlignRight); + newDeck->setData(2, Qt::DisplayRole, file->getUploadTime()); + + parent->addChild(newDeck); +} + +void TabDeckStorage::populateDeckList(DeckList_Directory *folder, QTreeWidgetItem *parent) { QFileIconProvider fip; QTreeWidgetItem *newItem = new QTreeWidgetItem(TWIFolderType); newItem->setIcon(0, fip.icon(QFileIconProvider::Folder)); newItem->setText(0, parent ? folder->getName() : "/"); - QString parentPath; if (parent) { parent->addChild(newItem); - parentPath = parent->data(0, Qt::UserRole).toString(); - } else + + QString path = parent->data(0, Qt::UserRole).toString(); + if (path.isEmpty()) + newItem->setData(0, Qt::UserRole, folder->getName()); + else + newItem->setData(0, Qt::UserRole, path + "/" + folder->getName()); + } else { serverDirView->addTopLevelItem(newItem); - newItem->setData(0, Qt::UserRole, parentPath + "/" + folder->getName()); + newItem->setData(0, Qt::UserRole, QString()); + } for (int i = 0; i < folder->size(); ++i) { - Response_DeckList::Directory *subFolder = dynamic_cast(folder->at(i)); + DeckList_Directory *subFolder = dynamic_cast(folder->at(i)); if (subFolder) populateDeckList(subFolder, newItem); - else { - Response_DeckList::File *file = dynamic_cast(folder->at(i)); - QTreeWidgetItem *newDeck = new QTreeWidgetItem(TWIDeckType); - newDeck->setIcon(0, fip.icon(QFileIconProvider::File)); - newDeck->setData(0, Qt::DisplayRole, file->getName()); - newDeck->setData(1, Qt::DisplayRole, file->getId()); - newDeck->setTextAlignment(1, Qt::AlignRight); - newDeck->setData(2, Qt::DisplayRole, file->getUploadTime()); - - newItem->addChild(newDeck); - } + else + addFileToTree(dynamic_cast(folder->at(i)), newItem); } } @@ -135,14 +144,15 @@ void TabDeckStorage::deckListFinished(ProtocolResponse *r) serverDirView->clear(); populateDeckList(resp->getRoot(), 0); + serverDirView->expandAll(); } void TabDeckStorage::actUpload() { - QModelIndex cur = sortFilter->mapToSource(localDirView->selectionModel()->currentIndex()); - if (localDirModel->isDir(cur)) + QModelIndex curLeft = sortFilter->mapToSource(localDirView->selectionModel()->currentIndex()); + if (localDirModel->isDir(curLeft)) return; - QString filePath = localDirModel->filePath(cur); + QString filePath = localDirModel->filePath(curLeft); DeckList *deck = new DeckList; if (!deck->loadFromFile(filePath, DeckList::CockatriceFormat)) return; @@ -162,18 +172,138 @@ void TabDeckStorage::actUpload() void TabDeckStorage::uploadFinished(ProtocolResponse *r) { - qDebug() << "buh"; + Response_DeckUpload *resp = qobject_cast(r); + if (!resp) + return; + Command_DeckUpload *cmd = static_cast(sender()); + + QTreeWidgetItemIterator it(serverDirView); + while (*it) { + if ((*it)->data(0, Qt::UserRole) == cmd->getPath()) { + addFileToTree(resp->getFile(), *it); + break; + } + ++it; + } } void TabDeckStorage::actDownload() { + QString filePath; + QModelIndex curLeft = sortFilter->mapToSource(localDirView->selectionModel()->currentIndex()); + if (!curLeft.isValid()) + filePath = localDirModel->rootPath(); + else { + while (!localDirModel->isDir(curLeft)) + curLeft = curLeft.parent(); + filePath = localDirModel->filePath(curLeft); + } + + QTreeWidgetItem *curRight = serverDirView->currentItem(); + if ((!curRight) || (curRight->type() != TWIDeckType)) + return; + filePath += "/" + curRight->data(1, Qt::DisplayRole).toString() + ".cod"; + + Command_DeckDownload *command = new Command_DeckDownload(curRight->data(1, Qt::DisplayRole).toInt()); + command->setExtraData(filePath); + connect(command, SIGNAL(finished(ProtocolResponse *)), this, SLOT(downloadFinished(ProtocolResponse *))); + client->sendCommand(command); +} + +void TabDeckStorage::downloadFinished(ProtocolResponse *r) +{ + Response_DeckDownload *resp = qobject_cast(r); + if (!resp) + return; + Command_DeckDownload *cmd = static_cast(sender()); + + QString filePath = cmd->getExtraData().toString(); + resp->getDeck()->saveToFile(filePath, DeckList::CockatriceFormat); } void TabDeckStorage::actNewFolder() { + QString folderName = QInputDialog::getText(this, tr("New folder"), tr("Name of new folder:")); + if (folderName.isEmpty()) + return; + + QString targetPath; + QTreeWidgetItem *curRight = serverDirView->currentItem(); + while ((curRight != 0) && (curRight->type() != TWIFolderType)) + curRight = curRight->parent(); + if (curRight) + targetPath = curRight->data(0, Qt::UserRole).toString(); + + Command_DeckNewDir *command = new Command_DeckNewDir(targetPath, folderName); + connect(command, SIGNAL(finished(ResponseCode)), this, SLOT(newFolderFinished(ResponseCode))); + client->sendCommand(command); +} + +void TabDeckStorage::newFolderFinished(ResponseCode resp) +{ + if (resp != RespOk) + return; + + Command_DeckNewDir *cmd = static_cast(sender()); + + qDebug() << cmd->getPath() << cmd->getDirName(); + QTreeWidgetItemIterator it(serverDirView); + while (*it) { + if ((*it)->data(0, Qt::UserRole) == cmd->getPath()) { + qDebug() << "gefunden"; + QFileIconProvider fip; + QTreeWidgetItem *newItem = new QTreeWidgetItem(TWIFolderType); + newItem->setIcon(0, fip.icon(QFileIconProvider::Folder)); + newItem->setText(0, cmd->getDirName()); + newItem->setData(0, Qt::UserRole, cmd->getPath() + "/" + cmd->getDirName()); + (*it)->addChild(newItem); + break; + } else + qDebug() << "path = " << (*it)->data(0, Qt::UserRole) << " nicht gefunden"; + ++it; + } } void TabDeckStorage::actDelete() { + Command *command; + QTreeWidgetItem *curRight = serverDirView->currentItem(); + if (curRight->type() == TWIFolderType) { + if (curRight->data(0, Qt::UserRole).toString().isEmpty()) + return; + command = new Command_DeckDelDir(curRight->data(0, Qt::UserRole).toString()); + } else + command = new Command_DeckDel(curRight->data(1, Qt::DisplayRole).toInt()); + connect(command, SIGNAL(finished(ResponseCode)), this, SLOT(deleteFinished(ResponseCode))); + client->sendCommand(command); } +void TabDeckStorage::deleteFinished(ResponseCode resp) +{ + if (resp != RespOk) + return; + + QTreeWidgetItem *toDelete = 0; + QTreeWidgetItemIterator it(serverDirView); + Command_DeckDelDir *cmdDelDir = qobject_cast(sender()); + if (cmdDelDir) { + while (*it) { + if ((*it)->data(0, Qt::UserRole).toString() == cmdDelDir->getPath()) { + toDelete = *it; + break; + } + ++it; + } + } else { + Command_DeckDel *cmdDel = qobject_cast(sender()); + while (*it) { + if ((*it)->data(1, Qt::DisplayRole).toInt() == cmdDel->getDeckId()) { + toDelete = *it; + break; + } + ++it; + } + } + if (toDelete) + delete toDelete; +} diff --git a/cockatrice/src/tab_deck_storage.h b/cockatrice/src/tab_deck_storage.h index 52cc3c79..53ba397c 100644 --- a/cockatrice/src/tab_deck_storage.h +++ b/cockatrice/src/tab_deck_storage.h @@ -2,7 +2,7 @@ #define TAB_DECK_STORAGE_H #include -#include "protocol.h" +#include "protocol_datastructures.h" class Client; class QTreeView; @@ -12,6 +12,7 @@ class QToolBar; class QTreeWidget; class QTreeWidgetItem; class QGroupBox; +class ProtocolResponse; class TabDeckStorage : public QWidget { Q_OBJECT @@ -25,7 +26,8 @@ private: QGroupBox *leftGroupBox, *rightGroupBox; QAction *aUpload, *aDownload, *aNewFolder, *aDelete; - void populateDeckList(Response_DeckList::Directory *folder, QTreeWidgetItem *parent); + void addFileToTree(DeckList_File *file, QTreeWidgetItem *parent); + void populateDeckList(DeckList_Directory *folder, QTreeWidgetItem *parent); void refreshServerList(); private slots: void deckListFinished(ProtocolResponse *r); @@ -34,8 +36,13 @@ private slots: void uploadFinished(ProtocolResponse *r); void actDownload(); + void downloadFinished(ProtocolResponse *r); + void actNewFolder(); + void newFolderFinished(ResponseCode resp); + void actDelete(); + void deleteFinished(ResponseCode resp); public: TabDeckStorage(Client *_client); void retranslateUi(); diff --git a/common/protocol.cpp b/common/protocol.cpp index 932eac17..38458be8 100644 --- a/common/protocol.cpp +++ b/common/protocol.cpp @@ -71,6 +71,7 @@ void ProtocolItem::initializeHash() ProtocolResponse::initializeHash(); itemNameHash.insert("respdeck_list", Response_DeckList::newItem); itemNameHash.insert("respdeck_download", Response_DeckDownload::newItem); + itemNameHash.insert("respdeck_upload", Response_DeckUpload::newItem); itemNameHash.insert("generic_eventlist_games", Event_ListGames::newItem); itemNameHash.insert("generic_eventlist_chat_channels", Event_ListChatChannels::newItem); @@ -174,7 +175,7 @@ void ProtocolResponse::initializeHash() responseHash.insert("spectators_not_allowed", RespSpectatorsNotAllowed); } -bool Response_DeckList::File::readElement(QXmlStreamReader *xml) +bool DeckList_File::readElement(QXmlStreamReader *xml) { if (xml->isEndElement()) return true; @@ -182,7 +183,7 @@ bool Response_DeckList::File::readElement(QXmlStreamReader *xml) return false; } -void Response_DeckList::File::writeElement(QXmlStreamWriter *xml) +void DeckList_File::writeElement(QXmlStreamWriter *xml) { xml->writeStartElement("file"); xml->writeAttribute("name", name); @@ -191,13 +192,13 @@ void Response_DeckList::File::writeElement(QXmlStreamWriter *xml) xml->writeEndElement(); } -Response_DeckList::Directory::~Directory() +DeckList_Directory::~DeckList_Directory() { for (int i = 0; i < size(); ++i) delete at(i); } -bool Response_DeckList::Directory::readElement(QXmlStreamReader *xml) +bool DeckList_Directory::readElement(QXmlStreamReader *xml) { if (currentItem) { if (currentItem->readElement(xml)) @@ -205,10 +206,10 @@ bool Response_DeckList::Directory::readElement(QXmlStreamReader *xml) return false; } if (xml->isStartElement() && (xml->name() == "directory")) { - currentItem = new Directory(xml->attributes().value("name").toString()); + currentItem = new DeckList_Directory(xml->attributes().value("name").toString()); append(currentItem); } else if (xml->isStartElement() && (xml->name() == "file")) { - currentItem = new File(xml->attributes().value("name").toString(), xml->attributes().value("id").toString().toInt(), QDateTime::fromTime_t(xml->attributes().value("upload_time").toString().toUInt())); + currentItem = new DeckList_File(xml->attributes().value("name").toString(), xml->attributes().value("id").toString().toInt(), QDateTime::fromTime_t(xml->attributes().value("upload_time").toString().toUInt())); append(currentItem); } else if (xml->isEndElement() && (xml->name() == "directory")) return true; @@ -216,7 +217,7 @@ bool Response_DeckList::Directory::readElement(QXmlStreamReader *xml) return false; } -void Response_DeckList::Directory::writeElement(QXmlStreamWriter *xml) +void DeckList_Directory::writeElement(QXmlStreamWriter *xml) { xml->writeStartElement("directory"); xml->writeAttribute("name", name); @@ -225,7 +226,7 @@ void Response_DeckList::Directory::writeElement(QXmlStreamWriter *xml) xml->writeEndElement(); } -Response_DeckList::Response_DeckList(int _cmdId, ResponseCode _responseCode, Directory *_root) +Response_DeckList::Response_DeckList(int _cmdId, ResponseCode _responseCode, DeckList_Directory *_root) : ProtocolResponse(_cmdId, _responseCode, "deck_list"), root(_root), readFinished(false) { } @@ -242,7 +243,7 @@ bool Response_DeckList::readElement(QXmlStreamReader *xml) if (!root) { if (xml->isStartElement() && (xml->name() == "directory")) { - root = new Directory; + root = new DeckList_Directory; return true; } return false; @@ -292,20 +293,38 @@ void Response_DeckDownload::writeElement(QXmlStreamWriter *xml) deck->writeElement(xml); } -Response_DeckUpload::Response_DeckUpload(int _cmdId, ResponseCode _responseCode, int _deckId) - : ProtocolResponse(_cmdId, _responseCode, "deck_upload"), deckId(_deckId) +Response_DeckUpload::Response_DeckUpload(int _cmdId, ResponseCode _responseCode, DeckList_File *_file) + : ProtocolResponse(_cmdId, _responseCode, "deck_upload"), file(_file), readFinished(false) { - setParameter("deck_id", deckId); } -void Response_DeckUpload::extractParameters() +Response_DeckUpload::~Response_DeckUpload() { - ProtocolResponse::extractParameters(); + delete file; +} + +bool Response_DeckUpload::readElement(QXmlStreamReader *xml) +{ + if (readFinished) + return false; - bool ok; - deckId = parameters["deck_id"].toInt(&ok); - if (!ok) - deckId = -1; + if (!file) { + if (xml->isStartElement() && (xml->name() == "file")) { + file = new DeckList_File(xml->attributes().value("name").toString(), xml->attributes().value("id").toString().toInt(), QDateTime::fromTime_t(xml->attributes().value("upload_time").toString().toUInt())); + return true; + } + return false; + } + + if (file->readElement(xml)) + readFinished = true; + return true; +} + +void Response_DeckUpload::writeElement(QXmlStreamWriter *xml) +{ + if (file) + file->writeElement(xml); } GenericEvent::GenericEvent(const QString &_eventName) diff --git a/common/protocol.h b/common/protocol.h index d940065e..d0c261d5 100644 --- a/common/protocol.h +++ b/common/protocol.h @@ -5,8 +5,7 @@ #include #include #include -#include -#include +#include #include "protocol_item_ids.h" #include "protocol_datastructures.h" @@ -70,6 +69,7 @@ private: int cmdId; int ticks; static int lastCmdId; + QVariant extraData; protected: QString getItemType() const { return "cmd"; } void extractParameters(); @@ -78,6 +78,8 @@ public: int getCmdId() const { return cmdId; } int tick() { return ++ticks; } void processResponse(ProtocolResponse *response); + void setExtraData(const QVariant &_extraData) { extraData = _extraData; } + QVariant getExtraData() const { return extraData; } }; class InvalidCommand : public Command { @@ -168,48 +170,18 @@ public: class Response_DeckList : public ProtocolResponse { Q_OBJECT -public: - class TreeItem { - protected: - QString name; - int id; - public: - TreeItem(const QString &_name, int _id) : name(_name), id(_id) { } - QString getName() const { return name; } - int getId() const { return id; } - virtual bool readElement(QXmlStreamReader *xml) = 0; - virtual void writeElement(QXmlStreamWriter *xml) = 0; - }; - class File : public TreeItem { - private: - QDateTime uploadTime; - public: - File(const QString &_name, int _id, QDateTime _uploadTime) : TreeItem(_name, _id), uploadTime(_uploadTime) { } - bool readElement(QXmlStreamReader *xml); - void writeElement(QXmlStreamWriter *xml); - QDateTime getUploadTime() const { return uploadTime; } - }; - class Directory : public TreeItem, public QList { - private: - TreeItem *currentItem; - public: - Directory(const QString &_name = QString(), int _id = 0) : TreeItem(_name, _id), currentItem(0) { } - ~Directory(); - bool readElement(QXmlStreamReader *xml); - void writeElement(QXmlStreamWriter *xml); - }; private: - Directory *root; + DeckList_Directory *root; bool readFinished; protected: bool readElement(QXmlStreamReader *xml); void writeElement(QXmlStreamWriter *xml); public: - Response_DeckList(int _cmdId = -1, ResponseCode _responseCode = RespOk, Directory *_root = 0); + Response_DeckList(int _cmdId = -1, ResponseCode _responseCode = RespOk, DeckList_Directory *_root = 0); ~Response_DeckList(); int getItemId() const { return ItemId_Response_DeckList; } static ProtocolItem *newItem() { return new Response_DeckList; } - Directory *getRoot() const { return root; } + DeckList_Directory *getRoot() const { return root; } }; class Response_DeckDownload : public ProtocolResponse { @@ -231,14 +203,17 @@ public: class Response_DeckUpload : public ProtocolResponse { Q_OBJECT private: - int deckId; + DeckList_File *file; + bool readFinished; protected: - void extractParameters(); + bool readElement(QXmlStreamReader *xml); + void writeElement(QXmlStreamWriter *xml); public: - Response_DeckUpload(int _cmdId = -1, ResponseCode _responseCode = RespOk, int _deckId = -1); + Response_DeckUpload(int _cmdId = -1, ResponseCode _responseCode = RespOk, DeckList_File *_file = 0); + ~Response_DeckUpload(); int getItemId() const { return ItemId_Response_DeckUpload; } static ProtocolItem *newItem() { return new Response_DeckUpload; } - int getDeckId() const { return deckId; } + DeckList_File *getFile() const { return file; } }; // -------------- diff --git a/common/protocol_datastructures.h b/common/protocol_datastructures.h index 3dc1dcaf..66dc0cb1 100644 --- a/common/protocol_datastructures.h +++ b/common/protocol_datastructures.h @@ -3,6 +3,10 @@ #include #include +#include + +class QXmlStreamReader; +class QXmlStreamWriter; enum ResponseCode { RespNothing, RespOk, RespInvalidCommand, RespInvalidData, RespNameNotFound, RespLoginNeeded, RespContextError, RespWrongPassword, RespSpectatorsNotAllowed }; @@ -155,4 +159,34 @@ public: QColor getColor() const { return color; } }; +class DeckList_TreeItem { +protected: + QString name; + int id; +public: + DeckList_TreeItem(const QString &_name, int _id) : name(_name), id(_id) { } + QString getName() const { return name; } + int getId() const { return id; } + virtual bool readElement(QXmlStreamReader *xml) = 0; + virtual void writeElement(QXmlStreamWriter *xml) = 0; +}; +class DeckList_File : public DeckList_TreeItem { +private: + QDateTime uploadTime; +public: + DeckList_File(const QString &_name, int _id, QDateTime _uploadTime) : DeckList_TreeItem(_name, _id), uploadTime(_uploadTime) { } + bool readElement(QXmlStreamReader *xml); + void writeElement(QXmlStreamWriter *xml); + QDateTime getUploadTime() const { return uploadTime; } +}; +class DeckList_Directory : public DeckList_TreeItem, public QList { +private: + DeckList_TreeItem *currentItem; +public: + DeckList_Directory(const QString &_name = QString(), int _id = 0) : DeckList_TreeItem(_name, _id), currentItem(0) { } + ~DeckList_Directory(); + bool readElement(QXmlStreamReader *xml); + void writeElement(QXmlStreamWriter *xml); +}; + #endif diff --git a/servatrice/src/serversocketinterface.cpp b/servatrice/src/serversocketinterface.cpp index db7e946c..526ffc51 100644 --- a/servatrice/src/serversocketinterface.cpp +++ b/servatrice/src/serversocketinterface.cpp @@ -135,7 +135,7 @@ int ServerSocketInterface::getDeckPathId(const QString &path) return getDeckPathId(0, path.split("/")); } -bool ServerSocketInterface::deckListHelper(Response_DeckList::Directory *folder) +bool ServerSocketInterface::deckListHelper(DeckList_Directory *folder) { QSqlQuery query; query.prepare("select id, name from decklist_folders where id_parent = :id_parent and user = :user"); @@ -145,7 +145,7 @@ bool ServerSocketInterface::deckListHelper(Response_DeckList::Directory *folder) return false; while (query.next()) { - Response_DeckList::Directory *newFolder = new Response_DeckList::Directory(query.value(1).toString(), query.value(0).toInt()); + DeckList_Directory *newFolder = new DeckList_Directory(query.value(1).toString(), query.value(0).toInt()); folder->append(newFolder); if (!deckListHelper(newFolder)) return false; @@ -157,7 +157,7 @@ bool ServerSocketInterface::deckListHelper(Response_DeckList::Directory *folder) return false; while (query.next()) { - Response_DeckList::File *newFile = new Response_DeckList::File(query.value(1).toString(), query.value(0).toInt(), query.value(2).toDateTime()); + DeckList_File *newFile = new DeckList_File(query.value(1).toString(), query.value(0).toInt(), query.value(2).toDateTime()); folder->append(newFile); } @@ -171,7 +171,7 @@ ResponseCode ServerSocketInterface::cmdDeckList(Command_DeckList *cmd) { servatrice->checkSql(); - Response_DeckList::Directory *root = new Response_DeckList::Directory(QString()); + DeckList_Directory *root = new DeckList_Directory(QString()); QSqlQuery query; if (!deckListHelper(root)) return RespContextError; @@ -279,7 +279,7 @@ ResponseCode ServerSocketInterface::cmdDeckUpload(Command_DeckUpload *cmd) query.bindValue(":content", deckContents); servatrice->execSqlQuery(query); - sendProtocolItem(new Response_DeckUpload(cmd->getCmdId(), RespOk, query.lastInsertId().toInt())); + sendProtocolItem(new Response_DeckUpload(cmd->getCmdId(), RespOk, new DeckList_File(deckName, query.lastInsertId().toInt(), QDateTime::currentDateTime()))); return RespNothing; } diff --git a/servatrice/src/serversocketinterface.h b/servatrice/src/serversocketinterface.h index 95eee7a1..3fffbe1d 100644 --- a/servatrice/src/serversocketinterface.h +++ b/servatrice/src/serversocketinterface.h @@ -43,7 +43,7 @@ private: int getDeckPathId(int basePathId, QStringList path); int getDeckPathId(const QString &path); - bool deckListHelper(Response_DeckList::Directory *folder); + bool deckListHelper(DeckList_Directory *folder); ResponseCode cmdDeckList(Command_DeckList *cmd); ResponseCode cmdDeckNewDir(Command_DeckNewDir *cmd); void deckDelDirHelper(int basePathId);