From 63af6abd29a161f6d1aa257aeb76f6891f512f74 Mon Sep 17 00:00:00 2001 From: Simon Robertshaw Date: Thu, 22 Mar 2012 22:12:16 +0000 Subject: [PATCH] Add and remove tags.\nBrings to light an interesting issue with adding or removing UI components within component Event handlers --- src/client/Client.cpp | 98 +++++++++++++++++++++++++++++++++++++ src/client/Client.h | 2 + src/tags/TagsController.cpp | 11 +++++ src/tags/TagsController.h | 2 + src/tags/TagsModel.cpp | 47 ++++++++++++++++++ src/tags/TagsModel.h | 5 ++ src/tags/TagsView.cpp | 79 ++++++++++++++++++++++++++++-- src/tags/TagsView.h | 7 ++- 8 files changed, 244 insertions(+), 7 deletions(-) diff --git a/src/client/Client.cpp b/src/client/Client.cpp index f6c2ecb01..e85d3e6ff 100644 --- a/src/client/Client.cpp +++ b/src/client/Client.cpp @@ -676,3 +676,101 @@ Thumbnail * Client::GetThumbnail(int saveID, int saveDate) //http_async_req_start(http, urlStream.str().c_str(), NULL, 0, 1); return NULL; } + +std::vector * Client::RemoveTag(int saveID, string tag) +{ + lastError = ""; + std::vector * tags = NULL; + std::stringstream urlStream; + char * data = NULL; + int dataStatus, dataLength; + urlStream << "http://" << SERVER << "/Browse/EditTag.json?Op=delete&ID=" << saveID << "&Tag=" << tag; + if(authUser.ID) + { + std::stringstream userIDStream; + userIDStream << authUser.ID; + data = http_auth_get((char *)urlStream.str().c_str(), (char *)(userIDStream.str().c_str()), NULL, (char *)(authUser.SessionID.c_str()), &dataStatus, &dataLength); + } + else + { + lastError = "Not authenticated"; + return NULL; + } + if(dataStatus == 200 && data) + { + try + { + std::istringstream dataStream(data); + json::Array tagsArray; + json::Reader::Read(tagsArray, dataStream); + + tags = new std::vector(); + + for(int j = 0; j < tagsArray.Size(); j++) + { + json::String tempTag = tagsArray[j]; + tags->push_back(tempTag.Value()); + } + } + catch (json::Exception &e) + { + lastError = "Could not read response"; + } + } + else + { + lastError = http_ret_text(dataStatus); + } + if(data) + free(data); + return tags; +} + +std::vector * Client::AddTag(int saveID, string tag) +{ + lastError = ""; + std::vector * tags = NULL; + std::stringstream urlStream; + char * data = NULL; + int dataStatus, dataLength; + urlStream << "http://" << SERVER << "/Browse/EditTag.json?Op=add&ID=" << saveID << "&Tag=" << tag; + if(authUser.ID) + { + std::stringstream userIDStream; + userIDStream << authUser.ID; + data = http_auth_get((char *)urlStream.str().c_str(), (char *)(userIDStream.str().c_str()), NULL, (char *)(authUser.SessionID.c_str()), &dataStatus, &dataLength); + } + else + { + lastError = "Not authenticated"; + return NULL; + } + if(dataStatus == 200 && data) + { + try + { + std::istringstream dataStream(data); + json::Array tagsArray; + json::Reader::Read(tagsArray, dataStream); + + tags = new std::vector(); + + for(int j = 0; j < tagsArray.Size(); j++) + { + json::String tempTag = tagsArray[j]; + tags->push_back(tempTag.Value()); + } + } + catch (json::Exception &e) + { + lastError = "Could not read response"; + } + } + else + { + lastError = http_ret_text(dataStatus); + } + if(data) + free(data); + return tags; +} diff --git a/src/client/Client.h b/src/client/Client.h index 084866bd2..55d813fa7 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -59,6 +59,8 @@ public: Save * GetSave(int saveID, int saveDate); void SetAuthUser(User user); User GetAuthUser(); + std::vector * RemoveTag(int saveID, string tag); + std::vector * AddTag(int saveID, string tag); std::string GetLastError() { return lastError; } diff --git a/src/tags/TagsController.cpp b/src/tags/TagsController.cpp index 5a457a1de..ee8f9248c 100644 --- a/src/tags/TagsController.cpp +++ b/src/tags/TagsController.cpp @@ -29,6 +29,17 @@ Save * TagsController::GetSave() return tagsModel->GetSave(); } +void TagsController::RemoveTag(string tag) +{ + tagsModel->RemoveTag(tag); +} + + +void TagsController::AddTag(string tag) +{ + tagsModel->AddTag(tag); +} + void TagsController::Exit() { if(ui::Engine::Ref().GetWindow() == tagsView) diff --git a/src/tags/TagsController.h b/src/tags/TagsController.h index 151cb73bc..0ab337f45 100644 --- a/src/tags/TagsController.h +++ b/src/tags/TagsController.h @@ -23,6 +23,8 @@ public: TagsController(ControllerCallback * callback, Save * save); TagsView * GetView() {return tagsView;} Save * GetSave(); + void RemoveTag(string tag); + void AddTag(string tag); void Exit(); virtual ~TagsController(); }; diff --git a/src/tags/TagsModel.cpp b/src/tags/TagsModel.cpp index b623ef781..a4e50832a 100644 --- a/src/tags/TagsModel.cpp +++ b/src/tags/TagsModel.cpp @@ -7,6 +7,7 @@ #include "TagsModel.h" #include "TagsView.h" +#include "client/Client.h" TagsModel::TagsModel(): save(NULL) @@ -26,6 +27,44 @@ Save * TagsModel::GetSave() return save; } +void TagsModel::RemoveTag(string tag) +{ + if(save) + { + std::vector * tags = Client::Ref().RemoveTag(save->GetID(), tag); + if(tags) + { + save->SetTags(vector(*tags)); + notifyTagsChanged(); + delete tags; + } + else + { + lastError = Client::Ref().GetLastError(); + notifyError(); + } + } +} + +void TagsModel::AddTag(string tag) +{ + if(save) + { + std::vector * tags = Client::Ref().AddTag(save->GetID(), tag); + if(tags) + { + save->SetTags(vector(*tags)); + notifyTagsChanged(); + delete tags; + } + else + { + lastError = Client::Ref().GetLastError(); + notifyError(); + } + } +} + void TagsModel::AddObserver(TagsView * observer) { observers.push_back(observer); @@ -40,6 +79,14 @@ void TagsModel::notifyTagsChanged() } } +void TagsModel::notifyError() +{ + for(int i = 0; i < observers.size(); i++) + { + observers[i]->NotifyError(this); + } +} + TagsModel::~TagsModel() { // TODO Auto-generated destructor stub } diff --git a/src/tags/TagsModel.h b/src/tags/TagsModel.h index 3d633c395..09e908e4a 100644 --- a/src/tags/TagsModel.h +++ b/src/tags/TagsModel.h @@ -14,13 +14,18 @@ class TagsView; class TagsModel { Save * save; + string lastError; std::vector observers; void notifyTagsChanged(); + void notifyError(); public: TagsModel(); void AddObserver(TagsView * observer); void SetSave(Save * save); + void RemoveTag(string tag); + void AddTag(string tag); Save * GetSave(); + string GetLastError(){ return lastError; } virtual ~TagsModel(); }; diff --git a/src/tags/TagsView.cpp b/src/tags/TagsView.cpp index b531190f9..4a4fd0663 100644 --- a/src/tags/TagsView.cpp +++ b/src/tags/TagsView.cpp @@ -5,18 +5,38 @@ * Author: Simon */ +#include "client/Client.h" #include "TagsView.h" +#include "dialogues/ErrorMessage.h" #include "TagsController.h" #include "TagsModel.h" TagsView::TagsView(): - ui::Window(ui::Point(-1, -1), ui::Point(200, 300)) + ui::Window(ui::Point(-1, -1), ui::Point(195, 250)) { - submitButton = new ui::Button(ui::Point(Size.X-56, Size.Y-24), ui::Point(50, 16)); - AddComponent(submitButton); - tagInput = new ui::Textbox(ui::Point(6, Size.Y-24), ui::Point(Size.X-80, 16), ""); + + class CloseAction : public ui::ButtonAction + { + TagsView * v; + public: + CloseAction(TagsView * _v) { v = _v; } + void ActionCallback(ui::Button * sender) + { + v->c->Exit(); + } + }; + closeButton = new ui::Button(ui::Point(0, Size.Y-16), ui::Point(195, 16), "Close"); + closeButton->SetAlignment(AlignLeft, AlignTop); + closeButton->SetActionCallback(new CloseAction(this)); + AddComponent(closeButton); + + tagInput = new ui::Textbox(ui::Point(8, Size.Y-40), ui::Point(Size.X-16, 16), ""); AddComponent(tagInput); + + title = new ui::Label(ui::Point(5, 5), ui::Point(185, 16), "Manage tags:"); + title->SetAlignment(AlignLeft, AlignTop); + AddComponent(title); } void TagsView::OnDraw() @@ -26,6 +46,11 @@ void TagsView::OnDraw() g->drawrect(Position.X, Position.Y, Size.X, Size.Y, 255, 255, 255, 255); } +void TagsView::NotifyError(TagsModel * sender) +{ + new ErrorMessage("Error", sender->GetLastError()); +} + void TagsView::NotifyTagsChanged(TagsModel * sender) { for(int i = 0; i < tags.size(); i++) @@ -35,17 +60,61 @@ void TagsView::NotifyTagsChanged(TagsModel * sender) } tags.clear(); + + class DeleteTagAction : public ui::ButtonAction + { + TagsView * v; + string tag; + public: + DeleteTagAction(TagsView * _v, string tag) { v = _v; this->tag = tag; } + void ActionCallback(ui::Button * sender) + { + v->c->RemoveTag(tag); + } + }; + if(sender->GetSave()) { for(int i = 0; i < sender->GetSave()->GetTags().size(); i++) { - ui::Label * tempLabel = new ui::Label(ui::Point(5, 10*i), ui::Point(50, 16), sender->GetSave()->GetTags()[i]); + ui::Label * tempLabel = new ui::Label(ui::Point(35, 35+(16*i)), ui::Point(120, 16), sender->GetSave()->GetTags()[i]); + tempLabel->SetAlignment(AlignLeft, AlignMiddle); tags.push_back(tempLabel); AddComponent(tempLabel); + + if(sender->GetSave()->GetUserName()==Client::Ref().GetAuthUser().Username) + { + ui::Button * tempButton = new ui::Button(ui::Point(15, 35+(16*i)), ui::Point(14, 14), "x"); + tempButton->SetAlignment(AlignCentre, AlignMiddle); + tempButton->SetActionCallback(new DeleteTagAction(this, sender->GetSave()->GetTags()[i])); + tags.push_back(tempButton); + AddComponent(tempButton); + } } } } +void TagsView::OnKeyPress(int key, Uint16 character, bool shift, bool ctrl, bool alt) +{ + switch(key) + { + /*case KEY_TAB: + if(IsFocused(usernameField)) + FocusComponent(passwordField); + else + FocusComponent(usernameField); + break;*/ + case KEY_ENTER: + case KEY_RETURN: + if(IsFocused(tagInput)) + { + c->AddTag(tagInput->GetText()); + tagInput->SetText(""); + } + break; + } +} + TagsView::~TagsView() { // TODO Auto-generated destructor stub } diff --git a/src/tags/TagsView.h b/src/tags/TagsView.h index e40151635..01074497a 100644 --- a/src/tags/TagsView.h +++ b/src/tags/TagsView.h @@ -18,13 +18,16 @@ class TagsController; class TagsModel; class TagsView: public ui::Window { TagsController * c; - ui::Button * submitButton; + ui::Button * closeButton; + ui::Label * title; ui::Textbox * tagInput; - std::vector tags; + std::vector tags; public: TagsView(); virtual void OnDraw(); + void NotifyError(TagsModel * sender); void AttachController(TagsController * c_) { c = c_; }; + virtual void OnKeyPress(int key, Uint16 character, bool shift, bool ctrl, bool alt); void NotifyTagsChanged(TagsModel * sender); virtual ~TagsView(); };