diff --git a/indra/newview/ascentfloatercontactgroups.cpp b/indra/newview/ascentfloatercontactgroups.cpp index 1012dcd53..e41b052c3 100644 --- a/indra/newview/ascentfloatercontactgroups.cpp +++ b/indra/newview/ascentfloatercontactgroups.cpp @@ -8,18 +8,7 @@ * ALL SOURCE CODE IS PROVIDED "AS IS." THE CREATOR MAKES NO * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. - * - * HACKERS CAN TURN YOUR COMPUTER INTO A BOMB. - * & BLOW YOUR FAMILY TO SMITHEREENS! - * - * \ . ./ - * \ .:";'.:.." / - * (M^^.^~~:.'"). - * - (/ . . . \ \) - - * ((| :. ~ ^ :. .|)) - * - (\- | \ / | /) - - * T -\ \ / /- - * [_]..........................\ \ / / + */ /* @@ -59,11 +48,13 @@ #include "llviewercontrol.h" #include "llviewerwindow.h" #include "llsdserialize.h" - +#include "lldarray.h" +#include "llfile.h" #include "llchat.h" #include "llfloaterchat.h" ASFloaterContactGroups* ASFloaterContactGroups::sInstance = NULL; +LLDynamicArray ASFloaterContactGroups::mSelectedUUIDs; ASFloaterContactGroups::ASFloaterContactGroups() : LLFloater(std::string("floater_contact_groups"), std::string("FloaterContactRect"), LLStringUtil::null) @@ -72,13 +63,90 @@ ASFloaterContactGroups::ASFloaterContactGroups() } // static -void ASFloaterContactGroups::show(void*) +void ASFloaterContactGroups::show(LLDynamicArray ids) { if (!sInstance) sInstance = new ASFloaterContactGroups(); + mSelectedUUIDs = ids; + sInstance->open(); sInstance->populateGroupList(); + sInstance->populateFriendList(); + + sInstance->childSetAction("Cancel", onBtnClose, sInstance); + sInstance->childSetAction("Save", onBtnSave, sInstance); + sInstance->childSetAction("Create", onBtnCreate, sInstance); + sInstance->childSetAction("Delete", onBtnDelete, sInstance); +} + +void ASFloaterContactGroups::onBtnDelete(void* userdata) +{ + ASFloaterContactGroups* self = (ASFloaterContactGroups*)userdata; + + if(self) + { + LLScrollListCtrl* scroller = self->getChild("group_scroll_list"); + if(scroller != NULL) + { + self->deleteContactGroup(scroller->getValue().asString()); + self->populateGroupList(); + } + } +} + +void ASFloaterContactGroups::onBtnSave(void* userdata) +{ + ASFloaterContactGroups* self = (ASFloaterContactGroups*)userdata; + + if(self) + { + if (self->mSelectedUUIDs.count() > 0) + { + LLScrollListCtrl* scroller = self->getChild("group_scroll_list"); + if(scroller != NULL) + { + for (S32 i = self->mSelectedUUIDs.count(); i > 0; --i) + { + self->addContactMember(scroller->getValue().asString(), self->mSelectedUUIDs.get(i)); + } + } + } + } +} + +void ASFloaterContactGroups::onBtnClose(void* userdata) +{ + ASFloaterContactGroups* self = (ASFloaterContactGroups*)userdata; + if(self) self->close(); +} + +void ASFloaterContactGroups::onBtnCreate(void* userdata) +{ + ASFloaterContactGroups* self = (ASFloaterContactGroups*)userdata; + if(self) + { + LLLineEditor* editor = self->getChild("add_group_lineedit"); + if (editor) + { + LLScrollListCtrl* scroller = self->getChild("friend_scroll_list"); + if(scroller != NULL) + { + self->createContactGroup(editor->getValue().asString()); + self->populateGroupList(); + } + } + else + { + LLChat msg("Null editor"); + LLFloaterChat::addChat(msg); + } + } + else + { + LLChat msg("Null floater"); + LLFloaterChat::addChat(msg); + } } ASFloaterContactGroups::~ASFloaterContactGroups() @@ -86,43 +154,144 @@ ASFloaterContactGroups::~ASFloaterContactGroups() sInstance=NULL; } +void ASFloaterContactGroups::populateFriendList() +{ + LLScrollListCtrl* scroller = getChild("friend_scroll_list"); + if(scroller != NULL) + { + + } +} + +std::string ASFloaterContactGroups::cleanFileName(std::string filename) +{ + std::string invalidChars = "\"\'\\/?*:<>| "; + S32 position = filename.find_first_of(invalidChars); + while (position != filename.npos) + { + filename[position] = '_'; + position = filename.find_first_of(invalidChars, position); + } + return filename; +} + +void ASFloaterContactGroups::addContactMember(std::string contact_grp, LLUUID to_add) +{ + std::string clean_contact_grp = cleanFileName(contact_grp); + std::string member_string = "Ascent." + clean_contact_grp + ".Members"; + + if (!gSavedSettings.controlExists(member_string)) + gSavedSettings.declareString(member_string, to_add.asString(), "Stores UUIDs of members for " + clean_contact_grp, TRUE); + else + gSavedSettings.setString(member_string, gSavedSettings.getString(member_string) + " " + to_add.asString()); +} + +void ASFloaterContactGroups::deleteContactGroup(std::string contact_grp) +{ + std::string clean_contact_grp = cleanFileName(contact_grp); + std::string display_string = "Ascent." + clean_contact_grp + ".Display"; + gSavedSettings.setString(display_string, "##DELETED##"); + + std::string group_list(gSavedSettings.getString("AscentContactGroups")); + + if (group_list.find(clean_contact_grp) != group_list.npos) + { + gSavedSettings.setString( + "AscentContactGroups", + group_list.erase( + group_list.find_first_of(clean_contact_grp), + clean_contact_grp.length() + ) + ); + } +} + +void ASFloaterContactGroups::createContactGroup(std::string contact_grp) +{ + std::string clean_contact_grp = cleanFileName(contact_grp); + std::string display_string = "Ascent." + clean_contact_grp + ".Display"; + std::string member_string = "Ascent." + clean_contact_grp + ".Members"; + + if (gSavedSettings.controlExists(display_string)) + { + std::string s_display = gSavedSettings.getString(display_string); + if (s_display != "##DELETED##") + { + LLChat msg("Can't create duplicate group names."); + LLFloaterChat::addChat(msg); + return; + } + } + + gSavedSettings.declareString(member_string, "NULL_KEY", "Stores UUIDs of members for " + clean_contact_grp, TRUE); + gSavedSettings.declareString(display_string, contact_grp, "Stores the real name of " + clean_contact_grp, TRUE); + + gSavedSettings.setString(display_string, contact_grp); + gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), TRUE); + + gSavedSettings.setString(member_string, "NULL_KEY"); + gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), TRUE); + + if (!gSavedSettings.controlExists("AscentContactGroups")) + { + gSavedSettings.declareString("AscentContactGroups", clean_contact_grp, "Stores titles of all Contact Groups", TRUE); + gSavedSettings.setString("AscentContactGroups", clean_contact_grp); + } + else + { + std::string group_list(gSavedSettings.getString("AscentContactGroups")); + group_list += " " + clean_contact_grp; + gSavedSettings.setString("AscentContactGroups", group_list); + } + + gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), TRUE); +} + +void StringSplit(std::string str, std::string delim, std::vector results) +{ + int cutAt; + while((cutAt = str.find_first_of(delim)) != str.npos) + { + if(cutAt > 0) + { + results.push_back(str.substr(0,cutAt)); + } + str = str.substr(cutAt+1); + } + + if(str.length() > 0) + { + results.push_back(str); + } +} + void ASFloaterContactGroups::populateGroupList() { LLScrollListCtrl* scroller = getChild("group_scroll_list"); if(scroller != NULL) { - std::string name; + scroller->deleteAllItems(); - gDirUtilp->getNextFileInDir(gDirUtilp->getPerAccountChatLogsDir(),"*",name,false);//stupid hack to clear last file search - scroller->clear(); - - std::string path_name(gDirUtilp->getPerAccountChatLogsDir() + gDirUtilp->getDirDelimiter()); - S32 count = gDirUtilp->countFilesInDir(path_name, "*.grp"); - bool found = true; - LLChat msg(count + " total files in folder " + path_name); - LLFloaterChat::addChat(msg); - while(found = gDirUtilp->getNextFileInDir(path_name, "*.grp", name, false)) + if (gSavedSettings.controlExists("AscentContactGroups")) { - if ((name == ".") || (name == "..")) continue; + scroller->addSimpleElement(gSavedSettings.getString("AscentContactGroups"), ADD_BOTTOM); + /** + std::vector group_list; + StringSplit(gSavedSettings.getString("AscentContactGroups"), " ", group_list); - //llinfos << "path name " << path_name << " and name " << name << " and found " << found << llendl; - if(found) + for (S32 i=0; i < group_list.size(); i++) { - LLChat msg("Found: " + name); - LLFloaterChat::addChat(msg); - scroller->addSimpleElement(name.substr(0, -4), ADD_BOTTOM); - } - else - { - LLChat msg("Skipped: " + name); + scroller->addSimpleElement(group_list[i], ADD_BOTTOM); + LLChat msg("Add " + group_list[i]); LLFloaterChat::addChat(msg); } + **/ } } else { LLChat msg("Null Scroller"); - LLFloaterChat::addChat(msg); + LLFloaterChat::addChat(msg); } } diff --git a/indra/newview/ascentfloatercontactgroups.h b/indra/newview/ascentfloatercontactgroups.h index 15dba2e5c..2f4b0e85c 100644 --- a/indra/newview/ascentfloatercontactgroups.h +++ b/indra/newview/ascentfloatercontactgroups.h @@ -16,6 +16,7 @@ #define ASCENT_CONTACT_GROUPS #include "llfloater.h" +#include "lldarray.h" class LLScrollListCtrl; @@ -27,15 +28,28 @@ public: virtual ~ASFloaterContactGroups(); // by convention, this shows the floater and does instance management - static void show(void*); + static void show(LLDynamicArray ids); + static std::string cleanFileName(std::string filename); + void populateGroupList(); + void populateFriendList(); + void addContactMember(std::string contact_grp, LLUUID to_add); + void createContactGroup(std::string contact_grp); + void deleteContactGroup(std::string contact_grp); + + // Buttons + static void onBtnClose(void* userdata); + static void onBtnSave(void* userdata); + static void onBtnCreate(void* userdata); + static void onBtnDelete(void* userdata); private: //assuming we just need one, which is typical static ASFloaterContactGroups* sInstance; + static LLDynamicArray mSelectedUUIDs; }; -#endif // ASCENT_UPLOAD_BROWSER +#endif // ASCENT_CONTACT_GROUPS /* diff --git a/indra/newview/llfloaterfriends.cpp b/indra/newview/llfloaterfriends.cpp index 810845642..1fa81163e 100644 --- a/indra/newview/llfloaterfriends.cpp +++ b/indra/newview/llfloaterfriends.cpp @@ -201,6 +201,84 @@ void LLPanelFriends::updateFriends(U32 changed_mask) // // Contact search and group system. // 09/05/2010 - Charley Levenque +std::string LLPanelFriends::cleanFileName(std::string filename) +{ + std::string invalidChars = "\"\'\\/?*:<>|"; + S32 position = filename.find_first_of(invalidChars); + while (position != filename.npos) + { + filename[position] = '_'; + position = filename.find_first_of(invalidChars, position); + } + return filename; +} + +void LLPanelFriends::populateContactGroupSelect() +{ + LLComboBox* combo = getChild("buddy_group_combobox"); + + if (combo) + { + combo->removeall(); + combo->add("All", ADD_BOTTOM); + + std::string name; + gDirUtilp->getNextFileInDir(gDirUtilp->getPerAccountChatLogsDir(),"*",name,false);//stupid hack to clear last file search + + std::string path_name(gDirUtilp->getPerAccountChatLogsDir() + gDirUtilp->getDirDelimiter()); + bool found = true; + while(found = gDirUtilp->getNextFileInDir(path_name, "*.grp", name, false)) + { + if ((name == ".") || (name == "..")) continue; + + //llinfos << "path name " << path_name << " and name " << name << " and found " << found << llendl; + if(found) + { + S32 periodIndex = name.find_last_of("."); + name = name.substr(0, periodIndex); + + if ((name == ".") || (name == "..")) continue; + + combo->add(name, ADD_BOTTOM); + LLChat msg("Combo Add " + name); + LLFloaterChat::addChat(msg); + } + } + } + else + { + LLChat msg("Null combo"); + LLFloaterChat::addChat(msg); + } +} + +void LLPanelFriends::setContactGroup(std::string contact_grp) +{ + std::string group_path = gDirUtilp->getPerAccountChatLogsDir() + gDirUtilp->getDirDelimiter(); + std::string filename = group_path + cleanFileName(contact_grp + ".grp"); + + FILE* fp = LLFile::fopen(filename, "w"); + + if (fp) + { + char buffer[10000]; /*Flawfinder: ignore*/ + char *bptr; + S32 len = 0; + + while ( fgets(buffer, 10000, fp) && !feof(fp) ) + { + len = strlen(buffer) - 1; /*Flawfinder: ignore*/ + for ( bptr = (buffer + len); (*bptr == '\n' || *bptr == '\r') && bptr>buffer; bptr--) *bptr='\0'; + } + + std::string file_contents(buffer); + mContactFilter = file_contents; + + LLChat msg(mContactFilter); + LLFloaterChat::addChat(msg); + } +} + void LLPanelFriends::filterContacts() { //LLComboBox* combo = getChild("buddy_group_combobox"); @@ -213,15 +291,13 @@ void LLPanelFriends::filterContacts() if (search_name != "" && search_name != mLastContactSearch) { mLastContactSearch = search_name; - //LLStringUtil::toLower(search_name); refreshNames(LLFriendObserver::ADD); std::vector vFriends = mFriendsList->getAllData(); // all of it. for (std::vector::iterator itr = vFriends.begin(); itr != vFriends.end(); ++itr) { - friend_name = (*itr)->getColumn(LIST_FRIEND_NAME)->getValue().asString(); - //LLStringUtil::toLower(friend_name); - BOOL show_entry = (friend_name.find(search_name) != std::string::npos); + friend_name = utf8str_tolower((*itr)->getColumn(LIST_FRIEND_NAME)->getValue().asString()); + BOOL show_entry = (friend_name.find(utf8str_tolower(search_name)) != std::string::npos); if (!show_entry) { mFriendsList->deleteItems((*itr)->getValue()); @@ -244,6 +320,20 @@ void LLPanelFriends::onContactSearchKeystroke(LLLineEditor* caller, void* user_d } } } + +void LLPanelFriends::onChangeContactGroup(LLUICtrl* ctrl, void* user_data) +{ + LLPanelFriends* panelp = (LLPanelFriends*)user_data; + + if(panelp) + { + LLComboBox* combo = panelp->getChild("buddy_group_combobox"); + if (combo->getValue().asString() != "All") + { + panelp->setContactGroup(combo->getValue().asString()); + } + } +} // -- // virtual @@ -254,6 +344,7 @@ BOOL LLPanelFriends::postBuild() mFriendsList->setMaximumSelectCallback(onMaximumSelect); mFriendsList->setCommitOnSelectionChange(TRUE); childSetCommitCallback("friend_list", onSelectName, this); + childSetCommitCallback("buddy_group_combobox", onChangeContactGroup, this); childSetDoubleClickCallback("friend_list", onClickIM); // @@ -264,7 +355,6 @@ BOOL LLPanelFriends::postBuild() { contact->setKeystrokeCallback(&onContactSearchKeystroke); } - // -- getChild("s_num")->setValue("0"); getChild("f_num")->setValue(llformat("%d", mFriendsList->getItemCount())); @@ -608,6 +698,7 @@ BOOL LLPanelFriends::refreshNamesPresence(const LLAvatarTracker::buddy_map_t & a // meal disk void LLPanelFriends::refreshUI() { + populateContactGroupSelect(); BOOL single_selected = FALSE; BOOL multiple_selected = FALSE; int num_selected = mFriendsList->getAllSelected().size(); @@ -655,7 +746,7 @@ LLDynamicArray LLPanelFriends::getSelectedIDs() return friend_ids; } -// static +// static void LLPanelFriends::onSelectName(LLUICtrl* ctrl, void* user_data) { LLPanelFriends* panelp = (LLPanelFriends*)user_data; @@ -695,7 +786,12 @@ void LLPanelFriends::onClickProfile(void* user_data) // static void LLPanelFriends::onClickAssign(void* user_data) { - ASFloaterContactGroups::show(user_data); + LLPanelFriends* panelp = (LLPanelFriends*)user_data; + if (panelp) + { + LLDynamicArray ids = panelp->getSelectedIDs(); + ASFloaterContactGroups::show(ids); + } } void LLPanelFriends::onClickIM(void* user_data) diff --git a/indra/newview/llfloaterfriends.h b/indra/newview/llfloaterfriends.h index 7f1197f4b..8ecc00a5e 100644 --- a/indra/newview/llfloaterfriends.h +++ b/indra/newview/llfloaterfriends.h @@ -103,6 +103,9 @@ private: void refreshNames(U32 changed_mask); // Contacts search and group system void filterContacts(); + void setContactGroup(std::string contact_grp); + void populateContactGroupSelect(); + std::string cleanFileName(std::string filename); // -- BOOL refreshNamesSync(const LLAvatarTracker::buddy_map_t & all_buddies); BOOL refreshNamesPresence(const LLAvatarTracker::buddy_map_t & all_buddies); @@ -125,6 +128,7 @@ private: // callback methods static void onSelectName(LLUICtrl* ctrl, void* user_data); + static void onChangeContactGroup(LLUICtrl* ctrl, void* user_data); static bool callbackAddFriend(const LLSD& notification, const LLSD& response); static bool callbackAddFriendWithMessage(const LLSD& notification, const LLSD& response); static void onPickAvatar(const std::vector& names, const std::vector& ids, void* user_data); @@ -154,6 +158,7 @@ private: LLUUID mAddFriendID; std::string mAddFriendName; LLScrollListCtrl* mFriendsList; + std::string mContactFilter; BOOL mShowMaxSelectWarning; BOOL mAllowRightsChange; S32 mNumRightsChanged; diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp index df8ea4226..9c3d07a45 100644 --- a/indra/newview/llpreviewgesture.cpp +++ b/indra/newview/llpreviewgesture.cpp @@ -542,18 +542,6 @@ BOOL LLPreviewGesture::postBuild() btn->setCallbackUserData(this); mSaveBtn = btn; - // - btn = getChild( "duplicate_btn"); - btn->setClickedCallback(onClickDuplicate); - btn->setCallbackUserData(this); - mDuplicateBtn = btn; - - btn = getChild( "open_btn"); - btn->setClickedCallback(onClickOpen); - btn->setCallbackUserData(this); - mOpenBtn = btn; - // - btn = getChild( "preview_btn"); btn->setClickedCallback(onClickPreview); btn->setCallbackUserData(this); diff --git a/indra/newview/skins/default/xui/en-us/floater_contact_groups.xml b/indra/newview/skins/default/xui/en-us/floater_contact_groups.xml index 7d5e04ba8..4df58d00a 100644 --- a/indra/newview/skins/default/xui/en-us/floater_contact_groups.xml +++ b/indra/newview/skins/default/xui/en-us/floater_contact_groups.xml @@ -35,27 +35,15 @@ width="112" />