/* * pawsquestwindow.cpp - Author: Keith Fulton * * Copyright (C) 2003 Atomic Blue (info@planeshift.it, http://www.atomicblue.org) * * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation (version 2 of the License) * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ ////////////////////////////////////////////////////////////////////// // STANDARD INCLUDE #include #include #include "globals.h" // COMMON/NET INCLUDES #include "net/messages.h" #include "net/msghandler.h" #include "net/cmdhandler.h" #include "util/strutil.h" #include "util/psxmlparser.h" #include #include "pscelclient.h" // PAWS INCLUDES #include "pawsquestwindow.h" #include "paws/pawsprefmanager.h" #include "inventorywindow.h" #include "gui/pawscontrolwindow.h" #include "paws/pawstextbox.h" #include "paws/pawsyesnobox.h" #define DISCARD_BUTTON 1201 #define VIEW_BUTTON 1200 #define SAVE_BUTTON 1203 #define CANCEL_BUTTON 1204 #define TAB_UNCOMPLETED_QUESTS 1000 #define TAB_COMPLETED_QUESTS 1001 ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// pawsQuestListWindow::pawsQuestListWindow() : psCmdBase( NULL,NULL, PawsManager::GetSingleton().GetObjectRegistry() ) { vfs = CS_QUERY_REGISTRY( PawsManager::GetSingleton().GetObjectRegistry(), iVFS ); xml = psengine->GetXMLParser(); questList = NULL; questTab = NULL; completedQuestList = NULL; uncompletedQuestList = NULL; description = NULL; notes = NULL; questID = -1; filename = "/this/data/questnotes_"; filename.Append(psengine->GetCelClient()->GetMainActor()->GetName()); filename.Append(".xml"); filename.ReplaceAllSubString(" ", "_"); // Load the quest notes file (if it doesn't exist, it will be made on first save) if ( vfs->Exists(filename) ) LoadNotes(filename); } pawsQuestListWindow::~pawsQuestListWindow() { if (msgqueue) { msgqueue->Unsubscribe(this, MSGTYPE_QUESTLIST); msgqueue->Unsubscribe(this, MSGTYPE_QUESTINFO); } while (quest_notes.Length() ) delete quest_notes.Pop(); } bool pawsQuestListWindow::PostSetup() { // Setup this widget to receive messages and commands if ( !psCmdBase::Setup( psengine->GetMsgHandler(), psengine->GetCmdHandler()) ) return false; // Subscribe to certain types of messages (those we want to handle) msgqueue->Subscribe(this, MSGTYPE_QUESTLIST); msgqueue->Subscribe(this, MSGTYPE_QUESTINFO); // Subscribe certain petition commands with this widget // cmdsource->Subscribe("/petition_list", PawsManager::GetSingleton().Translate("List all of the petitions you have submitted."), // CmdHandler::VISIBLE_TO_USER,this); questTab = (pawsTabWindow*)FindWidget("QuestTabs"); completedQuestList = (pawsListBox* )FindWidget("CompletedQuestList"); uncompletedQuestList = (pawsListBox* )FindWidget("UncompletedQuestList"); // get pointer to active listbox: questList = (pawsListBox*)questTab->GetActiveTab(); description = (pawsMessageTextBox*)FindWidget("Description"); notes = (pawsEditTextBox*)FindWidget("Notes"); return true; } ////////////////////////////////////////////////////////////////////// // Command and Message Handling ////////////////////////////////////////////////////////////////////// const char* pawsQuestListWindow::HandleCommand( const char* cmd ) { return NULL; } void pawsQuestListWindow::HandleMessage ( MsgEntry* me ) { if (me->GetType() == MSGTYPE_QUESTLIST) { // Get the petition message data from the server psQuestListMessage message(me); // The quest xml string contains all the quests for the // current user. The quests that have been completed // will be added to a different listbox than the quests that // still need to be done. So here we'll split the quest xml // string into two parts according to the quest status. psXMLString questxml = psXMLString(message.questxml); psXMLString section; size_t start = questxml.FindTag("q>"); size_t end = questxml.FindTag("/quest"); psString completedQuests = ""; psString uncompletedQuests = ""; if (start != SIZET_NOT_FOUND) { do { // a quest looks like this: // start += questxml.GetTagSection((int)start,"q",section); csString str = "status text=\""; char status = section.GetAt(section.FindSubString(str) + str.Length()); if (status == 'A') uncompletedQuests += section; else if (status == 'C') completedQuests += section; } while (section.Length()!=0 && startClear(); completedQuestList->SelfPopulateXML(completedQuests); // Add the uncompleted quests to the uncompletedQuestList(box) uncompletedQuestList->Clear(); uncompletedQuestList->SelfPopulateXML(uncompletedQuests); // Reset window questTab->SetTab(TAB_UNCOMPLETED_QUESTS); completedQuestList->Select(NULL); uncompletedQuestList->Select(NULL); description->Clear(); Show(); } else { psQuestInfoMessage message(me); SelfPopulateXML(message.xml); } } bool pawsQuestListWindow::OnButtonPressed( int mouseButton, int keyModifier, pawsWidget* widget ) { // We know that the calling widget is a button. int button = widget->GetID(); questList = (pawsListBox*)questTab->GetActiveTab(); switch( button ) { case TAB_COMPLETED_QUESTS: case TAB_UNCOMPLETED_QUESTS: { questID = -1; completedQuestList->Select(NULL); uncompletedQuestList->Select(NULL); description->Clear(); notes->Clear(); break; } // These cases are for the discard funciton, and it's confirmation prompt case DISCARD_BUTTON: { if (questID != -1) { PawsManager::GetSingleton().CreateYesNoBox( "Are you sure you want to discard the selected quest?", this ); questIDBuffer = questID; } break; } case CONFIRM_YES: { DiscardQuest(questIDBuffer); questID = -1; // Refresh window notes->Clear(); psUserCmdMessage msg("/quests"); psengine->GetMsgHandler()->SendMessage(msg.msg); break; } // These cases are for the edit window child of this case SAVE_BUTTON: { if (questID != -1) { bool found = false; for (size_t i=0; i < quest_notes.Length(); i++) { if (quest_notes[i]->id == questID) // Change notes { quest_notes[i]->notes = notes->GetText(); found = true; break; } } if (!found) // Add notes { QuestNote *qn = new QuestNote; qn->id = questID; qn->notes = notes->GetText(); quest_notes.Push(qn); } SaveNotes(filename); } break; } case CANCEL_BUTTON: { ShowNotes(); break; } } return true; } inline void pawsQuestListWindow::RequestQuestData(int id) { psQuestInfoMessage info(0,psQuestInfoMessage::CMD_QUERY,id,NULL,NULL); msgqueue->SendMessage(info.msg); } inline void pawsQuestListWindow::DiscardQuest(int id) { psQuestInfoMessage info(0,psQuestInfoMessage::CMD_DISCARD,id,NULL,NULL); msgqueue->SendMessage(info.msg); } void pawsQuestListWindow::OnListAction( pawsListBox* selected, int status ) { int previousQuestID = questID; size_t numOfQuests; unsigned int topLine = 0; pawsListBoxRow *row = selected->GetSelectedRow(); if (row) { pawsTextBox *field = (pawsTextBox*)row->GetColumn(QCOL_ID); questID = atoi(field->GetText()); numOfQuests = quest_notes.Length(); for (size_t i=0; i < numOfQuests; i++) { // if no previous quest selected, then 0 all toplines if (previousQuestID < 0) { quest_notes[i]->topLine = 0; } // store topline of 'old' quest notes else if (quest_notes[i]->id == previousQuestID) { quest_notes[i]->topLine = notes->GetTopLine(); } } for (size_t i=0; i < numOfQuests; i++) { // set new quest notes topline if (quest_notes[i]->id == questID) { topLine = quest_notes[i]->topLine; } } notes->SetTopLine(topLine); RequestQuestData(questID); ShowNotes(); } } void pawsQuestListWindow::SaveNotes(const char * fileName) { // Save quest notes to a local file char temp[20]; csRef xml = csPtr(new csTinyDocumentSystem); csRef doc = xml->CreateDocument(); csRef root = doc->CreateRoot(); csRef parentMain = root->CreateNodeBefore(CS_NODE_ELEMENT); parentMain->SetValue("questnotes"); csRef parent; csRef text; for (size_t i=0; i < quest_notes.Length(); i++) { QuestNote *qn = quest_notes[i]; if ( !(qn->notes).IsEmpty() ) { parent = parentMain->CreateNodeBefore(CS_NODE_ELEMENT); sprintf(temp, "quest%d", qn->id); parent->SetValue(temp); text = parent->CreateNodeBefore(CS_NODE_TEXT); text->SetValue(qn->notes); } } doc->Write(vfs, fileName); } void pawsQuestListWindow::LoadNotes(const char * fileName) { int id; csRef doc = xml->CreateDocument(); csRef buf (vfs->ReadFile (fileName)); if (!buf || !buf->GetSize()) { return; } const char* error = doc->Parse( buf ); if (error) { printf("Error loading quest notes: %s\n", error); return; } csRef iter = doc->GetRoot()->GetNode("questnotes")->GetNodes(); while ( iter->HasNext() ) { csRef child = iter->Next(); if ( child->GetType() != CS_NODE_ELEMENT ) continue; sscanf(child->GetValue(), "quest%d", &id); QuestNote *qn = new QuestNote; qn->id = id; qn->notes = child->GetContentsValue(); quest_notes.Push(qn); } } void pawsQuestListWindow::ShowNotes() { for (size_t i=0; i < quest_notes.Length(); i++) { if (quest_notes[i]->id == questID) { notes->SetText(quest_notes[i]->notes); return; } } notes->Clear(); // If didn't find notes, then blank }