diff --git a/indra/llmessage/llclassifiedflags.h b/indra/llmessage/llclassifiedflags.h index 9c6c268b397e76d5e9d51a8494e22b5d827e2cf2..dafd0ceb62560feba8d65bd2fa9df18c5f5d2d55 100644 --- a/indra/llmessage/llclassifiedflags.h +++ b/indra/llmessage/llclassifiedflags.h @@ -47,6 +47,7 @@ const U8 CLASSIFIED_QUERY_INC_ADULT = 1 << 6; const U8 CLASSIFIED_QUERY_INC_NEW_VIEWER = (CLASSIFIED_QUERY_INC_PG | CLASSIFIED_QUERY_INC_MATURE | CLASSIFIED_QUERY_INC_ADULT); const S32 MAX_CLASSIFIEDS = 100; +const S32 MINIMUM_PRICE_FOR_LISTING = 50; // L$ // This function is used in AO viewers to pack old query flags into the request // so that they can talk to old dataservers properly. When the AO servers are deployed on agni diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index ce8b7dcf041dd7909f87a1195d8e4973a944db07..48a6c314a66c4cf28188f5378cc0790f14298aa1 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -113,7 +113,6 @@ set(viewer_SOURCE_FILES bdfloaterposer.cpp bdfloaterposecreator.cpp bdposingmotion.cpp - fsfloatersearch.cpp fslslpreproc.cpp fslslpreprocviewer.cpp gltfscenemanager.cpp @@ -130,6 +129,7 @@ set(viewer_SOURCE_FILES llagentbenefits.cpp llagentcamera.cpp llagentdata.cpp + llagenthandler.cpp llagentlanguage.cpp llagentlistener.cpp llagentpicksinfo.cpp @@ -167,6 +167,7 @@ set(viewer_SOURCE_FILES llchiclet.cpp llchicletbar.cpp llclassifiedinfo.cpp + llclassifieditem.cpp llcofwearables.cpp llcolorswatch.cpp llcommanddispatcherlistener.cpp @@ -263,6 +264,7 @@ set(viewer_SOURCE_FILES llfloatercreatelandmark.cpp llfloaterdeleteprefpreset.cpp llfloaterdestinations.cpp + llfloaterdirectory.cpp llfloaterdisplayname.cpp llfloatereditenvironmentbase.cpp llfloatereditextdaycycle.cpp @@ -329,12 +331,14 @@ set(viewer_SOURCE_FILES llfloaterperformance.cpp llfloaterperms.cpp llfloaterprofile.cpp + llfloaterprofilelegacy.cpp llfloaterpreference.cpp llfloaterpreferencesgraphicsadvanced.cpp llfloaterpreferenceviewadvanced.cpp llfloaterpreviewtrash.cpp llfloaterprofiletexture.cpp llfloaterprogressview.cpp + llfloaterpublishclassified.cpp llfloaterregiondebugconsole.cpp llfloaterregioninfo.cpp llfloaterreporter.cpp @@ -367,6 +371,7 @@ set(viewer_SOURCE_FILES llfloatervoiceeffect.cpp llfloatervoicevolume.cpp llfloaterwebcontent.cpp + llfloaterwebprofile.cpp llfloaterwhitelistentry.cpp llfloaterwindowsize.cpp llfloaterworldmap.cpp @@ -485,6 +490,7 @@ set(viewer_SOURCE_FILES lloutputmonitorctrl.cpp llpanelappearancetab.cpp llpanelavatar.cpp + llpanelavatarlegacy.cpp llpanelavatartag.cpp llpanelblockedlist.cpp llpanelclassified.cpp @@ -494,6 +500,7 @@ set(viewer_SOURCE_FILES llpaneleditwearable.cpp llpanelemojicomplete.cpp llpanelenvironment.cpp + llpaneleventinfo.cpp llpanelexperiencelisteditor.cpp llpanelexperiencelog.cpp llpanelexperiencepicker.cpp @@ -533,6 +540,7 @@ set(viewer_SOURCE_FILES llpanelpeople.cpp llpanelpeoplemenus.cpp llpanelpermissions.cpp + llpanelpick.cpp llpanelplaceinfo.cpp llpanelplaceprofile.cpp llpanelplaces.cpp @@ -541,8 +549,17 @@ set(viewer_SOURCE_FILES llpanelpresetspulldown.cpp llpanelprimmediacontrols.cpp llpanelprofile.cpp + llpanelprofilelegacy.cpp llpanelprofileclassifieds.cpp llpanelprofilepicks.cpp + llpanelsearchbase.cpp + llpanelsearchclassifieds.cpp + llpanelsearchevents.cpp + llpanelsearchgroups.cpp + llpanelsearchlandsales.cpp + llpanelsearchpeople.cpp + llpanelsearchplaces.cpp + llpanelsearchweb.cpp llpanelsnapshot.cpp llpanelsnapshotinventory.cpp llpanelsnapshotlocal.cpp @@ -575,6 +592,7 @@ set(viewer_SOURCE_FILES llpersistentnotificationstorage.cpp llphysicsmotion.cpp llphysicsshapebuilderutil.cpp + llpickitem.cpp llpipelinelistener.cpp llplacesinventorybridge.cpp llplacesinventorypanel.cpp @@ -591,6 +609,7 @@ set(viewer_SOURCE_FILES llpreviewtexture.cpp llproductinforequest.cpp llprogressview.cpp + llprofileimagepicker.cpp llrecentpeople.cpp llreflectionmap.cpp llreflectionmapmanager.cpp @@ -842,7 +861,6 @@ set(viewer_HEADER_FILES bdfloaterposer.h bdfloaterposecreator.h bdposingmotion.h - fsfloatersearch.h fslslpreproc.h fslslpreprocviewer.h gltfscenemanager.h @@ -898,6 +916,7 @@ set(viewer_HEADER_FILES llchiclet.h llchicletbar.h llclassifiedinfo.h + llclassifieditem.h llcofwearables.h llcolorswatch.h llcommanddispatcherlistener.h @@ -994,6 +1013,7 @@ set(viewer_HEADER_FILES llfloatercreatelandmark.h llfloaterdeleteprefpreset.h llfloaterdestinations.h + llfloaterdirectory.h llfloaterdisplayname.h llfloatereditenvironmentbase.h llfloatereditextdaycycle.h @@ -1063,12 +1083,14 @@ set(viewer_HEADER_FILES llfloaterperformance.h llfloaterperms.h llfloaterprofile.h + llfloaterprofilelegacy.h llfloaterpreference.h llfloaterpreferencesgraphicsadvanced.h llfloaterpreferenceviewadvanced.h llfloaterpreviewtrash.h llfloaterprofiletexture.h llfloaterprogressview.h + llfloaterpublishclassified.h llfloaterregiondebugconsole.h llfloaterregioninfo.h llfloaterreporter.h @@ -1101,6 +1123,7 @@ set(viewer_HEADER_FILES llfloatervoiceeffect.h llfloatervoicevolume.h llfloaterwebcontent.h + llfloaterwebprofile.h llfloaterwhitelistentry.h llfloaterwindowsize.h llfloaterworldmap.h @@ -1208,6 +1231,7 @@ set(viewer_HEADER_FILES lloutputmonitorctrl.h llpanelappearancetab.h llpanelavatar.h + llpanelavatarlegacy.h llpanelavatartag.h llpanelblockedlist.h llpanelclassified.h @@ -1217,6 +1241,7 @@ set(viewer_HEADER_FILES llpaneleditwearable.h llpanelemojicomplete.h llpanelenvironment.h + llpaneleventinfo.h llpanelexperiencelisteditor.h llpanelexperiencelog.h llpanelexperiencepicker.h @@ -1257,6 +1282,7 @@ set(viewer_HEADER_FILES llpanelpeople.h llpanelpeoplemenus.h llpanelpermissions.h + llpanelpick.h llpanelplaceinfo.h llpanelplaceprofile.h llpanelplaces.h @@ -1265,8 +1291,17 @@ set(viewer_HEADER_FILES llpanelpresetspulldown.h llpanelprimmediacontrols.h llpanelprofile.h + llpanelprofilelegacy.h llpanelprofileclassifieds.h llpanelprofilepicks.h + llpanelsearchbase.h + llpanelsearchclassifieds.h + llpanelsearchevents.h + llpanelsearchgroups.h + llpanelsearchlandsales.h + llpanelsearchpeople.h + llpanelsearchplaces.h + llpanelsearchweb.h llpanelsnapshot.h llpanelteleporthistory.h llpaneltiptoast.h @@ -1294,6 +1329,7 @@ set(viewer_HEADER_FILES llpersistentnotificationstorage.h llphysicsmotion.h llphysicsshapebuilderutil.h + llpickitem.h llpipelinelistener.h llplacesinventorybridge.h llplacesinventorypanel.h @@ -1309,6 +1345,7 @@ set(viewer_HEADER_FILES llpreviewsound.h llpreviewtexture.h llproductinforequest.h + llprofileimagepicker.h llprogressview.h llrecentpeople.h llreflectionmap.h diff --git a/indra/newview/alavataractions.cpp b/indra/newview/alavataractions.cpp index b9bdbc2b13799bb4b0ed5020cfef95a9253d0a4c..7668577325aeea6de6fa34ebca902993d5e70b9c 100644 --- a/indra/newview/alavataractions.cpp +++ b/indra/newview/alavataractions.cpp @@ -36,8 +36,11 @@ #include "roles_constants.h" #include "llagent.h" +#include "llavataractions.h" +#include "llfloaterreg.h" #include "llfloaterregioninfo.h" #include "llfloaterreporter.h" +#include "llfloaterwebcontent.h" #include "llslurl.h" #include "llviewercontrol.h" #include "llviewermenu.h" @@ -853,3 +856,21 @@ bool ALAvatarActions::handleGodKick(const LLSD& notification, const LLSD& respon } return false; } + +// Webprofile junk... for posterity! + +static void on_avatar_name_show_profile(const LLUUID& agent_id, const LLAvatarName& av_name) +{ + LLFloaterWebContent::Params p; + p.url(getProfileURL(av_name.getAccountName())).id(agent_id.asString()); + LLFloaterReg::showInstance("webprofile", p); +} + +// static +void ALAvatarActions::showWebProfile(const LLUUID& id) +{ + if (id.notNull()) + { + LLAvatarNameCache::get(id, boost::bind(&on_avatar_name_show_profile, _1, _2)); + } +} diff --git a/indra/newview/alavataractions.h b/indra/newview/alavataractions.h index d6bb2f1792f574399b15a5751e95e94876b9da42..03dfe49e516ae470696a6b66fa54376e743c5a44 100644 --- a/indra/newview/alavataractions.h +++ b/indra/newview/alavataractions.h @@ -94,6 +94,9 @@ class ALAvatarActions static void godFreeze(const LLUUID& id); static void godUnfreeze(const LLUUID& id); + // Webprofile + static void showWebProfile(const LLUUID& id); + private: static bool handleParcelFreeze(const LLSD& notification, const LLSD& response); static bool handleParcelEject(const LLSD& notification, const LLSD& response); diff --git a/indra/newview/fsfloatersearch.cpp b/indra/newview/fsfloatersearch.cpp deleted file mode 100644 index 286bcdf2fe82261df17563aaeb6178dfe7ec444d..0000000000000000000000000000000000000000 --- a/indra/newview/fsfloatersearch.cpp +++ /dev/null @@ -1,3155 +0,0 @@ -/** - * @file fsfloatersearch.cpp - * @brief Firestorm Search Floater - * - * $LicenseInfo:firstyear=2012&license=fsviewerlgpl$ - * Phoenix Firestorm Viewer Source Code - * Copyright (C) 2012, Cinder Roxley <cinder.roxley@phoenixviewer.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA - * http://www.firestormviewer.org - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" - -#include "fsfloatersearch.h" - -#include "lldispatcher.h" -#include "llagent.h" -#include "llavataractions.h" -#include "llavatarname.h" -#include "llavatarnamecache.h" -#include "llavatarpropertiesprocessor.h" -#include "llclassifiedflags.h" -#include "llclassifiedinfo.h" -#include "llcombobox.h" -#include "lldateutil.h" -#include "lleventflags.h" -#include "lleventnotifier.h" -#include "llfloaterreg.h" -#include "llfloaterworldmap.h" -#include "llgroupactions.h" -#include "llgroupmgr.h" -#include "llloadingindicator.h" -#include "lllogininstance.h" -#include "llnotificationsutil.h" -#include "llpanelprofile.h" -#include "llpanelprofileclassifieds.h" -#include "llparcel.h" -#include "llproductinforequest.h" -#include "llqueryflags.h" -#include "llregionhandle.h" -#include "llremoteparcelrequest.h" -#include "lltimer.h" -#include "lltrans.h" -#include "llviewercontrol.h" -#include "llviewergenericmessage.h" -#include "llviewernetwork.h" -#include "llviewerregion.h" -#include "llworldmapmessage.h" -#include "message.h" -#include <boost/tokenizer.hpp> -#include <boost/algorithm/string.hpp> -#include <string> - -static const S32 MIN_SEARCH_STRING_SIZE = 2; -static const S32 RESULT_PAGE_SIZE = 100; - -std::string filterShortWords(std::string query_string); -void fillSearchComboBox(LLSearchComboBox* search_combo); - -//////////////////////////////////////// -// Observer Classes // -//////////////////////////////////////// - -class FSSearchRemoteParcelInfoObserver : public LLRemoteParcelInfoObserver -{ -public: - FSSearchRemoteParcelInfoObserver(FSFloaterSearch* floater, bool for_events) : LLRemoteParcelInfoObserver(), - mParent(floater), - mForEvents(for_events) - {} - - ~FSSearchRemoteParcelInfoObserver() - { - // remove any in-flight observers - std::set<LLUUID>::iterator it; - for (it = mParcelIDs.begin(); it != mParcelIDs.end(); ++it) - { - const LLUUID &id = *it; - LLRemoteParcelInfoProcessor::getInstance()->removeObserver(id, this); - } - mParcelIDs.clear(); - } - - /*virtual*/ void processParcelInfo(const LLParcelData& parcel_data) - { - if (mParent) - { - if (mForEvents) - { - mParent->displayEventParcelImage(parcel_data); - } - else - { - mParent->displayParcelDetails(parcel_data); - } - } - mParcelIDs.erase(parcel_data.parcel_id); - LLRemoteParcelInfoProcessor::getInstance()->removeObserver(parcel_data.parcel_id, this); - } - - /*virtual*/ void setParcelID(const LLUUID& parcel_id) - { - if (!parcel_id.isNull()) - { - mParcelIDs.insert(parcel_id); - LLRemoteParcelInfoProcessor::getInstance()->addObserver(parcel_id, this); - LLRemoteParcelInfoProcessor::getInstance()->sendParcelInfoRequest(parcel_id); - } - } - - /*virtual*/ void setErrorStatus(S32 status, const std::string& reason) - { - LL_WARNS("Search") << "Can't complete remote parcel request. Http Status: " << status << ". Reason : " << reason << LL_ENDL; - } -private: - std::set<LLUUID> mParcelIDs; - FSFloaterSearch* mParent; - bool mForEvents; -}; - -///// Avatar Properties Observer ///// - -class FSSearchAvatarPropertiesObserver : public LLAvatarPropertiesObserver -{ -public: - FSSearchAvatarPropertiesObserver(FSFloaterSearch* floater) : LLAvatarPropertiesObserver(), - mParent(floater) - {} - - ~FSSearchAvatarPropertiesObserver() - { - // remove any in-flight observers - std::set<LLUUID>::iterator it; - for (it = mAvatarIDs.begin(); it != mAvatarIDs.end(); ++it) - { - const LLUUID &id = *it; - LLAvatarPropertiesProcessor::getInstance()->removeObserver(id, this); - } - mAvatarIDs.clear(); - } - - void processProperties(void* data, EAvatarProcessorType type) - { - if (!data) - return; - - if (APT_PROPERTIES == type) - { - LLAvatarData* avatar_data = static_cast<LLAvatarData*>(data); - if (avatar_data) - { - mParent->displayAvatarDetails(avatar_data); - LLAvatarPropertiesProcessor::getInstance()->removeObserver(avatar_data->avatar_id, this); - } - } - else if (APT_PROPERTIES_LEGACY == type) - { - LLAvatarData avatar_data(*static_cast<LLAvatarLegacyData*>(data)); - mParent->displayAvatarDetails(&avatar_data); - LLAvatarPropertiesProcessor::getInstance()->removeObserver(avatar_data.avatar_id, this); - } - if (APT_CLASSIFIED_INFO == type) - { - LLAvatarClassifiedInfo* c_info = static_cast<LLAvatarClassifiedInfo*>(data); - if (c_info) - { - mParent->displayClassifiedDetails(c_info); - LLAvatarPropertiesProcessor::getInstance()->removeObserver(c_info->classified_id, this); - std::string url = gAgent.getRegionCapability("SearchStatRequest"); - if (!url.empty()) - { - LL_INFOS("Search") << "Classified stat request via capability" << LL_ENDL; - LLSD body; - body["classified_id"] = c_info->classified_id; - LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpPost(url, body, boost::bind(&LLPanelProfileClassified::handleSearchStatResponse, c_info->classified_id, _1)); - } - } - } - } -private: - std::set<LLUUID> mAvatarIDs; - FSFloaterSearch* mParent; -}; - -///// Group Info Observer ///// - -class FSSearchGroupInfoObserver : public LLGroupMgrObserver -{ -public: - FSSearchGroupInfoObserver(const LLUUID& group_id, FSFloaterSearch* parent) : - LLGroupMgrObserver(group_id), - mParent(parent) - { - LLGroupMgr* groupmgr = LLGroupMgr::getInstance(); - if (!group_id.isNull() && groupmgr) - { - groupmgr->addObserver(this); - mID = group_id; - groupmgr->sendGroupPropertiesRequest(group_id); - } - } - - ~FSSearchGroupInfoObserver() - { - LLGroupMgr::getInstance()->removeObserver(this); - } - - void changed(LLGroupChange gc) - { - if (gc == GC_PROPERTIES) - { - LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(mID); - mParent->displayGroupDetails(group_data); - LLGroupMgr::getInstance()->removeObserver(this); - } - } -private: - FSFloaterSearch* mParent; - LLUUID mID; -}; - -///// Silly Classified Clickthrough Class ///// -class FSDispatchClassifiedClickThrough : public LLDispatchHandler -{ -public: - virtual bool operator()( - const LLDispatcher* dispatcher, - const std::string& key, - const LLUUID& invoice, - const sparam_t& strings) - { - if (strings.size() != 4) return false; - LLUUID classified_id(strings[0]); - S32 teleport_clicks = atoi(strings[1].c_str()); - S32 map_clicks = atoi(strings[2].c_str()); - S32 profile_clicks = atoi(strings[3].c_str()); - - LLPanelProfileClassified::setClickThrough( - classified_id, teleport_clicks, map_clicks, profile_clicks, false); - - return true; - } -}; -static FSDispatchClassifiedClickThrough sClassifiedClickThrough; - -SearchQuery::SearchQuery() -: category("category", "") -, query("query") -{} - -//////////////////////////////////////// -// The floater itself // -//////////////////////////////////////// - -FSFloaterSearch::FSFloaterSearch(const Params& key) -: LLFloater(key) -{ - mRemoteParcelObserver = new FSSearchRemoteParcelInfoObserver(this, false); - mRemoteParcelEventLocationObserver = new FSSearchRemoteParcelInfoObserver(this, true); - mAvatarPropertiesObserver = new FSSearchAvatarPropertiesObserver(this); - mEventNotifierConnection = gEventNotifier.setNewEventCallback(boost::bind(&FSFloaterSearch::displayEventDetails, this, boost::placeholders::_1)); -} - -FSFloaterSearch::~FSFloaterSearch() -{ - mEventNotifierConnection.disconnect(); - delete mRemoteParcelObserver; - delete mRemoteParcelEventLocationObserver; - delete mAvatarPropertiesObserver; - gGenericDispatcher.addHandler("classifiedclickthrough", nullptr); -} - -// virtual -void FSFloaterSearch::onOpen(const LLSD& key) -{ - Params p(key); - mPanelWeb->loadURL(p.search); - if (key.has("query")) - { - mTabContainer->selectTabPanel(mPanelWeb); - } - else if (key.has("tab") && key["tab"].asString() == "groups") - { - mTabContainer->selectTabPanel(mPanelGroups); - } - - FSSearchPanelBase* current_panel = dynamic_cast<FSSearchPanelBase*>(mTabContainer->getCurrentPanel()); - if (current_panel) - { - current_panel->focusDefaultElement(); - } -} - -//virtual -void FSFloaterSearch::onClose(bool app_quitting) -{ - if (mTabContainer) - { - gSavedSettings.setS32("FSLastSearchTab", mTabContainer->getCurrentPanelIndex()); - } -} - -BOOL FSFloaterSearch::postBuild() -{ - childSetAction("people_profile_btn", boost::bind(&FSFloaterSearch::onBtnPeopleProfile, this)); - childSetAction("people_message_btn", boost::bind(&FSFloaterSearch::onBtnPeopleIM, this)); - childSetAction("people_friend_btn", boost::bind(&FSFloaterSearch::onBtnPeopleFriend, this)); - childSetAction("group_profile_btn", boost::bind(&FSFloaterSearch::onBtnGroupProfile, this)); - childSetAction("group_message_btn", boost::bind(&FSFloaterSearch::onBtnGroupChat, this)); - childSetAction("group_join_btn", boost::bind(&FSFloaterSearch::onBtnGroupJoin, this)); - childSetAction("event_reminder_btn", boost::bind(&FSFloaterSearch::onBtnEventReminder, this)); - childSetAction("teleport_btn", boost::bind(&FSFloaterSearch::onBtnTeleport, this)); - childSetAction("map_btn", boost::bind(&FSFloaterSearch::onBtnMap, this)); - resetVerbs(); - - mPanelPeople = findChild<FSPanelSearchPeople>("panel_ls_people"); - mPanelGroups = findChild<FSPanelSearchGroups>("panel_ls_groups"); - mPanelPlaces = findChild<FSPanelSearchPlaces>("panel_ls_places"); - mPanelEvents = findChild<FSPanelSearchEvents>("panel_ls_events"); - mPanelLand = findChild<FSPanelSearchLand>("panel_ls_land"); - mPanelClassifieds = findChild<FSPanelSearchClassifieds>("panel_ls_classifieds"); - mPanelWeb = findChild<FSPanelSearchWeb>("panel_ls_web"); - - mDetailsPanel = getChild<LLPanel>("panel_ls_details"); - mDetailTitle = getChild<LLTextEditor>("title"); - mDetailDesc = getChild<LLTextEditor>("desc"); - mDetailAux1 = getChild<LLTextEditor>("aux1"); - mDetailAux2 = getChild<LLTextEditor>("aux2"); - mDetailLocation = getChild<LLTextEditor>("location"); - mDetailSnapshot = getChild<LLTextureCtrl>("snapshot"); - mDetailSnapshotParcel = getChild<LLTextureCtrl>("snapshot_parcel"); - mDetailMaturity = getChild<LLIconCtrl>("maturity_icon"); - mTabContainer = getChild<LLTabContainer>("ls_tabs"); - - mTabContainer->setCommitCallback(boost::bind(&FSFloaterSearch::onTabChange, this)); - - flushDetails(); - - mDetailsPanel->setVisible(false); - - mHasSelection = false; - - if (!mTabContainer->selectTab(gSavedSettings.getS32("FSLastSearchTab"))) - { - mTabContainer->selectFirstTab(); - } - - return TRUE; -} - -void FSFloaterSearch::onTabChange() -{ - LLPanel* active_panel = mTabContainer->getCurrentPanel(); - - if (active_panel == mPanelWeb) - { - mDetailsPanel->setVisible(false); - mPanelWeb->resetFocusOnLoad(); - } - else if (active_panel == mPanelPeople) - { - mDetailsPanel->setVisible(mHasSelection); - } - - if (active_panel == mPanelPeople || active_panel == mPanelGroups) - { - mDetailSnapshotParcel->setVisible(FALSE); - mDetailSnapshot->setVisible(TRUE); - } - else if (active_panel == mPanelPlaces || active_panel == mPanelLand || - active_panel == mPanelEvents || active_panel == mPanelClassifieds) - { - mDetailSnapshot->setVisible(FALSE); - mDetailSnapshotParcel->setVisible(TRUE); - } -} - -//static -template <class T> -T* FSFloaterSearch::getSearchPanel(const std::string& panel_name) -{ - FSFloaterSearch* search_instance = LLFloaterReg::findTypedInstance<FSFloaterSearch>("search"); - if (search_instance && search_instance->mTabContainer) - { - return dynamic_cast<T*>(search_instance->mTabContainer->getPanelByName(panel_name)); - } - else - { - return nullptr; - } -} - -void FSFloaterSearch::onSelectedItem(const LLUUID& selected_item, ESearchCategory type) -{ - if (!selected_item.isNull()) - { - mSelectedID = selected_item; - resetVerbs(); - flushDetails(); - switch (type) - { - case SC_AVATAR: - { - LLAvatarPropertiesProcessor::getInstance()->addObserver(selected_item, mAvatarPropertiesObserver); - LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesRequest(selected_item); - } - break; - case SC_GROUP: - mGroupPropertiesRequest = new FSSearchGroupInfoObserver(selected_item, this); - break; - case SC_PLACE: - mRemoteParcelObserver->setParcelID(selected_item); - break; - case SC_CLASSIFIED: - LLAvatarPropertiesProcessor::getInstance()->addObserver(selected_item, mAvatarPropertiesObserver); - LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(selected_item); - gGenericDispatcher.addHandler("classifiedclickthrough", &sClassifiedClickThrough); - break; - } - setLoadingProgress(true); - } -} - -void FSFloaterSearch::onSelectedEvent(const S32 selected_event) -{ - resetVerbs(); - flushDetails(); - - gMessageSystem->newMessageFast(_PREHASH_EventInfoRequest); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgentID); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgentSessionID); - gMessageSystem->nextBlockFast(_PREHASH_EventData); - gMessageSystem->addU32Fast(_PREHASH_EventID, selected_event); - gAgent.sendReliableMessage(); -} - -void FSFloaterSearch::displayParcelDetails(const LLParcelData& parcel_data) -{ - S32 region_x; - S32 region_y; - S32 region_z; - region_x = ll_round(parcel_data.global_x) % REGION_WIDTH_UNITS; - region_y = ll_round(parcel_data.global_y) % REGION_WIDTH_UNITS; - region_z = ll_round(parcel_data.global_z); - // HACK: Flag 0x2 == adult region, - // Flag 0x1 == mature region, otherwise assume PG - if (parcel_data.flags & 0x2) - { - mDetailMaturity->setValue("Parcel_R_Dark"); - } - else if (parcel_data.flags & 0x1) - { - mDetailMaturity->setValue("Parcel_M_Dark"); - } - else - { - mDetailMaturity->setValue("Parcel_PG_Dark"); - } - - LLStringUtil::format_map_t map; - map["DWELL"] = llformat("%.0f", (F64)parcel_data.dwell); - map["AREA"] = llformat("%d m²", parcel_data.actual_area); - map["LOCATION"] = llformat("%s (%d, %d, %d)", parcel_data.sim_name.c_str(), region_x, region_y, region_z); - - mParcelGlobal = LLVector3d(parcel_data.global_x, parcel_data.global_y, parcel_data.global_z); - mDetailsPanel->setVisible(mTabContainer->getCurrentPanel()->getName() == "panel_ls_places" || mTabContainer->getCurrentPanel()->getName() == "panel_ls_land"); - mHasSelection = true; - mDetailMaturity->setVisible(true); - mDetailTitle->setValue(parcel_data.name); - mDetailDesc->setValue(parcel_data.desc); - mDetailAux1->setValue(getString("string.traffic", map)); - mDetailAux2->setValue(getString("string.area", map)); - mDetailLocation->setValue(getString("string.location", map)); - mDetailSnapshotParcel->setValue(parcel_data.snapshot_id); - childSetVisible("teleport_btn", true); - childSetVisible("map_btn", true); - setLoadingProgress(false); -} - -void FSFloaterSearch::displayAvatarDetails(LLAvatarData* avatar_data) -{ - if (avatar_data) - { - LLStringUtil::format_map_t map; - map["AGE"] = LLDateUtil::ageFromDate(avatar_data->born_on, LLDate::now()); - if (avatar_data->partner_id.notNull()) - { - map["PARTNER"] = LLSLURL("agent", avatar_data->partner_id, "inspect").getSLURLString(); - mDetailAux2->setValue(getString("string.partner", map)); - } - - mDetailsPanel->setVisible(mTabContainer->getCurrentPanel()->getName() == "panel_ls_people"); - mHasSelection = true; - mDetailTitle->setValue(LLTrans::getString("LoadingData")); - mDetailDesc->setValue(avatar_data->about_text); - mDetailSnapshot->setValue(avatar_data->image_id); - mDetailAux1->setValue(avatar_data->hide_age ? "" : getString("string.age", map)); - LLAvatarNameCache::get(avatar_data->avatar_id, boost::bind(&FSFloaterSearch::avatarNameUpdatedCallback,this, _1, _2)); - childSetVisible("people_profile_btn", true); - childSetVisible("people_message_btn", true); - childSetVisible("people_friend_btn", true); - getChildView("people_friend_btn")->setEnabled(!LLAvatarActions::isFriend(avatar_data->avatar_id)); - } -} - -void FSFloaterSearch::displayGroupDetails(LLGroupMgrGroupData*& group_data) -{ - if (group_data) - { - LLStringUtil::format_map_t map; - map["MEMBER_COUNT"] = llformat("%d",group_data->mMemberCount); - map["FOUNDER"] = LLSLURL("agent", group_data->mFounderID, "inspect").getSLURLString(); - - mDetailsPanel->setVisible(mTabContainer->getCurrentPanel()->getName() == "panel_ls_groups"); - mHasSelection = true; - mDetailTitle->setValue(LLTrans::getString("LoadingData")); - mDetailDesc->setValue(group_data->mCharter); - mDetailSnapshot->setValue(group_data->mInsigniaID); - mDetailAux1->setValue(getString("string.members", map)); - mDetailAux2->setValue(getString("string.founder", map)); - LLGroupData agent_gdatap; - bool is_member = gAgent.getGroupData(getSelectedID(),agent_gdatap) || gAgent.isGodlike(); - bool join_btn_enabled = !is_member && group_data->mOpenEnrollment; - childSetVisible("group_profile_btn", true); - childSetVisible("group_message_btn", true); - childSetVisible("group_join_btn", true); - getChildView("group_join_btn")->setEnabled(join_btn_enabled); - getChildView("group_message_btn")->setEnabled(is_member); - gCacheName->getGroup(getSelectedID(), boost::bind(&FSFloaterSearch::groupNameUpdatedCallback, this, _1, _2, _3)); - } -} - -void FSFloaterSearch::displayClassifiedDetails(LLAvatarClassifiedInfo*& c_info) -{ - if (c_info) - { - if (c_info->flags & CLASSIFIED_FLAG_MATURE) - { - mDetailMaturity->setValue("Parcel_M_Dark"); - } - else - { - mDetailMaturity->setValue("Parcel_PG_Dark"); - } - - LLStringUtil::format_map_t map; - map["LISTING_PRICE"] = llformat("L$%d", c_info->price_for_listing); - map["SLURL"] = LLSLURL("parcel", c_info->parcel_id, "about").getSLURLString(); - - mDetailsPanel->setVisible(mTabContainer->getCurrentPanel()->getName() == "panel_ls_classifieds"); - mHasSelection = true; - mDetailMaturity->setVisible(true); - mParcelGlobal = c_info->pos_global; - mDetailTitle->setValue(c_info->name); - mDetailDesc->setValue(c_info->description); - mDetailSnapshotParcel->setValue(c_info->snapshot_id); - mDetailAux1->setValue(getString("string.listing_price", map)); - mDetailLocation->setValue(getString("string.slurl", map)); - childSetVisible("teleport_btn", true); - childSetVisible("map_btn", true); - setLoadingProgress(false); - } -} - -bool FSFloaterSearch::displayEventDetails(LLEventStruct event) -{ - if (event.flags == EVENT_FLAG_ADULT) - { - mDetailMaturity->setValue("Parcel_R_Dark"); - } - else if (event.flags == EVENT_FLAG_MATURE) - { - mDetailMaturity->setValue("Parcel_M_Dark"); - } - else - { - mDetailMaturity->setValue("Parcel_PG_Dark"); - } - - S32 region_x; - S32 region_y; - S32 region_z; - region_x = (S64)ll_round(event.globalPos.mdV[VX]) % REGION_WIDTH_UNITS; - region_y = (S64)ll_round(event.globalPos.mdV[VY]) % REGION_WIDTH_UNITS; - region_z = (S32)ll_round(event.globalPos.mdV[VZ]); - LLStringUtil::format_map_t map; - map["DURATION"] = llformat("%d:%.2d", event.duration / 60, event.duration % 60); - map["LOCATION"] = llformat("%s (%d, %d, %d)", event.simName.c_str(), region_x, region_y, region_z); - if (event.cover > 0) - { - map["COVERCHARGE"] = llformat("L$%d", event.cover); - mDetailAux2->setValue(getString("string.covercharge", map)); - } - - mParcelGlobal = event.globalPos; - mEventID = event.eventId; - mDetailsPanel->setVisible(mTabContainer->getCurrentPanel()->getName() == "panel_ls_events"); - mHasSelection = true; - mDetailMaturity->setVisible(true); - mDetailTitle->setValue(event.eventName); - mDetailDesc->setValue(event.desc); - mDetailAux1->setValue(getString("string.duration", map)); - mDetailLocation->setValue(getString("string.location", map)); - mDetailSnapshotParcel->setValue(LLUUID::null); - childSetVisible("teleport_btn", true); - childSetVisible("map_btn", true); - childSetVisible("event_reminder_btn", true); - - LLWorldMapMessage::getInstance()->sendNamedRegionRequest(event.simName, boost::bind(&FSFloaterSearch::regionHandleCallback, this, _1, event.globalPos), "", false); - return true; -} - -void FSFloaterSearch::regionHandleCallback(U64 region_handle, LLVector3d pos_global) -{ - std::string url = gAgent.getRegionCapability("RemoteParcelRequest"); - if (!url.empty()) - { - auto region_origin = from_region_handle(region_handle); - LLVector3 pos_region(LLVector3(pos_global - region_origin)); - - LLRemoteParcelInfoProcessor::getInstance()->requestRegionParcelInfo(url, - LLUUID::null, pos_region, pos_global, mRemoteParcelEventLocationObserver->getObserverHandle()); - } - else - { - setLoadingProgress(false); - } -} - -void FSFloaterSearch::displayEventParcelImage(const LLParcelData& parcel_data) -{ - mDetailSnapshotParcel->setValue(parcel_data.snapshot_id); - setLoadingProgress(false); -} - -void FSFloaterSearch::avatarNameUpdatedCallback(const LLUUID& id, const LLAvatarName& av_name) -{ - if (id == getSelectedID()) - { - mDetailTitle->setValue(av_name.getCompleteName()); - setLoadingProgress(false); - } - // Otherwise possibly a request for an older selection, ignore it. -} - -void FSFloaterSearch::groupNameUpdatedCallback(const LLUUID& id, const std::string& name, bool is_group) -{ - if (id == getSelectedID()) - { - mDetailTitle->setValue( LLSD(name) ); - setLoadingProgress(false); - } - // Otherwise possibly a request for an older selection, ignore it. -} - -void FSFloaterSearch::setLoadingProgress(bool started) -{ - LLLoadingIndicator* indicator = getChild<LLLoadingIndicator>("loading"); - - indicator->setVisible(started); - - if (started) - { - indicator->start(); - } - else - { - indicator->stop(); - } -} - -void FSFloaterSearch::resetVerbs() -{ - childSetVisible("people_profile_btn", false); - childSetVisible("people_message_btn", false); - childSetVisible("people_friend_btn", false); - childSetVisible("group_profile_btn", false); - childSetVisible("group_message_btn", false); - childSetVisible("group_join_btn", false); - childSetVisible("event_reminder_btn", false); - childSetVisible("teleport_btn", false); - childSetVisible("map_btn", false); -} - -void FSFloaterSearch::flushDetails() -{ - mDetailTitle->setValue(""); - mDetailDesc->setValue(""); - mDetailAux1->setValue(""); - mDetailAux2->setValue(""); - mDetailLocation->setValue(""); - mDetailSnapshot->setValue(LLSD()); - mDetailMaturity->setVisible(false); - mParcelGlobal.setZero(); -} - -void FSFloaterSearch::onBtnPeopleProfile() -{ - LLAvatarActions::showProfile(getSelectedID()); -} - -void FSFloaterSearch::onBtnPeopleIM() -{ - LLAvatarActions::startIM(getSelectedID()); -} - -void FSFloaterSearch::onBtnPeopleFriend() -{ - LLAvatarActions::requestFriendshipDialog(getSelectedID()); -} - -void FSFloaterSearch::onBtnGroupProfile() -{ - LLGroupActions::show(getSelectedID()); -} - -void FSFloaterSearch::onBtnGroupChat() -{ - LLGroupActions::startIM(getSelectedID()); -} - -void FSFloaterSearch::onBtnGroupJoin() -{ - LLGroupActions::join(getSelectedID()); -} - -void FSFloaterSearch::onBtnTeleport() -{ - if (!mParcelGlobal.isExactlyZero()) - { - gAgent.teleportViaLocation(mParcelGlobal); - LLFloaterWorldMap::getInstance()->trackLocation(mParcelGlobal); - /// <FS:CR> What should we do when when we teleport? The default (1) is to close the floater, - /// the user may elect to minimize the floater (2), or to do nothing (any other setting) - static LLCachedControl<U32> teleport_action(gSavedSettings, "FSLegacySearchActionOnTeleport"); - if (teleport_action == 1) - { - closeFloater(); - } - else if (teleport_action == 2) - { - setMinimized(TRUE); - } - } -} - -void FSFloaterSearch::onBtnMap() -{ - if (!mParcelGlobal.isExactlyZero()) - { - LLFloaterWorldMap::getInstance()->trackLocation(mParcelGlobal); - LLFloaterReg::showInstance("world_map", "center"); - } -} - -void FSFloaterSearch::onBtnEventReminder() -{ - gEventNotifier.add(mEventID); -} - -//////////////////////////////////////// -// People Search Panel // -//////////////////////////////////////// - -static LLPanelInjector<FSPanelSearchPeople> t_panel_fs_search_people("panel_ls_people"); - -FSPanelSearchPeople::FSPanelSearchPeople() : FSSearchPanelBase() -, mQueryID(nullptr) -, mStartSearch(0) -, mResultsReceived(0) -, mResultsContent() -, mAvatarNameCallbackConnection() -{ -} - -FSPanelSearchPeople::~FSPanelSearchPeople() -{ - if (mAvatarNameCallbackConnection.connected()) - { - mAvatarNameCallbackConnection.disconnect(); - } -} - -BOOL FSPanelSearchPeople::postBuild() -{ - mSearchComboBox = findChild<LLSearchComboBox>("people_edit"); - mSearchResults = findChild<LLScrollListCtrl>("search_results_people"); - if (mSearchComboBox) - { - mSearchComboBox->setCommitCallback(boost::bind(&FSPanelSearchPeople::onBtnFind, this)); - fillSearchComboBox(mSearchComboBox); - } - if (mSearchResults) - { - mSearchResults->setCommitCallback(boost::bind(&FSPanelSearchPeople::onSelectItem, this)); - mSearchResults->setEnabled(FALSE); - mSearchResults->setCommentText(LLTrans::getString("no_results")); - mSearchResults->setContextMenu(LLScrollListCtrl::MENU_AVATAR); - } - - childSetAction("people_next", boost::bind(&FSPanelSearchPeople::onBtnNext, this)); - childSetAction("people_back", boost::bind(&FSPanelSearchPeople::onBtnBack, this)); - getChildView("people_next")->setEnabled(FALSE); - getChildView("people_back")->setEnabled(FALSE); - - return TRUE; -} - -void FSPanelSearchPeople::focusDefaultElement() -{ - mSearchComboBox->focusTextEntry(); -} - -void FSPanelSearchPeople::find() -{ - std::string text = mSearchComboBox->getSimple(); - boost::trim(text); - if (text.size() <= MIN_SEARCH_STRING_SIZE) - { - mSearchResults->setCommentText(LLTrans::getString("search_short")); - return; - } - - if (LLUUID::validate(text)) - { - LLUUID id(text); - - mSearchResults->deleteAllItems(); - mSearchResults->setCommentText(LLTrans::getString("searching")); - mResultsReceived = 0; - mNumResultsReturned = 0; - - if (mAvatarNameCallbackConnection.connected()) - { - mAvatarNameCallbackConnection.disconnect(); - } - mAvatarNameCallbackConnection = LLAvatarNameCache::get(id, boost::bind(&FSPanelSearchPeople::onAvatarNameCallback, this, _1, _2)); - - return; - } - - LLStringUtil::replaceChar(text, '.', ' '); - - mResultsReceived = 0; - if (mQueryID.notNull()) - { - mQueryID.setNull(); - } - mQueryID.generate(); - - if (mStartSearch < 0) - { - mStartSearch = 0; - } - - gMessageSystem->newMessage("DirFindQuery"); - gMessageSystem->nextBlock("AgentData"); - gMessageSystem->addUUID("AgentID", gAgentID); - gMessageSystem->addUUID("SessionID", gAgentSessionID); - gMessageSystem->nextBlock("QueryData"); - gMessageSystem->addUUID("QueryID", getQueryID()); - gMessageSystem->addString("QueryText", text); - gMessageSystem->addU32("QueryFlags", DFQ_PEOPLE); - gMessageSystem->addS32("QueryStart", mStartSearch); - gAgent.sendReliableMessage(); - LL_DEBUGS("Search") << "Firing off search request: " << getQueryID() << LL_ENDL; - - mSearchResults->deleteAllItems(); - mSearchResults->setCommentText(LLTrans::getString("searching")); - mNumResultsReturned = 0; -} - -void FSPanelSearchPeople::onBtnFind() -{ - std::string text = mSearchComboBox->getSimple(); - if (!text.empty()) - { - LLSearchHistory::getInstance()->addEntry(text); - } - - resetSearch(); - - find(); -} - -void FSPanelSearchPeople::onBtnNext() -{ - mStartSearch += RESULT_PAGE_SIZE; - getChildView("people_back")->setEnabled(TRUE); - - find(); -} - -void FSPanelSearchPeople::onBtnBack() -{ - mStartSearch -= RESULT_PAGE_SIZE; - getChildView("people_back")->setEnabled(mStartSearch > 0); - - find(); -} - -void FSPanelSearchPeople::resetSearch() -{ - mStartSearch = 0; - getChildView("people_back")->setEnabled(FALSE); - getChildView("people_next")->setEnabled(FALSE); -} - -S32 FSPanelSearchPeople::showNextButton(S32 rows) -{ - bool show_next_button = (mResultsReceived > RESULT_PAGE_SIZE); - getChildView("people_next")->setEnabled(show_next_button); - if (show_next_button) - { - rows -= (mResultsReceived - RESULT_PAGE_SIZE); - } - return rows; -} - -void FSPanelSearchPeople::onSelectItem() -{ - if (!mSearchResults) - { - return; - } - FSFloaterSearch* search_instance = LLFloaterReg::findTypedInstance<FSFloaterSearch>("search"); - if (search_instance) - { - search_instance->FSFloaterSearch::onSelectedItem(mSearchResults->getSelectedValue(), FSFloaterSearch::SC_AVATAR); - } -} - -// static -void FSPanelSearchPeople::processSearchReply(LLMessageSystem* msg, void**) -{ - LLUUID query_id; - std::string first_name; - std::string last_name; - LLUUID agent_id; - - msg->getUUIDFast(_PREHASH_QueryData, _PREHASH_QueryID, query_id); - msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id); - - // This result is not for us. - if (agent_id != gAgentID) - { - return; - } - LL_DEBUGS("Search") << "received search results - QueryID: " << query_id << " AgentID: " << agent_id << LL_ENDL; - - FSPanelSearchPeople* self = FSFloaterSearch::getSearchPanel<FSPanelSearchPeople>("panel_ls_people"); - - // floater is closed or these are not results from our last request - if (!self || query_id != self->getQueryID()) - { - return; - } - - LLScrollListCtrl* search_results = self->getChild<LLScrollListCtrl>("search_results_people"); - - if (self->mNumResultsReturned++ == 0) - { - search_results->deleteAllItems(); - } - - // Check for status messages - if (msg->getNumberOfBlocks("StatusData")) - { - U32 status; - msg->getU32("StatusData", "Status", status); - if (status & STATUS_SEARCH_PLACES_FOUNDNONE) - { - LLStringUtil::format_map_t map; - map["[TEXT]"] = self->getChild<LLUICtrl>("people_edit")->getValue().asString(); - search_results->setEnabled(FALSE); - search_results->setCommentText(LLTrans::getString("not_found", map)); - return; - } - else if (status & STATUS_SEARCH_PLACES_SHORTSTRING) - { - search_results->setEnabled(FALSE); - search_results->setCommentText(LLTrans::getString("search_short")); - return; - } - else if (status & STATUS_SEARCH_PLACES_BANNEDWORD) - { - search_results->setEnabled(FALSE); - search_results->setCommentText(LLTrans::getString("search_banned")); - return; - } - else if (status & STATUS_SEARCH_PLACES_SEARCHDISABLED) - { - search_results->setEnabled(FALSE); - search_results->setCommentText(LLTrans::getString("search_disabled")); - return; - } - } - - bool found_one = false; - S32 num_new_rows = msg->getNumberOfBlocksFast(_PREHASH_QueryReplies); - if (num_new_rows == 0 && self->mResultsReceived == 0) - { - LLStringUtil::format_map_t map; - map["[TEXT]"] = self->getChild<LLUICtrl>("people_edit")->getValue().asString(); - search_results->setEnabled(FALSE); - search_results->setCommentText(LLTrans::getString("not_found", map)); - } - - self->mResultsReceived += num_new_rows; - num_new_rows = self->showNextButton(num_new_rows); - - for (S32 i = 0; i < num_new_rows; i++) - { - msg->getStringFast( _PREHASH_QueryReplies, _PREHASH_FirstName, first_name, i); - msg->getStringFast( _PREHASH_QueryReplies, _PREHASH_LastName, last_name, i); - msg->getUUIDFast( _PREHASH_QueryReplies, _PREHASH_AgentID, agent_id, i); - //msg->getU8Fast( _PREHASH_QueryReplies, _PREHASH_Online, online, i); - - if (agent_id.isNull()) - { - LL_INFOS("Search") << "Null result returned for QueryID: " << query_id << LL_ENDL; - LLStringUtil::format_map_t map; - map["[TEXT]"] = self->getChild<LLUICtrl>("people_edit")->getValue().asString(); - search_results->setEnabled(FALSE); - search_results->setCommentText(LLTrans::getString("not_found", map)); - } - else - { - LL_DEBUGS("Search") << "Got: " << first_name << " " << last_name << " AgentID: " << agent_id << LL_ENDL; - search_results->setEnabled(TRUE); - found_one = true; - - std::string avatar_name; - avatar_name = LLCacheName::buildFullName(first_name, last_name); - - LLSD content; - LLSD element; - - element["id"] = agent_id; - - element["columns"][0]["column"] = "icon"; - element["columns"][0]["type"] = "icon"; - element["columns"][0]["value"] = "icon_avatar_offline.tga"; - - element["columns"][1]["column"] = "username"; - element["columns"][1]["value"] = avatar_name; - - content["name"] = avatar_name; - - search_results->addElement(element, ADD_BOTTOM); - self->mResultsContent[agent_id.asString()] = content; - } - } - if (found_one) - { - search_results->selectFirstItem(); - search_results->setFocus(TRUE); - self->onSelectItem(); - } -} - -void FSPanelSearchPeople::onAvatarNameCallback(const LLUUID& id, const LLAvatarName& av_name) -{ - if (mAvatarNameCallbackConnection.connected()) - { - mAvatarNameCallbackConnection.disconnect(); - } - - LLScrollListCtrl* search_results = getChild<LLScrollListCtrl>("search_results_people"); - - if (av_name.getAccountName() != "(?\?\?).(?\?\?)") - { - LLSD content; - LLSD data; - data["id"] = id; - - data["columns"][0]["column"] = "icon"; - data["columns"][0]["type"] = "icon"; - data["columns"][0]["value"] = "icon_avatar_offline.tga"; - - data["columns"][1]["name"] = "username"; - data["columns"][1]["value"] = av_name.getUserName(); - - content["name"] = av_name.getUserName(); - - search_results->addElement(data); - - mResultsContent[id.asString()] = content; - mResultsReceived = 1; - mNumResultsReturned = 1; - - search_results->setEnabled(TRUE); - search_results->selectFirstItem(); - search_results->setFocus(TRUE); - onSelectItem(); - } - else - { - LLStringUtil::format_map_t map; - map["[TEXT]"] = getChild<LLUICtrl>("people_edit")->getValue().asString(); - search_results->setEnabled(FALSE); - search_results->setCommentText(LLTrans::getString("not_found", map)); - } -} - -//////////////////////////////////////// -// Groups Search Panel // -//////////////////////////////////////// - -static LLPanelInjector<FSPanelSearchGroups> t_panel_fs_search_groups("panel_ls_groups"); - -FSPanelSearchGroups::FSPanelSearchGroups() : FSSearchPanelBase() -, mQueryID(nullptr) -, mStartSearch(0) -, mResultsReceived(0) -, mResultsContent() -{ -} - -FSPanelSearchGroups::~FSPanelSearchGroups() -{ -} - -BOOL FSPanelSearchGroups::postBuild() -{ - mSearchComboBox = findChild<LLSearchComboBox>("groups_edit"); - mSearchResults = findChild<LLScrollListCtrl>("search_results_groups"); - if (mSearchComboBox) - { - mSearchComboBox->setCommitCallback(boost::bind(&FSPanelSearchGroups::onBtnFind, this)); - fillSearchComboBox(mSearchComboBox); - } - if (mSearchResults) - { - mSearchResults->setCommitCallback(boost::bind(&FSPanelSearchGroups::onSelectItem, this)); - mSearchResults->setEnabled(FALSE); - mSearchResults->setCommentText(LLTrans::getString("no_results")); - } - - childSetAction("groups_next", boost::bind(&FSPanelSearchGroups::onBtnNext, this)); - childSetAction("groups_back", boost::bind(&FSPanelSearchGroups::onBtnBack, this)); - getChildView("groups_next")->setEnabled(FALSE); - getChildView("groups_back")->setEnabled(FALSE); - - return TRUE; -} - -void FSPanelSearchGroups::focusDefaultElement() -{ - mSearchComboBox->focusTextEntry(); -} - -void FSPanelSearchGroups::find() -{ - std::string text = filterShortWords(mSearchComboBox->getSimple()); - if (text.size() == 0) - { - mSearchResults->setCommentText(LLTrans::getString("search_short")); - return; - } - - static LLUICachedControl<bool> inc_pg("ShowPGSims", 1); - static LLUICachedControl<bool> inc_mature("ShowMatureSims", 0); - static LLUICachedControl<bool> inc_adult("ShowAdultSims", 0); - if (!(inc_pg || inc_mature || inc_adult)) - { - LLNotificationsUtil::add("NoContentToSearch"); - return; - } - U32 scope = 0; - if (gAgent.wantsPGOnly()) - { - scope |= DFQ_PG_SIMS_ONLY; - } - bool adult_enabled = gAgent.canAccessAdult(); - bool mature_enabled = gAgent.canAccessMature(); - if (inc_pg) - { - scope |= DFQ_INC_PG; - } - if (inc_mature && mature_enabled) - { - scope |= DFQ_INC_MATURE; - } - if (inc_adult && adult_enabled) - { - scope |= DFQ_INC_ADULT; - } - scope |= DFQ_GROUPS; - - mResultsReceived = 0; - if (mQueryID.notNull()) - { - mQueryID.setNull(); - } - mQueryID.generate(); - - if (mStartSearch < 0) - { - mStartSearch = 0; - } - - gMessageSystem->newMessage("DirFindQuery"); - gMessageSystem->nextBlock("AgentData"); - gMessageSystem->addUUID("AgentID", gAgentID); - gMessageSystem->addUUID("SessionID", gAgentSessionID); - gMessageSystem->nextBlock("QueryData"); - gMessageSystem->addUUID("QueryID", getQueryID()); - gMessageSystem->addString("QueryText", text); - gMessageSystem->addU32("QueryFlags", scope); - gMessageSystem->addS32("QueryStart", mStartSearch); - gAgent.sendReliableMessage(); - LL_DEBUGS("Search") << "Firing off search request: " << getQueryID() << LL_ENDL; - - mSearchResults->deleteAllItems(); - mSearchResults->setCommentText(LLTrans::getString("searching")); - mNumResultsReturned = 0; -} - -void FSPanelSearchGroups::onBtnFind() -{ - std::string text = mSearchComboBox->getSimple(); - if (!text.empty()) - { - LLSearchHistory::getInstance()->addEntry(text); - } - - resetSearch(); - - find(); -} - -void FSPanelSearchGroups::onBtnNext() -{ - mStartSearch += RESULT_PAGE_SIZE; - getChildView("groups_back")->setEnabled(TRUE); - - find(); -} - -void FSPanelSearchGroups::onBtnBack() -{ - mStartSearch -= RESULT_PAGE_SIZE; - getChildView("groups_back")->setEnabled(mStartSearch > 0); - - find(); -} - -void FSPanelSearchGroups::resetSearch() -{ - mStartSearch = 0; - getChildView("groups_back")->setEnabled(FALSE); - getChildView("groups_next")->setEnabled(FALSE); -} - -S32 FSPanelSearchGroups::showNextButton(S32 rows) -{ - bool show_next_button = (mResultsReceived > RESULT_PAGE_SIZE); - getChildView("groups_next")->setEnabled(show_next_button); - if (show_next_button) - { - rows -= (mResultsReceived - RESULT_PAGE_SIZE); - } - return rows; -} - -void FSPanelSearchGroups::onSelectItem() -{ - if (!mSearchResults) - { - return; - } - FSFloaterSearch* search_instance = LLFloaterReg::findTypedInstance<FSFloaterSearch>("search"); - if (search_instance) - { - search_instance->FSFloaterSearch::onSelectedItem(mSearchResults->getSelectedValue(), FSFloaterSearch::SC_GROUP); - } -} - -// static -void FSPanelSearchGroups::processSearchReply(LLMessageSystem* msg, void**) -{ - LLUUID query_id; - LLUUID group_id; - LLUUID agent_id; - std::string group_name; - S32 members; - F32 search_order; - - msg->getUUIDFast( _PREHASH_QueryData, _PREHASH_QueryID, query_id); - msg->getUUIDFast( _PREHASH_AgentData, _PREHASH_AgentID, agent_id); - - // Not for us - if (agent_id != gAgentID) - { - return; - } - LL_DEBUGS("Search") << "received directory request - QueryID: " << query_id << " AgentID: " << agent_id << LL_ENDL; - - FSPanelSearchGroups* self = FSFloaterSearch::getSearchPanel<FSPanelSearchGroups>("panel_ls_groups"); - - // floater is closed or these are not results from our last request - if (!self || query_id != self->mQueryID) - { - return; - } - - LLScrollListCtrl* search_results = self->getChild<LLScrollListCtrl>("search_results_groups"); - - // Clear "Searching" label on first results - if (self->mNumResultsReturned++ == 0) - { - search_results->deleteAllItems(); - } - - // Check for status messages - if (msg->getNumberOfBlocks("StatusData")) - { - U32 status; - msg->getU32("StatusData", "Status", status); - if (status & STATUS_SEARCH_PLACES_FOUNDNONE) - { - LLStringUtil::format_map_t map; - map["[TEXT]"] = self->getChild<LLUICtrl>("groups_edit")->getValue().asString(); - search_results->setEnabled(FALSE); - search_results->setCommentText(LLTrans::getString("not_found", map)); - return; - } - else if(status & STATUS_SEARCH_PLACES_SHORTSTRING) - { - search_results->setEnabled(FALSE); - search_results->setCommentText(LLTrans::getString("search_short")); - return; - } - else if (status & STATUS_SEARCH_PLACES_BANNEDWORD) - { - search_results->setEnabled(FALSE); - search_results->setCommentText(LLTrans::getString("search_banned")); - return; - } - else if (status & STATUS_SEARCH_PLACES_SEARCHDISABLED) - { - search_results->setEnabled(FALSE); - search_results->setCommentText(LLTrans::getString("search_disabled")); - return; - } - } - - bool found_one = false; - S32 num_new_rows = msg->getNumberOfBlocksFast(_PREHASH_QueryReplies); - if (num_new_rows == 0 && self->mResultsReceived == 0) - { - LLStringUtil::format_map_t map; - map["[TEXT]"] = self->getChild<LLUICtrl>("groups_edit")->getValue().asString(); - search_results->setEnabled(FALSE); - search_results->setCommentText(LLTrans::getString("not_found", map)); - } - - self->mResultsReceived += num_new_rows; - num_new_rows = self->showNextButton(num_new_rows); - - for (S32 i = 0; i < num_new_rows; i++) - { - msg->getUUIDFast( _PREHASH_QueryReplies, _PREHASH_GroupID, group_id, i); - msg->getStringFast( _PREHASH_QueryReplies, _PREHASH_GroupName, group_name, i); - msg->getS32Fast( _PREHASH_QueryReplies, _PREHASH_Members, members, i); - msg->getF32Fast( _PREHASH_QueryReplies, _PREHASH_SearchOrder, search_order,i); - if (group_id.isNull()) - { - LL_DEBUGS("Search") << "No results returned for QueryID: " << query_id << LL_ENDL; - LLStringUtil::format_map_t map; - map["[TEXT]"] = self->getChild<LLUICtrl>("groups_edit")->getValue().asString(); - search_results->setEnabled(FALSE); - search_results->setCommentText(LLTrans::getString("not_found", map)); - } - else - { - LL_DEBUGS("Search") << "Got: " << group_name << " GroupID: " << group_id << LL_ENDL; - search_results->setEnabled(TRUE); - found_one = true; - - LLSD content; - LLSD element; - - element["id"] = group_id; - - element["columns"][0]["column"] = "icon"; - element["columns"][0]["type"] = "icon"; - element["columns"][0]["value"] = "Icon_Group"; - - element["columns"][1]["column"] = "group_name"; - element["columns"][1]["value"] = group_name; - - element["columns"][2]["column"] = "members"; - element["columns"][2]["value"] = members; - - element["columns"][3]["column"] = "score"; - element["columns"][3]["value"] = search_order; - - content["name"] = group_name; - - search_results->addElement(element, ADD_BOTTOM); - self->mResultsContent[group_id.asString()] = content; - } - } - if (found_one) - { - search_results->selectFirstItem(); - search_results->setFocus(TRUE); - self->onSelectItem(); - } -} - -//////////////////////////////////////// -// Places Search Panel // -//////////////////////////////////////// - -static LLPanelInjector<FSPanelSearchPlaces> t_panel_fs_search_places("panel_ls_places"); - -FSPanelSearchPlaces::FSPanelSearchPlaces() : FSSearchPanelBase() -, mQueryID(nullptr) -, mStartSearch(0) -, mResultsReceived(0) -, mResultsContent() -{ - mCommitCallbackRegistrar.add("CommitSearch", boost::bind(&FSPanelSearchPlaces::find, this)); -} - -FSPanelSearchPlaces::~FSPanelSearchPlaces() -{ -} - -BOOL FSPanelSearchPlaces::postBuild() -{ - mSearchComboBox = findChild<LLSearchComboBox>("places_edit"); - mSearchResults = findChild<LLScrollListCtrl>("search_results_places"); - mPlacesCategory = findChild<LLComboBox>("places_category"); - if (mSearchComboBox) - { - mSearchComboBox->setCommitCallback(boost::bind(&FSPanelSearchPlaces::onBtnFind, this)); - fillSearchComboBox(mSearchComboBox); - } - if (mSearchResults) - { - mSearchResults->setCommitCallback(boost::bind(&FSPanelSearchPlaces::onSelectItem, this)); - mSearchResults->setEnabled(FALSE); - mSearchResults->setCommentText(LLTrans::getString("no_results")); - } - if (mPlacesCategory) - { - mPlacesCategory->add(LLTrans::getString("all_categories"), LLSD("any")); - mPlacesCategory->addSeparator(); - for (int category = LLParcel::C_LINDEN; category < LLParcel::C_COUNT; category++) - { - LLParcel::ECategory eCategory = (LLParcel::ECategory)category; - mPlacesCategory->add(LLTrans::getString(LLParcel::getCategoryUIString(eCategory)), LLParcel::getCategoryString(eCategory)); - } - } - childSetAction("places_next", boost::bind(&FSPanelSearchPlaces::onBtnNext, this)); - childSetAction("places_back", boost::bind(&FSPanelSearchPlaces::onBtnBack, this)); - getChildView("places_next")->setEnabled(FALSE); - getChildView("places_back")->setEnabled(FALSE); - - return TRUE; -} - -void FSPanelSearchPlaces::focusDefaultElement() -{ - mSearchComboBox->focusTextEntry(); -} - -void FSPanelSearchPlaces::find() -{ - std::string text = filterShortWords(mSearchComboBox->getSimple()); - if (text.empty()) - { - mSearchResults->setCommentText(LLTrans::getString("search_short")); - return; - } - - static LLUICachedControl<bool> inc_pg("ShowPGSims", 1); - static LLUICachedControl<bool> inc_mature("ShowMatureSims", 0); - static LLUICachedControl<bool> inc_adult("ShowAdultSims", 0); - if (!(inc_pg || inc_mature || inc_adult)) - { - LLNotificationsUtil::add("NoContentToSearch"); - return; - } - S8 category; - std::string category_string = mPlacesCategory->getSelectedValue(); - if (category_string == "any") - { - category = LLParcel::C_ANY; - } - else - { - category = LLParcel::getCategoryFromString(category_string); - } - U32 scope = 0; - if (gAgent.wantsPGOnly()) - { - scope |= DFQ_PG_SIMS_ONLY; - } - bool adult_enabled = gAgent.canAccessAdult(); - bool mature_enabled = gAgent.canAccessMature(); - if (inc_pg) - { - scope |= DFQ_INC_PG; - } - if (inc_mature && mature_enabled) - { - scope |= DFQ_INC_MATURE; - } - if (inc_adult && adult_enabled) - { - scope |= DFQ_INC_ADULT; - } - scope |= DFQ_DWELL_SORT; - - mResultsReceived = 0; - if (mQueryID.notNull()) - { - mQueryID.setNull(); - } - mQueryID.generate(); - - if (mStartSearch < 0) - { - mStartSearch = 0; - } - - gMessageSystem->newMessage("DirPlacesQuery"); - gMessageSystem->nextBlock("AgentData"); - gMessageSystem->addUUID("AgentID", gAgentID); - gMessageSystem->addUUID("SessionID", gAgentSessionID); - gMessageSystem->nextBlock("QueryData"); - gMessageSystem->addUUID("QueryID", getQueryID()); - gMessageSystem->addString("QueryText", text); - gMessageSystem->addU32("QueryFlags", scope); - gMessageSystem->addS8("Category", category); - // TODO: Search filter by region name. - gMessageSystem->addString("SimName", ""); - gMessageSystem->addS32("QueryStart", mStartSearch); - gAgent.sendReliableMessage(); - LL_DEBUGS("Search") << "Firing off places search request: " << getQueryID() << LL_ENDL; - - mSearchResults->deleteAllItems(); - mSearchResults->setCommentText(LLTrans::getString("searching")); - mNumResultsReturned = 0; -} - -void FSPanelSearchPlaces::onBtnFind() -{ - std::string text = mSearchComboBox->getSimple(); - if (!text.empty()) - { - LLSearchHistory::getInstance()->addEntry(text); - } - - resetSearch(); - - find(); -} - -void FSPanelSearchPlaces::onBtnNext() -{ - mStartSearch += RESULT_PAGE_SIZE; - getChildView("places_back")->setEnabled(TRUE); - - find(); -} - -void FSPanelSearchPlaces::onBtnBack() -{ - mStartSearch -= RESULT_PAGE_SIZE; - getChildView("places_back")->setEnabled(mStartSearch > 0); - - find(); -} - -void FSPanelSearchPlaces::resetSearch() -{ - mStartSearch = 0; - getChildView("places_back")->setEnabled(FALSE); - getChildView("places_next")->setEnabled(FALSE); -} - -S32 FSPanelSearchPlaces::showNextButton(S32 rows) -{ - bool show_next_button = (mResultsReceived > RESULT_PAGE_SIZE); - getChildView("places_next")->setEnabled(show_next_button); - if (show_next_button) - { - rows -= (mResultsReceived - RESULT_PAGE_SIZE); - } - return rows; -} - -void FSPanelSearchPlaces::onSelectItem() -{ - if (!mSearchResults) - { - return; - } - FSFloaterSearch* search_instance = LLFloaterReg::findTypedInstance<FSFloaterSearch>("search"); - if (search_instance) - { - search_instance->FSFloaterSearch::onSelectedItem(mSearchResults->getSelectedValue(), FSFloaterSearch::SC_PLACE); - } -} - -// static -void FSPanelSearchPlaces::processSearchReply(LLMessageSystem* msg, void**) -{ - LLUUID agent_id; - LLUUID query_id; - LLUUID parcel_id; - std::string name; - BOOL for_sale; - BOOL auction; - F32 dwell; - - msg->getUUID("AgentData", "AgentID", agent_id); - msg->getUUID("QueryData", "QueryID", query_id); - - // Not for us - if (agent_id != gAgentID) - { - return; - } - LL_DEBUGS("Search") << "received directory request - QueryID: " << query_id << " AgentID: " << agent_id << LL_ENDL; - - FSPanelSearchPlaces* self = FSFloaterSearch::getSearchPanel<FSPanelSearchPlaces>("panel_ls_places"); - - // floater is closed or these are not results from our last request - if (!self || query_id != self->getQueryID()) - { - return; - } - - LLScrollListCtrl* search_results = self->getChild<LLScrollListCtrl>("search_results_places"); - - // Clear "Searching" label on first results - if (self->mNumResultsReturned++ == 0) - { - search_results->deleteAllItems(); - } - - // Check for status messages - if (msg->getNumberOfBlocks("StatusData")) - { - U32 status; - msg->getU32("StatusData", "Status", status); - if (status & STATUS_SEARCH_PLACES_FOUNDNONE) - { - LLStringUtil::format_map_t map; - map["[TEXT]"] = self->getChild<LLUICtrl>("places_edit")->getValue().asString(); - search_results->setEnabled(FALSE); - search_results->setCommentText(LLTrans::getString("not_found", map)); - return; - } - else if(status & STATUS_SEARCH_PLACES_SHORTSTRING) - { - search_results->setEnabled(FALSE); - search_results->setCommentText(LLTrans::getString("search_short")); - return; - } - else if (status & STATUS_SEARCH_PLACES_BANNEDWORD) - { - search_results->setEnabled(FALSE); - search_results->setCommentText(LLTrans::getString("search_banned")); - return; - } - else if (status & STATUS_SEARCH_PLACES_SEARCHDISABLED) - { - search_results->setEnabled(FALSE); - search_results->setCommentText(LLTrans::getString("search_disabled")); - return; - } - else if (status & STATUS_SEARCH_PLACES_ESTATEEMPTY) - { - search_results->setEnabled(FALSE); - search_results->setCommentText(LLTrans::getString("search_disabled")); - return; - } - } - - bool found_one = false; - S32 num_new_rows = msg->getNumberOfBlocks("QueryReplies"); - if (num_new_rows == 0 && self->mResultsReceived == 0) - { - LLStringUtil::format_map_t map; - map["[TEXT]"] = self->getChild<LLUICtrl>("places_edit")->getValue().asString(); - search_results->setEnabled(FALSE); - search_results->setCommentText(LLTrans::getString("not_found", map)); - } - - self->mResultsReceived += num_new_rows; - num_new_rows = self->showNextButton(num_new_rows); - - for (S32 i = 0; i < num_new_rows; i++) - { - msg->getUUID( "QueryReplies", "ParcelID", parcel_id, i); - msg->getString( "QueryReplies", "Name", name, i); - msg->getBOOL( "QueryReplies", "ForSale", for_sale,i); - msg->getBOOL( "QueryReplies", "Auction", auction, i); - msg->getF32( "QueryReplies", "Dwell", dwell, i); - if (parcel_id.isNull()) - { - LL_DEBUGS("Search") << "Null result returned for QueryID: " << query_id << LL_ENDL; - LLStringUtil::format_map_t map; - map["[TEXT]"] = self->getChild<LLUICtrl>("places_edit")->getValue().asString(); - search_results->setEnabled(FALSE); - search_results->setCommentText(LLTrans::getString("not_found", map)); - } - else - { - LL_DEBUGS("Search") << "Got: " << name << " ParcelID: " << parcel_id << LL_ENDL; - search_results->setEnabled(TRUE); - found_one = true; - - LLSD content; - LLSD element; - - element["id"] = parcel_id; - - if (auction) - { - element["columns"][0]["column"] = "icon"; - element["columns"][0]["type"] = "icon"; - element["columns"][0]["value"] = "Icon_Auction"; - } - else if (for_sale) - { - element["columns"][0]["column"] = "icon"; - element["columns"][0]["type"] = "icon"; - element["columns"][0]["value"] = "Icon_For_Sale"; - } - else - { - element["columns"][0]["column"] = "icon"; - element["columns"][0]["type"] = "icon"; - element["columns"][0]["value"] = "Icon_Place"; - } - - element["columns"][1]["column"] = "place_name"; - element["columns"][1]["value"] = name; - - content["name"] = name; - - std::string buffer = llformat("%.0f", (F64)dwell); - element["columns"][2]["column"] = "dwell"; - element["columns"][2]["value"] = buffer; - - search_results->addElement(element, ADD_BOTTOM); - self->mResultsContent[parcel_id.asString()] = content; - } - } - if (found_one) - { - search_results->selectFirstItem(); - search_results->setFocus(TRUE); - self->onSelectItem(); - } -} - -//////////////////////////////////////// -// Land Search Panel // -//////////////////////////////////////// - -static LLPanelInjector<FSPanelSearchLand> t_panel_fs_search_land("panel_ls_land"); - -FSPanelSearchLand::FSPanelSearchLand() : FSSearchPanelBase() -, mQueryID(nullptr) -, mStartSearch(0) -, mResultsReceived(0) -, mResultsContent() -{ - mCommitCallbackRegistrar.add("CommitSearch", boost::bind(&FSPanelSearchLand::find, this)); -} - -FSPanelSearchLand::~FSPanelSearchLand() -{ -} - -BOOL FSPanelSearchLand::postBuild() -{ - mSearchResults = getChild<LLScrollListCtrl>("search_results_land"); - mPriceEditor = findChild<LLLineEditor>("price_edit"); - mAreaEditor = findChild<LLLineEditor>("area_edit"); - if (mSearchResults) - { - mSearchResults->setCommitCallback(boost::bind(&FSPanelSearchLand::onSelectItem, this)); - mSearchResults->setEnabled(FALSE); - mSearchResults->setCommentText(LLTrans::getString("no_results")); - } - if (mPriceEditor) - { - mPriceEditor->setCommitOnFocusLost(false); - mPriceEditor->setCommitCallback(boost::bind(&FSPanelSearchLand::onBtnFind, this)); - } - if (mAreaEditor) - { - mAreaEditor->setCommitOnFocusLost(false); - mAreaEditor->setCommitCallback(boost::bind(&FSPanelSearchLand::find, this)); - } - childSetAction("land_find", boost::bind(&FSPanelSearchLand::onBtnFind, this)); - childSetAction("land_next", boost::bind(&FSPanelSearchLand::onBtnNext, this)); - childSetAction("land_back", boost::bind(&FSPanelSearchLand::onBtnBack, this)); - - getChildView("land_next")->setEnabled(FALSE); - getChildView("land_back")->setEnabled(FALSE); - - return TRUE; -} - -void FSPanelSearchLand::find() -{ - static LLUICachedControl<bool> inc_pg("ShowPGLand", 1); - static LLUICachedControl<bool> inc_mature("ShowMatureLand", 0); - static LLUICachedControl<bool> inc_adult("ShowAdultLand", 0); - static LLUICachedControl<bool> limit_price("FindLandPrice", 1); - static LLUICachedControl<bool> limit_area("FindLandArea", 1); - if (!(inc_pg || inc_mature || inc_adult)) - { - LLNotificationsUtil::add("NoContentToSearch"); - return; - } - - U32 category = ST_ALL; - const std::string& selection = findChild<LLComboBox>("land_category")->getSelectedValue().asString(); - if (!selection.empty()) - { - if (selection == "Auction") - { - category = ST_AUCTION; - } - else if (selection == "Mainland") - { - category = ST_MAINLAND; - } - else if (selection == "Estate") - { - category = ST_ESTATE; - } - } - - U32 scope = 0; - if (gAgent.wantsPGOnly()) - { - scope |= DFQ_PG_SIMS_ONLY; - } - bool mature_enabled = gAgent.canAccessMature(); - bool adult_enabled = gAgent.canAccessAdult(); - if (inc_pg) - { - scope |= DFQ_INC_PG; - } - if (inc_mature && mature_enabled) - { - scope |= DFQ_INC_MATURE; - } - if (inc_adult && adult_enabled) - { - scope |= DFQ_INC_ADULT; - } - const std::string& sort = findChild<LLComboBox>("land_sort_combo")->getSelectedValue().asString(); - if (!sort.empty()) - { - if (sort == "Name") - { - scope |= DFQ_NAME_SORT; - } - else if (sort == "Price") - { - scope |= DFQ_PRICE_SORT; - } - else if (sort == "PPM") - { - scope |= DFQ_PER_METER_SORT; - } - else if (sort == "Area") - { - scope |= DFQ_AREA_SORT; - } - } - else - { - scope |= DFQ_PRICE_SORT; - } - if (childGetValue("ascending_check").asBoolean()) - { - scope |= DFQ_SORT_ASC; - } - if (limit_price) - { - scope |= DFQ_LIMIT_BY_PRICE; - } - if (limit_area) - { - scope |= DFQ_LIMIT_BY_AREA; - } - S32 price = childGetValue("edit_price").asInteger(); - S32 area = childGetValue("edit_area").asInteger(); - - mResultsReceived = 0; - if (mQueryID.notNull()) - { - mQueryID.setNull(); - } - mQueryID.generate(); - - if (mStartSearch < 0) - { - mStartSearch = 0; - } - - gMessageSystem->newMessage("DirLandQuery"); - gMessageSystem->nextBlock("AgentData"); - gMessageSystem->addUUID("AgentID", gAgentID); - gMessageSystem->addUUID("SessionID", gAgentSessionID); - gMessageSystem->nextBlock("QueryData"); - gMessageSystem->addUUID("QueryID", getQueryID()); - gMessageSystem->addU32("QueryFlags", scope); - gMessageSystem->addU32("SearchType", category); - gMessageSystem->addS32("Price", price); - gMessageSystem->addS32("Area", area); - gMessageSystem->addS32("QueryStart", mStartSearch); - gAgent.sendReliableMessage(); - LL_DEBUGS("Search") << "Firing off places search request: " << getQueryID() << category << LL_ENDL; - - mSearchResults->deleteAllItems(); - mSearchResults->setCommentText(LLTrans::getString("searching")); - mNumResultsReturned = 0; -} - -void FSPanelSearchLand::onBtnFind() -{ - resetSearch(); - - find(); -} - -void FSPanelSearchLand::onBtnNext() -{ - mStartSearch += RESULT_PAGE_SIZE; - getChildView("land_back")->setEnabled(TRUE); - - find(); -} - -void FSPanelSearchLand::onBtnBack() -{ - mStartSearch -= RESULT_PAGE_SIZE; - getChildView("land_back")->setEnabled(mStartSearch > 0); - - find(); -} - -void FSPanelSearchLand::resetSearch() -{ - mStartSearch = 0; - getChildView("land_back")->setEnabled(FALSE); - getChildView("land_next")->setEnabled(FALSE); -} - -S32 FSPanelSearchLand::showNextButton(S32 rows) -{ - bool show_next_button = (mResultsReceived > RESULT_PAGE_SIZE); - getChildView("land_next")->setEnabled(show_next_button); - if (show_next_button) - { - rows -= (mResultsReceived - RESULT_PAGE_SIZE); - } - return rows; -} - -void FSPanelSearchLand::onSelectItem() -{ - if (!mSearchResults) - { - return; - } - FSFloaterSearch* search_instance = LLFloaterReg::findTypedInstance<FSFloaterSearch>("search"); - if (search_instance) - { - search_instance->FSFloaterSearch::onSelectedItem(mSearchResults->getSelectedValue(), FSFloaterSearch::SC_PLACE); - } -} - -// static -void FSPanelSearchLand::processSearchReply(LLMessageSystem* msg, void**) -{ - LLUUID agent_id; - LLUUID query_id; - LLUUID parcel_id; - std::string name; - std::string land_sku; - std::string land_type; - BOOL auction; - BOOL for_sale; - S32 price; - S32 area; - - msg->getUUID("AgentData", "AgentID", agent_id); - msg->getUUID("QueryData", "QueryID", query_id); - - // Not for us - if (agent_id != gAgentID) - { - return; - } - LL_DEBUGS("Search") << "received directory request - QueryID: " << query_id << " AgentID: " << agent_id << LL_ENDL; - - FSPanelSearchLand* self = FSFloaterSearch::getSearchPanel<FSPanelSearchLand>("panel_ls_land"); - - // floater is closed or these are not results from our last request - if (!self || query_id != self->mQueryID) - { - return; - } - - LLScrollListCtrl* search_results = self->getChild<LLScrollListCtrl>("search_results_land"); - // clear "Searching" label on first results - if (self->mNumResultsReturned++ == 0) - { - search_results->deleteAllItems(); - } - - static LLUICachedControl<bool> use_price("FindLandPrice", 1); - static LLUICachedControl<bool> use_area("FindLandArea", 1); - S32 limit_price = self->childGetValue("edit_price").asInteger(); - S32 limit_area = self->childGetValue("edit_area").asInteger(); - - bool found_one = false; - S32 num_new_rows = msg->getNumberOfBlocks("QueryReplies"); - if (num_new_rows == 0 && self->mResultsReceived == 0) - { - LLStringUtil::format_map_t map; - map["[TEXT]"] = self->getChild<LLUICtrl>("events_edit")->getValue().asString(); - search_results->setEnabled(FALSE); - search_results->setCommentText(LLTrans::getString("not_found", map)); - } - self->mResultsReceived += num_new_rows; - - S32 not_auction = 0; - for (S32 i = 0; i < num_new_rows; i++) - { - msg->getUUID( "QueryReplies", "ParcelID", parcel_id, i); - msg->getString( "QueryReplies", "Name", name, i); - msg->getBOOL( "QueryReplies", "Auction", auction, i); - msg->getBOOL( "QueryReplies", "ForSale", for_sale, i); - msg->getS32( "QueryReplies", "SalePrice", price, i); - msg->getS32( "QueryReplies", "ActualArea", area, i); - if (parcel_id.isNull()) - { - LL_DEBUGS("Search") << "Null result returned for QueryID: " << query_id << LL_ENDL; - search_results->setEnabled(FALSE); - search_results->setCommentText(LLTrans::getString("no_results")); - } - else - { - LL_DEBUGS("Search") << "Got: " << name << " ClassifiedID: " << parcel_id << LL_ENDL; - search_results->setEnabled(TRUE); - found_one = true; - if (msg->getSizeFast(_PREHASH_QueryReplies, i, _PREHASH_ProductSKU) > 0) - { - msg->getStringFast( _PREHASH_QueryReplies, _PREHASH_ProductSKU, land_sku, i); - land_type = LLProductInfoRequestManager::instance().getDescriptionForSku(land_sku); - } - else - { - land_sku.clear(); - land_type = LLTrans::getString("land_type_unknown"); - } - if (parcel_id.isNull()) - { - continue; - } - if (use_price && (price > limit_price)) - { - continue; - } - if (use_area && (area < limit_area)) - { - continue; - } - - LLSD content; - LLSD element; - - element["id"] = parcel_id; - if (auction) - { - element["columns"][0]["column"] = "icon"; - element["columns"][0]["type"] = "icon"; - element["columns"][0]["value"] = "Icon_Auction"; - } - else if (for_sale) - { - element["columns"][0]["column"] = "icon"; - element["columns"][0]["type"] = "icon"; - element["columns"][0]["value"] = "Icon_For_Sale"; - } - else - { - element["columns"][0]["column"] = "icon"; - element["columns"][0]["type"] = "icon"; - element["columns"][0]["value"] = "Icon_Place"; - } - - element["columns"][1]["column"] = "land_name"; - element["columns"][1]["value"] = name; - - content["place_name"] = name; - - std::string buffer = "Auction"; - if (!auction) - { - buffer = llformat("%d", price); - not_auction++; - } - element["columns"][2]["column"] = "price"; - element["columns"][2]["value"] = price; - - element["columns"][3]["column"] = "area"; - element["columns"][3]["value"] = area; - if (!auction) - { - F32 ppm; - if (area > 0) - { - ppm = (F32)price / (F32)area; - } - else - { - ppm = 0.f; - } - std::string ppm_buffer = llformat("%.1f", ppm); - element["columns"][4]["column"] = "ppm"; - element["columns"][4]["value"] = ppm_buffer; - } - else - { - element["columns"][4]["column"] = "ppm"; - element["columns"][4]["value"] = "1.0"; - } - - element["columns"][5]["column"] = "land_type"; - element["columns"][5]["value"] = land_type; - - search_results->addElement(element, ADD_BOTTOM); - self->mResultsContent[parcel_id.asString()] = content; - } - // We test against non-auction properties because they don't count towards the page limit. - self->showNextButton(not_auction); - } - if (found_one) - { - search_results->selectFirstItem(); - search_results->setFocus(TRUE); - self->onSelectItem(); - } -} - -//////////////////////////////////////// -// Classifieds Search Panel // -//////////////////////////////////////// - -static LLPanelInjector<FSPanelSearchClassifieds> t_panel_fs_search_classifieds("panel_ls_classifieds"); - -FSPanelSearchClassifieds::FSPanelSearchClassifieds() : FSSearchPanelBase() -, mQueryID(nullptr) -, mStartSearch(0) -, mResultsReceived(0) -, mResultsContent() -{ - mCommitCallbackRegistrar.add("CommitSearch", boost::bind(&FSPanelSearchClassifieds::find, this)); -} - -FSPanelSearchClassifieds::~FSPanelSearchClassifieds() -{ -} - -BOOL FSPanelSearchClassifieds::postBuild() -{ - mSearchComboBox = findChild<LLSearchComboBox>("classifieds_edit"); - mSearchResults = getChild<LLScrollListCtrl>("search_results_classifieds"); - if (mSearchComboBox) - { - mSearchComboBox->setCommitCallback(boost::bind(&FSPanelSearchClassifieds::onBtnFind, this)); - fillSearchComboBox(mSearchComboBox); - } - if (mSearchResults) - { - mSearchResults->setCommitCallback(boost::bind(&FSPanelSearchClassifieds::onSelectItem, this)); - mSearchResults->setEnabled(FALSE); - mSearchResults->setCommentText(LLTrans::getString("no_results")); - } - - mClassifiedsCategory = getChild<LLComboBox>("classifieds_category"); - if (mClassifiedsCategory) - { - LLClassifiedInfo::cat_map::iterator iter; - mClassifiedsCategory->add(LLTrans::getString("all_categories"), LLSD(0)); - mClassifiedsCategory->addSeparator(); - for (iter = LLClassifiedInfo::sCategories.begin(); - iter != LLClassifiedInfo::sCategories.end(); - iter++) - { - mClassifiedsCategory->add(LLTrans::getString(iter->second), LLSD((S32)iter->first)); - } - } - childSetAction("classifieds_next", boost::bind(&FSPanelSearchClassifieds::onBtnNext, this)); - childSetAction("classifieds_back", boost::bind(&FSPanelSearchClassifieds::onBtnBack, this)); - - getChildView("classifieds_next")->setEnabled(FALSE); - getChildView("classifieds_back")->setEnabled(FALSE); - - return TRUE; -} - -void FSPanelSearchClassifieds::focusDefaultElement() -{ - mSearchComboBox->focusTextEntry(); -} - -void FSPanelSearchClassifieds::find() -{ - std::string text = filterShortWords(mSearchComboBox->getSimple()); - if (text.size() == 0) - { - mSearchResults->setCommentText(LLTrans::getString("search_short")); - return; - } - - static LLUICachedControl<bool> inc_pg("ShowPGClassifieds", 1); - static LLUICachedControl<bool> inc_mature("ShowMatureClassifieds", 0); - static LLUICachedControl<bool> inc_adult("ShowAdultClassifieds", 0); - if (!(inc_pg || inc_mature || inc_adult)) - { - LLNotificationsUtil::add("NoContentToSearch"); - return; - } - U32 category = mClassifiedsCategory->getValue().asInteger(); - BOOL auto_renew = FALSE; - U32 flags = pack_classified_flags_request(auto_renew, inc_pg, inc_mature, inc_adult); - - mResultsReceived = 0; - if (mQueryID.notNull()) - { - mQueryID.setNull(); - } - mQueryID.generate(); - - if (mStartSearch < 0) - { - mStartSearch = 0; - } - - gMessageSystem->newMessageFast(_PREHASH_DirClassifiedQuery); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgentID); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgentSessionID); - gMessageSystem->nextBlockFast(_PREHASH_QueryData); - gMessageSystem->addUUIDFast(_PREHASH_QueryID, getQueryID()); - gMessageSystem->addStringFast(_PREHASH_QueryText, text); - gMessageSystem->addU32Fast(_PREHASH_QueryFlags, flags); - gMessageSystem->addU32Fast(_PREHASH_Category, category); - gMessageSystem->addS32Fast(_PREHASH_QueryStart, mStartSearch); - gAgent.sendReliableMessage(); - LL_DEBUGS("Search") << "Firing off classified ad search request: " << getQueryID() << LL_ENDL; - - mSearchResults->deleteAllItems(); - mSearchResults->setCommentText(LLTrans::getString("searching")); - mNumResultsReturned = 0; -} - -void FSPanelSearchClassifieds::onBtnFind() -{ - std::string text = mSearchComboBox->getSimple(); - if (!text.empty()) - { - LLSearchHistory::getInstance()->addEntry(text); - } - - resetSearch(); - - find(); -} - -void FSPanelSearchClassifieds::onBtnNext() -{ - mStartSearch += RESULT_PAGE_SIZE; - getChildView("classifieds_back")->setEnabled(TRUE); - - find(); -} - -void FSPanelSearchClassifieds::onBtnBack() -{ - mStartSearch -= RESULT_PAGE_SIZE; - getChildView("classifieds_back")->setEnabled(mStartSearch > 0); - - find(); -} - -void FSPanelSearchClassifieds::resetSearch() -{ - mStartSearch = 0; - getChildView("classifieds_back")->setEnabled(FALSE); - getChildView("classifieds_next")->setEnabled(FALSE); -} - -S32 FSPanelSearchClassifieds::showNextButton(S32 rows) -{ - bool show_next_button = (mResultsReceived > RESULT_PAGE_SIZE); - getChildView("classifieds_next")->setEnabled(show_next_button); - if (show_next_button) - { - rows -= (mResultsReceived - RESULT_PAGE_SIZE); - } - return rows; -} - -void FSPanelSearchClassifieds::onSelectItem() -{ - if (!mSearchResults) - { - return; - } - FSFloaterSearch* search_instance = LLFloaterReg::findTypedInstance<FSFloaterSearch>("search"); - if (search_instance) - { - search_instance->FSFloaterSearch::onSelectedItem(mSearchResults->getSelectedValue(), FSFloaterSearch::SC_CLASSIFIED); - } -} - -// static -void FSPanelSearchClassifieds::processSearchReply(LLMessageSystem* msg, void**) -{ - LLUUID agent_id; - LLUUID query_id; - LLUUID classified_id; - std::string name; - U32 creation_date; - U32 expiration_date; - S32 price_for_listing; - - msg->getUUID("AgentData", "AgentID", agent_id); - msg->getUUID("QueryData", "QueryID", query_id); - - // Not for us - if (agent_id != gAgentID) - { - return; - } - LL_DEBUGS("Search") << "received directory request - QueryID: " << query_id << " AgentID: " << agent_id << LL_ENDL; - - FSPanelSearchClassifieds* self = FSFloaterSearch::getSearchPanel<FSPanelSearchClassifieds>("panel_ls_classifieds"); - - if (msg->getNumberOfBlocks("StatusData")) - { - U32 status; - msg->getU32("StatusData", "Status", status); - if (status & STATUS_SEARCH_CLASSIFIEDS_BANNEDWORD) - { - LLNotificationsUtil::add("SearchWordBanned"); - } - } - - // floater is closed or these are not results from our last request - if (!self || query_id != self->mQueryID) - { - return; - } - - LLScrollListCtrl* search_results = self->getChild<LLScrollListCtrl>("search_results_classifieds"); - - // Clear "Searching" label on first results - if (self->mNumResultsReturned++ == 0) - { - search_results->deleteAllItems(); - } - - // Check for status messages - if (msg->getNumberOfBlocks("StatusData")) - { - U32 status; - msg->getU32("StatusData", "Status", status); - if (status & STATUS_SEARCH_PLACES_FOUNDNONE) - { - LLStringUtil::format_map_t map; - map["[TEXT]"] = self->getChild<LLUICtrl>("classifieds_edit")->getValue().asString(); - search_results->setEnabled(FALSE); - search_results->setCommentText(LLTrans::getString("not_found", map)); - return; - } - else if(status & STATUS_SEARCH_PLACES_SHORTSTRING) - { - search_results->setEnabled(FALSE); - search_results->setCommentText(LLTrans::getString("search_short")); - return; - } - else if (status & STATUS_SEARCH_CLASSIFIEDS_BANNEDWORD) - { - search_results->setEnabled(FALSE); - search_results->setCommentText(LLTrans::getString("search_banned")); - return; - } - else if (status & STATUS_SEARCH_PLACES_SEARCHDISABLED) - { - search_results->setEnabled(FALSE); - search_results->setCommentText(LLTrans::getString("search_disabled")); - return; - } - } - - bool found_one = false; - S32 num_new_rows = msg->getNumberOfBlocks("QueryReplies"); - if (num_new_rows == 0 && self->mResultsReceived == 0) - { - LLStringUtil::format_map_t map; - map["[TEXT]"] = self->getChild<LLUICtrl>("classifieds_edit")->getValue().asString(); - search_results->setEnabled(FALSE); - search_results->setCommentText(LLTrans::getString("not_found", map)); - } - self->mResultsReceived += num_new_rows; - num_new_rows = self->showNextButton(num_new_rows); - - for (S32 i = 0; i < num_new_rows; i++) - { - msg->getUUID( "QueryReplies", "ClassifiedID", classified_id, i); - msg->getString( "QueryReplies", "Name", name, i); - msg->getU32( "QueryReplies", "CreationDate", creation_date, i); - msg->getU32( "QueryReplies", "ExpirationDate", expiration_date,i); - msg->getS32( "QueryReplies", "PriceForListing", price_for_listing,i); - if (classified_id.isNull()) - { - LL_DEBUGS("Search") << "Null result returned for QueryID: " << query_id << LL_ENDL; - LLStringUtil::format_map_t map; - map["[TEXT]"] = self->getChild<LLUICtrl>("classifieds_edit")->getValue().asString(); - search_results->setEnabled(FALSE); - search_results->setCommentText(LLTrans::getString("not_found", map)); - } - else - { - LL_DEBUGS("Search") << "Got: " << name << " ClassifiedID: " << classified_id << LL_ENDL; - search_results->setEnabled(TRUE); - found_one = true; - - LLSD content; - LLSD element; - - element["id"] = classified_id; - - element["columns"][0]["column"] = "icon"; - element["columns"][0]["type"] = "icon"; - element["columns"][0]["value"] = "icon_top_pick.tga"; - - element["columns"][1]["column"] = "classified_name"; - element["columns"][1]["value"] = name; - - element["columns"][2]["column"] = "price"; - element["columns"][2]["value"] = price_for_listing; - - content["name"] = name; - - search_results->addElement(element, ADD_BOTTOM); - self->mResultsContent[classified_id.asString()] = content; - } - } - if (found_one) - { - search_results->selectFirstItem(); - search_results->setFocus(TRUE); - self->onSelectItem(); - } -} - -//////////////////////////////////////// -// Events Search Panel // -//////////////////////////////////////// - -static LLPanelInjector<FSPanelSearchEvents> t_panel_fs_search_events("panel_ls_events"); - -FSPanelSearchEvents::FSPanelSearchEvents() : FSSearchPanelBase() -, mQueryID(nullptr) -, mResultsReceived(0) -, mStartSearch(0) -, mDay(0) -, mResultsContent() -{ - mCommitCallbackRegistrar.add("CommitSearch", boost::bind(&FSPanelSearchEvents::find, this)); -} - -FSPanelSearchEvents::~FSPanelSearchEvents() -{ -} - -BOOL FSPanelSearchEvents::postBuild() -{ - mSearchComboBox = findChild<LLSearchComboBox>("events_edit"); - mSearchResults = getChild<LLScrollListCtrl>("search_results_events"); - mEventsMode = findChild<LLRadioGroup>("events_search_mode"); - if (mSearchComboBox) - { - mSearchComboBox->setCommitCallback(boost::bind(&FSPanelSearchEvents::onBtnFind, this)); - fillSearchComboBox(mSearchComboBox); - } - if (mSearchResults) - { - mSearchResults->setCommitCallback(boost::bind(&FSPanelSearchEvents::onSelectItem, this)); - mSearchResults->setEnabled(FALSE); - mSearchResults->setCommentText(LLTrans::getString("no_results")); - } - if (mEventsMode) - { - mEventsMode->setCommitCallback(boost::bind(&FSPanelSearchEvents::onSearchModeChanged, this)); - mEventsMode->selectFirstItem(); - } - - childSetAction("events_next", boost::bind(&FSPanelSearchEvents::onBtnNext, this)); - childSetAction("events_back", boost::bind(&FSPanelSearchEvents::onBtnBack, this)); - childSetAction("events_tomorrow", boost::bind(&FSPanelSearchEvents::onBtnTomorrow, this)); - childSetAction("events_yesterday", boost::bind(&FSPanelSearchEvents::onBtnYesterday, this)); - childSetAction("events_today", boost::bind(&FSPanelSearchEvents::onBtnToday, this)); - - getChildView("events_next")->setEnabled(FALSE); - getChildView("events_back")->setEnabled(FALSE); - getChildView("events_tomorrow")->setEnabled(FALSE); - getChildView("events_yesterday")->setEnabled(FALSE); - getChildView("events_today")->setEnabled(FALSE); - setDay(0); - - return TRUE; -} - -void FSPanelSearchEvents::focusDefaultElement() -{ - mSearchComboBox->focusTextEntry(); -} - -void FSPanelSearchEvents::find() -{ - std::string text = filterShortWords(mSearchComboBox->getSimple()); - - static LLUICachedControl<bool> inc_pg("ShowPGEvents", 1); - static LLUICachedControl<bool> inc_mature("ShowMatureEvents", 0); - static LLUICachedControl<bool> inc_adult("ShowAdultEvents", 0); - if (!(inc_pg || inc_mature || inc_adult)) - { - LLNotificationsUtil::add("NoContentToSearch"); - return; - } - - U32 category = findChild<LLComboBox>("events_category")->getSelectedValue().asInteger(); - U32 scope = DFQ_DATE_EVENTS; - if (gAgent.wantsPGOnly()) - { - scope |= DFQ_PG_SIMS_ONLY; - } - bool mature_enabled = gAgent.canAccessMature(); - bool adult_enabled = gAgent.canAccessAdult(); - if (inc_pg) - { - scope |= DFQ_INC_PG; - } - if (inc_mature && mature_enabled) - { - scope |= DFQ_INC_MATURE; - } - if (inc_adult && adult_enabled) - { - scope |= DFQ_INC_ADULT; - } - - std::ostringstream string; - - if ("current" == childGetValue("events_search_mode").asString()) - { - string << "u|"; - } - else - { - string << mDay << "|"; - } - string << category << "|"; - string << text; - - mResultsReceived = 0; - if (mQueryID.notNull()) - { - mQueryID.setNull(); - } - mQueryID.generate(); - - if (mStartSearch < 0) - { - mStartSearch = 0; - } - - gMessageSystem->newMessage("DirFindQuery"); - gMessageSystem->nextBlock("AgentData"); - gMessageSystem->addUUID("AgentID", gAgentID); - gMessageSystem->addUUID("SessionID", gAgentSessionID); - gMessageSystem->nextBlock("QueryData"); - gMessageSystem->addUUID("QueryID", getQueryID()); - gMessageSystem->addString("QueryText", string.str()); - gMessageSystem->addU32("QueryFlags", scope); - gMessageSystem->addS32("QueryStart", mStartSearch); - gAgent.sendReliableMessage(); - LL_DEBUGS("Search") << "Firing off search request: " << getQueryID() << " Search Text: " << string.str() << LL_ENDL; - - mSearchResults->deleteAllItems(); - mSearchResults->setCommentText(LLTrans::getString("searching")); - mNumResultsReturned = 0; -} - -void FSPanelSearchEvents::onBtnFind() -{ - std::string text = mSearchComboBox->getSimple(); - if (!text.empty()) - { - LLSearchHistory::getInstance()->addEntry(text); - } - - resetSearch(); - - find(); -} - -void FSPanelSearchEvents::onBtnNext() -{ - mStartSearch += RESULT_PAGE_SIZE; - getChildView("events_back")->setEnabled(TRUE); - - find(); -} - -void FSPanelSearchEvents::onBtnBack() -{ - mStartSearch -= RESULT_PAGE_SIZE; - getChildView("events_back")->setEnabled(mStartSearch > 0); - - find(); -} - -void FSPanelSearchEvents::onBtnTomorrow() -{ - resetSearch(); - setDay(mDay + 1); - - find(); -} - -void FSPanelSearchEvents::onBtnYesterday() -{ - resetSearch(); - setDay(mDay - 1); - - find(); -} - -void FSPanelSearchEvents::onBtnToday() -{ - resetSearch(); - setDay(0); - - find(); -} - -void FSPanelSearchEvents::resetSearch() -{ - mStartSearch = 0; - getChildView("events_back")->setEnabled(FALSE); - getChildView("events_next")->setEnabled(FALSE); -} - -void FSPanelSearchEvents::onSearchModeChanged() -{ - if (mEventsMode->getValue().asString() == "current") - { - getChildView("events_yesterday")->setEnabled(FALSE); - getChildView("events_tomorrow")->setEnabled(FALSE); - getChildView("events_today")->setEnabled(FALSE); - } - else - { - getChildView("events_yesterday")->setEnabled(TRUE); - getChildView("events_tomorrow")->setEnabled(TRUE); - getChildView("events_today")->setEnabled(TRUE); - } -} - -void FSPanelSearchEvents::setDay(S32 day) -{ - mDay = day; - struct tm* internal_time; - - time_t utc = time_corrected(); - utc += day * 24 * 60 * 60; - internal_time = utc_to_pacific_time(utc, is_daylight_savings()); - std::string buffer = llformat("%d/%d", 1 + internal_time->tm_mon, internal_time->tm_mday); - childSetValue("events_date", buffer); -} - -S32 FSPanelSearchEvents::showNextButton(S32 rows) -{ - bool show_next_button = (mResultsReceived > RESULT_PAGE_SIZE); - getChildView("events_next")->setEnabled(show_next_button); - if (show_next_button) - { - rows -= (mResultsReceived - RESULT_PAGE_SIZE); - } - return rows; -} - -void FSPanelSearchEvents::onSelectItem() -{ - if (!mSearchResults) - { - return; - } - S32 event_id = mSearchResults->getSelectedValue(); - FSFloaterSearch* search_instance = LLFloaterReg::findTypedInstance<FSFloaterSearch>("search"); - if (search_instance) - { - search_instance->FSFloaterSearch::onSelectedEvent(event_id); - } -} - -// static -void FSPanelSearchEvents::processSearchReply(LLMessageSystem* msg, void**) -{ - LLUUID agent_id; - LLUUID query_id; - LLUUID owner_id; - std::string name; - std::string date; - - msg->getUUID("AgentData", "AgentID", agent_id); - msg->getUUID("QueryData", "QueryID", query_id); - - // Not for us - if (agent_id != gAgentID) - { - return; - } - LL_DEBUGS("Search") << "received directory request - QueryID: " << query_id << " AgentID: " << agent_id << LL_ENDL; - - FSPanelSearchEvents* self = FSFloaterSearch::getSearchPanel<FSPanelSearchEvents>("panel_ls_events"); - - // floater is closed or these are not results from our last request - if (!self || query_id != self->mQueryID) - { - return; - } - - LLScrollListCtrl* search_results = self->getChild<LLScrollListCtrl>("search_results_events"); - - // Clear "Searching" label on first results - if (self->mNumResultsReturned++ == 0) - { - search_results->deleteAllItems(); - } - // Check for status messages - if (msg->getNumberOfBlocks("StatusData")) - { - U32 status; - msg->getU32("StatusData", "Status", status); - if (status & STATUS_SEARCH_EVENTS_FOUNDNONE) - { - LLStringUtil::format_map_t map; - map["[TEXT]"] = self->getChild<LLUICtrl>("events_edit")->getValue().asString(); - search_results->setEnabled(FALSE); - search_results->setCommentText(LLTrans::getString("not_found", map)); - return; - } - else if(status & STATUS_SEARCH_EVENTS_SHORTSTRING) - { - search_results->setEnabled(FALSE); - search_results->setCommentText(LLTrans::getString("search_short")); - return; - } - else if (status & STATUS_SEARCH_EVENTS_BANNEDWORD) - { - search_results->setEnabled(FALSE); - search_results->setCommentText(LLTrans::getString("search_banned")); - return; - } - else if (status & STATUS_SEARCH_EVENTS_SEARCHDISABLED) - { - search_results->setEnabled(FALSE); - search_results->setCommentText(LLTrans::getString("search_disabled")); - return; - } - else if (status & STATUS_SEARCH_EVENTS_NODATEOFFSET) - { - search_results->setEnabled(FALSE); - search_results->setCommentText(LLTrans::getString("search_no_date_offset")); - return; - } - else if (status & STATUS_SEARCH_EVENTS_NOCATEGORY) - { - search_results->setEnabled(FALSE); - search_results->setCommentText(LLTrans::getString("search_no_events_category")); - return; - } - else if (status & STATUS_SEARCH_EVENTS_NOQUERY) - { - search_results->setEnabled(FALSE); - search_results->setCommentText(LLTrans::getString("search_no_query")); - return; - } - } - - S32 num_new_rows = msg->getNumberOfBlocks("QueryReplies"); - if (num_new_rows == 0 && self->mResultsReceived == 0) - { - LLStringUtil::format_map_t map; - map["[TEXT]"] = self->getChild<LLUICtrl>("events_edit")->getValue().asString(); - search_results->setEnabled(FALSE); - search_results->setCommentText(LLTrans::getString("not_found", map)); - } - - self->mResultsReceived += num_new_rows; - num_new_rows = self->showNextButton(num_new_rows); - static LLUICachedControl<bool> inc_pg("ShowPGEvents", 1); - static LLUICachedControl<bool> inc_mature("ShowMatureEvents", 0); - static LLUICachedControl<bool> inc_adult("ShowAdultEvents", 0); - bool found_one = false; - - for (S32 i = 0; i < num_new_rows; i++) - { - U32 event_id; - U32 unix_time; - U32 event_flags; - - msg->getUUID( "QueryReplies", "OwnerID", owner_id, i); - msg->getString( "QueryReplies", "Name", name, i); - msg->getU32( "QueryReplies", "EventID", event_id, i); - msg->getString( "QueryReplies", "Date", date, i); - msg->getU32( "QueryReplies", "UnixTime", unix_time, i); - msg->getU32( "QueryReplies", "EventFlags", event_flags,i); - - // Skip empty events... - if (owner_id.isNull()) - { - LL_INFOS("Search") << "Skipped " << event_id << " because of a nullptr owner result" << LL_ENDL; - continue; - } - // Skips events that don't match our scope... - if (((event_flags & (EVENT_FLAG_ADULT | EVENT_FLAG_MATURE)) == EVENT_FLAG_NONE) && !inc_pg) - { - LL_INFOS("Search") << "Skipped " << event_id << " because it was out of scope" << LL_ENDL; - continue; - } - if ((event_flags & EVENT_FLAG_MATURE) && !inc_mature) - { - LL_INFOS("Search") << "Skipped " << event_id << " because it was out of scope" << LL_ENDL; - continue; - } - if ((event_flags & EVENT_FLAG_ADULT) && !inc_adult) - { - LL_INFOS("Search") << "Skipped " << event_id << " because it was out of scope" << LL_ENDL; - continue; - } - search_results->setEnabled(TRUE); - found_one = true; - - LLSD content; - LLSD element; - - element["id"] = llformat("%u", event_id); - - if (event_flags == EVENT_FLAG_ADULT) - { - element["columns"][0]["column"] = "icon"; - element["columns"][0]["type"] = "icon"; - element["columns"][0]["value"] = "Icon_Legacy_Event_Adult"; - } - else if (event_flags == EVENT_FLAG_MATURE) - { - element["columns"][0]["column"] = "icon"; - element["columns"][0]["type"] = "icon"; - element["columns"][0]["value"] = "Icon_Legacy_Event_Mature"; - } - else - { - element["columns"][0]["column"] = "icon"; - element["columns"][0]["type"] = "icon"; - element["columns"][0]["value"] = "Icon_Legacy_Event_PG"; - } - element["columns"][1]["column"] = "name"; - element["columns"][1]["value"] = name; - - element["columns"][2]["column"] = "date"; - element["columns"][2]["value"] = date; - - element["columns"][3]["column"] = "time"; - element["columns"][3]["value"] = llformat("%u", unix_time); - - content["name"] = name; - content["event_id"] = (S32)event_id; - - search_results->addElement(element, ADD_BOTTOM); - std::string event = llformat("%u", event_id); - self->mResultsContent[event] = content; - } - if (found_one) - { - search_results->selectFirstItem(); - search_results->setFocus(TRUE); - self->onSelectItem(); - } -} - -//////////////////////////////////////// -// WebSearch Panel // -//////////////////////////////////////// - -static LLPanelInjector<FSPanelSearchWeb> t_panel_fs_search_web("panel_ls_web"); - -FSPanelSearchWeb::FSPanelSearchWeb() : FSSearchPanelBase() -, mWebBrowser(nullptr) -, mResetFocusOnLoad(false) -{ - // Second Life grids use a different URL format now - mCategoryPaths = LLSD::emptyMap(); - if (LLGridManager::getInstance()->isInSecondlife()) - { - // declare a map that transforms a category name into - // the parameter list that is used to search that category - mCategoryPaths["people"] = "collection_chosen=people"; - mCategoryPaths["places"] = "collection_chosen=places"; - mCategoryPaths["events"] = "collection_chosen=events"; - mCategoryPaths["groups"] = "collection_chosen=groups"; - mCategoryPaths["destinations"] = "collection_chosen=destinations"; - - mCategoryPaths["classifieds"] = "search_type=classified"; - mCategoryPaths["wiki"] = "search/wiki"; // not sure if this is still a thing in the new search - - mCategoryPaths["all"] = mCategoryPaths["people"].asString() + "&" + - mCategoryPaths["places"].asString() + "&" + - mCategoryPaths["events"].asString() + "&" + - mCategoryPaths["groups"].asString() + "&" + - mCategoryPaths["destinations"].asString(); - } - // OpenSim currently still uses the old URL format - else - { - // declare a map that transforms a category name into - // the URL suffix that is used to search that category - mCategoryPaths["all"] = "search"; - mCategoryPaths["people"] = "search/people"; - mCategoryPaths["places"] = "search/places"; - mCategoryPaths["events"] = "search/events"; - mCategoryPaths["groups"] = "search/groups"; - mCategoryPaths["wiki"] = "search/wiki"; - mCategoryPaths["destinations"] = "destinations"; - mCategoryPaths["classifieds"] = "classifieds"; - } -} - -BOOL FSPanelSearchWeb::postBuild() -{ - mWebBrowser = getChild<LLMediaCtrl>("search_browser"); - return TRUE; -} - -void FSPanelSearchWeb::loadURL(const SearchQuery &p) -{ - if (!mWebBrowser || !p.validateBlock()) - { - return; - } - - // CATEGORY is no longer used as part of the path on Second Life grids - LLSD subs = LLSD().with("CATEGORY", ""); - - // on OpenSim grids it probably is currently still being used, so keep the old behavior - if (!LLGridManager::getInstance()->isInSecondlife()) - { - // work out the subdir to use based on the requested category - LLSD subs = LLSD().with("CATEGORY", (mCategoryPaths.has(p.category.getValue()) ? mCategoryPaths[p.category.getValue()].asString() : mCategoryPaths["all"].asString())); - } - - // add the search query string - subs["QUERY"] = LLURI::escape(p.query.getValue()); - - // add the permissions token that login.cgi gave us - // We use "search_token", and fallback to "auth_token" if not present. - LLSD search_token = LLLoginInstance::getInstance()->getResponse("search_token"); - if (search_token.asString().empty()) - { - search_token = LLLoginInstance::getInstance()->getResponse("auth_token"); - } - subs["AUTH_TOKEN"] = search_token.asString(); - - // add the user's preferred maturity (can be changed via prefs) - std::string maturity; - - // on Second Life grids, the maturity level is now a "&maturity" parameter that's not in the provided search URL - if (LLGridManager::getInstance()->isInSecondlife()) - { - if (gAgent.prefersAdult()) - { - maturity = "gma"; // PG,Mature,Adult - } - else if (gAgent.prefersMature()) - { - maturity = "gm"; // PG,Mature - } - else - { - maturity = "g"; // PG - } - - // not used on the SL search anymore, so clear out the respective parameter - subs["MATURITY"] = ""; - } - // OpenSim probably still uses the old maturity variant, so keep the old behavior here - else - { - if (gAgent.prefersAdult()) - { - maturity = "42"; // PG,Mature,Adult - } - else if (gAgent.prefersMature()) - { - maturity = "21"; // PG,Mature - } - else - { - maturity = "13"; // PG - } - subs["MATURITY"] = maturity; - } - - // add the user's god status - subs["GODLIKE"] = gAgent.isGodlike() ? "1" : "0"; - - // Get the search URL and expand all of the substitutions - // (also adds things like [LANGUAGE], [VERSION], [OS], etc.) - - // add the maturity and category variables to the new Second Life search URL - std::string url = gAgent.getRegion() != nullptr ? gAgent.getRegion()->getSearchServerURL() - : gSavedSettings.getString(LLGridManager::getInstance()->isInOpenSim() ? "OpenSimSearchURL" : "SearchURL"); - if (LLGridManager::getInstance()->isInSecondlife()) - { - url.append("&maturity=" + maturity + "&" + mCategoryPaths[p.category.getValue()].asString()); - } - - url = LLWeb::expandURLSubstitutions(url, subs); - - // Finally, load the URL in the webpanel - mWebBrowser->navigateTo(url, HTTP_CONTENT_TEXT_HTML); -} - -void FSPanelSearchWeb::focusDefaultElement() -{ - mWebBrowser->setFocus(TRUE); -} - -void FSPanelSearchWeb::draw() -{ - if (mResetFocusOnLoad) - { - focusDefaultElement(); - mResetFocusOnLoad = false; - } - - FSSearchPanelBase::draw(); -} - -//////////////////////////////////////// -// Local functions // -//////////////////////////////////////// - -std::string filterShortWords(std::string query_string) -{ - if (query_string.length() < 1) - { - return ""; - } - - std::string final_query; - bool filtered = false; - boost::char_separator<char> sep(" "); - boost::tokenizer<boost::char_separator<char> > tokens(query_string, sep); - boost::tokenizer<boost::char_separator<char> >::iterator iter = tokens.begin(); - boost::tokenizer<boost::char_separator<char> >::iterator last = tokens.end(); - boost::tokenizer<boost::char_separator<char> >::iterator temp; - for (; iter != last; ++iter) - { - if ((*iter).length() > MIN_SEARCH_STRING_SIZE) - { - final_query.append((*iter)); - temp = iter; ++temp; - if (temp != last) - { - final_query.append(" "); - } - } - else - { - filtered = true; - } - } - - if (filtered) - { - LLSD args = LLSD().with("FINALQUERY", final_query); - LLNotificationsUtil::add("SeachFilteredOnShortWords", args); - } - - return final_query; -} - -void fillSearchComboBox(LLSearchComboBox* search_combo) -{ - if (search_combo == nullptr) - { - return; - } - - LLSearchHistory::getInstance()->load(); - - LLSearchHistory::search_history_list_t search_list = - LLSearchHistory::getInstance()->getSearchHistoryList(); - LLSearchHistory::search_history_list_t::const_iterator it = search_list.begin(); - for ( ; search_list.end() != it; ++it) - { - LLSearchHistory::LLSearchHistoryItem item = *it; - search_combo->add(item.search_query); - } -} diff --git a/indra/newview/fsfloatersearch.h b/indra/newview/fsfloatersearch.h deleted file mode 100644 index 61cef8bab9847d5edb1db338e6e6cee776f6f732..0000000000000000000000000000000000000000 --- a/indra/newview/fsfloatersearch.h +++ /dev/null @@ -1,404 +0,0 @@ -/** - * @file fsfloatersearch.h - * @brief Firestorm search definitions - * - * $LicenseInfo:firstyear=2012&license=fsviewerlgpl$ - * Phoenix Firestorm Viewer Source Code - * Copyright (C) 2012, Cinder Roxley <cinder.roxley@phoenixviewer.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA - * http://www.firestormviewer.org - * $/LicenseInfo$ - */ - -#ifndef FS_FLOATERSEARCH_H -#define FS_FLOATERSEARCH_H - -#include "llfloater.h" -#include "lliconctrl.h" -#include "lltexteditor.h" -#include "lltexturectrl.h" -#include "llremoteparcelrequest.h" -#include "llavatarpropertiesprocessor.h" -#include "llgroupmgr.h" -#include "llavatarnamecache.h" -#include "llmediactrl.h" -#include "llradiogroup.h" -#include "llsearchcombobox.h" -#include "llscrolllistctrl.h" -#include "lltabcontainer.h" -#include "lleventnotifier.h" - -class FSSearchRemoteParcelInfoObserver; -class LLAvatarPropertiesObserver; -class LLGroupMgrObserver; -class LLSearchEditor; -class LLSearchComboBox; -class FSFloaterSearch; -class LLPanelProfile; -class FSScrollListCtrl; - -struct SearchQuery : public LLInitParam::Block<SearchQuery> -{ - Optional<std::string> category; - Optional<std::string> query; - - SearchQuery(); -}; - -/////////////////////////////// -// Search Panels // -/////////////////////////////// - -class FSSearchPanelBase : public LLPanel -{ -public: - FSSearchPanelBase() : LLPanel() { } - virtual ~FSSearchPanelBase() = default; - virtual void focusDefaultElement() { } -}; - -class FSPanelSearchPeople : public FSSearchPanelBase -{ - LOG_CLASS(FSFloaterSearch); -public: - FSPanelSearchPeople(); - static void processSearchReply(LLMessageSystem* msg, void**); - - /*virtual*/ void focusDefaultElement(); - -protected: - const S32& getNumResultsReturned() const { return mNumResultsReturned; }; - const S32& getNumResultsReceived() const { return mResultsReceived; }; - -private: - /*virtual*/ BOOL postBuild(); - virtual ~FSPanelSearchPeople(); - - void onBtnFind(); - void onSelectItem(); - void onBtnNext(); - void onBtnBack(); - - void find(); - void resetSearch(); - S32 showNextButton(S32); - - const LLUUID& getQueryID() const { return mQueryID; } - - void onAvatarNameCallback(const LLUUID& id, const LLAvatarName& av_name); - - typedef boost::signals2::connection avatar_name_callback_connection_t; - avatar_name_callback_connection_t mAvatarNameCallbackConnection; - - S32 mNumResultsReturned; - S32 mStartSearch; - S32 mResultsReceived; - LLSD mResultsContent; - LLUUID mQueryID; - - LLSearchComboBox* mSearchComboBox; - LLScrollListCtrl* mSearchResults; -}; - -class FSPanelSearchGroups : public FSSearchPanelBase -{ - LOG_CLASS(FSFloaterSearch); -public: - FSPanelSearchGroups(); - static void processSearchReply(LLMessageSystem* msg, void**); - - /*virtual*/ void focusDefaultElement(); - -private: - /*virtual*/ BOOL postBuild(); - virtual ~FSPanelSearchGroups(); - - void onBtnFind(); - void onSelectItem(); - void onBtnNext(); - void onBtnBack(); - - void find(); - void resetSearch(); - S32 showNextButton(S32); - - const LLUUID& getQueryID() const { return mQueryID; } - - S32 mNumResultsReturned; - S32 mStartSearch; - S32 mResultsReceived; - LLSD mResultsContent; - LLUUID mQueryID; - - LLSearchComboBox* mSearchComboBox; - LLScrollListCtrl* mSearchResults; -}; - -class FSPanelSearchPlaces : public FSSearchPanelBase -{ - LOG_CLASS(FSFloaterSearch); -public: - FSPanelSearchPlaces(); - static void processSearchReply(LLMessageSystem* msg, void**); - - /*virtual*/ void focusDefaultElement(); - -private: - /*virtual*/ BOOL postBuild(); - virtual ~FSPanelSearchPlaces(); - - void onBtnFind(); - void onSelectItem(); - void onBtnNext(); - void onBtnBack(); - - void find(); - void resetSearch(); - S32 showNextButton(S32); - - const LLUUID& getQueryID() const { return mQueryID; } - - S32 mNumResultsReturned; - S32 mStartSearch; - S32 mResultsReceived; - LLSD mResultsContent; - LLUUID mQueryID; - - LLSearchComboBox* mSearchComboBox; - LLScrollListCtrl* mSearchResults; - LLComboBox* mPlacesCategory; -}; - -class FSPanelSearchLand : public FSSearchPanelBase -{ - LOG_CLASS(FSFloaterSearch); -public: - FSPanelSearchLand(); - static void processSearchReply(LLMessageSystem* msg, void**); - -private: - /*virtual*/ BOOL postBuild(); - virtual ~FSPanelSearchLand(); - - void onBtnFind(); - void onSelectItem(); - void onBtnNext(); - void onBtnBack(); - - void find(); - void resetSearch(); - S32 showNextButton(S32); - - const LLUUID& getQueryID() const { return mQueryID; } - - S32 mNumResultsReturned; - S32 mStartSearch; - S32 mResultsReceived; - LLSD mResultsContent; - LLUUID mQueryID; - - LLLineEditor* mPriceEditor; - LLLineEditor* mAreaEditor; - LLScrollListCtrl* mSearchResults; -}; - -class FSPanelSearchClassifieds : public FSSearchPanelBase -{ - LOG_CLASS(FSFloaterSearch); -public: - FSPanelSearchClassifieds(); - static void processSearchReply(LLMessageSystem* msg, void**); - - /*virtual*/ void focusDefaultElement(); - -private: - /*virtual*/ BOOL postBuild(); - virtual ~FSPanelSearchClassifieds(); - - void onBtnFind(); - void onSelectItem(); - void onBtnNext(); - void onBtnBack(); - - void find(); - void resetSearch(); - S32 showNextButton(S32); - - const LLUUID& getQueryID() const { return mQueryID; } - - S32 mNumResultsReturned; - S32 mStartSearch; - S32 mResultsReceived; - LLSD mResultsContent; - LLUUID mQueryID; - - LLSearchComboBox* mSearchComboBox; - LLScrollListCtrl* mSearchResults; - LLComboBox* mClassifiedsCategory; -}; - -class FSPanelSearchEvents : public FSSearchPanelBase -{ - LOG_CLASS(FSFloaterSearch); -public: - FSPanelSearchEvents(); - static void processSearchReply(LLMessageSystem* msg, void**); - - /*virtual*/ void focusDefaultElement(); - -private: - /*virtual*/ BOOL postBuild(); - virtual ~FSPanelSearchEvents(); - - void onBtnFind(); - void onSelectItem(); - void onBtnNext(); - void onBtnBack(); - void onBtnTomorrow(); - void onBtnYesterday(); - void onBtnToday(); - - void find(); - void setDay(S32 day); - void onSearchModeChanged(); - void resetSearch(); - S32 showNextButton(S32); - - const LLUUID& getQueryID() const { return mQueryID; } - - S32 mNumResultsReturned; - S32 mResultsReceived; - S32 mStartSearch; - S32 mDay; - LLSD mResultsContent; - LLUUID mQueryID; - - LLSearchComboBox* mSearchComboBox; - LLScrollListCtrl* mSearchResults; - LLRadioGroup* mEventsMode; -}; - -class FSPanelSearchWeb : public FSSearchPanelBase -{ - LOG_CLASS(FSFloaterSearch); -public: - FSPanelSearchWeb(); - /*virtual*/ BOOL postBuild(); - void loadURL(const SearchQuery &query); - /*virtual*/ void focusDefaultElement(); - /*virtual*/ void draw(); - void resetFocusOnLoad() { mResetFocusOnLoad = true; } - -private: - virtual ~FSPanelSearchWeb() {}; - - LLMediaCtrl* mWebBrowser; - LLSD mCategoryPaths; - - bool mResetFocusOnLoad; -}; - -class FSFloaterSearch : public LLFloater -{ - LOG_CLASS(FSFloaterSearch); -public: - typedef enum e_search_category - { - SC_AVATAR, - SC_GROUP, - SC_PLACE, - SC_CLASSIFIED - } ESearchCategory; - - struct _Params : public LLInitParam::Block<_Params, LLFloater::Params> - { - Optional<SearchQuery> search; - }; - - typedef LLSDParamAdapter<_Params> Params; - - FSFloaterSearch(const Params& key); - ~FSFloaterSearch(); - void onOpen(const LLSD& key); - BOOL postBuild(); - - void avatarNameUpdatedCallback(const LLUUID& id, const LLAvatarName& av_name); - void groupNameUpdatedCallback(const LLUUID& id, const std::string& name, bool is_group); - void onSelectedItem(const LLUUID& selected_item, ESearchCategory type); - void onSelectedEvent(const S32 selected_event); - void displayParcelDetails(const LLParcelData& parcel_data); - void displayClassifiedDetails(LLAvatarClassifiedInfo*& c_info); - void displayAvatarDetails(LLAvatarData* avatar_data); - void displayGroupDetails(LLGroupMgrGroupData*& group_data); - bool displayEventDetails(LLEventStruct event); - void displayEventParcelImage(const LLParcelData& parcel_data); - void setLoadingProgress(bool started); - - template <class T> - static T* getSearchPanel(const std::string& panel_name); - -private: - virtual void onClose(bool app_quitting); - const LLUUID& getSelectedID() { return mSelectedID; } - LLVector3d mParcelGlobal; - LLUUID mSelectedID; - U32 mEventID; - bool mHasSelection; - - void resetVerbs(); - void flushDetails(); - void onTabChange(); - void onBtnPeopleProfile(); - void onBtnPeopleIM(); - void onBtnPeopleFriend(); - void onBtnGroupProfile(); - void onBtnGroupChat(); - void onBtnGroupJoin(); - void onBtnEventReminder(); - void onBtnTeleport(); - void onBtnMap(); - - void regionHandleCallback(U64 region_handle, LLVector3d pos_global); - - FSSearchRemoteParcelInfoObserver* mRemoteParcelObserver; - FSSearchRemoteParcelInfoObserver* mRemoteParcelEventLocationObserver; - LLAvatarPropertiesObserver* mAvatarPropertiesObserver; - LLGroupMgrObserver* mGroupPropertiesRequest; - boost::signals2::connection mEventNotifierConnection; - - FSPanelSearchPeople* mPanelPeople; - FSPanelSearchGroups* mPanelGroups; - FSPanelSearchPlaces* mPanelPlaces; - FSPanelSearchEvents* mPanelEvents; - FSPanelSearchLand* mPanelLand; - FSPanelSearchClassifieds* mPanelClassifieds; - FSPanelSearchWeb* mPanelWeb; - - LLPanel* mDetailsPanel; - LLTextEditor* mDetailTitle; - LLTextEditor* mDetailDesc; - LLTextEditor* mDetailAux1; - LLTextEditor* mDetailAux2; - LLTextEditor* mDetailLocation; - LLTextureCtrl* mDetailSnapshot; - LLTextureCtrl* mDetailSnapshotParcel; - LLIconCtrl* mDetailMaturity; - LLTabContainer* mTabContainer; -}; - -#endif // FS_FLOATERSEARCH_H diff --git a/indra/newview/llagenthandler.cpp b/indra/newview/llagenthandler.cpp new file mode 100644 index 0000000000000000000000000000000000000000..688aa2b6aee172bc3932488941ea929e79ea1464 --- /dev/null +++ b/indra/newview/llagenthandler.cpp @@ -0,0 +1,188 @@ +/** + * @file llagenthandler.cpp + * @brief Command handler involving agent requests + * + * $LicenseInfo:firstyear=2005&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llavataractions.h" +#include "llcommandhandler.h" +#include "llfloaterreg.h" +#include "llfloaterreporter.h" +#include "llmutelist.h" +#include "llnotificationsutil.h" +//#include "llpanelblockedlist.h" +#include "llfloaterblocked.h" + +class LLAgentHandler : public LLCommandHandler +{ +public: + // requires trusted browser to trigger + LLAgentHandler() : LLCommandHandler("agent", UNTRUSTED_THROTTLE) { } + + virtual bool canHandleUntrusted( + const LLSD& params, + const LLSD& query_map, + LLMediaCtrl* web, + const std::string& nav_type) + { + if (params.size() < 2) + { + return true; // don't block, will fail later + } + + if (nav_type == NAV_TYPE_CLICKED + || nav_type == NAV_TYPE_EXTERNAL) + { + return true; + } + + const std::string verb = params[1].asString(); + if (verb == "about" || verb == "inspect" || verb == "reportAbuse") + { + return true; + } + return false; + } + + bool handle(const LLSD& params, const LLSD& query_map, const std::string& grid, + LLMediaCtrl* web) + { + if (params.size() < 2) return false; + LLUUID avatar_id; + if (!avatar_id.set(params[0].asStringRef(), FALSE)) + { + return false; + } + + const std::string verb = params[1].asString(); + if (verb == "about") + { + LLAvatarActions::showProfile(avatar_id); + return true; + } + + if (verb == "inspect") + { + LLFloaterReg::showInstance("inspect_avatar", LLSD().with("avatar_id", avatar_id)); + return true; + } + + if (verb == "im") + { + LLAvatarActions::startIM(avatar_id); + return true; + } + + if (verb == "pay") + { + if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnableAvatarPay")) + { + LLNotificationsUtil::add("NoAvatarPay", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit")); + return true; + } + + LLAvatarActions::pay(avatar_id); + return true; + } + + if (verb == "offerteleport") + { + LLAvatarActions::offerTeleport(avatar_id); + return true; + } + + if (verb == "requestfriend") + { + LLAvatarActions::requestFriendshipDialog(avatar_id); + return true; + } + + if (verb == "removefriend") + { + LLAvatarActions::removeFriendDialog(avatar_id); + return true; + } + + if (verb == "mute") + { + if (! LLAvatarActions::isBlocked(avatar_id)) + { + LLAvatarActions::toggleBlock(avatar_id); + } + return true; + } + + if (verb == "unmute") + { + if (LLAvatarActions::isBlocked(avatar_id)) + { + LLAvatarActions::toggleBlock(avatar_id); + } + return true; + } + + if (verb == "block") + { + if (params.size() > 2) + { + const std::string object_name = LLURI::unescape(params[2].asString()); + LLMute mute(avatar_id, object_name, LLMute::OBJECT); + LLMuteList::getInstance()->add(mute); + LLFloaterBlocked::showMuteAndSelect(mute.mID); + //LLPanelBlockedList::showPanelAndSelect(mute.mID); + } + return true; + } + + if (verb == "unblock") + { + if (params.size() > 2) + { + const std::string object_name = params[2].asString(); + LLMute mute(avatar_id, object_name, LLMute::OBJECT); + LLMuteList::getInstance()->remove(mute); + } + return true; + } + + // reportAbuse is here due to convoluted avatar handling + // in LLScrollListCtrl and LLTextBase + if (verb == "reportAbuse" && web == NULL) + { + LLAvatarName av_name; + if (LLAvatarNameCache::get(avatar_id, &av_name)) + { + LLFloaterReporter::showFromAvatar(avatar_id, av_name.getCompleteName()); + } + else + { + LLFloaterReporter::showFromAvatar(avatar_id, "not avaliable"); + } + return true; + } + return false; + } +}; +LLAgentHandler gAgentHandler; diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index 927618a0865d248a603c44b0a6a056c86b65c796..51e5dcd8d96aa1862511ce914b404752e0d6f27f 100644 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -50,6 +50,7 @@ #include "llfloaterreg.h" #include "llfloaterpay.h" #include "llfloaterprofile.h" +#include "llfloaterprofilelegacy.h" #include "llfloatersidepanelcontainer.h" #include "llfloaterwebcontent.h" #include "llfloaterworldmap.h" @@ -64,6 +65,7 @@ #include "llnotificationsutil.h" // for LLNotificationsUtil #include "llpaneloutfitedit.h" #include "llpanelprofile.h" +#include "llpanelprofilelegacy.h" #include "llparcel.h" #include "llrecentpeople.h" #include "lltrans.h" @@ -378,7 +380,15 @@ void LLAvatarActions::showProfile(const LLUUID& avatar_id) { if (avatar_id.notNull()) { - LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id)); + if (gSkinSettings.getBool("LegacyProfile")) + { + LLFloaterReg::showTypedInstance<LLFloaterProfileLegacy>( + "legacy_profile", LLSD().with("avatar_id", avatar_id), TAKE_FOCUS_YES); + } + else + { + LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id)); + } } } @@ -387,10 +397,21 @@ void LLAvatarActions::showPicks(const LLUUID& avatar_id) { if (avatar_id.notNull()) { - LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id))); - if (profilefloater) + if (gSkinSettings.getBool("LegacyProfile")) + { + const LLFloaterProfileLegacy* profile = LLFloaterReg::showTypedInstance<LLFloaterProfileLegacy>( + "legacy_profile", LLSD().with("avatar_id", avatar_id), TAKE_FOCUS_YES); + LLPanel* tab = profile->expandTab("avatar_picks_tab"); + tab->getChild<LLAccordionCtrl>("accordion")->expandTab("tab_picks"); + } + else { - profilefloater->showPick(); + LLFloaterProfile* profile = LLFloaterReg::showTypedInstance<LLFloaterProfile>( + "profile", LLSD().with("id", avatar_id)); + if (profile) + { + profile->showPick(); + } } } } @@ -400,10 +421,20 @@ void LLAvatarActions::showPick(const LLUUID& avatar_id, const LLUUID& pick_id) { if (avatar_id.notNull()) { - LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id))); - if (profilefloater) + if (gSkinSettings.getBool("LegacyProfile")) + { + const LLFloaterProfileLegacy* profile = LLFloaterReg::showTypedInstance<LLFloaterProfileLegacy>( + "legacy_profile", LLSD().with("avatar_id", avatar_id), TAKE_FOCUS_YES); + /*auto* tab = */dynamic_cast<LLPanelProfileLegacy::LLPanelProfilePicks*>(profile->expandTab("avatar_picks_tab")); + // *TODO: Finish + } + else { - profilefloater->showPick(pick_id); + LLFloaterProfile* profile = LLFloaterReg::showTypedInstance<LLFloaterProfile>("profile", LLSD().with("id", avatar_id)); + if (profile) + { + profile->showPick(pick_id); + } } } } @@ -411,9 +442,9 @@ void LLAvatarActions::showPick(const LLUUID& avatar_id, const LLUUID& pick_id) // static void LLAvatarActions::createPick() { - LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", gAgent.getID()))); + LLViewerRegion* region = gAgent.getRegion(); - if (profilefloater && region) + if (region) { LLPickData data; data.pos_global = gAgent.getPositionGlobal(); @@ -431,8 +462,7 @@ void LLAvatarActions::createPick() { data.name = region->getName(); } - - profilefloater->createPick(data); + createPick(data); } } @@ -441,10 +471,21 @@ bool LLAvatarActions::isPickTabSelected(const LLUUID& avatar_id) { if (avatar_id.notNull()) { - LLFloaterProfile* profilefloater = LLFloaterReg::findTypedInstance<LLFloaterProfile>("profile", LLSD().with("id", avatar_id)); - if (profilefloater) + static LLCachedControl<bool> legacy_profile(gSkinSettings, "LegacyProfile"); + if (legacy_profile) + { + const LLFloaterProfileLegacy* profile = LLFloaterReg::findTypedInstance<LLFloaterProfileLegacy>( + "legacy_profile", LLSD().with("avatar_id", avatar_id)); + if (profile == nullptr) { return false; } + return dynamic_cast<LLPanelProfileLegacy::LLPanelProfilePicks*>(profile->getExpandedTab()) != nullptr; + } + else { - return profilefloater->isPickTabSelected(); + LLFloaterProfile* profilefloater = LLFloaterReg::findTypedInstance<LLFloaterProfile>("profile", LLSD().with("id", avatar_id)); + if (profilefloater) + { + return profilefloater->isPickTabSelected(); + } } } return false; @@ -455,10 +496,21 @@ void LLAvatarActions::showClassifieds(const LLUUID& avatar_id) { if (avatar_id.notNull()) { - LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id))); - if (profilefloater) + if (gSkinSettings.getBool("LegacyProfile")) { - profilefloater->showClassified(); + const LLFloaterProfileLegacy* profile = LLFloaterReg::showTypedInstance<LLFloaterProfileLegacy>( + "legacy_profile", LLSD().with("avatar_id", avatar_id), TAKE_FOCUS_YES); + LLPanel* tab = profile->expandTab("avatar_picks_tab"); + tab->getChild<LLAccordionCtrl>("accordion")->expandTab("tab_classifieds"); + } + else + { + LLFloaterProfile* profilefloater = LLFloaterReg::showTypedInstance<LLFloaterProfile>( + "profile", LLSD().with("id", avatar_id)); + if (profilefloater) + { + profilefloater->showClassified(); + } } } } @@ -468,10 +520,22 @@ void LLAvatarActions::showClassified(const LLUUID& avatar_id, const LLUUID& clas { if (avatar_id.notNull()) { - LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id))); - if (profilefloater) + if (gSkinSettings.getBool("LegacyProfile")) + { + const LLFloaterProfileLegacy* profile = LLFloaterReg::showTypedInstance<LLFloaterProfileLegacy>( + "legacy_profile", LLSD().with("avatar_id", avatar_id), TAKE_FOCUS_YES); + LLPanel* tab = profile->expandTab("avatar_picks_tab"); + tab->getChild<LLAccordionCtrl>("accordion")->expandTab("tab_classifieds"); + // *TODO: Finish + } + else { - profilefloater->showClassified(classified_id, edit); + LLFloaterProfile* profilefloater = + dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id))); + if (profilefloater) + { + profilefloater->showClassified(classified_id, edit); + } } } } @@ -479,35 +543,68 @@ void LLAvatarActions::showClassified(const LLUUID& avatar_id, const LLUUID& clas // static void LLAvatarActions::createClassified() { - LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", gAgent.getID()))); - if (profilefloater) + if (gSkinSettings.getBool("LegacyProfile")) { - profilefloater->createClassified(); + const LLFloaterProfileLegacy* profile = LLFloaterReg::showTypedInstance<LLFloaterProfileLegacy>( + "legacy_profile", LLSD().with("avatar_id", gAgent.getID())); + auto* tab = dynamic_cast<LLPanelProfileLegacy::LLPanelProfilePicks*>(profile->expandTab("avatar_picks_tab")); + tab->createNewClassified(); + + } + else + { + LLFloaterProfile* profilefloater = + dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", gAgent.getID()))); + if (profilefloater) + { + profilefloater->createClassified(); + } } } //static bool LLAvatarActions::profileVisible(const LLUUID& avatar_id) { - LLSD sd; - sd["id"] = avatar_id; - LLFloater* floater = getProfileFloater(avatar_id); + LLFloater* floater = findProfileFloater(avatar_id); return floater && floater->isShown(); } //static -LLFloater* LLAvatarActions::getProfileFloater(const LLUUID& avatar_id) +LLFloater* LLAvatarActions::findProfileFloater(const LLUUID& avatar_id) { - LLFloaterProfile* floater = LLFloaterReg::findTypedInstance<LLFloaterProfile>("profile", LLSD().with("id", avatar_id)); - return floater; + LLFloater* profile = nullptr; + static LLCachedControl<bool> legacy_profile(gSkinSettings, "LegacyProfile"); + if (legacy_profile) + profile = LLFloaterReg::findTypedInstance<LLFloaterProfileLegacy>("legacy_profile", LLSD().with("avatar_id", avatar_id)); + else + profile = LLFloaterReg::findTypedInstance<LLFloaterProfile>("profile", LLSD().with("id", avatar_id)); + return profile; +} + +void LLAvatarActions::createPick(const LLPickData& data) +{ + if (gSkinSettings.getBool("LegacyProfile")) + { + const LLFloaterProfileLegacy* profile = LLFloaterReg::showTypedInstance<LLFloaterProfileLegacy>( + "legacy_profile", LLSD().with("avatar_id", gAgent.getID())); + auto* tab = dynamic_cast<LLPanelProfileLegacy::LLPanelProfilePicks*>(profile->expandTab("avatar_picks_tab")); + tab->createNewPick(); + } + else + { + LLFloaterProfile* floater = + dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", gAgent.getID()))); + if (floater) + { + floater->createPick(data); + } + } } //static void LLAvatarActions::hideProfile(const LLUUID& avatar_id) { - LLSD sd; - sd["id"] = avatar_id; - LLFloater* floater = getProfileFloater(avatar_id); + LLFloater* floater = findProfileFloater(avatar_id); if (floater) { floater->closeFloater(); diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h index 2493ec2b5030f90658b0ca32c57c7d3a681454bd..f69954bfe43b595fedcf8799dde076854ed15bf6 100644 --- a/indra/newview/llavataractions.h +++ b/indra/newview/llavataractions.h @@ -107,7 +107,9 @@ class LLAvatarActions static void hideProfile(const LLUUID& avatar_id); static bool profileVisible(const LLUUID& avatar_id); static bool isPickTabSelected(const LLUUID& avatar_id); - static LLFloater* getProfileFloater(const LLUUID& avatar_id); + static LLFloater* findProfileFloater(const LLUUID& avatar_id); + + static void createPick(const LLPickData& data); /** * Show avatar on world map. diff --git a/indra/newview/llclassifieditem.cpp b/indra/newview/llclassifieditem.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0f0f6924e0bec78c0befbca2f2b7d728aa03fb41 --- /dev/null +++ b/indra/newview/llclassifieditem.cpp @@ -0,0 +1,119 @@ +/** +* @file llclassifieditem.cpp +* @brief Widget +* +* $LicenseInfo:firstyear=2009&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2010, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library 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 +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ + +#include "llviewerprecompiledheaders.h" +#include "llclassifieditem.h" + +#include "llpanelclassified.h" + +LLClassifiedItem::LLClassifiedItem(const LLUUID& avatar_id, const LLUUID& classified_id) + : LLPanel() + , mAvatarId(avatar_id) + , mClassifiedId(classified_id) +{ + buildFromFile("panel_classifieds_list_item.xml"); + + LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(), this); + LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(getClassifiedId()); +} + +LLClassifiedItem::~LLClassifiedItem() +{ + LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this); +} + +void LLClassifiedItem::processProperties(void* data, EAvatarProcessorType type) +{ + if (APT_CLASSIFIED_INFO != type) + { + return; + } + + LLAvatarClassifiedInfo* c_info = static_cast<LLAvatarClassifiedInfo*>(data); + if (!c_info || c_info->classified_id != getClassifiedId()) + { + return; + } + + setClassifiedName(c_info->name); + setDescription(c_info->description); + setSnapshotId(c_info->snapshot_id); + setPosGlobal(c_info->pos_global); + + LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this); +} + +BOOL LLClassifiedItem::postBuild() +{ + setMouseEnterCallback(std::bind(&set_child_visible, this, "hovered_icon", true)); + setMouseLeaveCallback(std::bind(&set_child_visible, this, "hovered_icon", false)); + return TRUE; +} + +void LLClassifiedItem::setValue(const LLSD& value) +{ + if (!value.isMap()) return;; + if (!value.has("selected")) return; + getChildView("selected_icon")->setVisible(value["selected"]); +} + +void LLClassifiedItem::fillIn(LLPanelClassifiedEdit* panel) +{ + if (!panel) + { + return; + } + + setClassifiedName(panel->getClassifiedName()); + setDescription(panel->getDescription()); + setSnapshotId(panel->getSnapshotId()); + setCategory(panel->getCategory()); + setContentType(panel->getContentType()); + setAutoRenew(panel->getAutoRenew()); + setPriceForListing(panel->getPriceForListing()); + setPosGlobal(panel->getPosGlobal()); + setLocationText(panel->getClassifiedLocation()); +} + +void LLClassifiedItem::setClassifiedName(const std::string& name) +{ + getChild<LLUICtrl>("name")->setValue(name); +} + +void LLClassifiedItem::setDescription(const std::string& desc) +{ + getChild<LLUICtrl>("description")->setValue(desc); +} + +void LLClassifiedItem::setSnapshotId(const LLUUID& snapshot_id) +{ + getChild<LLUICtrl>("picture")->setValue(snapshot_id); +} + +LLUUID LLClassifiedItem::getSnapshotId() const +{ + return getChild<LLUICtrl>("picture")->getValue(); +} diff --git a/indra/newview/llclassifieditem.h b/indra/newview/llclassifieditem.h new file mode 100644 index 0000000000000000000000000000000000000000..212a53ee0c693055e52ad60aecce0c99f95d5bc3 --- /dev/null +++ b/indra/newview/llclassifieditem.h @@ -0,0 +1,83 @@ +/** +* @file llclassifieditem.h +* @brief Widget +* +* $LicenseInfo:firstyear=2009&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2010, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library 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 +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ + +#ifndef LL_CLASSIFIEDITEM_H +#define LL_CLASSIFIEDITEM_H + +#include "llavatarpropertiesprocessor.h" +#include "llpanel.h" + +class LLPanelClassifiedEdit; + +static const std::string CLASSIFIED_ID("classified_id"); +static const std::string CLASSIFIED_NAME("classified_name"); + +class LLClassifiedItem final : public LLPanel, public LLAvatarPropertiesObserver +{ +public: + + LLClassifiedItem(const LLUUID& avatar_id, const LLUUID& classified_id); + virtual ~LLClassifiedItem(); + + void processProperties(void* data, EAvatarProcessorType type) override; + BOOL postBuild() override; + void setValue(const LLSD& value) override; + void fillIn(LLPanelClassifiedEdit* panel); + LLUUID getAvatarId() const { return mAvatarId; } + void setAvatarId(const LLUUID& avatar_id) { mAvatarId = avatar_id; } + LLUUID getClassifiedId() const { return mClassifiedId; } + void setClassifiedId(const LLUUID& classified_id) { mClassifiedId = classified_id; } + void setPosGlobal(const LLVector3d& pos) { mPosGlobal = pos; } + const LLVector3d getPosGlobal() const { return mPosGlobal; } + void setLocationText(const std::string location) { mLocationText = std::move(location); } + std::string getLocationText() const { return mLocationText; } + void setClassifiedName(const std::string& name); + std::string getClassifiedName() const { return getChild<LLUICtrl>("name")->getValue().asString(); } + void setDescription(const std::string& desc); + std::string getDescription() const { return getChild<LLUICtrl>("description")->getValue().asString(); } + void setSnapshotId(const LLUUID& snapshot_id); + LLUUID getSnapshotId() const; + void setCategory(U32 cat) { mCategory = cat; } + U32 getCategory() const { return mCategory; } + void setContentType(U32 ct) { mContentType = ct; } + U32 getContentType() const { return mContentType; } + void setAutoRenew(U32 renew) { mAutoRenew = renew; } + bool getAutoRenew() const { return mAutoRenew; } + void setPriceForListing(S32 price) { mPriceForListing = price; } + S32 getPriceForListing() const { return mPriceForListing; } + +private: + LLUUID mAvatarId; + LLUUID mClassifiedId; + LLVector3d mPosGlobal; + std::string mLocationText; + U32 mCategory; + U32 mContentType; + bool mAutoRenew; + S32 mPriceForListing; +}; + +#endif // LL_CLASSIFIEDITEM_H diff --git a/indra/newview/lleventnotifier.cpp b/indra/newview/lleventnotifier.cpp index 04aad5aa0f41176cabe0a61dd6e98c4157a636ad..4bc481b21ec2415fee09a4e9cbfd283b70b81759 100644 --- a/indra/newview/lleventnotifier.cpp +++ b/indra/newview/lleventnotifier.cpp @@ -168,7 +168,8 @@ bool LLEventNotifier::handleResponse(U32 eventId, const LLSD& notification, cons bool LLEventNotifier::add(const LLEventStruct& event) { - if (mNewEventSignal(event)) return false; + if (mNewEventSignal(event)) { return false; } + LLEventNotification *new_enp = new LLEventNotification(event.eventId, event.eventEpoch, event.eventDateStr, event.eventName); LL_INFOS() << "Add event " << event.eventName << " id " << event.eventId << " date " << event.eventDateStr << LL_ENDL; @@ -207,21 +208,21 @@ void LLEventNotifier::processEventInfoReply(LLMessageSystem *msg, void **) U32 event_time_utc; msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id ); - msg->getU32("EventData", "EventID", event_id); - msg->getString("EventData", "Name", event_name); - msg->getString("EventData", "Date", eventd_date); - msg->getU32("EventData", "DateUTC", event_time_utc); + msg->getU32Fast(_PREHASH_EventData, _PREHASH_EventID, event_id); + msg->getStringFast(_PREHASH_EventData, _PREHASH_Name, event_name); + msg->getStringFast(_PREHASH_EventData, _PREHASH_Date, eventd_date); + msg->getU32Fast(_PREHASH_EventData, _PREHASH_DateUTC, event_time_utc); LLEventStruct event(event_id, (F64)event_time_utc, eventd_date, event_name); - msg->getString("EventData", "Creator", event.creator); - msg->getString("EventData", "Category", event.category); - msg->getString("EventData", "Desc", event.desc); - msg->getU32("EventData", "Duration", event.duration); - msg->getU32("EventData", "Cover", event.cover); - msg->getU32("EventData", "Amount", event.amount); - msg->getString("EventData", "SimName", event.simName); - msg->getVector3d("EventData", "GlobalPos", event.globalPos); - msg->getU32("EventData", "EventFlags", event.flags); + msg->getString(_PREHASH_EventData, _PREHASH_Creator, event.creator); + msg->getString(_PREHASH_EventData, _PREHASH_Category, event.category); + msg->getString(_PREHASH_EventData, _PREHASH_Desc, event.desc); + msg->getU32(_PREHASH_EventData, _PREHASH_Duration, event.duration); + msg->getU32(_PREHASH_EventData, _PREHASH_Cover, event.cover); + msg->getU32(_PREHASH_EventData, _PREHASH_Amount, event.amount); + msg->getString(_PREHASH_EventData, _PREHASH_SimName, event.simName); + msg->getVector3d(_PREHASH_EventData, _PREHASH_GlobalPos, event.globalPos); + msg->getU32(_PREHASH_EventData, _PREHASH_EventFlags, event.flags); gEventNotifier.add(event); } @@ -246,29 +247,22 @@ void LLEventNotifier::load(const LLSD& event_options) is_iso8601_date = true; } + std::string dateStr = response["event_date"].asString(); + if (is_iso8601_date) { - std::string dateStr; - - dateStr = "[" + LLTrans::getString("LTimeYear") + "]-[" - + LLTrans::getString("LTimeMthNum") + "]-[" - + LLTrans::getString("LTimeDay") + "] [" - + LLTrans::getString("LTimeHour") + "]:[" - + LLTrans::getString("LTimeMin") + "]:[" - + LLTrans::getString("LTimeSec") + "]"; + std::string iso8601date = + "[" + LLTrans::getString("LTimeYear") + "]-[" + LLTrans::getString("LTimeMthNum") + "]-[" + + LLTrans::getString("LTimeDay") + "] [" + LLTrans::getString("LTimeHour") + "]:[" + + LLTrans::getString("LTimeMin") + "]:[" + LLTrans::getString("LTimeSec") + "]"; LLSD substitution; substitution["datetime"] = date; - LLStringUtil::format(dateStr, substitution); - - LLEventStruct event(response["event_id"].asInteger(), response["event_date_ut"], dateStr, response["event_name"].asString()); - add(event); - } - else - { - LLEventStruct event(response["event_id"].asInteger(), response["event_date_ut"], response["event_date"].asString(), response["event_name"].asString()); - add(event); + LLStringUtil::format(iso8601date, substitution); + dateStr = iso8601date; } + + add(LLEventStruct(response["event_id"].asInteger(), response["event_date_ut"], dateStr, response["event_name"].asString())); } } @@ -311,11 +305,11 @@ void LLEventNotifier::serverPushRequest(U32 event_id, bool add) } -LLEventNotification::LLEventNotification(U32 eventId, F64 eventEpoch, std::string eventDateStr, std::string eventName) : +LLEventNotification::LLEventNotification(U32 eventId, F64 eventEpoch, const std::string& eventDateStr, const std::string &eventName) : mEventID(eventId), - mEventName(std::move(eventName)), + mEventName(eventName), mEventDateEpoch(eventEpoch), - mEventDateStr(std::move(eventDateStr)) + mEventDateStr(eventDateStr) { } diff --git a/indra/newview/lleventnotifier.h b/indra/newview/lleventnotifier.h index f30039f51b0fc5fcd16ade19d0980d99b58be5c9..14ced4908d8fe417ac18d6cf1f760fe2dedc6e6d 100644 --- a/indra/newview/lleventnotifier.h +++ b/indra/newview/lleventnotifier.h @@ -27,7 +27,6 @@ #ifndef LL_LLEVENTNOTIFIER_H #define LL_LLEVENTNOTIFIER_H -#include <utility> #include "llframetimer.h" #include "v3dmath.h" @@ -48,9 +47,9 @@ typedef struct event_st{ std::string simName; LLVector3d globalPos; U32 flags = 0; - event_st(U32 id, F64 epoch, std::string date_str, std::string name) - : eventId(id), eventEpoch(epoch), eventDateStr(std::move(date_str)), eventName(std::move(name)){} - event_st() = default; + event_st(U32 id, F64 epoch, const std::string& date_str, const std::string& name) + : eventId(id), eventEpoch(epoch), eventDateStr(date_str), eventName(name){} + event_st(){} } LLEventStruct; class LLEventNotifier @@ -91,12 +90,12 @@ class LLEventNotifier class LLEventNotification { public: - LLEventNotification(U32 eventId, F64 eventEpoch, std::string eventDateStr, std::string eventName); + LLEventNotification(U32 eventId, F64 eventEpoch, const std::string& eventDateStr, const std::string &eventName); U32 getEventID() const { return mEventID; } const std::string &getEventName() const { return mEventName; } - bool isValid() const { return mEventID > 0 && mEventDateEpoch != 0 && !mEventName.empty(); } + bool isValid() const { return mEventID > 0 && mEventDateEpoch != 0 && mEventName.size() > 0; } const F64 &getEventDateEpoch() const { return mEventDateEpoch; } const std::string &getEventDateStr() const { return mEventDateStr; } diff --git a/indra/newview/llfloaterdirectory.cpp b/indra/newview/llfloaterdirectory.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1df46a66fdbeb6d7ce81e9a480eaccf6f2aff56c --- /dev/null +++ b/indra/newview/llfloaterdirectory.cpp @@ -0,0 +1,1219 @@ +/* + * @file llfloaterdirectory.cpp + * @brief Legacy search facility + * + * Copyright (c) 2014-2022, Cinder Roxley <cinder@sdf.org> + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "llviewerprecompiledheaders.h" +#include "llfloaterdirectory.h" + +// llmessage +#include "lleventflags.h" +#include "llqueryflags.h" +#include "message.h" + +// llui +#include "llfloaterreg.h" +#include "lllayoutstack.h" +#include "llpanel.h" +#include "llresmgr.h" +#include "llscrolllistctrl.h" +#include "lltabcontainer.h" +#include "lltextbase.h" +#include "lltrans.h" + +// newview +#include "llagent.h" +#include "llpanelsearchbase.h" +#include "llpanelsearchweb.h" +#include "llproductinforequest.h" +#include "llviewercontrol.h" + +SearchQuery::SearchQuery() +: category("category", ""), + collection("collection", ""), + query("query") +{} + +static const std::array<std::string, 6> sSearchPanels{ {"panel_search_people", "panel_search_groups", "panel_search_places", "panel_search_classifieds", "panel_search_events", "panel_search_landsales"} }; +static const std::array<std::string, 5> sDetailPanels{ {"detail_avatar", "detail_group", "detail_place", "detail_classified", "detail_event"} }; + +LLFloaterDirectory::LLFloaterDirectory(const Params& key) + : LLFloater(key) + , mCurrentResultType(SE_UNDEFINED) + , mCurrentQuery() + , mResultStart(0) + , mNumResultsReceived(0) + , mQueryID() + , mTabContainer(nullptr) + , mPanelWeb(nullptr) + , mResultList(nullptr) + , mResultsStatus(nullptr) +{ +} + +LLFloaterDirectory::~LLFloaterDirectory() +{ +} + +BOOL LLFloaterDirectory::postBuild() +{ + mResultList = findChild<LLScrollListCtrl>("results"); + mResultList->setCommitCallback(boost::bind(&LLFloaterDirectory::onCommitSelection, this)); + for (std::string panel_name: sSearchPanels) + { + LLPanelSearch* panel = static_cast<LLPanelSearch*>(findChild<LLUICtrl>(panel_name)); + if (panel) + panel->setSearchFloater(this); + } + mPanelWeb = findChild<LLPanelSearchWeb>("panel_search_web"); + mTabContainer = findChild<LLTabContainer>("search_tabs"); + mTabContainer->setCommitCallback(boost::bind(&LLFloaterDirectory::onTabChanged, this)); + setProgress(false); + mResultsStatus = findChild<LLTextBase>("results_status"); + getChild<LLButton>("PageUp")->setCommitCallback(boost::bind(&LLFloaterDirectory::choosePage, this, _1)); + getChild<LLButton>("PageDn")->setCommitCallback(boost::bind(&LLFloaterDirectory::choosePage, this, _1)); + showDetailPanel(LLStringUtil::null); // hide all the panels + paginate(); + + if (!mTabContainer->selectTab(gSavedSettings.getS32("AlchemyLastDirectoryTab"))) + { + mTabContainer->selectFirstTab(); + } + + return LLFloater::postBuild(); +} + +void LLFloaterDirectory::onOpen(const LLSD& key) +{ + Params p(key); + mPanelWeb->loadUrl(p.search); + if (key.has("query")) + { + mTabContainer->selectTabPanel(mPanelWeb); + } + onTabChanged(); +} + +void LLFloaterDirectory::onClose(bool app_quitting) +{ + if (mTabContainer) + { + gSavedSettings.setS32("AlchemyLastDirectoryTab", mTabContainer->getCurrentPanelIndex()); + } +} + +void LLFloaterDirectory::setProgress(bool working) +{ + getChild<LLUICtrl>("loading")->setVisible(working); +} + +void LLFloaterDirectory::setResultsComment(const std::string& message) +{ + mResultList->setCommentText(message); +} + +void LLFloaterDirectory::onTabChanged() +{ + LLPanel* active_panel = mTabContainer->getCurrentPanel(); + bool show_detail = active_panel != mPanelWeb; + findChild<LLLayoutStack>("results_stack")->setVisible(show_detail); + findChild<LLButton>("PageUp")->setVisible(show_detail); + findChild<LLButton>("PageDn")->setVisible(show_detail); + mResultsStatus->setVisible(show_detail); +} + +void LLFloaterDirectory::onCommitSelection() +{ + switch (mCurrentResultType) + { + case SE_PEOPLE: + { + LLSD params; + params["avatar_id"] = mResultList->getSelectedValue().asUUID(); + getChild<LLPanel>("detail_avatar")->onOpen(params); + showDetailPanel("detail_avatar"); + break; + } + case SE_GROUPS: + { + LLSD params; + params["group_id"] = mResultList->getSelectedValue().asUUID(); + getChild<LLPanel>("detail_group")->onOpen(params); + showDetailPanel("detail_group"); + break; + } + case SE_LANDSALES: + case SE_PLACES: + { + LLSD params; + params["type"] = "remote_place"; + params["id"] = mResultList->getSelectedValue().asUUID(); + getChild<LLPanel>("detail_place")->onOpen(params); + showDetailPanel("detail_place"); + break; + } + case SE_CLASSIFIEDS: + { + LLSD params; + params["classified_id"] = mResultList->getSelectedValue().asUUID(); + getChild<LLPanel>("detail_classified")->onOpen(params); + showDetailPanel("detail_classified"); + break; + } + case SE_EVENTS: + { + getChild<LLPanel>("detail_event")->onOpen(mResultList->getSelectedValue().asInteger()); + showDetailPanel("detail_event"); + break; + } + case SE_UNDEFINED: + default: + LL_WARNS("Search") << "Unhandled search mode: " << mCurrentResultType << LL_ENDL; + break; + } +} + +void LLFloaterDirectory::paginate() +{ + if (mNumResultsReceived) + { + LLStringUtil::format_map_t args; + std::string total_str; + LLResMgr::getInstance()->getIntegerString(total_str, mResultStart + mNumResultsReceived - 1); + args["TOTAL"] = total_str; + args["VISIBLE_END"] = total_str; + total_str = LLStringUtil::null; + LLResMgr::getInstance()->getIntegerString(total_str, mResultStart + 1); + args["VISIBLE_BEGIN"] = total_str; + mResultsStatus->setText(getString((mNumResultsReceived > mCurrentQuery.results_per_page) + ? "result_spillover" : "result_count", + args)); + } + else + mResultsStatus->setText(getString("no_results")); + childSetEnabled("PageUp", mNumResultsReceived > mCurrentQuery.results_per_page); + childSetEnabled("PageDn", mResultStart > 0); +} + +void LLFloaterDirectory::choosePage(LLUICtrl* ctrl) +{ + if (ctrl->getName() == "PageUp") + mResultStart += mCurrentQuery.results_per_page; + else if (ctrl->getName() == "PageDn") + mResultStart -= mCurrentQuery.results_per_page; + else + { + LL_WARNS("Search") << "Unknown control: " << ctrl->getName() << LL_ENDL; + return; // Fuck you, you lose. + } + queryDirectory(mCurrentQuery, false); +} + +void LLFloaterDirectory::showDetailPanel(const std::string& panel_name) +{ + for (const std::string& panel_itr: sDetailPanels) + { + getChild<LLPanel>(panel_itr)->setVisible(panel_itr == panel_name); + } +} + +void LLFloaterDirectory::rebuildResultList() +{ + mResultList->clearColumns(); + switch (mCurrentResultType) + { + case SE_PEOPLE: + { + LLScrollListColumn::Params icon; + icon.name = "icon"; + icon.width.pixel_width = 20; + mResultList->addColumn(icon); + + LLScrollListColumn::Params name; + name.name = "name"; + name.header.label = "Name"; + name.width.relative_width = 1.f; + mResultList->addColumn(name); + break; + } + case SE_GROUPS: + { + LLScrollListColumn::Params icon; + icon.name = "icon"; + icon.width.pixel_width = 20; + mResultList->addColumn(icon); + + LLScrollListColumn::Params name; + name.name = "name"; + name.header.label = "Name"; + name.width.relative_width = 0.72f; + mResultList->addColumn(name); + + LLScrollListColumn::Params members; + members.name = "members"; + members.header.label = "Members"; + members.width.relative_width = 0.25f; + mResultList->addColumn(members); + + LLScrollListColumn::Params score; + score.name = "score"; + score.header.label = "Score"; + score.width.relative_width = 0.03f; + mResultList->addColumn(score); + break; + } + case SE_PLACES: + { + LLScrollListColumn::Params icon; + icon.name = "icon"; + icon.width.pixel_width = 20; + mResultList->addColumn(icon); + + LLScrollListColumn::Params name; + name.name = "name"; + name.header.label = "Name"; + name.width.relative_width = 0.81f; + mResultList->addColumn(name); + + LLScrollListColumn::Params dwell; + dwell.name = "dwell"; + dwell.header.label = "Traffic"; + dwell.width.relative_width = 0.19f; + mResultList->addColumn(dwell); + break; + } + case SE_LANDSALES: + { + LLScrollListColumn::Params icon; + icon.name = "icon"; + icon.width.pixel_width = 20; + mResultList->addColumn(icon); + + LLScrollListColumn::Params name; + name.name = "name"; + name.header.label = "Name"; + name.width.relative_width = 0.45f; + mResultList->addColumn(name); + + LLScrollListColumn::Params price; + price.name="price"; + price.header.label="Price"; + price.width.relative_width = 0.1f; + mResultList->addColumn(price); + + LLScrollListColumn::Params area; + area.name="area"; + area.header.label="Area"; + area.width.relative_width = 0.1f; + mResultList->addColumn(area); + + LLScrollListColumn::Params ppm; + ppm.name="ppm"; + ppm.header.label="L$/m"; + ppm.width.relative_width = 0.1f; + mResultList->addColumn(ppm); + + LLScrollListColumn::Params type; + type.name="type"; + type.header.label="Type"; + type.width.relative_width = 0.2f; + mResultList->addColumn(type); + break; + } + case SE_CLASSIFIEDS: + { + LLScrollListColumn::Params icon; + icon.name = "icon"; + icon.width.pixel_width = 20; + mResultList->addColumn(icon); + + LLScrollListColumn::Params name; + name.name = "name"; + name.header.label = "Name"; + name.width.relative_width = 0.7f; + mResultList->addColumn(name); + + LLScrollListColumn::Params price; + price.name="price"; + price.header.label="Price"; + price.width.relative_width = 0.3f; + mResultList->addColumn(price); + break; + } + case SE_EVENTS: + { + LLScrollListColumn::Params icon; + icon.name = "icon"; + icon.width.pixel_width = 20; + mResultList->addColumn(icon); + + LLScrollListColumn::Params name; + name.name = "name"; + name.header.label = "Name"; + name.width.relative_width = 0.65f; + mResultList->addColumn(name); + + //LLScrollListColumn::Params time; + //time.name="time"; + //time.header.label="Time"; + //time.width.relative_width = 0.2f; + //mResultList->addColumn(time); + + LLScrollListColumn::Params date; + date.name="date"; + date.header.label="Date"; + date.width.relative_width = 0.3f; + mResultList->addColumn(date); + break; + } + case SE_UNDEFINED: + default: + LL_WARNS("Search") << "Unhandled search mode: " << mCurrentResultType << LL_ENDL; + break; + + } +} + +void LLFloaterDirectory::queryDirectory(const LLDirQuery& query, bool new_search) +{ + if (mCurrentResultType != query.type) + { + mCurrentResultType = query.type; + rebuildResultList(); + } + mResultList->clearRows(); + + if (new_search) + { + mResultStart = 0; + } + + mCurrentQuery = query; + mNumResultsReceived = 0; + mQueryID.generate(); + + switch (mCurrentResultType) + { + case SE_PEOPLE: + { + gMessageSystem->newMessageFast(_PREHASH_DirFindQuery); + gMessageSystem->nextBlockFast(_PREHASH_AgentData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + gMessageSystem->nextBlockFast(_PREHASH_QueryData); + gMessageSystem->addUUIDFast(_PREHASH_QueryID, mQueryID); + gMessageSystem->addStringFast(_PREHASH_QueryText, query.text); + gMessageSystem->addU32Fast(_PREHASH_QueryFlags, DFQ_PEOPLE); + gMessageSystem->addS32Fast(_PREHASH_QueryStart, mResultStart); + gAgent.sendReliableMessage(); + LL_DEBUGS("Search") << "Firing off search request: " << mQueryID << LL_ENDL; + break; + } + case SE_GROUPS: + { + gMessageSystem->newMessageFast(_PREHASH_DirFindQuery); + gMessageSystem->nextBlockFast(_PREHASH_AgentData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + gMessageSystem->nextBlockFast(_PREHASH_QueryData); + gMessageSystem->addUUIDFast(_PREHASH_QueryID, mQueryID); + gMessageSystem->addStringFast(_PREHASH_QueryText, query.text); + gMessageSystem->addU32Fast(_PREHASH_QueryFlags, query.scope); + gMessageSystem->addS32Fast(_PREHASH_QueryStart, mResultStart); + gAgent.sendReliableMessage(); + LL_DEBUGS("Search") << "Firing off search request: " << mQueryID << LL_ENDL; + break; + } + case SE_EVENTS: + { + gMessageSystem->newMessageFast(_PREHASH_DirFindQuery); + gMessageSystem->nextBlockFast(_PREHASH_AgentData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + gMessageSystem->nextBlockFast(_PREHASH_QueryData); + gMessageSystem->addUUIDFast(_PREHASH_QueryID, mQueryID); + gMessageSystem->addStringFast(_PREHASH_QueryText, query.text); + gMessageSystem->addU32Fast(_PREHASH_QueryFlags, query.scope); + gMessageSystem->addS32Fast(_PREHASH_QueryStart, mResultStart); + gAgent.sendReliableMessage(); + LL_DEBUGS("Search") << "Firing off search request: " << mQueryID << " Search Text: " << query.text << LL_ENDL; + break; + } + case SE_PLACES: + { + gMessageSystem->newMessageFast(_PREHASH_DirPlacesQuery); + gMessageSystem->nextBlockFast(_PREHASH_AgentData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + gMessageSystem->nextBlockFast(_PREHASH_QueryData); + gMessageSystem->addUUIDFast(_PREHASH_QueryID, mQueryID); + gMessageSystem->addStringFast(_PREHASH_QueryText, query.text); + gMessageSystem->addU32Fast(_PREHASH_QueryFlags, query.scope); + gMessageSystem->addS8Fast(_PREHASH_Category, query.category_char); + // TODO: Search filter by region name. + gMessageSystem->addStringFast(_PREHASH_SimName, ""); + gMessageSystem->addS32Fast(_PREHASH_QueryStart, mResultStart); + gAgent.sendReliableMessage(); + LL_DEBUGS("Search") << "Firing off search request: " << mQueryID << LL_ENDL; + break; + } + case SE_LANDSALES: + { + gMessageSystem->newMessageFast(_PREHASH_DirLandQuery); + gMessageSystem->nextBlockFast(_PREHASH_AgentData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + gMessageSystem->nextBlockFast(_PREHASH_QueryData); + gMessageSystem->addUUIDFast(_PREHASH_QueryID, mQueryID); + gMessageSystem->addU32Fast(_PREHASH_QueryFlags, query.scope); + gMessageSystem->addU32Fast(_PREHASH_SearchType, query.category_int); + gMessageSystem->addS32Fast(_PREHASH_Price, query.price); + gMessageSystem->addS32Fast(_PREHASH_Area, query.area); + gMessageSystem->addS32Fast(_PREHASH_QueryStart, mResultStart); + gAgent.sendReliableMessage(); + LL_DEBUGS("Search") << "Firing off search request: " << mQueryID << query.category_int << LL_ENDL; + break; + } + case SE_CLASSIFIEDS: + { + gMessageSystem->newMessageFast(_PREHASH_DirClassifiedQuery); + gMessageSystem->nextBlockFast(_PREHASH_AgentData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + gMessageSystem->nextBlockFast(_PREHASH_QueryData); + gMessageSystem->addUUIDFast(_PREHASH_QueryID, mQueryID); + gMessageSystem->addStringFast(_PREHASH_QueryText, query.text); + gMessageSystem->addU32Fast(_PREHASH_QueryFlags, query.scope); + gMessageSystem->addU32Fast(_PREHASH_Category, query.category_int); + gMessageSystem->addS32Fast(_PREHASH_QueryStart, mResultStart); + gAgent.sendReliableMessage(); + LL_DEBUGS("Search") << "Firing off search request: " << mQueryID << LL_ENDL; + break; + } + case SE_UNDEFINED: + default: + break; + } + mResultList->setCommentText(getString("searching")); + setProgress(true); +} + +//static +void LLFloaterDirectory::processSearchPeopleReply(LLMessageSystem* msg, void**) +{ + LLUUID query_id; + std::string first_name; + std::string last_name; + LLUUID agent_id; + U8 online; + //S32 reputation; + + msg->getUUIDFast(_PREHASH_QueryData, _PREHASH_QueryID, query_id); + msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id); + + if (agent_id != gAgent.getID()) return; // not for us + LL_DEBUGS("Search") << "Received results for query id: " << query_id << LL_ENDL; + + // *TODO: Get rid of this so we can have multiple search windows + LLFloaterDirectory* self = LLFloaterReg::findTypedInstance<LLFloaterDirectory>("search"); + if (self == nullptr || query_id != self->mQueryID) return; // not the result we're waiting for + self->setProgress(false); + + LLScrollListCtrl* pResults = self->mResultList; + + S32 num_new_rows = msg->getNumberOfBlocksFast(_PREHASH_QueryReplies); + if (num_new_rows == 0) + { + LLStringUtil::format_map_t map; + map["[TEXT]"] = self->mCurrentQuery.text; + pResults->setCommentText(self->getString("not_found", map)); + } + + self->mNumResultsReceived += num_new_rows; + + for (S32 i = 0; i < num_new_rows; ++i) + { + msg->getStringFast( _PREHASH_QueryReplies, _PREHASH_FirstName, first_name, i); + msg->getStringFast( _PREHASH_QueryReplies, _PREHASH_LastName, last_name, i); + msg->getUUIDFast( _PREHASH_QueryReplies, _PREHASH_AgentID, agent_id, i); + //msg->getS32Fast( _PREHASH_QueryReplies, _PREHASH_Reputation, reputation, i); + msg->getU8Fast( _PREHASH_QueryReplies, _PREHASH_Online, online, i); + + if (agent_id.isNull()) + { + LL_INFOS("Search") << "Null result returned for QueryID: " << query_id << LL_ENDL; + LLStringUtil::format_map_t map; + map["[TEXT]"] = self->mCurrentQuery.text; + pResults->setCommentText(self->getString("not_found", map)); + } + else + { + LL_DEBUGS("Search") << "Got: " << first_name << " " << last_name << " AgentID: " << agent_id << LL_ENDL; + pResults->setEnabled(TRUE); + + std::string avatar_name = LLCacheName::buildFullName(first_name, last_name); + + LLSD element; + element["id"] = agent_id; + + element["columns"][0]["column"] = "icon"; + element["columns"][0]["type"] = "icon"; + element["columns"][0]["value"] = online ? "icon_avatar_online.tga" : "icon_avatar_offline.tga"; + + element["columns"][1]["column"] = "name"; + element["columns"][1]["value"] = avatar_name; + + pResults->addElement(element, ADD_BOTTOM); + } + } + self->paginate(); +} + +//static +void LLFloaterDirectory::processSearchGroupsReply(LLMessageSystem* msg, void**) +{ + LLUUID query_id; + LLUUID group_id; + LLUUID agent_id; + std::string group_name; + S32 members; + F32 search_order; + + msg->getUUIDFast(_PREHASH_QueryData, _PREHASH_QueryID, query_id); + msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id); + + if (agent_id != gAgent.getID()) return; // not for us + LL_DEBUGS("Search") << "Received results for query id: " << query_id << LL_ENDL; + + LLFloaterDirectory* self = LLFloaterReg::findTypedInstance<LLFloaterDirectory>("search"); + if (self == nullptr || query_id != self->mQueryID) return; // not the result we're waiting for + + self->setProgress(false); + LLScrollListCtrl* pResults = self->mResultList; + + // Check for status messages + if (msg->getNumberOfBlocks("StatusData")) + { + U32 status; + msg->getU32("StatusData", "Status", status); + if (status & STATUS_SEARCH_PLACES_FOUNDNONE) + { + LLStringUtil::format_map_t map; + map["[TEXT]"] = self->getChild<LLUICtrl>("groups_edit")->getValue().asString(); + pResults->setCommentText(self->getString("not_found", map)); + return; + } + else if(status & STATUS_SEARCH_PLACES_SHORTSTRING) + { + pResults->setCommentText(self->getString("search_short")); + return; + } + else if (status & STATUS_SEARCH_PLACES_BANNEDWORD) + { + pResults->setCommentText(self->getString("search_banned")); + return; + } + else if (status & STATUS_SEARCH_PLACES_SEARCHDISABLED) + { + pResults->setCommentText(self->getString("search_disabled")); + return; + } + } + + S32 num_new_rows = msg->getNumberOfBlocksFast(_PREHASH_QueryReplies); + if (num_new_rows == 0) + { + LLStringUtil::format_map_t map; + map["[TEXT]"] = self->mCurrentQuery.text; + pResults->setCommentText(self->getString("not_found", map)); + } + + self->mNumResultsReceived += num_new_rows; + for (S32 i = 0; i < num_new_rows; ++i) + { + msg->getUUIDFast( _PREHASH_QueryReplies, _PREHASH_GroupID, group_id, i); + msg->getStringFast( _PREHASH_QueryReplies, _PREHASH_GroupName, group_name, i); + msg->getS32Fast( _PREHASH_QueryReplies, _PREHASH_Members, members, i); + msg->getF32Fast( _PREHASH_QueryReplies, _PREHASH_SearchOrder, search_order,i); + if (group_id.isNull()) + { + LL_DEBUGS("Search") << "No results returned for QueryID: " << query_id << LL_ENDL; + LLStringUtil::format_map_t map; + map["[TEXT]"] = self->mCurrentQuery.text; + pResults->setCommentText(self->getString("not_found", map)); + } + else + { + LL_DEBUGS("Search") << "Got: " << group_name << " GroupID: " << group_id << LL_ENDL; + pResults->setEnabled(TRUE); + + LLSD element; + + element["id"] = group_id; + + element["columns"][0]["column"] = "icon"; + element["columns"][0]["type"] = "icon"; + element["columns"][0]["value"] = "Icon_Group"; + + element["columns"][1]["column"] = "name"; + element["columns"][1]["value"] = group_name; + + element["columns"][2]["column"] = "members"; + element["columns"][2]["value"] = members; + + element["columns"][3]["column"] = "score"; + element["columns"][3]["value"] = search_order; + + pResults->addElement(element, ADD_BOTTOM); + } + } + self->paginate(); +} + +//static +void LLFloaterDirectory::processSearchPlacesReply(LLMessageSystem* msg, void**) +{ + LLUUID agent_id; + LLUUID query_id; + LLUUID parcel_id; + std::string name; + BOOL for_sale; + BOOL auction; + F32 dwell; + + msg->getUUIDFast(_PREHASH_QueryData, _PREHASH_QueryID, query_id); + msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id); + + if (agent_id != gAgent.getID()) return; // not for us + LL_DEBUGS("Search") << "Received results for query id: " << query_id << LL_ENDL; + + LLFloaterDirectory* self = LLFloaterReg::findTypedInstance<LLFloaterDirectory>("search"); + if (self == nullptr || query_id != self->mQueryID) return; // not the result we're waiting for + + self->setProgress(false); + LLScrollListCtrl* pResults = self->mResultList; + + // Check for status messages + if (msg->getNumberOfBlocks("StatusData")) + { + U32 status; + msg->getU32("StatusData", "Status", status); + if (status & STATUS_SEARCH_PLACES_FOUNDNONE) + { + LLStringUtil::format_map_t map; + map["[TEXT]"] = self->mCurrentQuery.text; + pResults->setCommentText(self->getString("not_found", map)); + return; + } + else if(status & STATUS_SEARCH_PLACES_SHORTSTRING) + { + pResults->setCommentText(self->getString("search_short")); + return; + } + else if (status & STATUS_SEARCH_PLACES_BANNEDWORD) + { + pResults->setCommentText(self->getString("search_banned")); + return; + } + else if (status & STATUS_SEARCH_PLACES_SEARCHDISABLED) + { + pResults->setCommentText(self->getString("search_disabled")); + return; + } + } + + S32 num_new_rows = msg->getNumberOfBlocksFast(_PREHASH_QueryReplies); + if (num_new_rows == 0) + { + LLStringUtil::format_map_t map; + map["[TEXT]"] = self->mCurrentQuery.text; + pResults->setCommentText(self->getString("not_found", map)); + } + + self->mNumResultsReceived += num_new_rows; + for (S32 i = 0; i < num_new_rows; ++i) + { + msg->getUUID( "QueryReplies", "ParcelID", parcel_id, i); + msg->getString( "QueryReplies", "Name", name, i); + msg->getBOOL( "QueryReplies", "ForSale", for_sale, i); + msg->getBOOL( "QueryReplies", "Auction", auction, i); + msg->getF32( "QueryReplies", "Dwell", dwell, i); + if (parcel_id.isNull()) + { + LL_DEBUGS("Search") << "Null result returned for QueryID: " << query_id << LL_ENDL; + LLStringUtil::format_map_t map; + map["[TEXT]"] = self->mCurrentQuery.text; + pResults->setCommentText(self->getString("not_found", map)); + } + else + { + LL_DEBUGS("Search") << "Got: " << name << " ParcelID: " << parcel_id << LL_ENDL; + pResults->setEnabled(TRUE); + + LLSD element; + + element["id"] = parcel_id; + + if (auction) + { + element["columns"][0]["column"] = "icon"; + element["columns"][0]["type"] = "icon"; + element["columns"][0]["value"] = "Icon_Auction"; + } + else if (for_sale) + { + element["columns"][0]["column"] = "icon"; + element["columns"][0]["type"] = "icon"; + element["columns"][0]["value"] = "Icon_For_Sale"; + } + else + { + element["columns"][0]["column"] = "icon"; + element["columns"][0]["type"] = "icon"; + element["columns"][0]["value"] = "Icon_Place"; + } + + element["columns"][1]["column"] = "name"; + element["columns"][1]["value"] = name; + + std::string buffer = llformat("%.0f", dwell); + element["columns"][2]["column"] = "dwell"; + element["columns"][2]["value"] = buffer; + + pResults->addElement(element, ADD_BOTTOM); + } + } + self->paginate(); +} + +//static +void LLFloaterDirectory::processSearchClassifiedsReply(LLMessageSystem* msg, void**) +{ + LLUUID agent_id; + LLUUID query_id; + LLUUID classified_id; + std::string name; + U32 creation_date; + U32 expiration_date; + S32 price_for_listing; + + msg->getUUIDFast(_PREHASH_QueryData, _PREHASH_QueryID, query_id); + msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id); + + if (agent_id != gAgent.getID()) return; // not for us + LL_DEBUGS("Search") << "Received results for query id: " << query_id << LL_ENDL; + + LLFloaterDirectory* self = LLFloaterReg::findTypedInstance<LLFloaterDirectory>("search"); + if (self == nullptr || query_id != self->mQueryID) return; // not the result we're waiting for + + self->setProgress(false); + LLScrollListCtrl* pResults = self->mResultList; + + // Check for status messages + if (msg->getNumberOfBlocks("StatusData")) + { + U32 status; + msg->getU32("StatusData", "Status", status); + if (status & STATUS_SEARCH_PLACES_FOUNDNONE) + { + LLStringUtil::format_map_t map; + map["[TEXT]"] = self->mCurrentQuery.text; + pResults->setCommentText(self->getString("not_found", map)); + return; + } + else if(status & STATUS_SEARCH_PLACES_SHORTSTRING) + { + pResults->setCommentText(self->getString("search_short")); + return; + } + else if (status & STATUS_SEARCH_PLACES_BANNEDWORD) + { + pResults->setCommentText(self->getString("search_banned")); + return; + } + else if (status & STATUS_SEARCH_PLACES_SEARCHDISABLED) + { + pResults->setCommentText(self->getString("search_disabled")); + return; + } + } + + S32 num_new_rows = msg->getNumberOfBlocksFast(_PREHASH_QueryReplies); + if (num_new_rows == 0) + { + LLStringUtil::format_map_t map; + map["[TEXT]"] = self->mCurrentQuery.text; + pResults->setCommentText(self->getString("not_found", map)); + } + + self->mNumResultsReceived += num_new_rows; + for (S32 i = 0; i < num_new_rows; ++i) + { + msg->getUUID( "QueryReplies", "ClassifiedID", classified_id, i); + msg->getString( "QueryReplies", "Name", name, i); + msg->getU32( "QueryReplies", "CreationDate", creation_date, i); + msg->getU32( "QueryReplies", "ExpirationDate", expiration_date,i); + msg->getS32( "QueryReplies", "PriceForListing", price_for_listing,i); + if (classified_id.isNull()) + { + LL_DEBUGS("Search") << "No results returned for QueryID: " << query_id << LL_ENDL; + LLStringUtil::format_map_t map; + map["[TEXT]"] = self->mCurrentQuery.text; + pResults->setCommentText(self->getString("not_found", map)); + } + else + { + LL_DEBUGS("Search") << "Got: " << name << " ClassifiedID: " << classified_id << LL_ENDL; + pResults->setEnabled(TRUE); + + LLSD element; + + element["id"] = classified_id; + + element["columns"][0]["column"] = "icon"; + element["columns"][0]["type"] = "icon"; + element["columns"][0]["value"] = "icon_top_pick.tga"; + + element["columns"][1]["column"] = "name"; + element["columns"][1]["value"] = name; + + element["columns"][2]["column"] = "price"; + element["columns"][2]["value"] = price_for_listing; + + pResults->addElement(element, ADD_BOTTOM); + } + } + self->paginate(); +} + +// static +void LLFloaterDirectory::processSearchLandReply(LLMessageSystem* msg, void**) +{ + LLUUID agent_id; + LLUUID query_id; + LLUUID parcel_id; + std::string name; + std::string land_sku; + std::string land_type; + BOOL auction; + BOOL for_sale; + S32 price; + S32 area; + + msg->getUUIDFast(_PREHASH_QueryData, _PREHASH_QueryID, query_id); + msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id); + + if (agent_id != gAgent.getID()) return; // not for us + LL_DEBUGS("Search") << "Received results for query id: " << query_id << LL_ENDL; + + LLFloaterDirectory* self = LLFloaterReg::findTypedInstance<LLFloaterDirectory>("search"); + if (self == nullptr || query_id != self->mQueryID) return; // not the result we're waiting for + + self->setProgress(false); + LLScrollListCtrl* pResults = self->mResultList; + + // Check for status messages + if (msg->getNumberOfBlocks("StatusData")) + { + U32 status; + msg->getU32("StatusData", "Status", status); + if (status & STATUS_SEARCH_PLACES_FOUNDNONE) + { + LLStringUtil::format_map_t map; + map["[TEXT]"] = self->mCurrentQuery.text; + pResults->setCommentText(self->getString("not_found", map)); + return; + } + else if(status & STATUS_SEARCH_PLACES_SHORTSTRING) + { + pResults->setCommentText(self->getString("search_short")); + return; + } + else if (status & STATUS_SEARCH_PLACES_BANNEDWORD) + { + pResults->setCommentText(self->getString("search_banned")); + return; + } + else if (status & STATUS_SEARCH_PLACES_SEARCHDISABLED) + { + pResults->setCommentText(self->getString("search_disabled")); + return; + } + } + + S32 num_new_rows = msg->getNumberOfBlocksFast(_PREHASH_QueryReplies); + if (num_new_rows == 0) + { + LLStringUtil::format_map_t map; + map["[TEXT]"] = self->mCurrentQuery.text; + pResults->setCommentText(self->getString("not_found", map)); + } + + self->mNumResultsReceived += num_new_rows; + for (S32 i = 0; i < num_new_rows; ++i) + { + msg->getUUID( "QueryReplies", "ParcelID", parcel_id, i); + msg->getString( "QueryReplies", "Name", name, i); + msg->getBOOL( "QueryReplies", "Auction", auction, i); + msg->getBOOL( "QueryReplies", "ForSale", for_sale, i); + msg->getS32( "QueryReplies", "SalePrice", price, i); + msg->getS32( "QueryReplies", "ActualArea", area, i); + if (parcel_id.isNull()) + { + LL_DEBUGS("Search") << "Null result returned for QueryID: " << query_id << LL_ENDL; + pResults->setCommentText(self->getString("no_results")); + } + else + { + LL_DEBUGS("Search") << "Got: " << name << " ClassifiedID: " << parcel_id << LL_ENDL; + pResults->setEnabled(TRUE); + if ( msg->getSizeFast(_PREHASH_QueryReplies, i, _PREHASH_ProductSKU) > 0 ) + { + msg->getStringFast( _PREHASH_QueryReplies, _PREHASH_ProductSKU, land_sku, i); + land_type = LLProductInfoRequestManager::instance().getDescriptionForSku(land_sku); + } + else + { + land_sku.clear(); + land_type = LLTrans::getString("land_type_unknown"); + } + if (parcel_id.isNull()) + continue; + + LLSD element; + + element["id"] = parcel_id; + if (auction) + { + element["columns"][0]["column"] = "icon"; + element["columns"][0]["type"] = "icon"; + element["columns"][0]["value"] = "Icon_Auction"; + } + else if (for_sale) + { + element["columns"][0]["column"] = "icon"; + element["columns"][0]["type"] = "icon"; + element["columns"][0]["value"] = "Icon_For_Sale"; + } + else + { + element["columns"][0]["column"] = "icon"; + element["columns"][0]["type"] = "icon"; + element["columns"][0]["value"] = "Icon_Place"; + } + + element["columns"][1]["column"] = "name"; + element["columns"][1]["value"] = name; + + std::string buffer = "Auction"; + if (!auction) + { + buffer = llformat("%d", price); + } + element["columns"][2]["column"] = "price"; + element["columns"][2]["value"] = price; + + element["columns"][3]["column"] = "area"; + element["columns"][3]["value"] = area; + if (!auction) + { + F32 ppm; + if (area > 0) + ppm = (F32)price / (F32)area; + else + ppm = 0.f; + std::string buffer = llformat("%.1f", ppm); + element["columns"][4]["column"] = "ppm"; + element["columns"][4]["value"] = buffer; + } + else + { + element["columns"][4]["column"] = "ppm"; + element["columns"][4]["value"] = "1.0"; + } + + element["columns"][5]["column"] = "type"; + element["columns"][5]["value"] = land_type; + + pResults->addElement(element, ADD_BOTTOM); + } + } + self->paginate(); +} + +// static +void LLFloaterDirectory::processSearchEventsReply(LLMessageSystem* msg, void**) +{ + LLUUID agent_id; + LLUUID query_id; + LLUUID owner_id; + std::string name; + std::string date; + + msg->getUUIDFast(_PREHASH_QueryData, _PREHASH_QueryID, query_id); + msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id); + + if (agent_id != gAgent.getID()) return; // not for us + LL_DEBUGS("Search") << "Received results for query id: " << query_id << LL_ENDL; + + LLFloaterDirectory* self = LLFloaterReg::findTypedInstance<LLFloaterDirectory>("search"); + if (self == nullptr || query_id != self->mQueryID) return; // not the result we're waiting for + + self->setProgress(false); + LLScrollListCtrl* pResults = self->mResultList; + + // Check for status messages + if (msg->getNumberOfBlocks("StatusData")) + { + U32 status; + msg->getU32("StatusData", "Status", status); + if (status & STATUS_SEARCH_EVENTS_FOUNDNONE) + { + LLStringUtil::format_map_t map; + map["[TEXT]"] = self->mCurrentQuery.text; + pResults->setCommentText(self->getString("not_found", map)); + return; + } + else if(status & STATUS_SEARCH_EVENTS_SHORTSTRING) + { + pResults->setCommentText(self->getString("search_short")); + return; + } + else if (status & STATUS_SEARCH_EVENTS_BANNEDWORD) + { + pResults->setCommentText(self->getString("search_banned")); + return; + } + else if (status & STATUS_SEARCH_EVENTS_SEARCHDISABLED) + { + pResults->setCommentText(self->getString("search_disabled")); + return; + } + else if (status & STATUS_SEARCH_EVENTS_NODATEOFFSET) + { + pResults->setCommentText(self->getString("search_no_date_offset")); + return; + } + else if (status & STATUS_SEARCH_EVENTS_NOCATEGORY) + { + pResults->setCommentText(self->getString("search_no_events_category")); + return; + } + else if (status & STATUS_SEARCH_EVENTS_NOQUERY) + { + pResults->setCommentText(self->getString("search_no_query")); + return; + } + } + + S32 num_new_rows = msg->getNumberOfBlocksFast(_PREHASH_QueryReplies); + if (num_new_rows == 0) + { + LLStringUtil::format_map_t map; + map["[TEXT]"] = self->mCurrentQuery.text; + pResults->setCommentText(self->getString("not_found", map)); + } + + self->mNumResultsReceived += num_new_rows; + for (S32 i = 0; i < num_new_rows; ++i) + { + U32 event_id; + //U32 unix_time; + U32 event_flags; + + msg->getUUID( "QueryReplies", "OwnerID", owner_id, i); + msg->getString( "QueryReplies", "Name", name, i); + msg->getU32( "QueryReplies", "EventID", event_id, i); + msg->getString( "QueryReplies", "Date", date, i); + //msg->getU32( "QueryReplies", "UnixTime", unix_time, i); + msg->getU32( "QueryReplies", "EventFlags", event_flags,i); + + static LLUICachedControl<bool> inc_pg("ShowPGEvents", true); + static LLUICachedControl<bool> inc_mature("ShowMatureEvents", false); + static LLUICachedControl<bool> inc_adult("ShowAdultEvents", false); + + // Skip empty events... + if (owner_id.isNull()) + { + LL_INFOS("Search") << "Skipped " << event_id << " because of a NULL owner result" << LL_ENDL; + continue; + } + // Skips events that don't match our scope... + if (((event_flags & (EVENT_FLAG_ADULT | EVENT_FLAG_MATURE)) == EVENT_FLAG_NONE) && !inc_pg) + { + LL_INFOS("Search") << "Skipped " << event_id << " because it was out of scope" << LL_ENDL; + continue; + } + if ((event_flags & EVENT_FLAG_MATURE) && !inc_mature) + { + LL_INFOS("Search") << "Skipped " << event_id << " because it was out of scope" << LL_ENDL; + continue; + } + if ((event_flags & EVENT_FLAG_ADULT) && !inc_adult) + { + LL_INFOS("Search") << "Skipped " << event_id << " because it was out of scope" << LL_ENDL; + continue; + } + pResults->setEnabled(TRUE); + + LLSD element; + + element["id"] = llformat("%u", event_id); + + if (event_flags == EVENT_FLAG_ADULT) + { + element["columns"][0]["column"] = "icon"; + element["columns"][0]["type"] = "icon"; + element["columns"][0]["value"] = "Parcel_R_Dark"; + } + else if (event_flags == EVENT_FLAG_MATURE) + { + element["columns"][0]["column"] = "icon"; + element["columns"][0]["type"] = "icon"; + element["columns"][0]["value"] = "Parcel_M_Dark"; + } + else + { + element["columns"][0]["column"] = "icon"; + element["columns"][0]["type"] = "icon"; + element["columns"][0]["value"] = "Parcel_PG_Dark"; + } + + element["columns"][1]["column"] = "name"; + element["columns"][1]["value"] = name; + + element["columns"][2]["column"] = "date"; + element["columns"][2]["value"] = date; + + //element["columns"][3]["column"] = "time"; + //element["columns"][3]["value"] = llformat("%u", unix_time); + + pResults->addElement(element, ADD_BOTTOM); + } + self->paginate(); +} diff --git a/indra/newview/llfloaterdirectory.h b/indra/newview/llfloaterdirectory.h new file mode 100644 index 0000000000000000000000000000000000000000..0817f223ab432cc88409a3bda40df146d6d8075f --- /dev/null +++ b/indra/newview/llfloaterdirectory.h @@ -0,0 +1,134 @@ +/* + * @file llfloaterdirectory.h + * @brief Legacy search facility definitions + * + * Copyright (c) 2014-2022, Cinder Roxley <cinder@sdf.org> + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef LL_FLOATERDIRECTORY_H +#define LL_FLOATERDIRECTORY_H + +#include "llfloater.h" +#include "llsdparam.h" + +class LLUICtrl; +class LLPanel; +class LLPanelSearchWeb; +class LLScrollListCtrl; +class LLTabContainer; +class LLTextBase; + +static const size_t MIN_SEARCH_STRING_SIZE = 3; + +typedef enum { + SE_UNDEFINED = 0, + SE_PEOPLE, + SE_GROUPS, + SE_PLACES, + SE_LANDSALES, + SE_EVENTS, + SE_CLASSIFIEDS +} ESearch; + +struct SearchQuery : public LLInitParam::Block<SearchQuery> +{ + Optional<std::string> category; + Optional<std::string> collection; + Optional<std::string> query; + + SearchQuery(); +}; + +typedef struct dir_query +{ + dir_query() + : type(SE_UNDEFINED), text(LLStringUtil::null), scope(0), + category_int(0), category_char(0x0), price(0), area(0), results_per_page(100) {} + ESearch type; + std::string text; + U32 scope; + U32 category_int; + S8 category_char; + S32 price; + S32 area; + U32 results_per_page; +} LLDirQuery; + +class LLFloaterDirectory : public LLFloater +{ + friend class LLPanelSearchClassifieds; + friend class LLPanelSearchEvents; + friend class LLPanelSearchGroups; + friend class LLPanelSearchLandSales; + friend class LLPanelSearchPeople; + friend class LLPanelSearchPlaces; + +public: + struct _Params : LLInitParam::Block<_Params, LLFloater::Params> + { + Optional<SearchQuery> search; + }; + typedef LLSDParamAdapter<_Params> Params; + + LLFloaterDirectory(const Params& key); + BOOL postBuild() override; + void onOpen(const LLSD& key) override; + void onClose(bool app_quitting) override; + + static void processSearchPeopleReply(LLMessageSystem* msg, void**); + static void processSearchGroupsReply(LLMessageSystem* msg, void**); + static void processSearchPlacesReply(LLMessageSystem* msg, void**); + static void processSearchClassifiedsReply(LLMessageSystem* msg, void**); + static void processSearchLandReply(LLMessageSystem* msg, void**); + static void processSearchEventsReply(LLMessageSystem* msg, void**); + +protected: + void setProgress(bool working); + void queryDirectory(const LLDirQuery& query, bool new_search = false); + void setResultsComment(const std::string& message); + +private: + ~LLFloaterDirectory(); + void onCommitSelection(); + void choosePage(LLUICtrl* ctrl); + void onTabChanged(); + void paginate(); + void showDetailPanel(const std::string& panel_name); + void rebuildResultList(); + + ESearch mCurrentResultType; + LLDirQuery mCurrentQuery; + S32 mResultStart; + S32 mNumResultsReceived; + LLUUID mQueryID; + + LLTabContainer* mTabContainer; + LLPanelSearchWeb* mPanelWeb; + LLScrollListCtrl* mResultList; + LLTextBase* mResultsStatus; +}; + +#endif // LL_FLOATERDIRECTORY_H diff --git a/indra/newview/llfloaterevent.cpp b/indra/newview/llfloaterevent.cpp index b07f2963b270439d8b2c59e12be7d8169f6368e0..92d762fa9cb37bcfe3abca4e7d4bbc33cb013ee4 100644 --- a/indra/newview/llfloaterevent.cpp +++ b/indra/newview/llfloaterevent.cpp @@ -3,8 +3,9 @@ * @brief Display for events in the finder * * $LicenseInfo:firstyear=2004&license=viewerlgpl$ - * Second Life Viewer Source Code + * Alchemy Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2014, Cinder Roxley @ Second Life * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -27,93 +28,20 @@ #include "llviewerprecompiledheaders.h" #include "llfloaterevent.h" - -#include "message.h" -#include "llnotificationsutil.h" -#include "llui.h" - -#include "llagent.h" -#include "llviewerwindow.h" -#include "llbutton.h" -#include "llcachename.h" -#include "llcommandhandler.h" // secondlife:///app/chat/ support -#include "lleventflags.h" -#include "llmediactrl.h" -#include "llexpandabletextbox.h" -#include "llfloater.h" -#include "llfloaterreg.h" -#include "llmediactrl.h" -#include "llfloaterworldmap.h" -#include "llinventorymodel.h" -#include "llslurl.h" -#include "lltextbox.h" -#include "lltexteditor.h" -#include "lluiconstants.h" -#include "llviewercontrol.h" -#include "llweb.h" -#include "llworldmap.h" -#include "llworldmapmessage.h" -#include "lluictrlfactory.h" -#include "lltrans.h" +#include "llpaneleventinfo.h" LLFloaterEvent::LLFloaterEvent(const LLSD& key) - : LLFloater(key), - LLViewerMediaObserver(), - mBrowser(NULL), - mEventID(0) -{ -} - - -LLFloaterEvent::~LLFloaterEvent() -{ -} - - -BOOL LLFloaterEvent::postBuild() +: LLFloater(key) +, mEventId(0) { - mBrowser = getChild<LLMediaCtrl>("browser"); - if (mBrowser) - { - mBrowser->addObserver(this); - } - return TRUE; -} - -void LLFloaterEvent::handleMediaEvent(LLPluginClassMedia *self, EMediaEvent event) -{ - switch (event) - { - case MEDIA_EVENT_NAVIGATE_BEGIN: - getChild<LLUICtrl>("status_text")->setValue(getString("loading_text")); - break; - - case MEDIA_EVENT_NAVIGATE_COMPLETE: - getChild<LLUICtrl>("status_text")->setValue(getString("done_text")); - break; - - default: - break; - } } void LLFloaterEvent::setEventID(const U32 event_id) { - mEventID = event_id; - - if (event_id != 0) - { - LLSD subs; - subs["EVENT_ID"] = (S32)event_id; - // get the search URL and expand all of the substitutions - // (also adds things like [LANGUAGE], [VERSION], [OS], etc.) - - std::string expanded_url = LLWeb::expandURLSubstitutions(gSavedSettings.getString("EventURL"), subs); - - // and load the URL in the web view - mBrowser->navigateTo(expanded_url); + mEventId = event_id; + if (event_id == 0) closeFloater(); - } + getChild<LLPanel>("event_panel")->onOpen(mEventId); } diff --git a/indra/newview/llfloaterevent.h b/indra/newview/llfloaterevent.h index 169ce246ecb5c1ba902a1f8de0e6096ddfa97c0e..50eb86e07cbf7c0bb9193cd935d103c1ca2c09d5 100644 --- a/indra/newview/llfloaterevent.h +++ b/indra/newview/llfloaterevent.h @@ -3,8 +3,9 @@ * @brief Display for events in the finder * * $LicenseInfo:firstyear=2004&license=viewerlgpl$ - * Second Life Viewer Source Code + * Alchemy Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2014, Cinder Roxley @ Second Life * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -28,35 +29,17 @@ #define LL_LLFLOATEREVENT_H #include "llfloater.h" -#include "llviewermediaobserver.h" - -class LLMediaCtrl; -class LLButton; - -class LLFloaterEvent final : public LLFloater, - public LLViewerMediaObserver +class LLFloaterEvent final : public LLFloater { public: LLFloaterEvent(const LLSD& key); - /*virtual*/ ~LLFloaterEvent(); - - /*virtual*/ BOOL postBuild(); - + /*virtual*/ ~LLFloaterEvent() = default; void setEventID(const U32 event_id); - U32 getEventID() { return mEventID; } - - - -protected: - /*virtual*/ void handleMediaEvent(LLPluginClassMedia *self, EMediaEvent event); - - U32 mEventID; - - LLMediaCtrl* mBrowser; - +private: + S32 mEventId; }; #endif // LL_LLFLOATEREVENT_H diff --git a/indra/newview/llfloaterjoystick.cpp b/indra/newview/llfloaterjoystick.cpp index c3bc8e2f2b3703e11a4b907caa151f8f27c29598..03e587e38eea87ca46551b3a7c45cfb20c7708c9 100644 --- a/indra/newview/llfloaterjoystick.cpp +++ b/indra/newview/llfloaterjoystick.cpp @@ -134,15 +134,15 @@ void LLFloaterJoystick::draw() } } - for (U32 i = 0; i < 16; i++) - { + for (U32 i = 0; i < 16; i++) + { U32 value = joystick->getJoystickButton(i); - if (!mAxisButton[i]->getEnabled() && value) - { - mAxisButton[i]->setEnabled(TRUE); - } - mAxisButton[i]->setToggleState(value); - } + if (!mAxisButton[i]->getEnabled() && value) + { + mAxisButton[i]->setEnabled(TRUE); + } + mAxisButton[i]->setToggleState(value); + } LLFloater::draw(); } @@ -163,11 +163,11 @@ BOOL LLFloaterJoystick::postBuild() } } - for (U32 i = 0; i < 16; i++) - { - std::string btn_name = llformat("btn%d", i); - mAxisButton[i] = getChild<LLButton>(btn_name); - } + for (U32 i = 0; i < 16; i++) + { + std::string btn_name = llformat("btn%d", i); + mAxisButton[i] = getChild<LLButton>(btn_name); + } mJoysticksCombo = getChild<LLComboBox>("joystick_combo"); childSetCommitCallback("joystick_combo",onCommitJoystickEnabled,this); diff --git a/indra/newview/llfloaterjoystick.h b/indra/newview/llfloaterjoystick.h index ebc1a26190cec024421a637ab7749b83f11e25f3..5aa0dbd0104d957ff1f9e98531b4a095dde2872b 100644 --- a/indra/newview/llfloaterjoystick.h +++ b/indra/newview/llfloaterjoystick.h @@ -101,7 +101,7 @@ class LLFloaterJoystick final : public LLFloater // stats view LLStatBar* mAxisStatsBar[6]; - LLButton* mAxisButton[16]; + LLButton* mAxisButton[16]; }; #endif diff --git a/indra/newview/llfloaterprofilelegacy.cpp b/indra/newview/llfloaterprofilelegacy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..78df15de899971f367e5c2dff917f83d16f1e3a1 --- /dev/null +++ b/indra/newview/llfloaterprofilelegacy.cpp @@ -0,0 +1,81 @@ +/* + * @file llfloaterprofilelegacy.cpp + * @brief Floater that holds panel don't bitch about it, Dog; Merging is easy. + * + * Copyright (c) 2017-2022, Cinder Roxley <cinder@sdf.org> + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "llviewerprecompiledheaders.h" +#include "llfloaterprofilelegacy.h" + +#include "llavatarname.h" +#include "llavatarnamecache.h" +#include "llpanelprofilelegacy.h" + +LLFloaterProfileLegacy::LLFloaterProfileLegacy(LLSD const& key) +: LLFloater(key) +{ + +} + +LLFloaterProfileLegacy::~LLFloaterProfileLegacy() +{ + if (mAvatarNameCacheConnection.connected()) + mAvatarNameCacheConnection.disconnect(); +} + +BOOL LLFloaterProfileLegacy::postBuild() +{ + mPanel = dynamic_cast<LLPanelProfileLegacy*>(getChild<LLPanel>("panel_profile_legacy_sidetray")); + return TRUE; +} + +void LLFloaterProfileLegacy::onOpen(const LLSD& key) +{ + if (!key.has("avatar_id")) return; + const LLUUID av_id = key["avatar_id"].asUUID(); + + mAvatarNameCacheConnection = LLAvatarNameCache::get(av_id, + boost::bind(&LLFloaterProfileLegacy::onAvatarNameCache, this, _1, _2)); + + if (mPanel) { mPanel->onOpen(key); } +} + +void LLFloaterProfileLegacy::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name) +{ + setTitle(av_name.getCompleteName()); + mAvatarNameCacheConnection.disconnect(); +} + +LLPanel* LLFloaterProfileLegacy::expandTab(const std::string& name) const +{ + return mPanel != nullptr ? mPanel->expandTab(name) : nullptr; +} + +LLPanel* LLFloaterProfileLegacy::getExpandedTab() const +{ + return mPanel != nullptr ? mPanel->getExpandedTab() : nullptr; +} diff --git a/indra/newview/llfloaterprofilelegacy.h b/indra/newview/llfloaterprofilelegacy.h new file mode 100644 index 0000000000000000000000000000000000000000..59c9381fd8640ba8bc56931e383b92220cdf4d79 --- /dev/null +++ b/indra/newview/llfloaterprofilelegacy.h @@ -0,0 +1,58 @@ +/* +* @file llfloaterlegacyprofile.h +* @brief Floater that holds panel +* +* Copyright (c) 2017-2022, Cinder Roxley <cinder@sdf.org> +* +* Permission is hereby granted, free of charge, to any person or organization +* obtaining a copy of the software and accompanying documentation covered by +* this license (the "Software") to use, reproduce, display, distribute, +* execute, and transmit the Software, and to prepare derivative works of the +* Software, and to permit third-parties to whom the Software is furnished to +* do so, all subject to the following: +* +* The copyright notices in the Software and this entire statement, including +* the above license grant, this restriction and the following disclaimer, +* must be included in all copies of the Software, in whole or in part, and +* all derivative works of the Software, unless such copies or derivative +* works are solely in the form of machine-executable object code generated by +* a source language processor. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +* DEALINGS IN THE SOFTWARE. +* +*/ + +#ifndef LL_FLOATERLEGACYPROFILE_H +#define LL_FLOATERLEGACYPROFILE_H + +#include "llfloater.h" + +class LLAvatarName; +class LLPanelProfileLegacy; +class LLPanelProfileLegacyTab; + +class LLFloaterProfileLegacy final : public LLFloater +{ +public: + LLFloaterProfileLegacy(LLSD const& key); + BOOL postBuild() override; + void onOpen(const LLSD& key) override; + + LLPanel* expandTab(const std::string& name) const; + LLPanel* getExpandedTab() const; + +private: + ~LLFloaterProfileLegacy() override; + void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name); + + LLPanelProfileLegacy* mPanel; + boost::signals2::connection mAvatarNameCacheConnection; +}; + +#endif // LL_FLOATERLEGACYPROFILE_H diff --git a/indra/newview/llfloaterpublishclassified.cpp b/indra/newview/llfloaterpublishclassified.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b19cc8f97e2f33d3549a67054591561219116a49 --- /dev/null +++ b/indra/newview/llfloaterpublishclassified.cpp @@ -0,0 +1,63 @@ +/** + * @file llfloaterpublishclassified.cpp + * @brief Publish classified floater + * + * $LicenseInfo:firstyear=2004&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llfloaterpublishclassified.h" + +LLFloaterPublishClassified::LLFloaterPublishClassified(const LLSD& key) + : LLFloater(key) +{ +} + +BOOL LLFloaterPublishClassified::postBuild() +{ + LLFloater::postBuild(); + + childSetAction("publish_btn", boost::bind(&LLFloater::closeFloater, this, false)); + childSetAction("cancel_btn", boost::bind(&LLFloater::closeFloater, this, false)); + + return TRUE; +} + +void LLFloaterPublishClassified::setPrice(S32 price) +{ + getChild<LLUICtrl>("price_for_listing")->setValue(price); +} + +S32 LLFloaterPublishClassified::getPrice() +{ + return getChild<LLUICtrl>("price_for_listing")->getValue().asInteger(); +} + +void LLFloaterPublishClassified::setPublishClickedCallback(const commit_signal_t::slot_type& cb) +{ + getChild<LLButton>("publish_btn")->setClickedCallback(cb); +} + +void LLFloaterPublishClassified::setCancelClickedCallback(const commit_signal_t::slot_type& cb) +{ + getChild<LLButton>("cancel_btn")->setClickedCallback(cb); +} diff --git a/indra/newview/llfloaterpublishclassified.h b/indra/newview/llfloaterpublishclassified.h new file mode 100644 index 0000000000000000000000000000000000000000..f5d79656119eb3c212d9fa0f5369f91188a2ff9b --- /dev/null +++ b/indra/newview/llfloaterpublishclassified.h @@ -0,0 +1,48 @@ +/** + * @file llfloaterpublishclassified.h + * @brief Publish classified floater + * + * $LicenseInfo:firstyear=2004&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + + +#ifndef LL_PUBLISHCLASSIFIEDFLOATER_H +#define LL_PUBLISHCLASSIFIEDFLOATER_H + +#include "llfloater.h" + +class LLFloaterPublishClassified final : public LLFloater +{ +public: + LLFloaterPublishClassified(const LLSD& key); + ~LLFloaterPublishClassified() override = default; + + BOOL postBuild() override; + + void setPrice(S32 price); + S32 getPrice(); + + void setPublishClickedCallback(const commit_signal_t::slot_type& cb); + void setCancelClickedCallback(const commit_signal_t::slot_type& cb); +}; + +#endif // LL_PUBLISHCLASSIFIEDFLOATER_H diff --git a/indra/newview/llfloaterwebprofile.cpp b/indra/newview/llfloaterwebprofile.cpp new file mode 100644 index 0000000000000000000000000000000000000000..05ec0028548ba3ba2c5c91034f428f46af3d6fa8 --- /dev/null +++ b/indra/newview/llfloaterwebprofile.cpp @@ -0,0 +1,81 @@ +/** + * @file llfloaterwebprofile.cpp + * @brief Web profile floater. + * + * $LicenseInfo:firstyear=2009&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloaterwebprofile.h" + +#include "llviewercontrol.h" + +LLFloaterWebProfile::LLFloaterWebProfile(const Params& key) : + LLFloaterWebContent(key) +{ +} + +void LLFloaterWebProfile::onOpen(const LLSD& key) +{ + Params p(key); + p.show_chrome(true); + p.window_class("web_content"); + p.allow_address_entry(false); + p.trusted_content(true); + LLFloaterWebContent::onOpen(p); + applyPreferredRect(); +} + +// virtual +void LLFloaterWebProfile::handleReshape(const LLRect& new_rect, bool by_user) +{ + LL_DEBUGS() << "handleReshape: " << new_rect << LL_ENDL; + + if (by_user && !isMinimized()) + { + LL_DEBUGS() << "Storing new rect" << LL_ENDL; + gSavedSettings.setRect("WebProfileFloaterRect", new_rect); + } + + LLFloaterWebContent::handleReshape(new_rect, by_user); +} + +LLFloater* LLFloaterWebProfile::create(const LLSD& key) +{ + LLFloaterWebContent::Params p(key); + preCreate(p); + return new LLFloaterWebProfile(p); +} + +void LLFloaterWebProfile::applyPreferredRect() +{ + const LLRect preferred_rect = gSavedSettings.getRect("WebProfileFloaterRect"); + LL_DEBUGS() << "Applying preferred rect: " << preferred_rect << LL_ENDL; + + // Don't override position that may have been set by floater stacking code. + LLRect new_rect = getRect(); + new_rect.setLeftTopAndSize( + new_rect.mLeft, new_rect.mTop, + preferred_rect.getWidth(), preferred_rect.getHeight()); + setShape(new_rect); +} diff --git a/indra/newview/llfloaterwebprofile.h b/indra/newview/llfloaterwebprofile.h new file mode 100644 index 0000000000000000000000000000000000000000..df9ebc892850144353c0c85da8849a664433da4e --- /dev/null +++ b/indra/newview/llfloaterwebprofile.h @@ -0,0 +1,56 @@ +/** + * @file llfloaterwebprofile.h + * @brief Web profile floater. + * + * $LicenseInfo:firstyear=2009&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLFLOATERWEBPROFILE_H +#define LL_LLFLOATERWEBPROFILE_H + +#include "llfloaterwebcontent.h" +#include "llviewermediaobserver.h" + +class LLMediaCtrl; + +/** + * Displays avatar profile web page. + */ +class LLFloaterWebProfile final +: public LLFloaterWebContent +{ + LOG_CLASS(LLFloaterWebProfile); +public: + typedef LLFloaterWebContent::Params Params; + + LLFloaterWebProfile(const Params& key); + + /*virtual*/ void onOpen(const LLSD& key) override; + /*virtual*/ void handleReshape(const LLRect& new_rect, bool by_user = false) override; + + static LLFloater* create(const LLSD& key); + +private: + void applyPreferredRect(); +}; + +#endif // LL_LLFLOATERWEBPROFILE_H diff --git a/indra/newview/llhudeffectresetskeleton.h b/indra/newview/llhudeffectresetskeleton.h index 39a613705481319a639700c194faafe8b5a750ee..ddac84165f39ec24521b1f8dc17e09920c24cd9e 100644 --- a/indra/newview/llhudeffectresetskeleton.h +++ b/indra/newview/llhudeffectresetskeleton.h @@ -1,25 +1,25 @@ -/** +/** * @file llhudeffectresetskeleton.h * @brief LLHUDEffectResetSkeleton class definition * * $LicenseInfo:firstyear=2024&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2024, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library 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 * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -36,24 +36,24 @@ class LLVOAvatar; class LLHUDEffectResetSkeleton final : public LLHUDEffect { public: - friend class LLHUDObject; + friend class LLHUDObject; - /*virtual*/ void markDead(); - /*virtual*/ void setSourceObject(LLViewerObject* objectp); + /*virtual*/ void markDead(); + /*virtual*/ void setSourceObject(LLViewerObject* objectp); - void setTargetObject(LLViewerObject *objp); - void setResetAnimations(bool enable){ mResetAnimations = enable; }; + void setTargetObject(LLViewerObject *objp); + void setResetAnimations(bool enable){ mResetAnimations = enable; }; protected: - LLHUDEffectResetSkeleton(const U8 type); - ~LLHUDEffectResetSkeleton(); + LLHUDEffectResetSkeleton(const U8 type); + ~LLHUDEffectResetSkeleton(); - /*virtual*/ void packData(LLMessageSystem *mesgsys); - /*virtual*/ void unpackData(LLMessageSystem *mesgsys, S32 blocknum); + /*virtual*/ void packData(LLMessageSystem *mesgsys); + /*virtual*/ void unpackData(LLMessageSystem *mesgsys, S32 blocknum); - void update(); + void update(); private: - bool mResetAnimations; + bool mResetAnimations; }; #endif // LL_LLHUDEFFECTRESETSKELETON_H diff --git a/indra/newview/llpanelavatarlegacy.cpp b/indra/newview/llpanelavatarlegacy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c0a943b6757998982ebb0869f80cc034782aa329 --- /dev/null +++ b/indra/newview/llpanelavatarlegacy.cpp @@ -0,0 +1,109 @@ +/** + * @file llpanelavatarlegacy.cpp + * @brief LLPanelAvatar and related class implementations + * + * $LicenseInfo:firstyear=2004&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llpanelavatarlegacy.h" + +#include "llagent.h" +#include "llavataractions.h" +#include "llcallingcard.h" + +#include "llscrollcontainer.h" +#include "llavatariconctrl.h" +#include "lltextbox.h" + +LLPanelProfileLegacyTab::LLPanelProfileLegacyTab() +: LLPanel() +, mAvatarId(LLUUID::null) +{ +} + +LLPanelProfileLegacyTab::~LLPanelProfileLegacyTab() +{ + if(getAvatarId().notNull()) + { + LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this); + } +} + +void LLPanelProfileLegacyTab::setAvatarId(const LLUUID& id) +{ + if(id.notNull()) + { + if(getAvatarId().notNull()) + { + LLAvatarPropertiesProcessor::getInstance()->removeObserver(mAvatarId,this); + } + mAvatarId = id; + LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(),this); + } +} + +void LLPanelProfileLegacyTab::onOpen(const LLSD& key) +{ + // Don't reset panel if we are opening it for same avatar. + if(getAvatarId() != key.asUUID()) + { + resetControls(); + resetData(); + + scrollToTop(); + } + + // Update data even if we are viewing same avatar profile as some data might been changed. + setAvatarId(key.asUUID()); + updateData(); + updateButtons(); +} + +void LLPanelProfileLegacyTab::scrollToTop() const +{ + LLScrollContainer* scrollContainer = findChild<LLScrollContainer>("profile_scroll"); + if (scrollContainer) + scrollContainer->goToTop(); +} + +void LLPanelProfileLegacyTab::onMapButtonClick() +{ + LLAvatarActions::showOnMap(getAvatarId()); +} + +void LLPanelProfileLegacyTab::updateButtons() +{ + bool is_buddy_online = LLAvatarTracker::instance().isBuddyOnline(getAvatarId()); + + if(LLAvatarActions::isFriend(getAvatarId())) + { + getChildView("teleport")->setEnabled(is_buddy_online); + } + else + { + getChildView("teleport")->setEnabled(true); + } + + bool enable_map_btn = (is_buddy_online && LLAvatarActions::isAgentMappable(getAvatarId())) || gAgent.isGodlike(); + getChildView("show_on_map_btn")->setEnabled(enable_map_btn); +} diff --git a/indra/newview/llpanelavatarlegacy.h b/indra/newview/llpanelavatarlegacy.h new file mode 100644 index 0000000000000000000000000000000000000000..ef442b16bc55eb98eaa4569d48bee9ff00d79830 --- /dev/null +++ b/indra/newview/llpanelavatarlegacy.h @@ -0,0 +1,105 @@ +/** + * @file llpanelavatarlegacy.h + * @brief LLPanelAvatar and related class definitions + * + * $LicenseInfo:firstyear=2004&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLPANELAVATARLEGACY_H +#define LL_LLPANELAVATARLEGACY_H + +#include "llpanel.h" +#include "llavatarpropertiesprocessor.h" + +class LLComboBox; +class LLLineEditor; + +/** +* Base class for any Profile View. +*/ +class LLPanelProfileLegacyTab + : public LLPanel + , public LLAvatarPropertiesObserver +{ +public: + + /** + * Sets avatar ID, sets panel as observer of avatar related info replies from server. + */ + virtual void setAvatarId(const LLUUID& id); + + /** + * Returns avatar ID. + */ + virtual const LLUUID& getAvatarId() { return mAvatarId; } + + /** + * Sends update data request to server. + */ + virtual void updateData() = 0; + + /** + * Clears panel data if viewing avatar info for first time and sends update data request. + */ + void onOpen(const LLSD& key) override; + + /** + * Profile tabs should close any opened panels here. + * + * Called from LLPanelProfile::onOpen() before opening new profile. + * See LLPanelPicks::onClosePanel for example. LLPanelPicks closes picture info panel + * before new profile is displayed, otherwise new profile will + * be hidden behind picture info panel. + */ + virtual void onClosePanel() {} + + /** + * Resets controls visibility, state, etc. + */ + virtual void resetControls(){}; + + /** + * Clears all data received from server. + */ + virtual void resetData(){}; + + ~LLPanelProfileLegacyTab() override; + +protected: + + LLPanelProfileLegacyTab(); + + /** + * Scrolls panel to top when viewing avatar info for first time. + */ + void scrollToTop() const; + + virtual void onMapButtonClick(); + + virtual void updateButtons(); + +private: + + LLUUID mAvatarId; +}; + +#endif // LL_LLPANELAVATARLEGACY_H diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp index 11d12394592d427b73b3ff85c0432f98446ddee7..b8b95fc711a8e3692df07413770a14e96d4958e0 100644 --- a/indra/newview/llpanelclassified.cpp +++ b/indra/newview/llpanelclassified.cpp @@ -34,21 +34,32 @@ #include "lldispatcher.h" #include "llfloaterreg.h" +#include "llnotifications.h" +#include "llnotificationsutil.h" #include "llparcel.h" #include "llagent.h" #include "llclassifiedflags.h" +#include "llclassifiedinfo.h" #include "lliconctrl.h" +#include "lllineeditor.h" +#include "llcombobox.h" +#include "lllogininstance.h" #include "lltexturectrl.h" +#include "lltexteditor.h" +#include "llviewerparcelmgr.h" #include "llfloaterworldmap.h" #include "llviewergenericmessage.h" // send_generic_message #include "llviewerregion.h" +#include "llviewertexture.h" +#include "lltrans.h" #include "llscrollcontainer.h" +#include "llstatusbar.h" #include "llcorehttputil.h" //static LLPanelClassifiedInfo::panel_list_t LLPanelClassifiedInfo::sAllPanels; -static LLPanelInjector<LLPanelClassifiedInfo> t_panel_panel_classified_info("panel_classified_info"); +static LLPanelInjector<LLPanelClassifiedInfo> t_panel_classified_info("panel_classified_info"); // "classifiedclickthrough" // strings[0] = classified_id @@ -82,6 +93,8 @@ static LLDispatchClassifiedClickThrough sClassifiedClickThrough; ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// +static LLPanelInjector<LLPanelClassifiedInfo> t_classified_info("panel_classified_info"); + LLPanelClassifiedInfo::LLPanelClassifiedInfo() : LLPanel() , mInfoLoaded(false) @@ -103,6 +116,10 @@ LLPanelClassifiedInfo::LLPanelClassifiedInfo() LLPanelClassifiedInfo::~LLPanelClassifiedInfo() { + if (getAvatarId().notNull()) + { + LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this); + } sAllPanels.remove(this); if (getAvatarId().notNull()) @@ -111,8 +128,17 @@ LLPanelClassifiedInfo::~LLPanelClassifiedInfo() } } +// static +LLPanelClassifiedInfo* LLPanelClassifiedInfo::create() +{ + LLPanelClassifiedInfo* panel = new LLPanelClassifiedInfo(); + panel->buildFromFile("panel_classified_info.xml"); + return panel; +} + BOOL LLPanelClassifiedInfo::postBuild() { + childSetAction("back_btn", boost::bind(&LLPanelClassifiedInfo::onExit, this)); childSetAction("show_on_map_btn", boost::bind(&LLPanelClassifiedInfo::onMapClick, this)); childSetAction("teleport_btn", boost::bind(&LLPanelClassifiedInfo::onTeleportClick, this)); @@ -128,6 +154,16 @@ BOOL LLPanelClassifiedInfo::postBuild() return TRUE; } +void LLPanelClassifiedInfo::setExitCallback(const commit_callback_t& cb) +{ + getChild<LLButton>("back_btn")->setClickedCallback(cb); +} + +void LLPanelClassifiedInfo::setEditClassifiedCallback(const commit_callback_t& cb) +{ + getChild<LLButton>("edit_btn")->setClickedCallback(cb); +} + void LLPanelClassifiedInfo::reshape(S32 width, S32 height, BOOL called_from_parent /* = TRUE */) { LLPanel::reshape(width, height, called_from_parent); @@ -156,7 +192,7 @@ void LLPanelClassifiedInfo::onOpen(const LLSD& key) LLUUID avatar_id = key["classified_creator_id"]; if(avatar_id.isNull()) { - return; + //return; } if(getAvatarId().notNull()) @@ -180,6 +216,7 @@ void LLPanelClassifiedInfo::onOpen(const LLSD& key) LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(), this); LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(getClassifiedId()); + gGenericDispatcher.addHandler("classifiedclickthrough", &sClassifiedClickThrough); if (gAgent.getRegion()) @@ -259,9 +296,11 @@ void LLPanelClassifiedInfo::processProperties(void* data, EAvatarProcessorType t LLStringUtil::format(date_str, LLSD().with("datetime", (S32) c_info->creation_date)); getChild<LLUICtrl>("creation_date")->setValue(date_str); - setInfoLoaded(true); + date_str = date_fmt; + LLStringUtil::format(date_str, LLSD().with("datetime", (S32) c_info->expiration_date)); + getChild<LLUICtrl>("expiration_date")->setValue(date_str); - LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this); + setInfoLoaded(true); } } } @@ -372,9 +411,8 @@ void LLPanelClassifiedInfo::setClickThrough( << teleport << ", " << map << ", " << profile << "] (" << (from_new_table ? "new" : "old") << ")" << LL_ENDL; - for (panel_list_t::iterator iter = sAllPanels.begin(); iter != sAllPanels.end(); ++iter) + for (auto self : sAllPanels) { - LLPanelClassifiedInfo* self = *iter; if (self->getClassifiedId() != classified_id) { continue; @@ -566,4 +604,551 @@ void LLPanelClassifiedInfo::onTeleportClick() } } -//EOF +void LLPanelClassifiedInfo::onExit() +{ + LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this); + gGenericDispatcher.addHandler("classifiedclickthrough", nullptr); // deregister our handler +} + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +static const S32 CB_ITEM_MATURE = 0; +static const S32 CB_ITEM_PG = 1; + +LLPanelClassifiedEdit::LLPanelClassifiedEdit() + : LLPanelClassifiedInfo() + , mIsNew(false) + , mIsNewWithErrors(false) + , mCanClose(false) + , mPublishFloater(nullptr) +{ +} + +LLPanelClassifiedEdit::~LLPanelClassifiedEdit() +{ +} + +//static +LLPanelClassifiedEdit* LLPanelClassifiedEdit::create() +{ + LLPanelClassifiedEdit* panel = new LLPanelClassifiedEdit(); + panel->buildFromFile("panel_edit_classified.xml"); + return panel; +} + +BOOL LLPanelClassifiedEdit::postBuild() +{ + LLPanelClassifiedInfo::postBuild(); + + LLUICtrl* edit_icon = getChild<LLUICtrl>("edit_icon"); + mSnapshotCtrl->setMouseEnterCallback(boost::bind(&LLPanelClassifiedEdit::onTexturePickerMouseEnter, this, edit_icon)); + mSnapshotCtrl->setMouseLeaveCallback(boost::bind(&LLPanelClassifiedEdit::onTexturePickerMouseLeave, this, edit_icon)); + edit_icon->setVisible(false); + + LLLineEditor* line_edit = getChild<LLLineEditor>("classified_name"); + line_edit->setKeystrokeCallback(boost::bind(&LLPanelClassifiedEdit::onChange, this), nullptr); + + LLTextEditor* text_edit = getChild<LLTextEditor>("classified_desc"); + text_edit->setKeystrokeCallback(boost::bind(&LLPanelClassifiedEdit::onChange, this)); + + LLComboBox* combobox = getChild<LLComboBox>( "category"); + LLClassifiedInfo::cat_map::iterator iter; + for (iter = LLClassifiedInfo::sCategories.begin(); + iter != LLClassifiedInfo::sCategories.end(); + iter++) + { + combobox->add(LLTrans::getString(iter->second)); + } + + combobox->setCommitCallback(boost::bind(&LLPanelClassifiedEdit::onChange, this)); + + childSetCommitCallback("content_type", boost::bind(&LLPanelClassifiedEdit::onChange, this), nullptr); + childSetCommitCallback("price_for_listing", boost::bind(&LLPanelClassifiedEdit::onChange, this), nullptr); + childSetCommitCallback("auto_renew", boost::bind(&LLPanelClassifiedEdit::onChange, this), nullptr); + + childSetAction("save_changes_btn", boost::bind(&LLPanelClassifiedEdit::onSaveClick, this)); + childSetAction("set_to_curr_location_btn", boost::bind(&LLPanelClassifiedEdit::onSetLocationClick, this)); + + mSnapshotCtrl->setOnSelectCallback(boost::bind(&LLPanelClassifiedEdit::onTextureSelected, this)); + + return TRUE; +} + +void LLPanelClassifiedEdit::fillIn(const LLSD& key) +{ + setAvatarId(gAgent.getID()); + + if(key.isUndefined()) + { + setPosGlobal(gAgent.getPositionGlobal()); + + LLUUID snapshot_id = LLUUID::null; + std::string desc; + LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); + + if(parcel) + { + desc = parcel->getDesc(); + snapshot_id = parcel->getSnapshotID(); + } + + std::string region_name = LLTrans::getString("ClassifiedUpdateAfterPublish"); + LLViewerRegion* region = gAgent.getRegion(); + if (region) + { + region_name = region->getName(); + } + + getChild<LLUICtrl>("classified_name")->setValue(makeClassifiedName()); + getChild<LLUICtrl>("classified_desc")->setValue(desc); + setSnapshotId(snapshot_id); + setClassifiedLocation(createLocationText(getLocationNotice(), region_name, getPosGlobal())); + // server will set valid parcel id + setParcelId(LLUUID::null); + } + else + { + setClassifiedId(key["classified_id"]); + setClassifiedName(key["name"]); + setDescription(key["desc"]); + setSnapshotId(key["snapshot_id"]); + setCategory((U32)key["category"].asInteger()); + setContentType((U32)key["content_type"].asInteger()); + setClassifiedLocation(key["location_text"]); + getChild<LLUICtrl>("auto_renew")->setValue(key["auto_renew"]); + getChild<LLUICtrl>("price_for_listing")->setValue(key["price_for_listing"].asInteger()); + } +} + +void LLPanelClassifiedEdit::onOpen(const LLSD& key) +{ + mIsNew = key.isUndefined(); + + scrollToTop(); + + // classified is not created yet + bool is_new = isNew() || isNewWithErrors(); + + if(is_new) + { + resetData(); + resetControls(); + + fillIn(key); + + if(isNew()) + { + LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(), this); + } + } + else + { + LLPanelClassifiedInfo::onOpen(key); + } + + std::string save_btn_label = is_new ? getString("publish_label") : getString("save_label"); + getChild<LLUICtrl>("save_changes_btn")->setLabelArg("[LABEL]", save_btn_label); + + enableVerbs(is_new); + enableEditing(is_new); + showEditing(!is_new); + resetDirty(); + setInfoLoaded(false); +} + +void LLPanelClassifiedEdit::processProperties(void* data, EAvatarProcessorType type) +{ + if(APT_CLASSIFIED_INFO == type) + { + LLAvatarClassifiedInfo* c_info = static_cast<LLAvatarClassifiedInfo*>(data); + if(c_info && getClassifiedId() == c_info->classified_id) + { + // see LLPanelClassifiedEdit::sendUpdate() for notes + mIsNewWithErrors = false; + // for just created classified - panel will probably be closed when we get here. + if(!getVisible()) + { + return; + } + + enableEditing(true); + + setClassifiedName(c_info->name); + setDescription(c_info->description); + setSnapshotId(c_info->snapshot_id); + setParcelId(c_info->parcel_id); + setPosGlobal(c_info->pos_global); + + setClassifiedLocation(createLocationText(c_info->parcel_name, c_info->sim_name, c_info->pos_global)); + // *HACK see LLPanelClassifiedEdit::sendUpdate() + setCategory(c_info->category - 1); + + bool mature = is_cf_mature(c_info->flags); + bool auto_renew = is_cf_auto_renew(c_info->flags); + + setContentType(mature ? CB_ITEM_MATURE : CB_ITEM_PG); + getChild<LLUICtrl>("auto_renew")->setValue(auto_renew); + getChild<LLUICtrl>("price_for_listing")->setValue(c_info->price_for_listing); + getChildView("price_for_listing")->setEnabled(isNew()); + + resetDirty(); + setInfoLoaded(true); + enableVerbs(false); + + // for just created classified - in case user opened edit panel before processProperties() callback + getChild<LLUICtrl>("save_changes_btn")->setLabelArg("[LABEL]", getString("save_label")); + } + } +} + +BOOL LLPanelClassifiedEdit::isDirty() const +{ + if(mIsNew) + { + return TRUE; + } + + BOOL dirty = false; + + dirty |= LLPanelClassifiedInfo::isDirty(); + dirty |= getChild<LLUICtrl>("classified_snapshot")->isDirty(); + dirty |= getChild<LLUICtrl>("classified_name")->isDirty(); + dirty |= getChild<LLUICtrl>("classified_desc")->isDirty(); + dirty |= getChild<LLUICtrl>("category")->isDirty(); + dirty |= getChild<LLUICtrl>("content_type")->isDirty(); + dirty |= getChild<LLUICtrl>("auto_renew")->isDirty(); + dirty |= getChild<LLUICtrl>("price_for_listing")->isDirty(); + + return dirty; +} + +void LLPanelClassifiedEdit::resetDirty() +{ + LLPanelClassifiedInfo::resetDirty(); + getChild<LLUICtrl>("classified_snapshot")->resetDirty(); + getChild<LLUICtrl>("classified_name")->resetDirty(); + + LLTextEditor* desc = getChild<LLTextEditor>("classified_desc"); + // call blockUndo() to really reset dirty(and make isDirty work as intended) + desc->blockUndo(); + desc->resetDirty(); + + getChild<LLUICtrl>("category")->resetDirty(); + getChild<LLUICtrl>("content_type")->resetDirty(); + getChild<LLUICtrl>("auto_renew")->resetDirty(); + getChild<LLUICtrl>("price_for_listing")->resetDirty(); +} + +void LLPanelClassifiedEdit::setSaveCallback(const commit_signal_t::slot_type& cb) +{ + mSaveButtonClickedSignal.connect(cb); +} + +void LLPanelClassifiedEdit::setCancelCallback(const commit_signal_t::slot_type& cb) +{ + getChild<LLButton>("cancel_btn")->setClickedCallback(cb); +} + +void LLPanelClassifiedEdit::resetControls() +{ + LLPanelClassifiedInfo::resetControls(); + + getChild<LLComboBox>("category")->setCurrentByIndex(0); + getChild<LLComboBox>("content_type")->setCurrentByIndex(0); + getChild<LLUICtrl>("auto_renew")->setValue(false); + if (LLLoginInstance::getInstance()->hasResponse("classified_fee")) + { + getChild<LLUICtrl>("price_for_listing")->setValue(LLLoginInstance::getInstance()-> + getResponse("classified_fee").asInteger()); + } + else + { + getChild<LLUICtrl>("price_for_listing")->setValue(MINIMUM_PRICE_FOR_LISTING); + } + getChildView("price_for_listing")->setEnabled(TRUE); +} + +bool LLPanelClassifiedEdit::canClose() +{ + return mCanClose; +} + +void LLPanelClassifiedEdit::draw() +{ + LLPanel::draw(); + + // Need to re-stretch on every draw because LLTextureCtrl::onSelectCallback + // does not trigger callbacks when user navigates through images. + stretchSnapshot(); +} + +void LLPanelClassifiedEdit::stretchSnapshot() +{ + LLPanelClassifiedInfo::stretchSnapshot(); + + getChild<LLUICtrl>("edit_icon")->setShape(mSnapshotCtrl->getRect()); +} + +U32 LLPanelClassifiedEdit::getContentType() +{ + LLComboBox* ct_cb = getChild<LLComboBox>("content_type"); + return ct_cb->getCurrentIndex(); +} + +void LLPanelClassifiedEdit::setContentType(U32 content_type) +{ + LLComboBox* ct_cb = getChild<LLComboBox>("content_type"); + ct_cb->setCurrentByIndex(content_type); + ct_cb->resetDirty(); +} + +bool LLPanelClassifiedEdit::getAutoRenew() +{ + return getChild<LLUICtrl>("auto_renew")->getValue().asBoolean(); +} + +void LLPanelClassifiedEdit::sendUpdate() +{ + LLAvatarClassifiedInfo c_data; + + if(getClassifiedId().isNull()) + { + setClassifiedId(LLUUID::generateNewID()); + } + + c_data.agent_id = gAgent.getID(); + c_data.classified_id = getClassifiedId(); + // *HACK + // Categories on server start with 1 while combo-box index starts with 0 + c_data.category = getCategory() + 1; + c_data.name = getClassifiedName(); + c_data.description = getDescription(); + c_data.parcel_id = getParcelId(); + c_data.snapshot_id = getSnapshotId(); + c_data.pos_global = getPosGlobal(); + c_data.flags = getFlags(); + c_data.price_for_listing = getPriceForListing(); + + LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoUpdate(&c_data); + + if(isNew()) + { + // Lets assume there will be some error. + // Successful sendClassifiedInfoUpdate will trigger processProperties and + // let us know there was no error. + mIsNewWithErrors = true; + } +} + +U32 LLPanelClassifiedEdit::getCategory() +{ + LLComboBox* cat_cb = getChild<LLComboBox>("category"); + return cat_cb->getCurrentIndex(); +} + +void LLPanelClassifiedEdit::setCategory(U32 category) +{ + LLComboBox* cat_cb = getChild<LLComboBox>("category"); + cat_cb->setCurrentByIndex(category); + cat_cb->resetDirty(); +} + +U8 LLPanelClassifiedEdit::getFlags() +{ + bool auto_renew = getChild<LLUICtrl>("auto_renew")->getValue().asBoolean(); + + LLComboBox* content_cb = getChild<LLComboBox>("content_type"); + bool mature = content_cb->getCurrentIndex() == CB_ITEM_MATURE; + + return pack_classified_flags_request(auto_renew, false, mature, false); +} + +void LLPanelClassifiedEdit::enableVerbs(bool enable) +{ + getChildView("save_changes_btn")->setEnabled(enable); +} + +void LLPanelClassifiedEdit::enableEditing(bool enable) +{ + getChildView("classified_snapshot")->setEnabled(enable); + getChildView("classified_name")->setEnabled(enable); + getChildView("classified_desc")->setEnabled(enable); + getChildView("set_to_curr_location_btn")->setEnabled(enable); + getChildView("category")->setEnabled(enable); + getChildView("content_type")->setEnabled(enable); + getChildView("price_for_listing")->setEnabled(enable); + getChildView("auto_renew")->setEnabled(enable); +} + +void LLPanelClassifiedEdit::showEditing(bool show) +{ + getChildView("price_for_listing_label")->setVisible( show); + getChildView("price_for_listing")->setVisible( show); +} + +std::string LLPanelClassifiedEdit::makeClassifiedName() +{ + std::string name; + + LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); + if(parcel) + { + name = parcel->getName(); + } + + if(!name.empty()) + { + return name; + } + + LLViewerRegion* region = gAgent.getRegion(); + if(region) + { + name = region->getName(); + } + + return name; +} + +S32 LLPanelClassifiedEdit::getPriceForListing() +{ + return getChild<LLUICtrl>("price_for_listing")->getValue().asInteger(); +} + +void LLPanelClassifiedEdit::setPriceForListing(S32 price) +{ + getChild<LLUICtrl>("price_for_listing")->setValue(price); +} + +void LLPanelClassifiedEdit::onSetLocationClick() +{ + setPosGlobal(gAgent.getPositionGlobal()); + setParcelId(LLUUID::null); + + std::string region_name = LLTrans::getString("ClassifiedUpdateAfterPublish"); + LLViewerRegion* region = gAgent.getRegion(); + if (region) + { + region_name = region->getName(); + } + + setClassifiedLocation(createLocationText(getLocationNotice(), region_name, getPosGlobal())); + + // mark classified as dirty + setValue(LLSD()); + + onChange(); +} + +void LLPanelClassifiedEdit::onChange() +{ + enableVerbs(isDirty()); +} + +void LLPanelClassifiedEdit::onSaveClick() +{ + mCanClose = false; + + if(!isValidName()) + { + notifyInvalidName(); + return; + } + if(isNew() || isNewWithErrors()) + { + if(gStatusBar->getBalance() < getPriceForListing()) + { + LLNotificationsUtil::add("ClassifiedInsufficientFunds"); + return; + } + + mPublishFloater = LLFloaterReg::findTypedInstance<LLFloaterPublishClassified>( + "publish_classified", LLSD()); + + if(!mPublishFloater) + { + mPublishFloater = LLFloaterReg::getTypedInstance<LLFloaterPublishClassified>( + "publish_classified", LLSD()); + + mPublishFloater->setPublishClickedCallback(boost::bind + (&LLPanelClassifiedEdit::onPublishFloaterPublishClicked, this)); + } + + // set spinner value before it has focus or value wont be set + mPublishFloater->setPrice(getPriceForListing()); + mPublishFloater->openFloater(mPublishFloater->getKey()); + mPublishFloater->center(); + } + else + { + doSave(); + } +} + +void LLPanelClassifiedEdit::doSave() +{ + mCanClose = true; + sendUpdate(); + resetDirty(); + + mSaveButtonClickedSignal(this, LLSD()); +} + +void LLPanelClassifiedEdit::onPublishFloaterPublishClicked() +{ + setPriceForListing(mPublishFloater->getPrice()); + + doSave(); +} + +std::string LLPanelClassifiedEdit::getLocationNotice() +{ + static std::string location_notice = getString("location_notice"); + return location_notice; +} + +bool LLPanelClassifiedEdit::isValidName() +{ + std::string name = getClassifiedName(); + if (name.empty()) + { + return false; + } + if (!isalnum(name[0])) + { + return false; + } + + return true; +} + +void LLPanelClassifiedEdit::notifyInvalidName() +{ + std::string name = getClassifiedName(); + if (name.empty()) + { + LLNotificationsUtil::add("BlankClassifiedName"); + } + else if (!isalnum(name[0])) + { + LLNotificationsUtil::add("ClassifiedMustBeAlphanumeric"); + } +} + +void LLPanelClassifiedEdit::onTexturePickerMouseEnter(LLUICtrl* ctrl) +{ + ctrl->setVisible(TRUE); +} + +void LLPanelClassifiedEdit::onTexturePickerMouseLeave(LLUICtrl* ctrl) +{ + ctrl->setVisible(FALSE); +} + +void LLPanelClassifiedEdit::onTextureSelected() +{ + setSnapshotId(mSnapshotCtrl->getValue().asUUID()); + onChange(); +} diff --git a/indra/newview/llpanelclassified.h b/indra/newview/llpanelclassified.h index 88346df6c332825e89cf8c907f48fa5014c47495..e742328df25ebabe47957dd76cb5e5f1b5c104bf 100644 --- a/indra/newview/llpanelclassified.h +++ b/indra/newview/llpanelclassified.h @@ -1,10 +1,10 @@ /** * @file llpanelclassified.h - * @brief LLPanelClassifiedInfo class definition + * @brief LLPanelClassified class definition * - * $LicenseInfo:firstyear=2021&license=viewerlgpl$ + * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2021, Linden Research, Inc. + * Copyright (C) 2010, Linden Research, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -27,31 +27,34 @@ // Display of a classified used both for the global view in the // Find directory, and also for each individual user's classified in their // profile. + #ifndef LL_LLPANELCLASSIFIED_H #define LL_LLPANELCLASSIFIED_H #include "llavatarpropertiesprocessor.h" -#include "llclassifiedinfo.h" -#include "llfloater.h" +#include "llfloaterpublishclassified.h" #include "llpanel.h" #include "llrect.h" class LLScrollContainer; class LLTextureCtrl; +class LLUICtrl; class LLPanelClassifiedInfo : public LLPanel, public LLAvatarPropertiesObserver { LOG_CLASS(LLPanelClassifiedInfo); public: + static LLPanelClassifiedInfo* create(); + LLPanelClassifiedInfo(); virtual ~LLPanelClassifiedInfo(); - /*virtual*/ void onOpen(const LLSD& key); + /*virtual*/ void onOpen(const LLSD& key) override; - /*virtual*/ BOOL postBuild(); + /*virtual*/ BOOL postBuild() override; - /*virtual*/ void processProperties(void* data, EAvatarProcessorType type); + /*virtual*/ void processProperties(void* data, EAvatarProcessorType type) override; void setAvatarId(const LLUUID& avatar_id) { mAvatarId = avatar_id; } @@ -112,9 +115,13 @@ class LLPanelClassifiedInfo : public LLPanel, public LLAvatarPropertiesObserver const LLVector3d& global_pos, const std::string& sim_name); - /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); + void setExitCallback(const commit_callback_t& cb); + + void setEditClassifiedCallback(const commit_callback_t& cb); + + /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE) override; - /*virtual*/ void draw(); + /*virtual*/ void draw() override; protected: @@ -136,6 +143,7 @@ class LLPanelClassifiedInfo : public LLPanel, public LLAvatarPropertiesObserver void onMapClick(); void onTeleportClick(); + void onExit(); bool mSnapshotStreched; LLRect mSnapshotRect; @@ -172,4 +180,100 @@ class LLPanelClassifiedInfo : public LLPanel, public LLAvatarPropertiesObserver static panel_list_t sAllPanels; }; +class LLPanelClassifiedEdit : public LLPanelClassifiedInfo +{ + LOG_CLASS(LLPanelClassifiedEdit); +public: + + static LLPanelClassifiedEdit* create(); + + virtual ~LLPanelClassifiedEdit(); + + /*virtual*/ BOOL postBuild() override; + + void fillIn(const LLSD& key); + + /*virtual*/ void onOpen(const LLSD& key) override; + + /*virtual*/ void processProperties(void* data, EAvatarProcessorType type) override; + + /*virtual*/ BOOL isDirty() const override; + + /*virtual*/ void resetDirty() override; + + void setSaveCallback(const commit_signal_t::slot_type& cb); + + void setCancelCallback(const commit_signal_t::slot_type& cb); + + /*virtual*/ void resetControls() override; + + bool isNew() { return mIsNew; } + + bool isNewWithErrors() { return mIsNewWithErrors; } + + bool canClose(); + + void draw() override; + + void stretchSnapshot(); + + U32 getCategory(); + + void setCategory(U32 category); + + U32 getContentType(); + + void setContentType(U32 content_type); + + bool getAutoRenew(); + + S32 getPriceForListing(); + +protected: + + LLPanelClassifiedEdit(); + + void sendUpdate(); + + void enableVerbs(bool enable); + + void enableEditing(bool enable); + + void showEditing(bool show); + + std::string makeClassifiedName(); + + void setPriceForListing(S32 price); + + U8 getFlags(); + + std::string getLocationNotice(); + + bool isValidName(); + + void notifyInvalidName(); + + void onSetLocationClick(); + void onChange(); + void onSaveClick(); + + void doSave(); + + void onPublishFloaterPublishClicked(); + + void onTexturePickerMouseEnter(LLUICtrl* ctrl); + void onTexturePickerMouseLeave(LLUICtrl* ctrl); + + void onTextureSelected(); + +private: + bool mIsNew; + bool mIsNewWithErrors; + bool mCanClose; + + LLFloaterPublishClassified* mPublishFloater; + + commit_signal_t mSaveButtonClickedSignal; +}; + #endif // LL_LLPANELCLASSIFIED_H diff --git a/indra/newview/llpaneleventinfo.cpp b/indra/newview/llpaneleventinfo.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d9ffc02e42d418449d411fa0f762fc939f710d74 --- /dev/null +++ b/indra/newview/llpaneleventinfo.cpp @@ -0,0 +1,158 @@ +/* + * @file llpaneleventinfo.cpp + * @brief Event info panel + * + * Copyright (c) 2014, Cinder Roxley <cinder@sdf.org> + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "llviewerprecompiledheaders.h" +#include "llpaneleventinfo.h" + +#include "llbutton.h" +#include "lleventflags.h" +#include "lliconctrl.h" +#include "llfloaterreg.h" +#include "llresmgr.h" +#include "llslurl.h" +#include "lltrans.h" + +#include "llagent.h" +#include "llfloaterworldmap.h" +#include "llviewercontrol.h" + +static LLPanelInjector<LLPanelEventInfo> t_event_info("panel_event_info"); + +LLPanelEventInfo::LLPanelEventInfo() +: LLPanel() +, mEvent() +, mEventID(0) +{ + mEventNotifierConnection = gEventNotifier.setNewEventCallback(boost::bind(&LLPanelEventInfo::processEventReply, this, _1)); +} + +LLPanelEventInfo::~LLPanelEventInfo() +{ + if (mEventNotifierConnection.connected()) + { + mEventNotifierConnection.disconnect(); + } +} + +BOOL LLPanelEventInfo::postBuild() +{ + childSetAction("teleport_btn", boost::bind(&LLPanelEventInfo::onBtnTeleport, this)); + childSetAction("show_on_map_btn", boost::bind(&LLPanelEventInfo::onBtnMap, this)); + childSetAction("remind_btn", boost::bind(&LLPanelEventInfo::onBtnRemind, this)); + return TRUE; +} + +void LLPanelEventInfo::onOpen(const LLSD& key) +{ + U32 id(key.asInteger()); + setEventID(id); + + gEventNotifier.add(getEventID()); +} + +// *TODO: localize this bitch. +std::string LLPanelEventInfo::formatFromMinutes(U32 time) +{ + U32 hours = time / 60; + U32 minutes = time % 60; + + std::ostringstream output; + if (hours) + output << hours << " " << getString("hours") << " "; + if (minutes) + output << minutes << " " << getString("minutes"); + return output.str(); +} + +bool LLPanelEventInfo::processEventReply(const LLEventStruct& event) +{ + if (event.eventId != getEventID()) return false; // no + mEvent = event; + getChild<LLUICtrl>("name")->setValue(mEvent.eventName); + getChild<LLUICtrl>("desc")->setValue(mEvent.desc); + getChild<LLUICtrl>("duration")->setValue(formatFromMinutes(mEvent.duration)); + getChild<LLUICtrl>("host")->setValue(LLSLURL("agent", LLUUID(mEvent.creator), "inspect").getSLURLString()); + getChild<LLUICtrl>("time")->setValue(mEvent.eventDateStr); + // *TODO: Prettier + //std::string time; + //LLStringUtil::formatDatetime(time, "%a %d %b %Y %H:%M", "slt", mEvent.eventEpoch); + //getChild<LLUICtrl>("time")->setValue(time); + + // *TODO: Add translation strings + //getChild<LLUICtrl>("category")->setValue(LLTrans::getString(mEvent.category)); + getChild<LLUICtrl>("category")->setValue(mEvent.category); + getChild<LLUICtrl>("cover")->setValue(mEvent.cover + ? LLResMgr::getInstance()->getMonetaryString(mEvent.amount) + : getString("free")); + bool mature = (mEvent.flags & EVENT_FLAG_MATURE); + getChild<LLUICtrl>("content_type")->setValue(getString(mature ? "type_mature" : "type_pg")); + getChild<LLIconCtrl>("content_type_moderate")->setVisible(mature); + getChild<LLIconCtrl>("content_type_general")->setVisible(!mature); + getChild<LLUICtrl>("location")->setValue(LLSLURL(mEvent.simName, mEvent.globalPos).getSLURLString()); + getChild<LLButton>("remind_btn")->setLabel(getString(gEventNotifier.hasNotification(mEvent.eventId) + ? "no_reminder" + : "reminder")); + return true; +} + +void LLPanelEventInfo::onBtnTeleport() +{ + if (!mEvent.globalPos.isExactlyZero()) + { + gAgent.teleportViaLocation(mEvent.globalPos); + LLFloaterWorldMap* worldmap = LLFloaterWorldMap::getInstance(); + if (worldmap) + worldmap->trackLocation(mEvent.globalPos); + } +} + +void LLPanelEventInfo::onBtnMap() +{ + LLFloaterWorldMap* worldmap = LLFloaterWorldMap::getInstance(); + if (!mEvent.globalPos.isExactlyZero() && worldmap) + { + worldmap->trackLocation(mEvent.globalPos); + LLFloaterReg::showInstance("world_map", "center"); + } +} + +void LLPanelEventInfo::onBtnRemind() +{ + if (gEventNotifier.hasNotification(mEvent.eventId)) + { + gEventNotifier.remove(mEvent.eventId); + getChild<LLButton>("remind_btn")->setLabel(getString("reminder")); + } + else + { + gEventNotifier.add(mEvent.eventId); + getChild<LLButton>("remind_btn")->setLabel(getString("no_reminder")); + } +} diff --git a/indra/newview/llpaneleventinfo.h b/indra/newview/llpaneleventinfo.h new file mode 100644 index 0000000000000000000000000000000000000000..3852dba91ed9248bead9ce789839f1bca11d9860 --- /dev/null +++ b/indra/newview/llpaneleventinfo.h @@ -0,0 +1,59 @@ +/* + * @file llpaneleventinfo.cpp + * @brief Event info panel + * + * Copyright (c) 2014, Cinder Roxley <cinder@sdf.org> + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef LL_PANELEVENTINFO_H +#define LL_PANELEVENTINFO_H + +#include "llpanel.h" +#include "lleventnotifier.h" + +class LLPanelEventInfo : public LLPanel +{ +public: + LLPanelEventInfo(); + /*virtual*/ BOOL postBuild() override; + /*virtual*/ void onOpen(const LLSD& key) override; + +private: + ~LLPanelEventInfo(); + bool processEventReply(const LLEventStruct& event); + std::string formatFromMinutes(U32 time); + void setEventID(U32 id) { mEventID = id; } + U32 getEventID() const { return mEventID; } + void onBtnTeleport(); + void onBtnMap(); + void onBtnRemind(); + + LLEventStruct mEvent; + U32 mEventID; + boost::signals2::connection mEventNotifierConnection; +}; + +#endif // LL_PANELEVENTINFO_H diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp index f05f92706713dd734736df804a5c119efef7ae9a..95bc7896f44f7b90d6d837d9657c62b5af649d15 100644 --- a/indra/newview/llpanellandmarks.cpp +++ b/indra/newview/llpanellandmarks.cpp @@ -1104,11 +1104,7 @@ void LLLandmarksPanel::doProcessParcelInfo(LLLandmark* landmark, data.snapshot_id = parcel_data.snapshot_id; data.parcel_id = parcel_data.parcel_id; - LLFloaterProfile* profile_floater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", gAgentID))); - if (profile_floater) - { - profile_floater->createPick(data); - } + LLAvatarActions::createPick(data); } void LLLandmarksPanel::doCreatePick(LLLandmark* landmark, const LLUUID &item_id) diff --git a/indra/newview/llpanelpick.cpp b/indra/newview/llpanelpick.cpp new file mode 100644 index 0000000000000000000000000000000000000000..113f9b0b9e418015289578820242b9e114ca8c76 --- /dev/null +++ b/indra/newview/llpanelpick.cpp @@ -0,0 +1,612 @@ +/** + * @file llpanelpick.cpp + * @brief LLPanelPick class implementation + * + * $LicenseInfo:firstyear=2004&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +// Display of a "Top Pick" used both for the global top picks in the +// Find directory, and also for each individual user's picks in their +// profile. + +#include "llviewerprecompiledheaders.h" + +#include "llpanelpick.h" + +#include "message.h" + +#include "llparcel.h" + +#include "llbutton.h" +#include "llfloaterreg.h" +#include "lliconctrl.h" +#include "lllineeditor.h" +#include "llpanel.h" +#include "llscrollcontainer.h" +#include "lltexteditor.h" + +#include "llagent.h" +#include "llagentpicksinfo.h" +#include "llavatarpropertiesprocessor.h" +#include "llfloaterworldmap.h" +#include "lltexturectrl.h" +#include "llviewerparcelmgr.h" +#include "llviewerregion.h" + +static const std::string XML_PANEL_EDIT_PICK("panel_edit_pick.xml"); +static const std::string XML_PANEL_PICK_INFO("panel_pick_info.xml"); + +static const std::string XML_NAME("pick_name"); +static const std::string XML_DESC("pick_desc"); +static const std::string XML_SNAPSHOT("pick_snapshot"); +static const std::string XML_LOCATION("pick_location"); + +static const std::string XML_BTN_ON_TXTR("edit_icon"); +static const std::string XML_BTN_SAVE("save_changes_btn"); + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +//static +LLPanelPickInfo* LLPanelPickInfo::create() +{ + LLPanelPickInfo* panel = new LLPanelPickInfo(); + panel->buildFromFile(XML_PANEL_PICK_INFO); + return panel; +} + +LLPanelPickInfo::LLPanelPickInfo() + : LLPanel() + , LLAvatarPropertiesObserver() + , LLRemoteParcelInfoObserver() + , mScrollingPanelMinHeight(0) + , mScrollingPanelWidth(0) + , mScrollContainer(nullptr) + , mScrollingPanel(nullptr) + , mSnapshotCtrl(nullptr) + , mAvatarId(LLUUID::null) + , mParcelId(LLUUID::null) + , mPickId(LLUUID::null) + , mRequestedId(LLUUID::null) +{ +} + +LLPanelPickInfo::~LLPanelPickInfo() +{ + LLAvatarPropertiesProcessor::getInstance()->removeObserver(LLPanelPickInfo::getAvatarId(), this); + + if (mParcelId.notNull()) + { + LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelId, this); + } +} + +void LLPanelPickInfo::onOpen(const LLSD& key) +{ + LLUUID avatar_id = key["avatar_id"]; + if(avatar_id.isNull()) + { + return; + } + + if(getAvatarId().notNull()) + { + LLAvatarPropertiesProcessor::getInstance()->removeObserver( + getAvatarId(), this); + } + + setAvatarId(avatar_id); + + resetData(); + resetControls(); + + setPickId(key["pick_id"]); + setPickName(key["pick_name"]); + setPickDesc(key["pick_desc"]); + setSnapshotId(key["snapshot_id"]); + + LLAvatarPropertiesProcessor::getInstance()->addObserver( + getAvatarId(), this); + LLAvatarPropertiesProcessor::getInstance()->sendPickInfoRequest( + getAvatarId(), getPickId()); +} + +BOOL LLPanelPickInfo::postBuild() +{ + mSnapshotCtrl = getChild<LLTextureCtrl>(XML_SNAPSHOT); + + childSetAction("teleport_btn", boost::bind(&LLPanelPickInfo::onClickTeleport, this)); + childSetAction("show_on_map_btn", boost::bind(&LLPanelPickInfo::onClickMap, this)); + childSetAction("back_btn", boost::bind(&LLPanelPickInfo::onClickBack, this)); + + mScrollingPanel = getChild<LLPanel>("scroll_content_panel"); + mScrollContainer = getChild<LLScrollContainer>("profile_scroll"); + + mScrollingPanelMinHeight = mScrollContainer->getScrolledViewRect().getHeight(); + mScrollingPanelWidth = mScrollingPanel->getRect().getWidth(); + + LLTextEditor* text_desc = getChild<LLTextEditor>(XML_DESC); + text_desc->setContentTrusted(false); + + return TRUE; +} + +void LLPanelPickInfo::reshape(S32 width, S32 height, BOOL called_from_parent) +{ + LLPanel::reshape(width, height, called_from_parent); + + if (!mScrollContainer || !mScrollingPanel) + return; + + static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0); + + S32 scroll_height = mScrollContainer->getRect().getHeight(); + if (mScrollingPanelMinHeight >= scroll_height) + { + mScrollingPanel->reshape(mScrollingPanelWidth, mScrollingPanelMinHeight); + } + else + { + mScrollingPanel->reshape(mScrollingPanelWidth + scrollbar_size, scroll_height); + } +} + +void LLPanelPickInfo::processProperties(void* data, EAvatarProcessorType type) +{ + if(APT_PICK_INFO != type) + { + return; + } + LLPickData* pick_info = static_cast<LLPickData*>(data); + if(!pick_info + || pick_info->creator_id != getAvatarId() + || pick_info->pick_id != getPickId()) + { + return; + } + + mParcelId = pick_info->parcel_id; + setSnapshotId(pick_info->snapshot_id); + setPickName(pick_info->name); + setPickDesc(pick_info->desc); + setPosGlobal(pick_info->pos_global); + + // Send remote parcel info request to get parcel name and sim (region) name. + sendParcelInfoRequest(); + + // *NOTE dzaporozhan + // We want to keep listening to APT_PICK_INFO because user may + // edit the Pick and we have to update Pick info panel. + // revomeObserver is called from onClickBack +} + +void LLPanelPickInfo::sendParcelInfoRequest() +{ + if (mParcelId != mRequestedId) + { + LLRemoteParcelInfoProcessor::getInstance()->addObserver(mParcelId, this); + LLRemoteParcelInfoProcessor::getInstance()->sendParcelInfoRequest(mParcelId); + + mRequestedId = mParcelId; + } +} + +void LLPanelPickInfo::setExitCallback(const commit_callback_t& cb) +{ + getChild<LLButton>("back_btn")->setClickedCallback(cb); +} + +void LLPanelPickInfo::processParcelInfo(const LLParcelData& parcel_data) +{ + setPickLocation(createLocationText(LLStringUtil::null, parcel_data.name, + parcel_data.sim_name, getPosGlobal())); + + // We have received parcel info for the requested ID so clear it now. + mRequestedId.setNull(); + + if (mParcelId.notNull()) + { + LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelId, this); + } +} + +void LLPanelPickInfo::setEditPickCallback(const commit_callback_t& cb) +{ + getChild<LLButton>("edit_btn")->setClickedCallback(cb); +} + +// PROTECTED AREA + +void LLPanelPickInfo::resetControls() +{ + if(getAvatarId() == gAgent.getID()) + { + getChildView("edit_btn")->setEnabled(TRUE); + getChildView("edit_btn")->setVisible( TRUE); + } + else + { + getChildView("edit_btn")->setEnabled(FALSE); + getChildView("edit_btn")->setVisible( FALSE); + } +} + +void LLPanelPickInfo::resetData() +{ + setPickName(LLStringUtil::null); + setPickDesc(LLStringUtil::null); + setPickLocation(LLStringUtil::null); + setPickId(LLUUID::null); + setSnapshotId(LLUUID::null); + mPosGlobal.clearVec(); + mParcelId.setNull(); + mRequestedId.setNull(); +} + +// static +std::string LLPanelPickInfo::createLocationText(const std::string& owner_name, const std::string& original_name, const std::string& sim_name, const LLVector3d& pos_global) +{ + std::string location_text; + location_text.append(owner_name); + if (!original_name.empty()) + { + if (!location_text.empty()) location_text.append(", "); + location_text.append(original_name); + + } + if (!sim_name.empty()) + { + if (!location_text.empty()) location_text.append(", "); + location_text.append(sim_name); + } + + if (!location_text.empty()) location_text.append(" "); + + if (!pos_global.isNull()) + { + S32 region_x = ll_round((F32)pos_global.mdV[VX]) % REGION_WIDTH_UNITS; + S32 region_y = ll_round((F32)pos_global.mdV[VY]) % REGION_WIDTH_UNITS; + S32 region_z = ll_round((F32)pos_global.mdV[VZ]); + location_text.append(llformat(" (%d, %d, %d)", region_x, region_y, region_z)); + } + return location_text; +} + +void LLPanelPickInfo::setSnapshotId(const LLUUID& id) +{ + mSnapshotCtrl->setImageAssetID(id); + mSnapshotCtrl->setValid(TRUE); +} + +void LLPanelPickInfo::setPickName(const std::string& name) +{ + getChild<LLUICtrl>(XML_NAME)->setValue(name); +} + +void LLPanelPickInfo::setPickDesc(const std::string& desc) +{ + getChild<LLUICtrl>(XML_DESC)->setValue(desc); +} + +void LLPanelPickInfo::setPickLocation(const std::string& location) +{ + getChild<LLUICtrl>(XML_LOCATION)->setValue(location); +} + +void LLPanelPickInfo::onClickMap() +{ + LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal()); + LLFloaterReg::showInstance("world_map", "center"); +} + +void LLPanelPickInfo::onClickTeleport() +{ + if (!getPosGlobal().isExactlyZero()) + { + gAgent.teleportViaLocation(getPosGlobal()); + LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal()); + } +} + +void LLPanelPickInfo::onClickBack() +{ + LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this); +} + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +//static +LLPanelPickEdit* LLPanelPickEdit::create() +{ + LLPanelPickEdit* panel = new LLPanelPickEdit(); + panel->buildFromFile(XML_PANEL_EDIT_PICK); + return panel; +} + +LLPanelPickEdit::LLPanelPickEdit() + : LLPanelPickInfo() + , mLocationChanged(false) + , mNeedData(true) + , mNewPick(false) + , text_icon(nullptr) +{ +} + +void LLPanelPickEdit::onOpen(const LLSD& key) +{ + LLUUID pick_id = key["pick_id"]; + mNeedData = true; + + // creating new Pick + if(pick_id.isNull()) + { + mNewPick = true; + + setAvatarId(gAgent.getID()); + + resetData(); + resetControls(); + + setPosGlobal(gAgent.getPositionGlobal()); + + LLUUID parcel_id = LLUUID::null, snapshot_id = LLUUID::null; + std::string pick_name, pick_desc, region_name; + + LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); + if(parcel) + { + parcel_id = parcel->getID(); + pick_name = parcel->getName(); + pick_desc = parcel->getDesc(); + snapshot_id = parcel->getSnapshotID(); + } + + LLViewerRegion* region = gAgent.getRegion(); + if(region) + { + region_name = region->getName(); + } + + setParcelID(parcel_id); + getChild<LLUICtrl>("pick_name")->setValue(pick_name.empty() ? region_name : pick_name); + getChild<LLUICtrl>("pick_desc")->setValue(pick_desc); + setSnapshotId(snapshot_id); + setPickLocation(createLocationText(getLocationNotice(), pick_name, region_name, getPosGlobal())); + + enableSaveButton(true); + } + // editing existing pick + else + { + mNewPick = false; + LLPanelPickInfo::onOpen(key); + + enableSaveButton(false); + } + + resetDirty(); +} + +void LLPanelPickEdit::setPickData(const LLPickData* pick_data) +{ + if(!pick_data) + { + return; + } + + mNeedData = false; + + setParcelID(pick_data->parcel_id); + getChild<LLUICtrl>("pick_name")->setValue(pick_data->name); + getChild<LLUICtrl>("pick_desc")->setValue(pick_data->desc); + setSnapshotId(pick_data->snapshot_id); + setPosGlobal(pick_data->pos_global); + setPickLocation(createLocationText(LLStringUtil::null, pick_data->name, + pick_data->sim_name, pick_data->pos_global)); +} + +BOOL LLPanelPickEdit::postBuild() +{ + LLPanelPickInfo::postBuild(); + + mSnapshotCtrl->setCommitCallback(boost::bind(&LLPanelPickEdit::onSnapshotChanged, this)); + + LLLineEditor* line_edit = getChild<LLLineEditor>("pick_name"); + line_edit->setKeystrokeCallback(boost::bind(&LLPanelPickEdit::onPickChanged, this, _1), nullptr); + + LLTextEditor* text_edit = getChild<LLTextEditor>("pick_desc"); + text_edit->setKeystrokeCallback(boost::bind(&LLPanelPickEdit::onPickChanged, this, _1)); + + childSetAction(XML_BTN_SAVE, boost::bind(&LLPanelPickEdit::onClickSave, this)); + childSetAction("set_to_curr_location_btn", boost::bind(&LLPanelPickEdit::onClickSetLocation, this)); + + initTexturePickerMouseEvents(); + + return TRUE; +} + +void LLPanelPickEdit::setSaveCallback(const commit_callback_t& cb) +{ + getChild<LLButton>("save_changes_btn")->setClickedCallback(cb); +} + +void LLPanelPickEdit::setCancelCallback(const commit_callback_t& cb) +{ + getChild<LLButton>("cancel_btn")->setClickedCallback(cb); +} + +void LLPanelPickEdit::resetDirty() +{ + LLPanelPickInfo::resetDirty(); + + getChild<LLLineEditor>("pick_name")->resetDirty(); + getChild<LLTextEditor>("pick_desc")->resetDirty(); + mSnapshotCtrl->resetDirty(); + mLocationChanged = false; +} + +BOOL LLPanelPickEdit::isDirty() const +{ + if( mNewPick + || LLPanelPickInfo::isDirty() + || mLocationChanged + || mSnapshotCtrl->isDirty() + || getChild<LLLineEditor>("pick_name")->isDirty() + || getChild<LLTextEditor>("pick_desc")->isDirty()) + { + return TRUE; + } + return FALSE; +} + +void LLPanelPickEdit::sendUpdate() +{ + LLPickData pick_data; + + // If we don't have a pick id yet, we'll need to generate one, + // otherwise we'll keep overwriting pick_id 00000 in the database. + if (getPickId().isNull()) + { + getPickId().generate(); + } + + pick_data.agent_id = gAgent.getID(); + pick_data.session_id = gAgent.getSessionID(); + pick_data.pick_id = getPickId(); + pick_data.creator_id = gAgent.getID();; + + //legacy var need to be deleted + pick_data.top_pick = FALSE; + pick_data.parcel_id = mParcelId; + pick_data.name = getChild<LLUICtrl>(XML_NAME)->getValue().asString(); + pick_data.desc = getChild<LLUICtrl>(XML_DESC)->getValue().asString(); + pick_data.snapshot_id = mSnapshotCtrl->getImageAssetID(); + pick_data.pos_global = getPosGlobal(); + pick_data.sort_order = 0; + pick_data.enabled = TRUE; + + LLAvatarPropertiesProcessor::instance().sendPickInfoUpdate(&pick_data); + + if(mNewPick) + { + // Assume a successful create pick operation, make new number of picks + // available immediately. Actual number of picks will be requested in + // LLAvatarPropertiesProcessor::sendPickInfoUpdate and updated upon server respond. + LLAgentPicksInfo::getInstance()->incrementNumberOfPicks(); + } +} + +void LLPanelPickEdit::onSnapshotChanged() +{ + enableSaveButton(true); +} + +void LLPanelPickEdit::onPickChanged(LLUICtrl* ctrl) +{ + enableSaveButton(isDirty()); +} + +void LLPanelPickEdit::resetData() +{ + LLPanelPickInfo::resetData(); + mLocationChanged = false; +} + +void LLPanelPickEdit::enableSaveButton(bool enable) +{ + getChildView(XML_BTN_SAVE)->setEnabled(enable); +} + +void LLPanelPickEdit::onClickSetLocation() +{ + // Save location for later use. + setPosGlobal(gAgent.getPositionGlobal()); + + std::string parcel_name, region_name; + + LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); + if (parcel) + { + mParcelId = parcel->getID(); + parcel_name = parcel->getName(); + } + + LLViewerRegion* region = gAgent.getRegion(); + if(region) + { + region_name = region->getName(); + } + + setPickLocation(createLocationText(getLocationNotice(), parcel_name, region_name, getPosGlobal())); + + mLocationChanged = true; + enableSaveButton(TRUE); +} + +void LLPanelPickEdit::onClickSave() +{ + sendUpdate(); + + mLocationChanged = false; + + LLSD params; + params["action"] = "save_new_pick"; + notifyParent(params); +} + +std::string LLPanelPickEdit::getLocationNotice() +{ + static std::string notice = getString("location_notice"); + return notice; +} + +void LLPanelPickEdit::processProperties(void* data, EAvatarProcessorType type) +{ + if(mNeedData) + { + LLPanelPickInfo::processProperties(data, type); + } +} + +// PRIVATE AREA + +void LLPanelPickEdit::initTexturePickerMouseEvents() +{ + text_icon = getChild<LLIconCtrl>(XML_BTN_ON_TXTR); + mSnapshotCtrl->setMouseEnterCallback(boost::bind(&LLPanelPickEdit::onTexturePickerMouseEnter, this, _1)); + mSnapshotCtrl->setMouseLeaveCallback(boost::bind(&LLPanelPickEdit::onTexturePickerMouseLeave, this, _1)); + + text_icon->setVisible(FALSE); +} + +void LLPanelPickEdit::onTexturePickerMouseEnter(LLUICtrl* ctrl) +{ + text_icon->setVisible(TRUE); +} + +void LLPanelPickEdit::onTexturePickerMouseLeave(LLUICtrl* ctrl) +{ + text_icon->setVisible(FALSE); +} diff --git a/indra/newview/llpanelpick.h b/indra/newview/llpanelpick.h new file mode 100644 index 0000000000000000000000000000000000000000..21f2b7d702447d5bae55143fe0173c59334b08e8 --- /dev/null +++ b/indra/newview/llpanelpick.h @@ -0,0 +1,255 @@ +/** + * @file llpanelpick.h + * @brief LLPanelPick class definition + * + * $LicenseInfo:firstyear=2004&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +// Display of a "Top Pick" used both for the global top picks in the +// Find directory, and also for each individual user's picks in their +// profile. + +#ifndef LL_LLPANELPICK_H +#define LL_LLPANELPICK_H + +#include "llpanel.h" +#include "llremoteparcelrequest.h" +#include "llavatarpropertiesprocessor.h" + +class LLIconCtrl; +class LLTextureCtrl; +class LLScrollContainer; +class LLMessageSystem; +class LLAvatarPropertiesObserver; + +/** + * Panel for displaying Pick Information - snapshot, name, description, etc. + */ +class LLPanelPickInfo : public LLPanel, public LLAvatarPropertiesObserver, LLRemoteParcelInfoObserver +{ + LOG_CLASS(LLPanelPickInfo); +public: + + // Creates new panel + static LLPanelPickInfo* create(); + + virtual ~LLPanelPickInfo(); + + /** + * Initializes panel properties + * + * By default Pick will be created for current Agent location. + * Use setPickData to change Pick properties. + */ + /*virtual*/ void onOpen(const LLSD& key) override; + + /*virtual*/ BOOL postBuild() override; + + /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE) override; + + /*virtual*/ void processProperties(void* data, EAvatarProcessorType type) override; + + /** + * Sends remote parcel info request to resolve parcel name from its ID. + */ + void sendParcelInfoRequest(); + + /** + * Sets "Back" button click callback + */ + virtual void setExitCallback(const commit_callback_t& cb); + + /** + * Sets "Edit" button click callback + */ + virtual void setEditPickCallback(const commit_callback_t& cb); + + //This stuff we got from LLRemoteParcelObserver, in the last one we intentionally do nothing + /*virtual*/ void processParcelInfo(const LLParcelData& parcel_data) override; + /*virtual*/ void setParcelID(const LLUUID& parcel_id) override { mParcelId = parcel_id; } + /*virtual*/ void setErrorStatus(S32 status, const std::string& reason) override {}; + +protected: + + LLPanelPickInfo(); + + /** + * Resets Pick information + */ + virtual void resetData(); + + /** + * Resets UI controls (visibility, values) + */ + virtual void resetControls(); + + /** + * "Location text" is actually the owner name, the original + * name that owner gave the parcel, and the location. + */ + static std::string createLocationText( + const std::string& owner_name, + const std::string& original_name, + const std::string& sim_name, + const LLVector3d& pos_global); + + virtual void setAvatarId(const LLUUID& avatar_id) { mAvatarId = avatar_id; } + virtual LLUUID& getAvatarId() { return mAvatarId; } + + /** + * Sets snapshot id. + * + * Will mark snapshot control as valid if id is not null. + * Will mark snapshot control as invalid if id is null. If null id is a valid value, + * you have to manually mark snapshot is valid. + */ + virtual void setSnapshotId(const LLUUID& id); + + virtual void setPickId(const LLUUID& id) { mPickId = id; } + virtual LLUUID& getPickId() { return mPickId; } + + virtual void setPickName(const std::string& name); + + virtual void setPickDesc(const std::string& desc); + + virtual void setPickLocation(const std::string& location); + + virtual void setPosGlobal(const LLVector3d& pos) { mPosGlobal = pos; } + virtual LLVector3d& getPosGlobal() { return mPosGlobal; } + + /** + * Callback for "Map" button, opens Map + */ + void onClickMap(); + + /** + * Callback for "Teleport" button, teleports user to Pick location. + */ + void onClickTeleport(); + + void onClickBack(); + + S32 mScrollingPanelMinHeight; + S32 mScrollingPanelWidth; + LLScrollContainer* mScrollContainer; + LLPanel* mScrollingPanel; + LLTextureCtrl* mSnapshotCtrl; + + LLUUID mAvatarId; + LLVector3d mPosGlobal; + LLUUID mParcelId; + LLUUID mPickId; + LLUUID mRequestedId; +}; + +/** + * Panel for creating/editing Pick. + */ +class LLPanelPickEdit final : public LLPanelPickInfo +{ + LOG_CLASS(LLPanelPickEdit); +public: + + /** + * Creates new panel + */ + static LLPanelPickEdit* create(); + + ~LLPanelPickEdit() = default; + void onOpen(const LLSD& key) override; + virtual void setPickData(const LLPickData* pick_data); + BOOL postBuild() override; + + /** + * Sets "Save" button click callback + */ + virtual void setSaveCallback(const commit_callback_t& cb); + + /** + * Sets "Cancel" button click callback + */ + virtual void setCancelCallback(const commit_callback_t& cb); + + /** + * Resets panel and all cantrols to unedited state + */ + void resetDirty() override; + + /** + * Returns true if any of Pick properties was changed by user. + */ + BOOL isDirty() const override; + + void processProperties(void* data, EAvatarProcessorType type) override; + + /** + * Sends Pick properties to server. + */ + void sendUpdate(); + +protected: + + LLPanelPickEdit(); + + /** + * Called when snapshot image changes. + */ + void onSnapshotChanged(); + + /** + * Callback for Pick snapshot, name and description changed event. + */ + void onPickChanged(LLUICtrl* ctrl); + + /*virtual*/ void resetData() override; + + /** + * Enables/disables "Save" button + */ + void enableSaveButton(bool enable); + + /** + * Callback for "Set Location" button click + */ + void onClickSetLocation(); + + /** + * Callback for "Save" button click + */ + void onClickSave(); + + std::string getLocationNotice(); + + bool mLocationChanged; + bool mNeedData; + bool mNewPick; + +private: + + void initTexturePickerMouseEvents(); + void onTexturePickerMouseEnter(LLUICtrl* ctrl); + void onTexturePickerMouseLeave(LLUICtrl* ctrl); + + LLIconCtrl* text_icon; +}; + +#endif // LL_LLPANELPICK_H diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp index 3f12deb36ad99bea57d9f8d99597b50bb8f13e86..f1445ad4386d74b7afca8b458e140ca59eadd160 100644 --- a/indra/newview/llpanelplaceinfo.cpp +++ b/indra/newview/llpanelplaceinfo.cpp @@ -321,11 +321,7 @@ void LLPanelPlaceInfo::createPick(const LLVector3d& pos_global) data.snapshot_id = mSnapshotCtrl->getImageAssetID(); data.parcel_id = mParcelID; - LLFloaterProfile* profile_floater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", gAgentID))); - if (profile_floater) - { - profile_floater->createPick(data); - } + LLAvatarActions::createPick(data); } // static diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 68fbfa3fb0a4f3ae7148f2d0a8795535806acb9f..f6d19dfe9bd2d321a48cd60238da5864d318bb3b 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -62,8 +62,7 @@ #include "llcommandhandler.h" #include "llfloaterprofiletexture.h" #include "llfloaterreg.h" -#include "llfloaterblocked.h" -#include "llfloaterreporter.h" +#include "lltexturectrl.h" #include "llfilepicker.h" #include "llfirstuse.h" #include "llgroupactions.h" @@ -104,167 +103,14 @@ static const std::string PROFILE_IMAGE_UPLOAD_CAP = "UploadAgentProfileImage"; ////////////////////////////////////////////////////////////////////////// -LLUUID post_profile_image(std::string cap_url, const LLSD &first_data, std::string path_to_image, LLHandle<LLPanel> *handle) -{ - LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); - LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t - httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("post_profile_image_coro", httpPolicy)); - LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); - LLCore::HttpHeaders::ptr_t httpHeaders; - - LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); - httpOpts->setFollowRedirects(true); - - LLSD result = httpAdapter->postAndSuspend(httpRequest, cap_url, first_data, httpOpts, httpHeaders); - - LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; - LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); - - if (!status) - { - // todo: notification? - LL_WARNS("AvatarProperties") << "Failed to get uploader cap " << status.toString() << LL_ENDL; - return LLUUID::null; - } - if (!result.has("uploader")) - { - // todo: notification? - LL_WARNS("AvatarProperties") << "Failed to get uploader cap, response contains no data." << LL_ENDL; - return LLUUID::null; - } - std::string uploader_cap = result["uploader"].asString(); - if (uploader_cap.empty()) - { - LL_WARNS("AvatarProperties") << "Failed to get uploader cap, cap invalid." << LL_ENDL; - return LLUUID::null; - } - - // Upload the image - LLCore::HttpRequest::ptr_t uploaderhttpRequest(new LLCore::HttpRequest); - LLCore::HttpHeaders::ptr_t uploaderhttpHeaders(new LLCore::HttpHeaders); - LLCore::HttpOptions::ptr_t uploaderhttpOpts(new LLCore::HttpOptions); - S64 length; - - { - llifstream instream(path_to_image.c_str(), std::iostream::binary | std::iostream::ate); - if (!instream.is_open()) - { - LL_WARNS("AvatarProperties") << "Failed to open file " << path_to_image << LL_ENDL; - return LLUUID::null; - } - length = instream.tellg(); - } - - uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, "application/jp2"); // optional - uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_LENGTH, llformat("%d", length)); // required! - uploaderhttpOpts->setFollowRedirects(true); - - result = httpAdapter->postFileAndSuspend(uploaderhttpRequest, uploader_cap, path_to_image, uploaderhttpOpts, uploaderhttpHeaders); - - httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; - status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); - - LL_DEBUGS("AvatarProperties") << result << LL_ENDL; - - if (!status) - { - LL_WARNS("AvatarProperties") << "Failed to upload image " << status.toString() << LL_ENDL; - return LLUUID::null; - } - - if (result["state"].asString() != "complete") - { - if (result.has("message")) - { - LL_WARNS("AvatarProperties") << "Failed to upload image, state " << result["state"] << " message: " << result["message"] << LL_ENDL; - } - else - { - LL_WARNS("AvatarProperties") << "Failed to upload image " << result << LL_ENDL; - } - return LLUUID::null; - } - - return result["new_asset"].asUUID(); -} - -enum EProfileImageType -{ - PROFILE_IMAGE_SL, - PROFILE_IMAGE_FL, -}; - -void post_profile_image_coro(std::string cap_url, EProfileImageType type, std::string path_to_image, LLHandle<LLPanel> *handle) -{ - LLSD data; - switch (type) - { - case PROFILE_IMAGE_SL: - data["profile-image-asset"] = "sl_image_id"; - break; - case PROFILE_IMAGE_FL: - data["profile-image-asset"] = "fl_image_id"; - break; - } - - LLUUID result = post_profile_image(cap_url, data, path_to_image, handle); - - // reset loading indicator - if (!handle->isDead()) - { - switch (type) - { - case PROFILE_IMAGE_SL: - { - LLPanelProfileSecondLife* panel = static_cast<LLPanelProfileSecondLife*>(handle->get()); - if (result.notNull()) - { - panel->setProfileImageUploaded(result); - } - else - { - // failure, just stop progress indicator - panel->setProfileImageUploading(false); - } - break; - } - case PROFILE_IMAGE_FL: - { - LLPanelProfileFirstLife* panel = static_cast<LLPanelProfileFirstLife*>(handle->get()); - if (result.notNull()) - { - panel->setProfileImageUploaded(result); - } - else - { - // failure, just stop progress indicator - panel->setProfileImageUploading(false); - } - break; - } - } - } - - if (type == PROFILE_IMAGE_SL && result.notNull()) - { - LLAvatarIconIDCache::getInstance()->add(gAgentID, result); - // Should trigger callbacks in icon controls - LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesRequest(gAgentID); - } - - // Cleanup - LLFile::remove(path_to_image); - delete handle; -} - ////////////////////////////////////////////////////////////////////////// -// LLProfileHandler +// LLWebProfileHandler -class LLProfileHandler : public LLCommandHandler +class LLWebProfileHandler : public LLCommandHandler { public: // requires trusted browser to trigger - LLProfileHandler() : LLCommandHandler("profile", UNTRUSTED_THROTTLE) { } + LLWebProfileHandler() : LLCommandHandler("profile", UNTRUSTED_THROTTLE) { } bool handle(const LLSD& params, const LLSD& query_map, @@ -280,6 +126,8 @@ class LLProfileHandler : public LLCommandHandler return true; } }; +LLWebProfileHandler gWebProfileHandler; +#if 0 // ALCHMERGE LLProfileHandler gProfileHandler; @@ -324,7 +172,7 @@ class LLAgentHandler : public LLCommandHandler { if (params.size() < 2) return false; LLUUID avatar_id; - if (!avatar_id.set(params[0].asString(), FALSE)) + if (!avatar_id.set(params[0], FALSE)) { return false; } @@ -403,8 +251,7 @@ class LLAgentHandler : public LLCommandHandler const std::string object_name = LLURI::unescape(params[2].asString()); LLMute mute(avatar_id, object_name, LLMute::OBJECT); LLMuteList::getInstance()->add(mute); - LLFloaterBlocked::showMuteAndSelect(mute.mID); - //LLPanelBlockedList::showPanelAndSelect(mute.mID); + LLPanelBlockedList::showPanelAndSelect(mute.mID); } return true; } @@ -439,7 +286,7 @@ class LLAgentHandler : public LLCommandHandler } }; LLAgentHandler gAgentHandler; - +#endif ///---------------------------------------------------------------------------- /// LLFloaterProfilePermissions @@ -1268,93 +1115,12 @@ void LLPanelProfileSecondLife::setLoaded() } } - -class LLProfileImagePicker : public LLFilePickerThread -{ -public: - LLProfileImagePicker(EProfileImageType type, LLHandle<LLPanel> *handle); - ~LLProfileImagePicker(); - void notify(const std::vector<std::string>& filenames) override; - -private: - LLHandle<LLPanel> *mHandle; - EProfileImageType mType; -}; - -LLProfileImagePicker::LLProfileImagePicker(EProfileImageType type, LLHandle<LLPanel> *handle) - : LLFilePickerThread(LLFilePicker::FFLOAD_IMAGE), - mHandle(handle), - mType(type) -{ -} - -LLProfileImagePicker::~LLProfileImagePicker() -{ - delete mHandle; -} - -void LLProfileImagePicker::notify(const std::vector<std::string>& filenames) -{ - if (mHandle->isDead()) - { - return; - } - if (filenames.empty()) - { - return; - } - std::string file_path = filenames[0]; - if (file_path.empty()) - { - return; - } - - // generate a temp texture file for coroutine - std::string temp_file = gDirUtilp->getTempFilename(); - U32 codec = LLImageBase::getCodecFromExtension(gDirUtilp->getExtension(file_path)); - const S32 MAX_DIM = 256; - if (!LLViewerTextureList::createUploadFile(file_path, temp_file, codec, MAX_DIM)) - { - //todo: image not supported notification - LL_WARNS("AvatarProperties") << "Failed to upload profile image of type " << (S32)PROFILE_IMAGE_SL << ", failed to open image" << LL_ENDL; - return; - } - - std::string cap_url = gAgent.getRegionCapability(PROFILE_IMAGE_UPLOAD_CAP); - if (cap_url.empty()) - { - LL_WARNS("AvatarProperties") << "Failed to upload profile image of type " << (S32)PROFILE_IMAGE_SL << ", no cap found" << LL_ENDL; - return; - } - - switch (mType) - { - case PROFILE_IMAGE_SL: - { - LLPanelProfileSecondLife* panel = static_cast<LLPanelProfileSecondLife*>(mHandle->get()); - panel->setProfileImageUploading(true); - } - break; - case PROFILE_IMAGE_FL: - { - LLPanelProfileFirstLife* panel = static_cast<LLPanelProfileFirstLife*>(mHandle->get()); - panel->setProfileImageUploading(true); - } - break; - } - - LLCoros::instance().launch("postAgentUserImageCoro", - boost::bind(post_profile_image_coro, cap_url, mType, temp_file, mHandle)); - - mHandle = nullptr; // transferred to post_profile_image_coro -} - void LLPanelProfileSecondLife::onCommitMenu(const LLSD& userdata) { const std::string item_name = userdata.asString(); const LLUUID agent_id = getAvatarId(); // todo: consider moving this into LLAvatarActions::onCommit(name, id) - // and making all other flaoters, like people menu do the same + // and making all other floaters, like people menu, do the same if (item_name == "im") { LLAvatarActions::startIM(agent_id); @@ -1457,7 +1223,8 @@ void LLPanelProfileSecondLife::onCommitMenu(const LLSD& userdata) } else if (item_name == "upload_photo") { - (new LLProfileImagePicker(PROFILE_IMAGE_SL, new LLHandle<LLPanel>(LLPanel::getHandle())))->getFile(); + (new LLProfileImagePicker(PROFILE_IMAGE_SL, new LLHandle<LLPanel>(LLPanel::getHandle()), + [this] (LLUUID const& id) { setProfileImageUploaded(id); }))->getFile(); LLFloater* floaterp = mFloaterTexturePickerHandle.get(); if (floaterp) @@ -2007,7 +1774,8 @@ void LLPanelProfileFirstLife::commitUnsavedChanges() void LLPanelProfileFirstLife::onUploadPhoto() { - (new LLProfileImagePicker(PROFILE_IMAGE_FL, new LLHandle<LLPanel>(LLPanel::getHandle())))->getFile(); + (new LLProfileImagePicker(PROFILE_IMAGE_FL, new LLHandle<LLPanel>(LLPanel::getHandle()), + [this](LLUUID const& id) { setProfileImageUploaded(id); }))->getFile(); LLFloater* floaterp = mFloaterTexturePickerHandle.get(); if (floaterp) diff --git a/indra/newview/llpanelprofile.h b/indra/newview/llpanelprofile.h index a2f0fbbfe1df0effbbf38dd591f98dbfa3f1b0af..1f7435eaa821b2eea73aab714b321e59fd311eca 100644 --- a/indra/newview/llpanelprofile.h +++ b/indra/newview/llpanelprofile.h @@ -33,6 +33,7 @@ #include "llpanel.h" #include "llpanelavatar.h" #include "llmediactrl.h" +#include "llprofileimagepicker.h" #include "llvoiceclient.h" // class LLPanelProfileClassifieds; diff --git a/indra/newview/llpanelprofileclassifieds.cpp b/indra/newview/llpanelprofileclassifieds.cpp index 23266a2279f78b2e8b5f7c5302bcb51e14487885..e2768ff807491c6821318d3c83496feca725aa91 100644 --- a/indra/newview/llpanelprofileclassifieds.cpp +++ b/indra/newview/llpanelprofileclassifieds.cpp @@ -32,13 +32,14 @@ #include "llavataractions.h" #include "llavatarpropertiesprocessor.h" #include "llclassifiedflags.h" +#include "llclassifiedinfo.h" #include "llcombobox.h" #include "llcommandhandler.h" // for classified HTML detail page click tracking #include "llcorehttputil.h" #include "lldispatcher.h" #include "llfloaterclassified.h" #include "llfloaterreg.h" -#include "llfloatersidepanelcontainer.h" +#include "llfloaterpublishclassified.h" #include "llfloaterworldmap.h" #include "lliconctrl.h" #include "lllineeditor.h" @@ -46,7 +47,6 @@ #include "llnotificationsutil.h" #include "llpanelavatar.h" #include "llparcel.h" -#include "llregistry.h" #include "llscrollcontainer.h" #include "llstartup.h" #include "llstatusbar.h" @@ -57,8 +57,6 @@ #include "llviewergenericmessage.h" // send_generic_message #include "llviewerparcelmgr.h" #include "llviewerregion.h" -#include "llviewertexture.h" -#include "llviewertexture.h" #include "rlvactions.h" #include "rlvhandler.h" @@ -66,7 +64,6 @@ //*TODO: verify this limit const S32 MAX_AVATAR_CLASSIFIEDS = 100; -const S32 MINIMUM_PRICE_FOR_LISTING = 50; // L$ const S32 DEFAULT_EDIT_CLASSIFIED_SCROLL_HEIGHT = 530; //static @@ -137,7 +134,7 @@ class LLClassifiedHandler : public LLCommandHandler, public LLAvatarPropertiesOb // get the ID for the classified LLUUID classified_id; - if (!classified_id.set(params[0].asString(), FALSE)) + if (!classified_id.set(params[0].asStringRef(), FALSE)) { return false; } @@ -981,12 +978,12 @@ void LLPanelProfileClassified::onSaveClick() return; } - mPublishFloater = LLFloaterReg::findTypedInstance<LLPublishClassifiedFloater>( + mPublishFloater = LLFloaterReg::findTypedInstance<LLFloaterPublishClassified>( "publish_classified", LLSD()); if(!mPublishFloater) { - mPublishFloater = LLFloaterReg::getTypedInstance<LLPublishClassifiedFloater>( + mPublishFloater = LLFloaterReg::getTypedInstance<LLFloaterPublishClassified>( "publish_classified", LLSD()); mPublishFloater->setPublishClickedCallback(boost::bind @@ -1526,47 +1523,3 @@ void LLPanelProfileClassified::updateTabLabel(const std::string& title) parent->setCurrentTabName(title); } } - - -//----------------------------------------------------------------------------- -// LLPublishClassifiedFloater -//----------------------------------------------------------------------------- - -LLPublishClassifiedFloater::LLPublishClassifiedFloater(const LLSD& key) - : LLFloater(key) -{ -} - -LLPublishClassifiedFloater::~LLPublishClassifiedFloater() -{ -} - -BOOL LLPublishClassifiedFloater::postBuild() -{ - LLFloater::postBuild(); - - childSetAction("publish_btn", boost::bind(&LLFloater::closeFloater, this, false)); - childSetAction("cancel_btn", boost::bind(&LLFloater::closeFloater, this, false)); - - return TRUE; -} - -void LLPublishClassifiedFloater::setPrice(S32 price) -{ - getChild<LLUICtrl>("price_for_listing")->setValue(price); -} - -S32 LLPublishClassifiedFloater::getPrice() -{ - return getChild<LLUICtrl>("price_for_listing")->getValue().asInteger(); -} - -void LLPublishClassifiedFloater::setPublishClickedCallback(const commit_signal_t::slot_type& cb) -{ - getChild<LLButton>("publish_btn")->setClickedCallback(cb); -} - -void LLPublishClassifiedFloater::setCancelClickedCallback(const commit_signal_t::slot_type& cb) -{ - getChild<LLButton>("cancel_btn")->setClickedCallback(cb); -} diff --git a/indra/newview/llpanelprofileclassifieds.h b/indra/newview/llpanelprofileclassifieds.h index 5f029b22f4a1ba4c7dc0ab5d7aed71db58688b46..e6aa761ff023c65fcda00198ad4a0abbe3b0466b 100644 --- a/indra/newview/llpanelprofileclassifieds.h +++ b/indra/newview/llpanelprofileclassifieds.h @@ -28,14 +28,11 @@ #define LL_PANELPROFILECLASSIFIEDS_H #include "llavatarpropertiesprocessor.h" -#include "llclassifiedinfo.h" -#include "llfloater.h" +#include "llfloaterpublishclassified.h" #include "llpanel.h" #include "llpanelavatar.h" -#include "llrect.h" #include "lluuid.h" #include "v3dmath.h" -#include "llcoros.h" #include "lleventcoro.h" class LLCheckBoxCtrl; @@ -47,23 +44,6 @@ class LLTextEditor; class LLTextureCtrl; class LLUICtrl; - -class LLPublishClassifiedFloater final : public LLFloater -{ -public: - LLPublishClassifiedFloater(const LLSD& key); - virtual ~LLPublishClassifiedFloater(); - - BOOL postBuild() override; - - void setPrice(S32 price); - S32 getPrice(); - - void setPublishClickedCallback(const commit_signal_t::slot_type& cb); - void setCancelClickedCallback(const commit_signal_t::slot_type& cb); -}; - - /** * Panel for displaying Avatar's picks. */ @@ -325,11 +305,8 @@ class LLPanelProfileClassified S32 mPriceForListing; -public: static void handleSearchStatResponse(LLUUID classifiedId, LLSD result); -private: - typedef std::list<LLPanelProfileClassified*> panel_list_t; static panel_list_t sAllPanels; @@ -339,7 +316,7 @@ class LLPanelProfileClassified bool mCanClose; bool mEditOnLoad; - LLPublishClassifiedFloater* mPublishFloater; + LLFloaterPublishClassified* mPublishFloater; }; #endif // LL_PANELPROFILECLASSIFIEDS_H diff --git a/indra/newview/llpanelprofilelegacy.cpp b/indra/newview/llpanelprofilelegacy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..de6167984017908e9b8af14a5766c9fea5ec6b1d --- /dev/null +++ b/indra/newview/llpanelprofilelegacy.cpp @@ -0,0 +1,1668 @@ +/* + * @file llpanelprofilelegacy.cpp + * @brief Legacy protocol avatar profile panel + * + * Copyright (c) 2014-2022, Cinder Roxley <cinder@sdf.org> + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "llviewerprecompiledheaders.h" +#include "llpanelprofilelegacy.h" + +// libraries +#include "llaccordionctrl.h" +#include "llaccordionctrltab.h" +#include "llavatarnamecache.h" +#include "llcheckboxctrl.h" +#include "llflatlistview.h" +#include "llfloaterreg.h" +#include "lllineeditor.h" +#include "llloadingindicator.h" +#include "llnotificationsutil.h" +#include "lltexteditor.h" +#include "lltexturectrl.h" +#include "lltoggleablemenu.h" +#include "lltrans.h" + +// newview +#include "alavataractions.h" +#include "llagent.h" +#include "llagentdata.h" +#include "llagentpicksinfo.h" +#include "llavataractions.h" +#include "llcallingcard.h" // for LLAvatarTracker +#include "llclassifieditem.h" +#include "lldateutil.h" +#include "lldroptarget.h" +#include "llfloaterreporter.h" +#include "llfloaterworldmap.h" +#include "llgroupactions.h" +#include "llpanelclassified.h" +#include "llpanelpick.h" +#include "llpickitem.h" +#include "llmutelist.h" +#include "llsidetraypanelcontainer.h" +#include "llslurl.h" +#include "llviewerdisplayname.h" +#include "llviewermenu.h" // gMenuHolder + +static constexpr std::string_view AGENT_PROFILE_CAP("AgentProfile"); +//static constexpr std::string_view UPLOAD_AGENT_PROFILE_CAP("UploadAgentProfileImage"); + +// These are order-senstitive so don't fk with 'em! +static const std::array<std::string, 8> sWantCheckboxes{{"wanna_build", "wanna_explore", "wanna_yiff", "wanna_work", "wanna_group", "wanna_buy", "wanna_sell", "wanna_hire"}}; +static const std::array<std::string, 6> sSkillsCheckboxes{{"can_texture", "can_architect", "can_model", "can_event", "can_script", "can_characters"}}; + +static LLPanelInjector<LLPanelProfileLegacy> t_panel_lprofile("panel_profile_legacy_sidetray"); +static LLPanelInjector<LLPanelProfileLegacy::LLPanelProfileGroups> t_panel_group("panel_profile_legacy_groups"); +static LLPanelInjector<LLPanelProfileLegacy::LLPanelProfilePicks> t_panel_picks("panel_profile_legacy_picks"); + +LLPanelProfileLegacy::LLPanelProfileLegacy() +: LLPanelProfileLegacyTab() +, mPanelPicks(nullptr) +, mPanelGroups(nullptr) +{ + mChildStack.setParent(this); + //mCommitCallbackRegistrar.add("Profile.CommitInterest", boost::bind(&LLPanelProfileLegacy::onCommitInterest, this)); + mCommitCallbackRegistrar.add("Profile.CommitProperties", boost::bind(&LLPanelProfileLegacy::onCommitAvatarProperties, this)); + mCommitCallbackRegistrar.add("Profile.CommitRights", boost::bind(&LLPanelProfileLegacy::onCommitRights, this)); + mCommitCallbackRegistrar.add("Profile.CommitModifyObjectRights", boost::bind(&LLPanelProfileLegacy::onCommitModifyObjectsRights, this, _1)); + mCommitCallbackRegistrar.add("Profile.Action", boost::bind(&LLPanelProfileLegacy::onCommitAction, this, _2)); + mEnableCallbackRegistrar.add("Profile.Enable", boost::bind(&LLPanelProfileLegacy::isActionEnabled, this, _2)); +} + +LLPanelProfileLegacy::~LLPanelProfileLegacy() +{ + if (LLAvatarPropertiesProcessor::instanceExists() && LLPanelProfileLegacyTab::getAvatarId().notNull()) + LLAvatarPropertiesProcessor::getInstance()->removeObserver(LLPanelProfileLegacyTab::getAvatarId(), this); + if (mAvatarNameCacheConnection.connected()) + mAvatarNameCacheConnection.disconnect(); + if (mNameChangedConnection.connected()) + mNameChangedConnection.disconnect(); +} + +// virtual +BOOL LLPanelProfileLegacy::postBuild() +{ + mPanelGroups = static_cast<LLPanelProfileGroups*>(getChild<LLUICtrl>("avatar_groups_tab_panel")); + mPanelPicks = static_cast<LLPanelProfilePicks*>(getChild<LLUICtrl>("avatar_picks_tab_panel")); + mPanelPicks->setProfilePanel(this); + + if (dynamic_cast<LLSideTrayPanelContainer*>(getParent()) != nullptr) + getChild<LLUICtrl>("back")->setCommitCallback(boost::bind(&LLPanelProfileLegacy::onBackBtnClick, this)); + else if (dynamic_cast<LLFloater*>(getParent()) != nullptr) + getChild<LLUICtrl>("back")->setCommitCallback(boost::bind(&LLPanelProfileLegacy::closeParentFloater, this)); + else + getChild<LLUICtrl>("back")->setEnabled(FALSE); + getChild<LLTextEditor>("sl_about")->setCommitCallback(boost::bind(&LLPanelProfileLegacy::onCommitAvatarProperties, this)); + getChild<LLTextEditor>("fl_about")->setCommitCallback(boost::bind(&LLPanelProfileLegacy::onCommitAvatarProperties, this)); + getChild<LLTextureCtrl>("sl_profile_pic")->setCommitCallback(boost::bind(&LLPanelProfileLegacy::onCommitAvatarProperties, this)); + getChild<LLTextureCtrl>("fl_profile_pic")->setCommitCallback(boost::bind(&LLPanelProfileLegacy::onCommitAvatarProperties, this)); + getChild<LLTextEditor>("notes")->setCommitCallback(boost::bind(&LLPanelProfileLegacy::onCommitNotes, this, _1)); + getChild<LLTextEditor>("avatar_name")->setDoubleClickCallback(boost::bind(&LLPanelProfileLegacy::onDoubleClickName, this)); + return TRUE; +} + +// virtual +void LLPanelProfileLegacy::reshape(S32 width, S32 height, BOOL called_from_parent) +{ + // Temporarily add saved children back and reshape them. + mChildStack.preParentReshape(); + LLPanel::reshape(width, height, called_from_parent); + mChildStack.postParentReshape(); +} + +// virtual +void LLPanelProfileLegacy::onOpen(const LLSD& key) +{ + if (!key.has("avatar_id")) return; + const LLUUID av_id = key["avatar_id"].asUUID(); + + if (key.has("action")) + { + // *TODO: Actions, if any + return; + } + + if (mNameChangedConnection.connected()) + { + mNameChangedConnection.disconnect(); + } + + setAvatarId(av_id); + + mPanelGroups->onOpen(LLSD(av_id)); + mPanelPicks->onOpen(LLSD(av_id)); + // Oh joy! + bool is_self = (getAvatarId() == gAgentID); + getChild<LLView>("sl_profile_pic")->setEnabled(is_self); + getChild<LLView>("fl_profile_pic")->setEnabled(is_self); + getChild<LLView>("sl_about")->setEnabled(is_self); + getChild<LLView>("fl_about")->setEnabled(is_self); + getChild<LLView>("www")->setVisible(!is_self); + getChild<LLView>("www_edit")->setVisible(is_self); + getChild<LLView>("allow_publish")->setVisible(is_self); + //childSetEnabled("wanna_something", is_self); + //childSetEnabled("can_something", is_self); + //childSetEnabled("languages", is_self); + for (const std::string& checkbox: sWantCheckboxes) + childSetEnabled(checkbox, is_self); + for (const std::string& checkbox: sSkillsCheckboxes) + childSetEnabled(checkbox, is_self); + childSetEnabled("drop_target", !is_self); + getChild<LLLayoutPanel>("avatar_in_search", is_self); + getChild<LLDropTarget>("drop_target")->setAgentID(av_id); + //resetInterestsControlValues(); + + updateData(); + resetControls(); + + getChild<LLAccordionCtrl>("avatar_accordion")->expandDefaultTab(); +} + +void LLPanelProfileLegacy::resetControls() +{ + LLButton* button = getChild<LLButton>("btn_chat"); + button->setEnabled(getAvatarId() != gAgentID); + button = getChild<LLButton>("btn_friend"); + button->setEnabled(getAvatarId() != gAgentID); + button->setLabel(getString((LLAvatarTracker::instance().getBuddyInfo(getAvatarId()) == nullptr) + ? "add_friend" : "remove_friend")); + button = getChild<LLButton>("btn_block"); + button->setEnabled(getAvatarId() != gAgentID); + button->setLabel(LLTrans::getString(LLMuteList::getInstance()->isMuted(getAvatarId()) + ? "UnmuteAvatar" + : "MuteAvatar")); +} + +//void LLPanelProfileLegacy::resetInterestsControlValues() +//{ +// for (U32 i = 0; i < sWantCheckboxes.size(); ++i) +// { +// getChild<LLCheckBoxCtrl>(sWantCheckboxes.at(i))->setValue(FALSE); +// } +// +// for (U32 i = 0; i < sSkillsCheckboxes.size(); ++i) +// { +// getChild<LLCheckBoxCtrl>(sSkillsCheckboxes.at(i))->setValue(FALSE); +// } +// getChild<LLLineEditor>("wanna_something")->setText(LLStringUtil::null); +// getChild<LLLineEditor>("can_something")->setText(LLStringUtil::null); +// getChild<LLLineEditor>("languages")->setText(LLStringUtil::null); +//} + +void LLPanelProfileLegacy::updateData() +{ + setProgress(true); + + const std::string cap_url = gAgent.getRegionCapability(AGENT_PROFILE_CAP); + if (!cap_url.empty()) + { + const auto& agent_id = getAvatarId(); + auto handle = getHandle(); + LLCoros::instance().launch("requestAvatarProfileCoro", [cap_url, agent_id, handle]() { + LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t + httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("request_avatar_properties_coro", httpPolicy)); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + LLCore::HttpHeaders::ptr_t httpHeaders; + + LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); + httpOpts->setFollowRedirects(true); + + std::string finalUrl = cap_url + "/" + agent_id.asString(); + + LLSD result = httpAdapter->getAndSuspend(httpRequest, finalUrl, httpOpts, httpHeaders); + + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + LL_DEBUGS("AvatarProperties") << "Agent id: " << agent_id << " Result: " << httpResults << LL_ENDL; + + if (!status + || !result.has("id") + || agent_id != result["id"].asUUID()) + { + LL_WARNS("AvatarProperties") << "Failed to get agent information for id " << agent_id << LL_ENDL; + return; + } + + if (handle.isDead()) + { + // panel is dead + return; + } + + LLPanelProfileLegacy* legacy_sidetray = (LLPanelProfileLegacy*)handle.get(); + if (!legacy_sidetray) + { + return; + } + + // AgentProfile dumps all results into a big ol' map. Let's build some structs and make a bunch of calls + // to processProperties() + LLAvatarData avatar_data; + + avatar_data.agent_id = agent_id; + avatar_data.avatar_id = agent_id; + avatar_data.image_id = result["sl_image_id"].asUUID(); + avatar_data.fl_image_id = result["fl_image_id"].asUUID(); + avatar_data.partner_id = result["partner_id"].asUUID(); + avatar_data.about_text = result["sl_about_text"].asString(); + avatar_data.fl_about_text = result["fl_about_text"].asString(); + avatar_data.born_on = result["member_since"].asDate(); + avatar_data.profile_url = result.has("home_page") + ? result["home_page"].asString() : getProfileURL(agent_id.asString()); + + avatar_data.flags = 0; + if (result["online"].asBoolean()) + { + avatar_data.flags |= AVATAR_ONLINE; + } + if (result["allow_publish"].asBoolean()) + { + avatar_data.flags |= AVATAR_ALLOW_PUBLISH; + } + if (result["identified"].asBoolean()) + { + avatar_data.flags |= AVATAR_IDENTIFIED; + } + if (result["transacted"].asBoolean()) + { + avatar_data.flags |= AVATAR_TRANSACTED; + } + + avatar_data.caption_index = 0; + if (result.has("charter_member")) // won't be present if "caption" is set + { + avatar_data.caption_index = result["charter_member"].asInteger(); + } + else if (result.has("caption")) + { + avatar_data.caption_text = result["caption"].asString(); + } + legacy_sidetray->processProperties(&avatar_data, APT_PROPERTIES); + + LLSD groups_array = result["groups"]; + LLAvatarGroups avatar_groups; + avatar_groups.agent_id = agent_id; + avatar_groups.avatar_id = agent_id; + + for (LLSD::array_const_iterator it = groups_array.beginArray(); + it != groups_array.endArray(); ++it) + { + const LLSD& group_info = *it; + LLAvatarGroups::LLGroupData group_data; + group_data.group_powers = 0; + group_data.group_title = group_info["name"].asString(); + group_data.group_id = group_info["id"].asUUID(); + group_data.group_name = group_info["name"].asString(); + group_data.group_insignia_id = group_info["image_id"].asUUID(); + + avatar_groups.group_list.push_back(group_data); + } + + auto* groups_panel = static_cast<LLPanelProfileGroups*>(legacy_sidetray->getChild<LLUICtrl>("avatar_groups_tab_panel")); + + groups_panel->processProperties(&avatar_groups, APT_GROUPS); + legacy_sidetray->processProperties(&avatar_groups, APT_GROUPS); + + LLAvatarNotes avatar_notes; + avatar_notes.agent_id = agent_id; + avatar_notes.target_id = agent_id; + avatar_notes.notes = result["notes"].asString(); + + legacy_sidetray->processProperties(&avatar_notes, APT_NOTES); + + LLSD picks_array = result["picks"]; + LLAvatarPicks avatar_picks; + avatar_picks.agent_id = agent_id; + avatar_picks.target_id = agent_id; + for (LLSD::array_const_iterator it = picks_array.beginArray(); + it != picks_array.endArray(); ++it) + { + const LLSD& pick_data = *it; + avatar_picks.picks_list.emplace_back(pick_data["id"].asUUID(), pick_data["name"].asString()); + } + + legacy_sidetray->processProperties(&avatar_picks, APT_PICKS); + + // bonus time... + if (result.has("customer_type")) + { + LLUICtrl* internal_icon = legacy_sidetray->getChild<LLUICtrl>("account_type_internal"); + LLUICtrl* premium_icon = legacy_sidetray->getChild<LLUICtrl>("account_type_premium"); + LLUICtrl* plus_icon = legacy_sidetray->getChild<LLUICtrl>("account_type_plus"); + const std::string& type = result["customer_type"].asStringRef(); + + if (type == "Internal") + { + internal_icon->setVisible(true); + premium_icon->setVisible(false); + plus_icon->setVisible(false); + } + else if (type == "Monthly" || type == "Quarterly" || type == "Annual") + { + internal_icon->setVisible(false); + premium_icon->setVisible(true); + plus_icon->setVisible(false); + } + else if (type.substr(0, 12) == "Premium_Plus") + { + internal_icon->setVisible(false); + premium_icon->setVisible(false); + plus_icon->setVisible(true); + } + else /* if (type == "Base") */ + { + internal_icon->setVisible(false); + premium_icon->setVisible(false); + plus_icon->setVisible(false); + } + } + + }); + } + + mAvatarNameCacheConnection = LLAvatarNameCache::get(getAvatarId(), + boost::bind(&LLPanelProfileLegacy::onAvatarNameCache, this, _1, _2)); + + const LLRelationship* relation = LLAvatarTracker::instance().getBuddyInfo(getAvatarId()); + bool is_other = (relation && getAvatarId() != gAgentID); + getChild<LLLayoutPanel>("avatar_perm")->setVisible(is_other); + if (is_other) + { + S32 rights = relation->getRightsGrantedTo(); + getChild<LLCheckBoxCtrl>("allow_show_online")->setValue(rights & LLRelationship::GRANT_ONLINE_STATUS ? TRUE : FALSE); + getChild<LLCheckBoxCtrl>("allow_mapping")->setValue(rights & LLRelationship::GRANT_MAP_LOCATION ? TRUE : FALSE); + getChild<LLCheckBoxCtrl>("allow_object_perms")->setValue(rights & LLRelationship::GRANT_MODIFY_OBJECTS ? TRUE : FALSE); + } +} + +void LLPanelProfileLegacy::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name) +{ + getChild<LLTextEditor>("avatar_name")->setText(av_name.getCompleteName()); +} + +void LLPanelProfileLegacy::sendAvatarProfileCoro(std::string url, LLSD payload) +{ + LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t + httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("send_avatar_profile_coro", httpPolicy)); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + LLCore::HttpHeaders::ptr_t httpHeaders; + + LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); + httpOpts->setFollowRedirects(true); + + std::string full_url = url + "/" + getAvatarId().asString(); + + LLSD result = httpAdapter->putAndSuspend(httpRequest, full_url, payload, httpOpts, httpHeaders); + + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + if (!status) + { + LL_WARNS("LegacyProfiles") << "Failed to put agent information " << payload << " for id " << getAvatarId() << LL_ENDL; + return; + } + + LL_DEBUGS("LegacyProfiles") << "Agent id: " << getAvatarId() << " Payload: " << payload << " Result: " << httpResults << LL_ENDL; +} + +void LLPanelProfileLegacy::processProperties(void* data, EAvatarProcessorType type) +{ + if (!data) return; + switch(type) + { + case APT_PROPERTIES: + { + const LLAvatarData* pData = static_cast<const LLAvatarData*>(data); + if (!pData || pData->avatar_id != getAvatarId()) return; + getChild<LLTextureCtrl>("sl_profile_pic")->setValue(pData->image_id); + getChild<LLTextureCtrl>("fl_profile_pic")->setValue(pData->fl_image_id); + if (pData->partner_id.notNull()) + { + getChild<LLTextBase>("partner_info")->setText(LLSLURL("agent", pData->partner_id, "inspect").getSLURLString()); + getChild<LLTextBase>("partner_label")->setVisible(TRUE); + getChild<LLTextBase>("partner_info")->setVisible(TRUE); + } + else + { + getChild<LLTextBase>("partner_label")->setVisible(FALSE); + getChild<LLTextBase>("partner_info")->setVisible(FALSE); + } + getChild<LLTextEditor>("sl_about")->setText(pData->about_text); + getChild<LLTextEditor>("fl_about")->setText(pData->fl_about_text); + getChild<LLTextBase>("www")->setText(pData->profile_url); + getChild<LLLineEditor>("www_edit")->setText(pData->profile_url); + + LLStringUtil::format_map_t args; + std::string birth_date = LLTrans::getString("AvatarBirthDateFormatFull"); + LLStringUtil::format(birth_date, LLSD().with("datetime", static_cast<S32>(pData->born_on.secondsSinceEpoch()))); + args["[AGE]"] = LLDateUtil::ageFromDate(pData->born_on, LLDate::now()); + args["[REZDAY]"] = birth_date; + args["[ACCOUNT_TYPE]"] = LLAvatarPropertiesProcessor::accountType(pData); + args["[PAYMENT_INFO]"] = LLAvatarPropertiesProcessor::paymentInfo(pData); + args["[AGE_VERIFIED]"] = pData->flags & AVATAR_AGEVERIFIED ? getString("age_verified") : LLStringUtil::null; + LLSD formatted_info(getString("account_info_fmt", args)); + getChild<LLTextBase>("account_info")->setValue(formatted_info); + formatted_info = LLSD(getString("rezday_fmt", args)); + getChild<LLTextBase>("rezday")->setValue(formatted_info); + getChild<LLView>("cake")->setVisible(pData->born_on.toHTTPDateString(LLStringExplicit("%d %b")) == + LLDate::now().toHTTPDateString(LLStringExplicit("%d %b"))); + getChild<LLCheckBoxCtrl>("allow_publish")->setValue(static_cast<bool>(pData->flags & AVATAR_ALLOW_PUBLISH)); + getChild<LLUICtrl>("online")->setVisible(static_cast<BOOL>(pData->flags & AVATAR_ONLINE || + pData->avatar_id == gAgentID)); + break; + } + case APT_NOTES: + { + const LLAvatarNotes* pData = static_cast<const LLAvatarNotes*>(data); + if (!pData || pData->target_id != getAvatarId()) return; + getChild<LLTextEditor>("notes")->setValue(pData->notes); + break; + } + //case APT_INTERESTS: + //{ + // const LLAvatarInterests* pData = static_cast<const LLAvatarInterests*>(data); + // if (!pData || pData->avatar_id != getAvatarId()) return; + + // for (U32 i = 0; i < sWantCheckboxes.size(); ++i) + // { + // getChild<LLCheckBoxCtrl>(sWantCheckboxes.at(i))->setValue(pData->want_to_mask & (1<<i) ? TRUE : FALSE); + // } + + // for (U32 i = 0; i < sSkillsCheckboxes.size(); ++i) + // { + // getChild<LLCheckBoxCtrl>(sSkillsCheckboxes.at(i))->setValue(pData->skills_mask & (1<<i) ? TRUE : FALSE); + // } + // getChild<LLLineEditor>("wanna_something")->setText(pData->want_to_text); + // getChild<LLLineEditor>("can_something")->setText(pData->skills_text); + // getChild<LLLineEditor>("languages")->setText(pData->languages_text); + // break; + //} + case APT_GROUPS: + { + const LLAvatarGroups* pData = static_cast<LLAvatarGroups*>(data); + if(!pData || getAvatarId() != pData->avatar_id) return; + + showTab("avatar_groups_tab", !pData->group_list.empty()); + break; + } + // These are handled by their respective panels + case APT_PICKS: + case APT_CLASSIFIEDS: + case APT_PICK_INFO: + case APT_CLASSIFIED_INFO: + // Used by LLAgent not profiles. ;) + case APT_TEXTURES: + default: + break; + } + setProgress(false); +} + +void LLPanelProfileLegacy::setProgress(bool started) +{ + LLLoadingIndicator* indicator = getChild<LLLoadingIndicator>("progress_indicator"); + indicator->setVisible(started); + if (started) + indicator->start(); + else + indicator->stop(); +} + +void LLPanelProfileLegacy::showTab(std::string_view name, bool show) const +{ + getChild<LLAccordionCtrlTab>(name)->setVisible(show); + getChild<LLAccordionCtrl>("avatar_accordion")->arrange(); +} + +LLPanel* LLPanelProfileLegacy::expandTab(const std::string& name) const +{ + getChild<LLAccordionCtrl>("avatar_accordion")->expandTab(name); + return getChild<LLAccordionCtrlTab>(name)->getChild<LLPanel>(name + "_panel"); +} + +LLPanel* LLPanelProfileLegacy::getExpandedTab() const +{ + const LLAccordionCtrlTab* tab = getChild<LLAccordionCtrl>("avatar_accordion")->getExpandedTab(); + return tab ? tab->getChild<LLPanel>(tab->getName() + "_panel") : nullptr; +} + +void LLPanelProfileLegacy::onCommitAction(const LLSD& userdata) +{ + const std::string action = userdata.asString(); + if (action == "friend") + { + if (LLAvatarTracker::instance().getBuddyInfo(getAvatarId()) == nullptr) + LLAvatarActions::requestFriendshipDialog(getAvatarId()); + else + LLAvatarActions::removeFriendDialog(getAvatarId()); + resetControls(); + } + else if (action == "block") + { + LLAvatarActions::toggleBlock(getAvatarId()); + resetControls(); + } + else if (action == "chat") + LLAvatarActions::startIM(getAvatarId()); + else if (action == "call") + LLAvatarActions::startCall(getAvatarId()); + else if (action == "share") + LLAvatarActions::share(getAvatarId()); + else if (action == "teleport") + LLAvatarActions::offerTeleport(getAvatarId()); + else if (action == "req_teleport") + LLAvatarActions::teleportRequest(getAvatarId()); + else if (action == "map") + LLAvatarActions::showOnMap(getAvatarId()); + else if (action == "pay") + LLAvatarActions::pay(getAvatarId()); + else if (action == "report_abuse") + LLFloaterReporter::showFromObject(getAvatarId()); + else if (action == "upload_sl") + { + // *TODO: + } + else if (action == "upload_fl") + { + // *TODO: + } + else if (action == "webprofile") + ALAvatarActions::showWebProfile(getAvatarId()); + else + LL_WARNS("LegacyProfiles") << "Unhandled action: " << action << LL_ENDL; +} + +bool LLPanelProfileLegacy::isActionEnabled(const LLSD& userdata) +{ + bool action_enabled = false; + const std::string check = userdata.asString(); + if (check == "can_has_telefono") + action_enabled = (LLAvatarActions::canCall() && getAvatarId() != gAgentID); + else if (check == "can_has_teleport") + action_enabled = (LLAvatarActions::canOfferTeleport(getAvatarId()) && getAvatarId() != gAgentID); + else if (check == "can_has_map") + { + action_enabled = (LLAvatarTracker::instance().isBuddyOnline(getAvatarId()) + && LLAvatarActions::isAgentMappable(getAvatarId())) + || gAgent.isGodlike(); + } + else if (check == "can_has_pay") + action_enabled = (getAvatarId() != gAgentID); + else if (check == "can_share") + action_enabled = (getAvatarId() != gAgentID); + else if (check == "can_drama") + action_enabled = (getAvatarId() != gAgentID); + else if (check == "can_upload_pic") + { + action_enabled = getAvatarId() == gAgentID + && !gAgent.getRegionCapability("UploadAgentProfileImage").empty(); + } + else + LL_INFOS("LegacyProfiles") << "Unhandled check " << check << LL_ENDL; + return action_enabled; +} + +void LLPanelProfileLegacy::onCommitAvatarProperties() +{ + if (getAvatarId() != gAgentID) return; + + + std::string cap = gAgent.getRegionCapability(AGENT_PROFILE_CAP); + if (!cap.empty()) + { + LLSD data; + data["sl_about_text"] = getChild<LLTextEditor>("sl_about")->getText(); + data["fl_about_text"] = getChild<LLTextEditor>("fl_about")->getText(); + data["profile_url"] = getChild<LLLineEditor>("www_edit")->getText(); + data["allow_publish"] = getChild<LLCheckBoxCtrl>("allow_publish")->getValue().asBoolean(); + + LLCoros::instance().launch( + "sendAvatarProfileCoro", + boost::bind(&LLPanelProfileLegacy::sendAvatarProfileCoro, this, cap, data)); + } +} + +void LLPanelProfileLegacy::onCommitNotes(LLUICtrl* ctrl) +{ + std::string cap = gAgent.getRegionCapability(AGENT_PROFILE_CAP); + if (!cap.empty()) + { + LLCoros::instance().launch("sendAvatarProfileCoro", + boost::bind(&LLPanelProfileLegacy::sendAvatarProfileCoro, this, cap, + LLSD().with("notes", ctrl->getValue().asString()))); + } +} + +void LLPanelProfileLegacy::onDoubleClickName() +{ + if (getAvatarId() == gAgentID) + { + LLFloaterReg::showInstance("display_name"); + mNameChangedConnection = LLViewerDisplayName::addNameChangedCallback(boost::bind(&LLPanelProfileLegacy::onNameChanged, this)); + } +} + +void LLPanelProfileLegacy::onNameChanged() +{ + mAvatarNameCacheConnection = LLAvatarNameCache::get(getAvatarId(), + boost::bind(&LLPanelProfileLegacy::onAvatarNameCache, this, _1, _2)); +} + +void LLPanelProfileLegacy::onBackBtnClick() +{ + LLSideTrayPanelContainer* parent = dynamic_cast<LLSideTrayPanelContainer*>(getParent()); + if(parent) + { + parent->openPreviousPanel(); + } +} + +void LLPanelProfileLegacy::onCommitModifyObjectsRights(LLUICtrl* ctrl) +{ + if (ctrl->getValue().asBoolean()) // We want to confirm that the user really wants to grant object rights + { + LLNotificationsUtil::add("GrantModifyRights", + LLSD().with("NAME", LLSLURL("agent", getAvatarId(), "inspect").getSLURLString()), + LLSD(), + boost::bind(&LLPanelProfileLegacy::handleConfirmModifyRightsCallback, this, _1, _2)); + } + else // No confirmation needed on removing rights + { + onCommitRights(); + } +} + +bool LLPanelProfileLegacy::handleConfirmModifyRightsCallback(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (option == 0) + { + onCommitRights(); + return true; + } + // Make sure to flip the checkbox back off + findChild<LLCheckBoxCtrl>("allow_object_perms")->setValue(false); + return false; +} + +void LLPanelProfileLegacy::closeParentFloater() +{ + LLFloater* floater = dynamic_cast<LLFloater*>(getParent()); + if (floater) floater->closeFloater(); +} + +void LLPanelProfileLegacy::onCommitRights() +{ + if (!LLAvatarActions::isFriend(getAvatarId())) return; + S32 flags = 0; + if (getChild<LLCheckBoxCtrl>("allow_show_online")->getValue().asBoolean()) + flags |= LLRelationship::GRANT_ONLINE_STATUS; + if (getChild<LLCheckBoxCtrl>("allow_mapping")->getValue().asBoolean()) + flags |= LLRelationship::GRANT_MAP_LOCATION; + if (getChild<LLCheckBoxCtrl>("allow_object_perms")->getValue().asBoolean()) + flags |= LLRelationship::GRANT_MODIFY_OBJECTS; + + LLAvatarPropertiesProcessor::getInstance()->sendFriendRights(getAvatarId(), flags); +} + +void LLPanelProfileLegacy::openPanel(LLPanel* panel, const LLSD& params) +{ + // Hide currently visible panel. + mChildStack.push(); + + // Add the panel or bring it to front. + if (panel->getParent() != this) + { + addChild(panel); + } + else + { + sendChildToFront(panel); + } + + panel->setVisible(TRUE); + panel->setFocus(TRUE); // prevent losing focus by the floater + panel->onOpen(params); + + LLRect new_rect = getRect(); + panel->reshape(new_rect.getWidth(), new_rect.getHeight()); + new_rect.setLeftTopAndSize(0, new_rect.getHeight(), new_rect.getWidth(), new_rect.getHeight()); + panel->setRect(new_rect); +} + +void LLPanelProfileLegacy::closePanel(LLPanel* panel) +{ + panel->setVisible(FALSE); + + if (panel->getParent() == this) + { + removeChild(panel); + + // Make the underlying panel visible. + mChildStack.pop(); + + // Prevent losing focus by the floater + const child_list_t* child_list = getChildList(); + if (!child_list->empty()) + { + child_list->front()->setFocus(TRUE); + } + else + { + LL_WARNS() << "No underlying panel to focus." << LL_ENDL; + } + } +} + +// LLPanelProfilePicks // +LLPanelProfileLegacy::LLPanelProfilePicks::LLPanelProfilePicks() +: LLPanelProfileLegacyTab() +, mProfilePanel(nullptr) +, mClassifiedsList(nullptr) +, mPicksList(nullptr) +, mPanelPickEdit(nullptr) +, mPanelPickInfo(nullptr) +, mPanelClassifiedInfo(nullptr) +, mPopupMenuHandle() +, mPlusMenuHandle() +{ +} + +LLPanelProfileLegacy::LLPanelProfilePicks::~LLPanelProfilePicks() +{ + auto popup_menu = static_cast<LLMenuGL*>(mPopupMenuHandle.get()); + auto plus_menu = mPlusMenuHandle.get(); + if (popup_menu) + { + popup_menu->die(); + mPopupMenuHandle.markDead(); + } + + if (plus_menu) + { + plus_menu->die(); + mPlusMenuHandle.markDead(); + } +} + +BOOL LLPanelProfileLegacy::LLPanelProfilePicks::postBuild() +{ + mPicksList = getChild<LLFlatListView>("picks_list"); + mClassifiedsList = getChild<LLFlatListView>("classifieds_list"); + childSetAction("add_btn", boost::bind(&LLPanelProfilePicks::onClickPlusBtn, this)); + childSetAction("teleport_btn", boost::bind(&LLPanelProfilePicks::onClickTeleport, this)); + childSetAction("show_on_map_btn", boost::bind(&LLPanelProfilePicks::onClickShowOnMap, this)); + childSetAction("info_btn", boost::bind(&LLPanelProfilePicks::onClickInfo, this)); + + // setup menu + CommitCallbackRegistry::ScopedRegistrar registar; + registar.add("Pick.Info", boost::bind(&LLPanelProfilePicks::onClickInfo, this)); + registar.add("Pick.Edit", boost::bind(&LLPanelProfilePicks::onPanelEdit, this)); + registar.add("Pick.Teleport", boost::bind(&LLPanelProfilePicks::onClickTeleport, this)); + registar.add("Pick.Map", boost::bind(&LLPanelProfilePicks::onClickShowOnMap, this)); + registar.add("Pick.Delete", boost::bind(&LLPanelProfilePicks::onClickDelete, this)); + //EnableCallbackRegistry::ScopedRegistrar enable_registar; + //enable_registar.add("Pick.Enable", boost::bind(&LLPanelProfilePicks::onEnableMenuItem, this, _2)); + + auto popup_menu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>("menu_picks.xml", gMenuHolder, child_registry_t::instance()); + if (popup_menu) + mPopupMenuHandle = popup_menu->getHandle(); + + CommitCallbackRegistry::ScopedRegistrar plus_registar; + plus_registar.add("Picks.Plus.Action", boost::bind(&LLPanelProfilePicks::onPlusMenuItemClicked, this, _2)); + mEnableCallbackRegistrar.add("Picks.Plus.Enable", boost::bind(&LLPanelProfilePicks::isActionEnabled, this, _2)); + auto plus_menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_picks_plus.xml", gMenuHolder, child_registry_t::instance()); + if (plus_menu) + mPlusMenuHandle = plus_menu->getHandle(); + + updateButtons(); + return TRUE; +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::onOpen(const LLSD& key) +{ + const LLUUID id(key.asUUID()); + BOOL self = (gAgent.getID() == id); + + setAvatarId(id); + updateData(); + + getChild<LLView>("add_btn_lp")->setVisible(self); + auto menu = static_cast<LLMenuGL*>(mPopupMenuHandle.get()); + if (menu) + { + menu->setItemVisible("pick_delete", self); + menu->setItemVisible("pick_edit", self); + menu->setItemVisible("pick_separator", self); + } +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::updateData() +{ + mPicksList->clear(); + mClassifiedsList->clear(); + LLAvatarPropertiesProcessor::getInstance()->sendAvatarClassifiedsRequest(getAvatarId()); +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::processProperties(void* data, EAvatarProcessorType type) +{ + if (APT_PICKS == type) + { + mPicksList->clear(); + LLAvatarPicks* avatar_picks = static_cast<LLAvatarPicks*>(data); + if (!avatar_picks || getAvatarId() != avatar_picks->target_id) return; + for (const LLAvatarPicks::pick_data_t& pick: avatar_picks->picks_list) + { + const LLUUID pick_id = pick.first; + const std::string pick_name = pick.second; + + LLPickItem* picture = LLPickItem::create(); + picture->childSetAction("info_chevron", boost::bind(&LLPanelProfilePicks::onClickInfo, this)); + picture->setPickName(pick_name); + picture->setPickId(pick_id); + picture->setCreatorId(getAvatarId()); + + LLAvatarPropertiesProcessor::instance().addObserver(getAvatarId(), picture); + picture->update(); + + LLSD pick_value = LLSD(); + pick_value.insert(PICK_ID, pick_id); + pick_value.insert(PICK_NAME, pick_name); + pick_value.insert(PICK_CREATOR_ID, getAvatarId()); + + mPicksList->addItem(picture, pick_value); + picture->setMouseUpCallback(boost::bind(&LLPanelProfilePicks::updateButtons, this)); + picture->setRightMouseUpCallback(boost::bind(&LLPanelProfilePicks::onRightMouseUpItem, this, _1, _2, _3, _4)); + } + showAccordion("tab_picks", mPicksList->size()); + } + else if (APT_CLASSIFIEDS == type) + { + mClassifiedsList->clear(); + LLAvatarClassifieds* c_info = static_cast<LLAvatarClassifieds*>(data); + if (!c_info || getAvatarId() != c_info->target_id) return; + for (const LLAvatarClassifieds::classified_data& c_data: c_info->classifieds_list) + { + LLClassifiedItem* c_item = new LLClassifiedItem(getAvatarId(), c_data.classified_id); + c_item->childSetAction("info_chevron", boost::bind(&LLPanelProfilePicks::onClickInfo, this)); + c_item->setClassifiedName(c_data.name); + + LLSD pick_value = LLSD(); + pick_value.insert(CLASSIFIED_ID, c_data.classified_id); + pick_value.insert(CLASSIFIED_NAME, c_data.name); + + if (!findClassifiedById(c_data.classified_id)) + { + mClassifiedsList->addItem(c_item, pick_value); + } + c_item->setMouseUpCallback(boost::bind(&LLPanelProfilePicks::updateButtons, this)); + c_item->setRightMouseUpCallback(boost::bind(&LLPanelProfilePicks::onRightMouseUpItem, this, _1, _2, _3, _4)); + } + showAccordion("tab_classifieds", mClassifiedsList->size()); + } + updateButtons(); +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::showAccordion(const std::string& name, bool show) +{ + getChild<LLAccordionCtrlTab>(name)->setVisible(show); + LLAccordionCtrl* acc = getChild<LLAccordionCtrl>("accordion"); + acc->arrange(); +} + +LLClassifiedItem *LLPanelProfileLegacy::LLPanelProfilePicks::findClassifiedById(const LLUUID& classified_id) const +{ + // HACK - find item by classified id. Should be a better way. + std::vector<LLPanel*> items; + mClassifiedsList->getItems(items); + LLClassifiedItem* c_item = nullptr; + for(LLPanel* it: items) + { + LLClassifiedItem *test_item = dynamic_cast<LLClassifiedItem*>(it); + if (test_item && test_item->getClassifiedId() == classified_id) + { + c_item = test_item; + break; + } + } + return c_item; +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::updateButtons() +{ + bool has_selected = (mPicksList->numSelected() > 0|| + mClassifiedsList->numSelected() > 0); + + getChildView("info_btn")->setEnabled(has_selected); + getChildView("teleport_btn")->setEnabled(has_selected); + getChildView("show_on_map_btn")->setEnabled(has_selected); +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::onClickInfo() +{ + if(mClassifiedsList->numSelected() > 0) + openClassifiedInfo(); + else if(mPicksList->numSelected() > 0) + openPickInfo(); +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::onClickPlusBtn() +{ + auto menu = mPlusMenuHandle.get(); + if (menu) + { + LLRect rect(getChildView("add_btn")->getRect()); + menu->setButtonRect(rect, this); + LLMenuGL::showPopup(this, menu, rect.mLeft, rect.mTop); + } +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::onClickTeleport() +{ + LLPickItem* pick_item = static_cast<LLPickItem*>(mPicksList->getSelectedItem()); + LLClassifiedItem* c_item = getSelectedClassifiedItem(); + + LLVector3d pos; + if (pick_item) + { + pos = pick_item->getPosGlobal(); + } + else if (c_item) + { + pos = c_item->getPosGlobal(); + LLPanelClassifiedInfo::sendClickMessage("teleport", false, + c_item->getClassifiedId(), LLUUID::null, pos, LLStringUtil::null); + } + + if (!pos.isExactlyZero()) + { + gAgent.teleportViaLocation(pos); + LLFloaterWorldMap::getInstance()->trackLocation(pos); + } +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::onClickShowOnMap() +{ + LLPickItem* pick_item = static_cast<LLPickItem*>(mPicksList->getSelectedItem()); + LLClassifiedItem* c_item = getSelectedClassifiedItem(); + + LLVector3d pos; + if (pick_item) + { + pos = pick_item->getPosGlobal(); + } + else if (c_item) + { + LLPanelClassifiedInfo::sendClickMessage("map", false, + c_item->getClassifiedId(), LLUUID::null, pos, LLStringUtil::null); + pos = c_item->getPosGlobal(); + } + + LLFloaterWorldMap::getInstance()->trackLocation(pos); + LLFloaterReg::showInstance("world_map", "center"); +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::onClickDelete() +{ + LLSD value = mPicksList->getSelectedValue(); + if (value.isDefined()) + { + LLSD args; + args["PICK"] = value[PICK_NAME]; + LLNotificationsUtil::add("ProfileDeletePick", args, LLSD(), + boost::bind(&LLPanelProfilePicks::callbackDeletePick, this, _1, _2)); + return; + } + value = mClassifiedsList->getSelectedValue(); + if (value.isDefined()) + { + LLSD args; + args["CLASSIFIED"] = value[CLASSIFIED_NAME]; + LLNotificationsUtil::add("ProfileDeleteClassified", args, LLSD(), + boost::bind(&LLPanelProfilePicks::callbackDeleteClassified, this, _1, _2)); + return; + } +} + +bool LLPanelProfileLegacy::LLPanelProfilePicks::callbackDeletePick(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + LLSD pick_value = mPicksList->getSelectedValue(); + + if (0 == option) + { + LLAvatarPropertiesProcessor::instance().sendPickDelete(pick_value[PICK_ID]); + mPicksList->removeItemByValue(pick_value); + } + updateButtons(); + return false; +} + +bool LLPanelProfileLegacy::LLPanelProfilePicks::callbackDeleteClassified(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + LLSD value = mClassifiedsList->getSelectedValue(); + + if (0 == option) + { + LLAvatarPropertiesProcessor::instance().sendClassifiedDelete(value[CLASSIFIED_ID]); + mClassifiedsList->removeItemByValue(value); + } + updateButtons(); + return false; +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::openPickInfo() +{ + LLSD selected_value = mPicksList->getSelectedValue(); + if (selected_value.isUndefined()) return; + + LLPickItem* pick = dynamic_cast<LLPickItem*>(mPicksList->getSelectedItem()); + + if (!mPanelPickInfo) + { + mPanelPickInfo = LLPanelPickInfo::create(); + mPanelPickInfo->setExitCallback(boost::bind(&LLPanelProfilePicks::onPanelPickClose, this, mPanelPickInfo)); + mPanelPickInfo->setEditPickCallback(boost::bind(&LLPanelProfilePicks::onPanelPickEdit, this)); + mPanelPickInfo->setVisible(FALSE); + } + + LLSD params; + params["pick_id"] = pick->getPickId(); + params["avatar_id"] = pick->getCreatorId(); + params["snapshot_id"] = pick->getSnapshotId(); + params["pick_name"] = pick->getPickName(); + params["pick_desc"] = pick->getPickDesc(); + + getProfilePanel()->openPanel(mPanelPickInfo, params); +} + +// virtual +void LLPanelProfileLegacy::LLPanelProfilePicks::onRightMouseUpItem(LLUICtrl* item, S32 x, S32 y, MASK mask) +{ + updateButtons(); + + auto menu = static_cast<LLContextMenu*>(mPopupMenuHandle.get()); + if (menu) + { + menu->buildDrawLabels(); + menu->show(x, y); + LLMenuGL::showPopup(item, menu, x, y); + } +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::openClassifiedInfo() +{ + LLSD selected_value = mClassifiedsList->getSelectedValue(); + if (selected_value.isUndefined()) return; + + LLClassifiedItem* c_item = getSelectedClassifiedItem(); + + if (!mPanelClassifiedInfo) + { + mPanelClassifiedInfo = LLPanelClassifiedInfo::create(); + mPanelClassifiedInfo->setExitCallback(boost::bind(&LLPanelProfilePicks::onPanelClassifiedClose, this, mPanelClassifiedInfo)); + mPanelClassifiedInfo->setEditClassifiedCallback(boost::bind(&LLPanelProfilePicks::onPanelClassifiedEdit, this)); + mPanelClassifiedInfo->setVisible(FALSE); + } + + LLSD params; + params["classified_id"] = c_item->getClassifiedId(); + params["classified_creator_id"] = c_item->getAvatarId(); + params["classified_snapshot_id"] = c_item->getSnapshotId(); + params["classified_name"] = c_item->getClassifiedName(); + params["classified_desc"] = c_item->getDescription(); + params["from_search"] = false; + + getProfilePanel()->openPanel(mPanelClassifiedInfo, params); +} + +LLClassifiedItem* LLPanelProfileLegacy::LLPanelProfilePicks::getSelectedClassifiedItem() const +{ + LLPanel* selected_item = mClassifiedsList->getSelectedItem(); + if (!selected_item) return nullptr; + + return dynamic_cast<LLClassifiedItem*>(selected_item); +} + +LLPickItem* LLPanelProfileLegacy::LLPanelProfilePicks::getSelectedPickItem() const +{ + LLPanel* selected_item = mPicksList->getSelectedItem(); + if (!selected_item) return nullptr; + + return dynamic_cast<LLPickItem*>(selected_item); +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::onPanelClassifiedSave(LLPanelClassifiedEdit* panel) +{ + if (!panel->canClose()) + { + return; + } + + if (panel->isNew()) + { + mEditClassifiedPanels[panel->getClassifiedId()] = panel; + + LLClassifiedItem* c_item = new LLClassifiedItem(getAvatarId(), panel->getClassifiedId()); + c_item->fillIn(panel); + + LLSD c_value; + c_value.insert(CLASSIFIED_ID, c_item->getClassifiedId()); + c_value.insert(CLASSIFIED_NAME, c_item->getClassifiedName()); + mClassifiedsList->addItem(c_item, c_value, ADD_TOP); + + //c_item->setDoubleClickCallback(boost::bind(&LLPanelProfilePicks::onDoubleClickClassifiedItem, this, _1)); + c_item->setRightMouseUpCallback(boost::bind(&LLPanelProfilePicks::onRightMouseUpItem, this, _1, _2, _3, _4)); + c_item->setMouseUpCallback(boost::bind(&LLPanelProfilePicks::updateButtons, this)); + c_item->childSetAction("info_chevron", boost::bind(&LLPanelProfilePicks::onClickInfo, this)); + + // order does matter, showTab will invoke arrange for accordions. + //mClassifiedsAccTab->changeOpenClose(false); + //showTab("tab_classifieds", true); + } + else if (panel->isNewWithErrors()) + { + LLClassifiedItem* c_item = dynamic_cast<LLClassifiedItem*>(mClassifiedsList->getSelectedItem()); + llassert(c_item); + if (c_item) + { + c_item->fillIn(panel); + } + } + else + { + onPanelClassifiedClose(panel); + return; + } + + onPanelPickClose(panel); + updateButtons(); +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::onPanelClassifiedClose(LLPanelClassifiedInfo* panel) +{ + if(panel->getInfoLoaded() && !panel->isDirty()) + { + std::vector<LLSD> values; + mClassifiedsList->getValues(values); + for (auto& value : values) + { + LLUUID c_id = value[CLASSIFIED_ID].asUUID(); + if(panel->getClassifiedId() == c_id) + { + LLClassifiedItem* c_item = dynamic_cast<LLClassifiedItem*>(mClassifiedsList->getItemByValue(value)); + llassert(c_item); + if (c_item) + { + c_item->setClassifiedName(panel->getClassifiedName()); + c_item->setDescription(panel->getDescription()); + c_item->setSnapshotId(panel->getSnapshotId()); + } + } + } + } + + onPanelPickClose(panel); +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::onDoubleClickClassifiedItem(LLUICtrl* item) +{ + LLSD value = mClassifiedsList->getSelectedValue(); + if (value.isUndefined()) return; + + LLSD args; + args["CLASSIFIED"] = value[CLASSIFIED_NAME]; + LLNotificationsUtil::add("TeleportToClassified", args, LLSD(), + boost::bind(&LLPanelProfilePicks::callbackTeleport, this, _1, _2)); +} + +bool LLPanelProfileLegacy::LLPanelProfilePicks::callbackTeleport(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + + if (0 == option) + { + onClickTeleport(); + } + return false; +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::onPanelPickClose(LLPanel* panel) +{ + getProfilePanel()->closePanel(panel); +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::onPanelPickSave(LLPanel* panel) +{ + getProfilePanel()->closePanel(panel); + updateButtons(); +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::onPanelPickEditSave(LLPanelPickEdit* panel) +{ + panel->sendUpdate(); + getProfilePanel()->closePanel(panel); +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::onPanelEdit() +{ + if (getSelectedPickItem()) + { + onPanelPickEdit(); + } + else if (getSelectedClassifiedItem()) + { + onPanelClassifiedEdit(); + } +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::onPanelClassifiedEdit() +{ + LLSD selected_value = mClassifiedsList->getSelectedValue(); + if (selected_value.isUndefined()) return; + + LLClassifiedItem* c_item = dynamic_cast<LLClassifiedItem*>(mClassifiedsList->getSelectedItem()); + llassert(c_item); + if (!c_item) return; + editClassified(c_item->getClassifiedId()); +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::editClassified(const LLUUID& classified_id) +{ + LLClassifiedItem* c_item = findClassifiedById(classified_id); + if (!c_item) + { + LL_WARNS() << "item not found for classified_id " << classified_id << LL_ENDL; + return; + } + + LLSD params; + params["classified_id"] = c_item->getClassifiedId(); + params["classified_creator_id"] = c_item->getAvatarId(); + params["snapshot_id"] = c_item->getSnapshotId(); + params["name"] = c_item->getClassifiedName(); + params["desc"] = c_item->getDescription(); + params["category"] = (S32)c_item->getCategory(); + params["content_type"] = (S32)c_item->getContentType(); + params["auto_renew"] = c_item->getAutoRenew(); + params["price_for_listing"] = c_item->getPriceForListing(); + params["location_text"] = c_item->getLocationText(); + + LLPanelClassifiedEdit* panel = mEditClassifiedPanels[c_item->getClassifiedId()]; + if (!panel) + { + createClassifiedEditPanel(&panel); + mEditClassifiedPanels[c_item->getClassifiedId()] = panel; + } + getProfilePanel()->openPanel(panel, params); + panel->setPosGlobal(c_item->getPosGlobal()); +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::onPanelPickEdit() +{ + LLSD selected_value = mPicksList->getSelectedValue(); + if (selected_value.isUndefined()) return; + + LLPickItem* pick = dynamic_cast<LLPickItem*>(mPicksList->getSelectedItem()); + + LLSD params; + params["pick_id"] = pick->getPickId(); + params["avatar_id"] = pick->getCreatorId(); + params["snapshot_id"] = pick->getSnapshotId(); + params["pick_name"] = pick->getPickName(); + params["pick_desc"] = pick->getPickDesc(); + + mPanelPickEdit = LLPanelPickEdit::create(); + mPanelPickEdit->setExitCallback(boost::bind(&LLPanelProfilePicks::onPanelPickClose, this, mPanelPickEdit)); + mPanelPickEdit->setCancelCallback(boost::bind(&LLPanelProfilePicks::onPanelPickClose, this, mPanelPickEdit)); + mPanelPickEdit->setSaveCallback(boost::bind(&LLPanelProfilePicks::onPanelPickEditSave, this, mPanelPickEdit)); + getProfilePanel()->openPanel(mPanelPickEdit, params); +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::onPlusMenuItemClicked(const LLSD& param) +{ + std::string value = param.asString(); + + if ("new_pick" == value) + { + createNewPick(); + } + else if ("new_classified" == value) + { + createNewClassified(); + } +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::createNewPick() +{ + createPickEditPanel(); + + getProfilePanel()->openPanel(mPanelPickEdit, LLSD()); +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::createNewClassified() +{ + LLPanelClassifiedEdit* panel = nullptr; + createClassifiedEditPanel(&panel); + + getProfilePanel()->openPanel(panel, LLSD()); +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::createPickEditPanel() +{ + mPanelPickEdit = LLPanelPickEdit::create(); + mPanelPickEdit->setExitCallback(boost::bind(&LLPanelProfilePicks::onPanelPickClose, this, mPanelPickEdit)); + mPanelPickEdit->setSaveCallback(boost::bind(&LLPanelProfilePicks::onPanelPickSave, this, mPanelPickEdit)); + mPanelPickEdit->setCancelCallback(boost::bind(&LLPanelProfilePicks::onPanelPickClose, this, mPanelPickEdit)); + mPanelPickEdit->setVisible(FALSE); +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::createClassifiedEditPanel(LLPanelClassifiedEdit** panel) +{ + + if (panel) + { + LLPanelClassifiedEdit* new_panel = LLPanelClassifiedEdit::create(); + new_panel->setExitCallback(boost::bind(&LLPanelProfilePicks::onPanelClassifiedClose, this, new_panel)); + new_panel->setSaveCallback(boost::bind(&LLPanelProfilePicks::onPanelClassifiedSave, this, new_panel)); + new_panel->setCancelCallback(boost::bind(&LLPanelProfilePicks::onPanelClassifiedClose, this, new_panel)); + new_panel->setVisible(FALSE); + *panel = new_panel; + } +} + +bool LLPanelProfileLegacy::LLPanelProfilePicks::isActionEnabled(const LLSD& userdata) const +{ + return (!(userdata.asString() == LLStringExplicit("new_pick") && LLAgentPicksInfo::getInstance()->isPickLimitReached())); +} + +void LLPanelProfileLegacy::LLPanelProfilePicks::setProfilePanel(LLPanelProfileLegacy* profile_panel) +{ + mProfilePanel = profile_panel; +} + +inline LLPanelProfileLegacy* LLPanelProfileLegacy::LLPanelProfilePicks::getProfilePanel() const +{ + llassert_always(mProfilePanel != nullptr); + return mProfilePanel; +} + +// LLPanelProfileGroups // + +LLPanelProfileLegacy::LLPanelProfileGroups::LLPanelProfileGroups() +: LLPanelProfileLegacyTab() +, mGroupsText(nullptr) +, mGroupsList(nullptr) +{ + +} + +BOOL LLPanelProfileLegacy::LLPanelProfileGroups::postBuild() +{ + mGroupsList = getChild<LLFlatListView>("groups_detail_list"); + mGroupsText = getChild<LLTextBase>("groups_panel_text"); + return TRUE; +} + +void LLPanelProfileLegacy::LLPanelProfileGroups::onOpen(const LLSD& key) +{ + const LLUUID id(key.asUUID()); + setAvatarId(id); + + updateData(); +} + +void LLPanelProfileLegacy::LLPanelProfileGroups::updateData() +{ + mGroupsText->setVisible(TRUE); + mGroupsList->clear(); +} + +void LLPanelProfileLegacy::LLPanelProfileGroups::processProperties(void* data, EAvatarProcessorType type) +{ + if (APT_GROUPS != type) return; + const LLAvatarGroups* avatar_groups = static_cast<LLAvatarGroups*>(data); + if(!avatar_groups || getAvatarId() != avatar_groups->avatar_id) return; + + for (auto const& gdata: avatar_groups->group_list) + { + LLProfileGroupItem* item = LLProfileGroupItem::create(); + item->childSetAction("info_chevron", boost::bind(&LLPanelProfileGroups::showGroup, this, gdata.group_id)); + item->init(gdata); + + LLSD item_value = LLSD(); + item_value.insert("group_id", gdata.group_id); + item_value.insert("group_name", gdata.group_name); + item_value.insert("group_icon", gdata.group_insignia_id); + item_value.insert("group_desc", LLStringUtil::null); + + if (!mGroupsList->valueExists(item_value)) + { + mGroupsList->addItem(item, item_value); + } + } +} + +void LLPanelProfileLegacy::LLPanelProfileGroups::showGroup(const LLUUID& id) +{ + LLGroupActions::show(id); +} + +// LLProfileGroupItem // + +LLPanelProfileLegacy::LLProfileGroupItem::LLProfileGroupItem() +: LLPanel() +, mInsignia(LLUUID::null) +, mGroupName(LLStringUtil::null) +, mCharter(LLStringUtil::null) +{ + buildFromFile("panel_profile_legacy_group_list_item.xml"); +} + +LLPanelProfileLegacy::LLProfileGroupItem::~LLProfileGroupItem() +{ + LLGroupMgr::getInstance()->removeObserver(this); +} + +//static +LLPanelProfileLegacy::LLProfileGroupItem* LLPanelProfileLegacy::LLProfileGroupItem::create() +{ + return new LLProfileGroupItem(); +} + +void LLPanelProfileLegacy::LLProfileGroupItem::init(const LLAvatarGroups::LLGroupData& data) +{ + setId(data.group_id); + setGroupName(data.group_name); + setInsignia(data.group_insignia_id); + LLGroupMgr::getInstance()->addObserver(this); + LLGroupMgr::getInstance()->sendGroupPropertiesRequest(data.group_id); + + LLTextureCtrl* picture = getChild<LLTextureCtrl>("picture"); + picture->setImageAssetID(data.group_insignia_id); +} + +BOOL LLPanelProfileLegacy::LLProfileGroupItem::postBuild() +{ + setMouseEnterCallback(boost::bind(&set_child_visible, this, "hovered_icon", true)); + setMouseLeaveCallback(boost::bind(&set_child_visible, this, "hovered_icon", false)); + return TRUE; +} + +void LLPanelProfileLegacy::LLProfileGroupItem::setValue(const LLSD& value) +{ + if (!value.isMap()) return;; + if (!value.has("selected")) return; + getChildView("selected_icon")->setVisible( value["selected"]); +} + +void LLPanelProfileLegacy::LLProfileGroupItem::setId(const LLUUID& id) +{ + mID = id; +} + +void LLPanelProfileLegacy::LLProfileGroupItem::setInsignia(const LLUUID& id) +{ + mInsignia = id; + getChild<LLTextureCtrl>("picture")->setImageAssetID(id); +} + +void LLPanelProfileLegacy::LLProfileGroupItem::setGroupName(const std::string& name) +{ + mGroupName = name; + getChild<LLUICtrl>("name")->setValue(name); +} + +void LLPanelProfileLegacy::LLProfileGroupItem::setCharter(const std::string& charter) +{ + mCharter = charter; + getChild<LLUICtrl>("description")->setValue(charter); +} + +void LLPanelProfileLegacy::LLProfileGroupItem::changed(LLGroupChange gc) +{ + if (gc != GC_PROPERTIES) return; + LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(mID); + if (group_data) + { + setCharter(group_data->mCharter); + } + LLGroupMgr::getInstance()->removeObserver(this); +} + +// ChildStack // + +LLPanelProfileLegacy::ChildStack::ChildStack() +: mParent(nullptr) +{ +} + +LLPanelProfileLegacy::ChildStack::~ChildStack() +{ + while (!mStack.empty()) + { + view_list_t& top = mStack.back(); + for (auto viewp : top) + { + if (viewp) + { + viewp->die(); + } + } + mStack.pop_back(); + } +} + +void LLPanelProfileLegacy::ChildStack::setParent(LLPanel* parent) +{ + llassert_always(parent != nullptr); + mParent = parent; +} + +/// Save current parent's child views and remove them from the child list. +bool LLPanelProfileLegacy::ChildStack::push() +{ + view_list_t vlist = *mParent->getChildList(); + + for (auto viewp : vlist) + { + mParent->removeChild(viewp); + } + + mStack.push_back(vlist); + dump(); + return true; +} + +/// Restore saved children (adding them back to the child list). +bool LLPanelProfileLegacy::ChildStack::pop() +{ + if (mStack.empty()) + { + LL_WARNS() << "Empty stack" << LL_ENDL; + llassert(mStack.size() == 0); + return false; + } + + view_list_t& top = mStack.back(); + for (auto viewp : top) + { + mParent->addChild(viewp); + } + + mStack.pop_back(); + dump(); + return true; +} + +/// Temporarily add all saved children back. +void LLPanelProfileLegacy::ChildStack::preParentReshape() +{ + mSavedStack = mStack; + while(!mStack.empty()) + { + pop(); + } +} + +/// Add the temporarily saved children back. +void LLPanelProfileLegacy::ChildStack::postParentReshape() +{ + mStack = mSavedStack; + mSavedStack = stack_t(); + + for (const auto& vlist : mStack) + { + for (auto viewp : vlist) + { + LL_DEBUGS() << "removing " << viewp->getName() << LL_ENDL; + mParent->removeChild(viewp); + } + } +} + +void LLPanelProfileLegacy::ChildStack::dump() +{ + unsigned lvl = 0; + LL_DEBUGS() << "child stack dump:" << LL_ENDL; + for (const auto& vlist : mStack) + { + ++lvl; + std::ostringstream dbg_line; + dbg_line << "lvl #" << lvl << ":"; + for (const auto& list_it : vlist) + { + dbg_line << " " << list_it->getName(); + } + LL_DEBUGS() << dbg_line.str() << LL_ENDL; + } +} diff --git a/indra/newview/llpanelprofilelegacy.h b/indra/newview/llpanelprofilelegacy.h new file mode 100644 index 0000000000000000000000000000000000000000..9c30519ab5c49af4e66117e632c30fce82f73a80 --- /dev/null +++ b/indra/newview/llpanelprofilelegacy.h @@ -0,0 +1,230 @@ +/* + * @file llpanelprofilelegacy.h + * @brief Legacy protocol avatar profile panel + * + * Copyright (c) 2014-2022, Cinder Roxley <cinder@sdf.org> + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef LL_PANELPROFILELEGACY_H +#define LL_PANELPROFILELEGACY_H + +#include "llgroupmgr.h" +#include "llpanelavatarlegacy.h" + +class LLAvatarName; +class LLClassifiedItem; +class LLFlatListView; +class LLPanel; +class LLPanelPickEdit; +class LLPanelPickInfo; +class LLPanelClassifiedInfo; +class LLPanelClassifiedEdit; +class LLPickItem; +class LLTextBase; +class LLToggleableMenu; + +class LLPanelProfileLegacy final : public LLPanelProfileLegacyTab +{ +public: + LLPanelProfileLegacy(); + BOOL postBuild() override; + void onOpen(const LLSD& key) override; + void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE) override; + void showTab(std::string_view name, bool show) const; + LLPanel* expandTab(const std::string& name) const; + LLPanel* getExpandedTab() const; + +protected: + void openPanel(LLPanel* panel, const LLSD& params); + void closePanel(LLPanel* panel); + +private: + ~LLPanelProfileLegacy() override; + void updateData() override; + void processProperties(void* data, EAvatarProcessorType type) override; + void resetControls() override; + void resetInterestsControlValues(); + void setProgress(bool started); + void sendAvatarProfileCoro(std::string url, LLSD payload); + void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name); + void onCommitAvatarProperties(); + void onCommitInterest(); + void onCommitNotes(LLUICtrl* ctrl); + void onDoubleClickName(); + void onCommitRights(); + void onBackBtnClick(); + void onCommitModifyObjectsRights(LLUICtrl* ctrl); + void onCommitAction(const LLSD& userdata); + void onNameChanged(); + bool isActionEnabled(const LLSD& userdata); + bool handleConfirmModifyRightsCallback(const LLSD& notification, const LLSD& response); + void closeParentFloater(); + + boost::signals2::connection mAvatarNameCacheConnection; + boost::signals2::connection mNameChangedConnection; + + class ChildStack + { + public: + ChildStack(); + ~ChildStack(); + void setParent(LLPanel* parent); + + bool push(); + bool pop(); + void preParentReshape(); + void postParentReshape(); + + private: + void dump(); + + typedef LLView::child_list_t view_list_t; + typedef std::list<view_list_t> stack_t; + + stack_t mStack; + stack_t mSavedStack; + LLPanel* mParent; + }; + ChildStack mChildStack; + +public: + class LLPanelProfilePicks final : public LLPanelProfileLegacyTab + { + friend class LLPanelProfileLegacy; + public: + LLPanelProfilePicks(); + ~LLPanelProfilePicks() override; + BOOL postBuild() override; + + void createNewPick(); + void createNewClassified(); + + protected: + void onOpen(const LLSD& key) override; + + private: + void updateData() override; + void processProperties(void* data, EAvatarProcessorType type) override; + void resetControls() override {}; + void showAccordion(const std::string& name, bool show); + void setProfilePanel(LLPanelProfileLegacy* profile_panel); + LLPanelProfileLegacy* getProfilePanel() const; + void onPanelPickClose(LLPanel* panel); + void onPanelPickSave(LLPanel* panel); + void onPanelPickEditSave(LLPanelPickEdit* panel); + void onPanelEdit(); + void onPanelClassifiedEdit(); + void onPanelPickEdit(); + void onPlusMenuItemClicked(const LLSD& param); + void editClassified(const LLUUID& classified_id); + void updateButtons() override; + void onClickPlusBtn(); + void onClickInfo(); + void onClickTeleport(); + void onClickShowOnMap(); + void onClickDelete(); + void openPickInfo(); + void openClassifiedInfo(); + void onPanelClassifiedSave(LLPanelClassifiedEdit* panel); + void onPanelClassifiedClose(LLPanelClassifiedInfo* panel); + void onDoubleClickClassifiedItem(LLUICtrl* item); + LLClassifiedItem* findClassifiedById(const LLUUID& classified_id) const; + LLClassifiedItem* getSelectedClassifiedItem() const; + LLPickItem* getSelectedPickItem() const; + + void createPickEditPanel(); + void createClassifiedEditPanel(LLPanelClassifiedEdit** panel); + + bool isActionEnabled(const LLSD& userdata) const; + bool callbackDeletePick(const LLSD& notification, const LLSD& response); + bool callbackDeleteClassified(const LLSD& notification, const LLSD& response); + bool callbackTeleport(const LLSD& notification, const LLSD& response); + virtual void onRightMouseUpItem(LLUICtrl* item, S32 x, S32 y, MASK mask); + + LLPanelProfileLegacy* mProfilePanel; + LLFlatListView* mClassifiedsList; + LLFlatListView* mPicksList; + LLPanelPickEdit* mPanelPickEdit; + LLPanelPickInfo* mPanelPickInfo; + LLPanelClassifiedInfo* mPanelClassifiedInfo; + LLHandle<LLView> mPopupMenuHandle; + LLHandle<LLToggleableMenu> mPlusMenuHandle; + + // This map is needed for newly created classifieds. The purpose of panel is to + // sit in this map and listen to LLPanelClassifiedEdit::processProperties callback. + std::map<LLUUID, LLPanelClassifiedEdit*> mEditClassifiedPanels; + }; + + class LLPanelProfileGroups final : public LLPanelProfileLegacyTab + { + friend class LLPanelProfileLegacy; + public: + LLPanelProfileGroups(); + BOOL postBuild() override; + + protected: + void onOpen(const LLSD& key) override; + + private: + void updateData() override; + void processProperties(void* data, EAvatarProcessorType type) override; + void resetControls() override {}; + void showGroup(const LLUUID& id); + + LLTextBase* mGroupsText; + LLFlatListView* mGroupsList; + }; + + class LLProfileGroupItem final : public LLPanel, public LLGroupMgrObserver + { + public: + LLProfileGroupItem(); + ~LLProfileGroupItem() override; + static LLProfileGroupItem* create(); + void init(const LLAvatarGroups::LLGroupData& data); + BOOL postBuild() override; + + void setValue(const LLSD& value) override; + void setId(const LLUUID& id); + void setInsignia(const LLUUID& id); + void setGroupName(const std::string& name); + void setCharter(const std::string& charter); + + protected: + void changed(LLGroupChange gc) override; + + private: + LLUUID mInsignia; + std::string mGroupName; + std::string mCharter; + }; + +private: + LLPanelProfilePicks* mPanelPicks; + LLPanelProfileGroups* mPanelGroups; +}; + +#endif //LL_PANELPROFILELEGACY_H diff --git a/indra/newview/llpanelsearchbase.cpp b/indra/newview/llpanelsearchbase.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ba11c8a009633eb35b3934992f10d3b599ff794c --- /dev/null +++ b/indra/newview/llpanelsearchbase.cpp @@ -0,0 +1,44 @@ +/* + * @file llpanelsearchbase.cpp + * @brief Search panel base class + * + * Copyright (c) 2014, Cinder Roxley <cinder@sdf.org> + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "llviewerprecompiledheaders.h" +#include "llpanelsearchbase.h" +#include "llfloaterdirectory.h" + +LLPanelSearch::LLPanelSearch() +: LLPanel() +, mFloater(nullptr) +{ +} + +void LLPanelSearch::setSearchFloater(LLFloaterDirectory* floater) +{ + mFloater = floater; +} diff --git a/indra/newview/llpanelsearchbase.h b/indra/newview/llpanelsearchbase.h new file mode 100644 index 0000000000000000000000000000000000000000..3e54edce0eecb15c3211c92fe04658a8b60e51e5 --- /dev/null +++ b/indra/newview/llpanelsearchbase.h @@ -0,0 +1,55 @@ +/* + * @file llpanelsearchbase.h + * @brief Search panel base class + * + * Copyright (c) 2014, Cinder Roxley <cinder@sdf.org> + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef LL_PANELSEARCHBASE_H +#define LL_PANELSEARCHBASE_H + +#include "llpanel.h" + +class LLUICtrl; +class LLFloaterDirectory; + +class LLPanelSearch : public LLPanel +{ +public: + LLPanelSearch(); + BOOL postBuild() override { return FALSE; } + void setSearchFloater(LLFloaterDirectory* floater); + +protected: + virtual ~LLPanelSearch() = default;; + LLFloaterDirectory* mFloater; + +private: + virtual void onCommitSearch(LLUICtrl* ctrl) {} + virtual void search() {} +}; + +#endif // LL_PANELSEARCHBASE_H diff --git a/indra/newview/llpanelsearchclassifieds.cpp b/indra/newview/llpanelsearchclassifieds.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4834c63adf11334ab8123ab1cdfeaea90fafb8b5 --- /dev/null +++ b/indra/newview/llpanelsearchclassifieds.cpp @@ -0,0 +1,110 @@ +/* + * @file llpanelsearchclassifieds.cpp + * @brief Groups search panel + * + * Copyright (c) 2014, Cinder Roxley <cinder@sdf.org> + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "llviewerprecompiledheaders.h" +#include "llpanelsearchclassifieds.h" +#include "llfloaterdirectory.h" + +#include "llfloaterreg.h" +#include "llqueryflags.h" +#include "lltrans.h" + +#include "llagent.h" +#include "llclassifiedflags.h" +#include "llclassifiedinfo.h" +#include "llcombobox.h" +#include "llnotificationsutil.h" +#include "llparcel.h" +#include "llsearcheditor.h" +#include "llsearchhistory.h" + +static LLPanelInjector<LLPanelSearchClassifieds> t_panel_search_classifieds("panel_search_classifieds"); + +LLPanelSearchClassifieds::LLPanelSearchClassifieds() + : LLPanelSearch() + , mSearchEditor(nullptr) + , mClassifiedsCategory(nullptr) +{ + mCommitCallbackRegistrar.add("Search.query", boost::bind(&LLPanelSearchClassifieds::onCommitSearch, this, _1)); +} + +BOOL LLPanelSearchClassifieds::postBuild() +{ + mClassifiedsCategory = getChild<LLComboBox>("classifieds_category"); + mClassifiedsCategory->add("All categories", LLSD("any")); + mClassifiedsCategory->addSeparator(); + for (auto iter = LLClassifiedInfo::sCategories.cbegin(); + iter != LLClassifiedInfo::sCategories.cend(); + ++iter) + { + mClassifiedsCategory->add(LLTrans::getString(iter->second)); + } + + mSearchEditor = getChild<LLSearchEditor>("search_bar"); + //mSearchEditor->setKeystrokeCallback(boost::bind(&LLPanelSearchClassifieds::onCommitSearch, this, _1)); + + return TRUE; +} + +void LLPanelSearchClassifieds::onCommitSearch(LLUICtrl* ctrl) +{ + LLSearchEditor* pSearchEditor = dynamic_cast<LLSearchEditor*>(ctrl); + if (pSearchEditor) + { + std::string text = pSearchEditor->getText(); + LLStringUtil::trim(text); + if (text.length() <= MIN_SEARCH_STRING_SIZE) + LLSearchHistory::getInstance()->addEntry(text); + } + search(); +} + +void LLPanelSearchClassifieds::search() +{ + LLDirQuery query; + query.type = SE_CLASSIFIEDS; + query.results_per_page = 100; + query.text = mSearchEditor->getText(); + LLStringUtil::trim(query.text); + + query.category_int = mClassifiedsCategory->getValue().asInteger(); + + static LLUICachedControl<bool> inc_pg("ShowPGClassifieds", true); + static LLUICachedControl<bool> inc_mature("ShowMatureClassifieds", false); + static LLUICachedControl<bool> inc_adult("ShowAdultClassifieds", false); + if (!(inc_pg || inc_mature || inc_adult)) + { + LLNotificationsUtil::add("NoContentToSearch"); + return; + } + query.scope = pack_classified_flags_request(/*auto_renew*/ FALSE, inc_pg, inc_mature, inc_adult); + + mFloater->queryDirectory(query, true); +} diff --git a/indra/newview/llpanelsearchclassifieds.h b/indra/newview/llpanelsearchclassifieds.h new file mode 100644 index 0000000000000000000000000000000000000000..64992be6bb9b2c2592fb914aec7a174c1189bbed --- /dev/null +++ b/indra/newview/llpanelsearchclassifieds.h @@ -0,0 +1,53 @@ +/* + * @file llpanelsearchclassifieds.h + * @brief Groups search panel + * + * Copyright (c) 2014, Cinder Roxley <cinder@sdf.org> + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef LL_PANELSEARCHCLASSIFIEDS_H +#define LL_PANELSEARCHCLASSIFIEDS_H + +#include "llpanelsearchbase.h" + +class LLComboBox; +class LLSearchEditor; + +class LLPanelSearchClassifieds : public LLPanelSearch +{ +public: + LLPanelSearchClassifieds(); + /*virtual*/ BOOL postBuild() override; + +private: + /*virtual*/ void onCommitSearch(LLUICtrl* ctrl) override; + /*virtual*/ void search() override; + + LLSearchEditor* mSearchEditor; + LLComboBox* mClassifiedsCategory; +}; + +#endif // LL_PANELSEARCHCLASSIFIEDS_H diff --git a/indra/newview/llpanelsearchevents.cpp b/indra/newview/llpanelsearchevents.cpp new file mode 100644 index 0000000000000000000000000000000000000000..425d5a157bc15fb22657c6bf65b448adf77be190 --- /dev/null +++ b/indra/newview/llpanelsearchevents.cpp @@ -0,0 +1,135 @@ +/* + * @file llpanelsearchevents.cpp + * @brief Events search panel + * + * Copyright (c) 2014, Cinder Roxley <cinder@sdf.org> + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "llviewerprecompiledheaders.h" +#include "llpanelsearchevents.h" +#include "llfloaterdirectory.h" + +#include "llfloaterreg.h" +#include "llqueryflags.h" + +#include "llagent.h" +#include "llcombobox.h" +#include "llnotificationsutil.h" +#include "llparcel.h" +#include "llsearcheditor.h" +#include "llsearchhistory.h" + +static LLPanelInjector<LLPanelSearchEvents> t_panel_search_events("panel_search_events"); + +LLPanelSearchEvents::LLPanelSearchEvents() +: LLPanelSearch() +, mDate(0) +{ + mCommitCallbackRegistrar.add("Search.query", boost::bind(&LLPanelSearchEvents::onCommitSearch, this, _1)); + mCommitCallbackRegistrar.add("Search.AddDay", boost::bind(&LLPanelSearchEvents::addDay, this)); + mCommitCallbackRegistrar.add("Search.MinusDay", boost::bind(&LLPanelSearchEvents::minusDay, this)); +} + +BOOL LLPanelSearchEvents::postBuild() +{ + mSearchEditor = getChild<LLSearchEditor>("search_bar"); + //mSearchEditor->setKeystrokeCallback(boost::bind(&LLPanelSearchEvents::onCommitSearch, this, _1)); + setDate(0); + + return TRUE; +} + +void LLPanelSearchEvents::onCommitSearch(LLUICtrl* ctrl) +{ + LLSearchEditor* pSearchEditor = dynamic_cast<LLSearchEditor*>(ctrl); + if (pSearchEditor) + { + std::string text = pSearchEditor->getText(); + LLStringUtil::trim(text); + if (text.length() <= MIN_SEARCH_STRING_SIZE) + LLSearchHistory::getInstance()->addEntry(text); + } + search(); +} + +void LLPanelSearchEvents::search() +{ + LLDirQuery query; + query.type = SE_EVENTS; + query.results_per_page = 200; + std::string text = mSearchEditor->getText(); + LLStringUtil::trim(text); + + static LLUICachedControl<bool> inc_pg("ShowPGEvents", true); + static LLUICachedControl<bool> inc_mature("ShowMatureEvents", false); + static LLUICachedControl<bool> inc_adult("ShowAdultEvents", false); + if (!(inc_pg || inc_mature || inc_adult)) + { + LLNotificationsUtil::add("NoContentToSearch"); + return; + } + + query.scope = DFQ_DATE_EVENTS; + if (inc_pg) + query.scope |= DFQ_INC_PG; + if (inc_mature && gAgent.canAccessMature()) + query.scope |= DFQ_INC_MATURE; + if (inc_adult && gAgent.canAccessAdult()) + query.scope |= DFQ_INC_ADULT; + + std::ostringstream string; + string << (childGetValue("events_search_mode").asString() == "current" ? "u" : llformat("%d",mDate)) << "|" + << getChild<LLComboBox>("events_category")->getSelectedValue().asInteger() << "|" + << text; + query.text = string.str(); + + mFloater->queryDirectory(query, true); +} + +void LLPanelSearchEvents::setDate(S32 day) +{ + mDate = day; + + time_t utc = time_corrected(); + utc += day * 24 * 60 * 60; + struct tm * internal_time = utc_to_pacific_time(utc, is_daylight_savings()); + const std::string date = llformat("%d/%d", 1 + internal_time->tm_mon, internal_time->tm_mday); + childSetValue("events_date", date); +} + +void LLPanelSearchEvents::addDay() +{ + setDate(++mDate); + if (childGetValue("events_search_mode").asString() == "date") + search(); +} + +void LLPanelSearchEvents::minusDay() +{ + setDate(--mDate); + if (childGetValue("events_search_mode").asString() == "date") + search(); +} diff --git a/indra/newview/llpanelsearchevents.h b/indra/newview/llpanelsearchevents.h new file mode 100644 index 0000000000000000000000000000000000000000..1f2af30622f89a218e48f4f8dade34e7d512cac8 --- /dev/null +++ b/indra/newview/llpanelsearchevents.h @@ -0,0 +1,56 @@ +/* + * @file llpanelsearchevents.h + * @brief Events search panel + * + * Copyright (c) 2014, Cinder Roxley <cinder@sdf.org> + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef LL_PANELSEARCHEVENTS_H +#define LL_PANELSEARCHEVENTS_H + +#include "llpanelsearchbase.h" + +class LLComboBox; +class LLSearchEditor; + +class LLPanelSearchEvents : public LLPanelSearch +{ +public: + LLPanelSearchEvents(); + /*virtual*/ BOOL postBuild() override; + +private: + /*virtual*/ void onCommitSearch(LLUICtrl* ctrl) override; + /*virtual*/ void search() override; + void setDate(S32 day); + void addDay(); + void minusDay(); + + S32 mDate; + LLSearchEditor* mSearchEditor; +}; + +#endif // LL_PANELSEARCHEVENTS_H diff --git a/indra/newview/llpanelsearchgroups.cpp b/indra/newview/llpanelsearchgroups.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b4fbea45d86941e09238b746430d9f298a4f814b --- /dev/null +++ b/indra/newview/llpanelsearchgroups.cpp @@ -0,0 +1,99 @@ +/* + * @file llpanelsearchgroups.cpp + * @brief Groups search panel + * + * Copyright (c) 2014, Cinder Roxley <cinder@sdf.org> + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "llviewerprecompiledheaders.h" +#include "llpanelsearchgroups.h" +#include "llfloaterdirectory.h" + +#include "llfloaterreg.h" +#include "llqueryflags.h" + +#include "llagent.h" +#include "llnotificationsutil.h" +#include "llsearcheditor.h" +#include "llsearchhistory.h" + +static LLPanelInjector<LLPanelSearchGroups> t_panel_search_groups("panel_search_groups"); + +LLPanelSearchGroups::LLPanelSearchGroups() + : LLPanelSearch() + , mSearchEditor(nullptr) +{ + mCommitCallbackRegistrar.add("Search.query", boost::bind(&LLPanelSearchGroups::onCommitSearch, this, _1)); +} + +BOOL LLPanelSearchGroups::postBuild() +{ + mSearchEditor = getChild<LLSearchEditor>("search_bar"); + //mSearchEditor->setKeystrokeCallback(boost::bind(&LLPanelSearchGroups::onCommitSearch, this, _1)); + + return TRUE; +} + +void LLPanelSearchGroups::onCommitSearch(LLUICtrl* ctrl) +{ + LLSearchEditor* pSearchEditor = dynamic_cast<LLSearchEditor*>(ctrl); + if (pSearchEditor) + { + std::string text = pSearchEditor->getText(); + LLStringUtil::trim(text); + if (text.length() <= MIN_SEARCH_STRING_SIZE) + LLSearchHistory::getInstance()->addEntry(text); + } + search(); +} + +void LLPanelSearchGroups::search() +{ + LLDirQuery query; + query.type = SE_GROUPS; + query.results_per_page = 100; + query.text = mSearchEditor->getText(); + LLStringUtil::trim(query.text); + + static LLUICachedControl<bool> inc_pg("ShowPGGroups", true); + static LLUICachedControl<bool> inc_mature("ShowMatureGroups", false); + static LLUICachedControl<bool> inc_adult("ShowAdultGroups", false); + if (!(inc_pg || inc_mature || inc_adult)) + { + LLNotificationsUtil::add("NoContentToSearch"); + return; + } + + if (inc_pg) + query.scope |= DFQ_INC_PG; + if (inc_mature && gAgent.canAccessMature()) + query.scope |= DFQ_INC_MATURE; + if (inc_adult && gAgent.canAccessAdult()) + query.scope |= DFQ_INC_ADULT; + query.scope |= DFQ_GROUPS; + + mFloater->queryDirectory(query, true); +} diff --git a/indra/newview/llpanelsearchgroups.h b/indra/newview/llpanelsearchgroups.h new file mode 100644 index 0000000000000000000000000000000000000000..f3e80c6b17199e4100d3027c3eaf51fea6d76211 --- /dev/null +++ b/indra/newview/llpanelsearchgroups.h @@ -0,0 +1,51 @@ +/* + * @file llpanelsearchgroups.h + * @brief Groups search panel + * + * Copyright (c) 2014, Cinder Roxley <cinder@sdf.org> + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef LL_PANELSEARCHGROUPS_H +#define LL_PANELSEARCHGROUPS_H + +#include "llpanelsearchbase.h" + +class LLSearchEditor; + +class LLPanelSearchGroups : public LLPanelSearch +{ +public: + LLPanelSearchGroups(); + /*virtual*/ BOOL postBuild() override; + +private: + /*virtual*/ void onCommitSearch(LLUICtrl* ctrl) override; + /*virtual*/ void search() override; + + LLSearchEditor* mSearchEditor; +}; + +#endif // LL_PANELSEARCHGROUPS_H diff --git a/indra/newview/llpanelsearchlandsales.cpp b/indra/newview/llpanelsearchlandsales.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a2def0f36a6c16948d3eded04e9183eec5fb2fd7 --- /dev/null +++ b/indra/newview/llpanelsearchlandsales.cpp @@ -0,0 +1,118 @@ +/* + * @file llpanelsearchlandsales.cpp + * @brief Groups search panel + * + * Copyright (c) 2014, Cinder Roxley <cinder@sdf.org> + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "llviewerprecompiledheaders.h" +#include "llpanelsearchlandsales.h" +#include "llfloaterdirectory.h" + +#include "llfloaterreg.h" +#include "llqueryflags.h" + +#include "llagent.h" +#include "llnotificationsutil.h" +#include "llsearcheditor.h" +#include "llsearchhistory.h" +#include "llviewercontrol.h" + +static LLPanelInjector<LLPanelSearchLandSales> t_panel_search_land_sales("panel_search_landsales"); + +LLPanelSearchLandSales::LLPanelSearchLandSales() +: LLPanelSearch() +{ + mCommitCallbackRegistrar.add("Search.query", boost::bind(&LLPanelSearchLandSales::onCommitSearch, this, _1)); +} + +BOOL LLPanelSearchLandSales::postBuild() +{ + return TRUE; +} + +void LLPanelSearchLandSales::onCommitSearch(LLUICtrl* ctrl) +{ + search(); +} + +void LLPanelSearchLandSales::search() +{ + LLDirQuery query; + query.type = SE_LANDSALES; + query.results_per_page = 100; + + static LLUICachedControl<bool> inc_pg("ShowPGLand", true); + static LLUICachedControl<bool> inc_mature("ShowMatureLand", false); + static LLUICachedControl<bool> inc_adult("ShowAdultLand", false); + static LLUICachedControl<bool> limit_price("FindLandPrice", true); + static LLUICachedControl<bool> limit_area("FindLandArea", true); + if (!(inc_pg || inc_mature || inc_adult)) + { + LLNotificationsUtil::add("NoContentToSearch"); + return; + } + + const std::string& type = gSavedSettings.getString("FindLandType"); + if (type == "All") + query.category_int = ST_ALL; + else if (type == "Auction") + query.category_int = ST_AUCTION; + else if (type == "Mainland") + query.category_int = ST_MAINLAND; + else if (type == "Estate") + query.category_int = ST_ESTATE; + + if (gAgent.wantsPGOnly()) + query.scope |= DFQ_PG_SIMS_ONLY; + if (inc_pg) + query.scope |= DFQ_INC_PG; + if (inc_mature && gAgent.canAccessMature()) + query.scope |= DFQ_INC_MATURE; + if (inc_adult && gAgent.canAccessAdult()) + query.scope |= DFQ_INC_ADULT; + + const std::string& sort = gSavedSettings.getString("FindLandSort"); + if (sort == "Name") + query.scope |= DFQ_NAME_SORT; + else if (sort == "Price") + query.scope |= DFQ_PRICE_SORT; + else if (sort == "PPM") + query.scope |= DFQ_PER_METER_SORT; + else if (sort == "Area") + query.scope |= DFQ_AREA_SORT; + + if (gSavedSettings.getBOOL("FindLandSortAscending")) + query.scope |= DFQ_SORT_ASC; + if (limit_price) + query.scope |= DFQ_LIMIT_BY_PRICE; + if (limit_area) + query.scope |= DFQ_LIMIT_BY_AREA; + query.price = childGetValue("edit_price").asInteger(); + query.area = childGetValue("edit_area").asInteger(); + + mFloater->queryDirectory(query, true); +} diff --git a/indra/newview/llpanelsearchlandsales.h b/indra/newview/llpanelsearchlandsales.h new file mode 100644 index 0000000000000000000000000000000000000000..f0f27407719333b67bef0b86b3aa344a2a81eb78 --- /dev/null +++ b/indra/newview/llpanelsearchlandsales.h @@ -0,0 +1,47 @@ +/* + * @file llpanelsearchlandsales.h + * @brief Land sale search panel + * + * Copyright (c) 2014, Cinder Roxley <cinder@sdf.org> + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef LL_PANELSEARCHLANDSALES_H +#define LL_PANELSEARCHLANDSALES_H + +#include "llpanelsearchbase.h" + +class LLPanelSearchLandSales : public LLPanelSearch +{ +public: + LLPanelSearchLandSales(); + /*virtual*/ BOOL postBuild() override; + +private: + /*virtual*/ void search() override; + /*virtual*/ void onCommitSearch(LLUICtrl* ctrl) override; +}; + +#endif // LL_PANELSEARCHLANDSALES_H diff --git a/indra/newview/llpanelsearchpeople.cpp b/indra/newview/llpanelsearchpeople.cpp new file mode 100644 index 0000000000000000000000000000000000000000..69b2c3fc5c4adee9059322d7f1918538187cef5b --- /dev/null +++ b/indra/newview/llpanelsearchpeople.cpp @@ -0,0 +1,87 @@ +/* + * @file llpanelsearchpeople.cpp + * @brief People search panel + * + * Copyright (c) 2014, Cinder Roxley <cinder@sdf.org> + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "llviewerprecompiledheaders.h" +#include "llpanelsearchpeople.h" +#include "llfloaterdirectory.h" + +#include "llfloaterreg.h" + +#include "llagent.h" +#include "llsearcheditor.h" +#include "llsearchhistory.h" + +static LLPanelInjector<LLPanelSearchPeople> t_panel_search_people("panel_search_people"); + +LLPanelSearchPeople::LLPanelSearchPeople() +: LLPanelSearch() +{ + mCommitCallbackRegistrar.add("Search.query", boost::bind(&LLPanelSearchPeople::onCommitSearch, this, _1)); +} + +BOOL LLPanelSearchPeople::postBuild() +{ + mSearchEditor = getChild<LLSearchEditor>("search_bar"); + //mSearchEditor->setKeystrokeCallback(boost::bind(&LLPanelSearchPeople::onCommitSearch, this, _1)); + + return TRUE; +} + +void LLPanelSearchPeople::onCommitSearch(LLUICtrl* ctrl) +{ + LLSearchEditor* pSearchEditor = dynamic_cast<LLSearchEditor*>(ctrl); + if (pSearchEditor) + { + std::string text = pSearchEditor->getText(); + LLStringUtil::trim(text); + if (text.length() <= MIN_SEARCH_STRING_SIZE) + LLSearchHistory::getInstance()->addEntry(text); + } + search(); +} + +bool isNotAlphaNum(char c) +{ + return !std::isalnum(c); +} + +void LLPanelSearchPeople::search() +{ + LLDirQuery query; + query.type = SE_PEOPLE; + query.results_per_page = 100; + query.text = mSearchEditor->getText(); + std::replace_if(query.text.begin(), query.text.end(), isNotAlphaNum, ' '); + LLStringUtil::trim(query.text); + + mFloater->queryDirectory(query, true); + if (query.text.length() < MIN_SEARCH_STRING_SIZE) + mFloater->setResultsComment(getString("SeachFilteredOnShortWordsEmpty")); +} diff --git a/indra/newview/llpanelsearchpeople.h b/indra/newview/llpanelsearchpeople.h new file mode 100644 index 0000000000000000000000000000000000000000..e55645f7f626ae438f99d23aeecc6a6231ba3ba2 --- /dev/null +++ b/indra/newview/llpanelsearchpeople.h @@ -0,0 +1,51 @@ +/* + * @file llpanelsearchpeople.h + * @brief People search panel + * + * Copyright (c) 2014, Cinder Roxley <cinder@sdf.org> + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef LL_PANELSEARCHPEOPLE_H +#define LL_PANELSEARCHPEOPLE_H + +#include "llpanelsearchbase.h" + +class LLSearchEditor; + +class LLPanelSearchPeople : public LLPanelSearch +{ +public: + LLPanelSearchPeople(); + /*virtual*/ BOOL postBuild() override; + +private: + /*virtual*/ void onCommitSearch(LLUICtrl* ctrl) override; + /*virtual*/ void search() override; + + LLSearchEditor* mSearchEditor; +}; + +#endif // LL_PANELSEARCHPEOPLE_H diff --git a/indra/newview/llpanelsearchplaces.cpp b/indra/newview/llpanelsearchplaces.cpp new file mode 100644 index 0000000000000000000000000000000000000000..97b758dea427417cf47cc10236ba509af28f1630 --- /dev/null +++ b/indra/newview/llpanelsearchplaces.cpp @@ -0,0 +1,113 @@ +/* + * @file llpanelsearchplaces.cpp + * @brief Groups search panel + * + * Copyright (c) 2014, Cinder Roxley <cinder@sdf.org> + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "llviewerprecompiledheaders.h" +#include "llpanelsearchplaces.h" +#include "llfloaterdirectory.h" + +#include "llfloaterreg.h" +#include "llqueryflags.h" + +#include "llagent.h" +#include "llcombobox.h" +#include "llnotificationsutil.h" +#include "llparcel.h" +#include "llsearcheditor.h" +#include "llsearchhistory.h" + +static LLPanelInjector<LLPanelSearchPlaces> t_panel_search_places("panel_search_places"); + +LLPanelSearchPlaces::LLPanelSearchPlaces() +: LLPanelSearch() +{ + mCommitCallbackRegistrar.add("Search.query", boost::bind(&LLPanelSearchPlaces::onCommitSearch, this, _1)); +} + +BOOL LLPanelSearchPlaces::postBuild() +{ + mPlacesCategory = getChild<LLComboBox>("places_category"); + mPlacesCategory->add("All categories", LLSD("any")); + mPlacesCategory->addSeparator(); + for (size_t category = LLParcel::C_LINDEN; category < LLParcel::C_COUNT; ++category) + { + LLParcel::ECategory eCategory = static_cast<LLParcel::ECategory>(category); + mPlacesCategory->add(LLParcel::getCategoryUIString(eCategory), LLParcel::getCategoryString(eCategory)); + } + + mSearchEditor = getChild<LLSearchEditor>("search_bar"); + //mSearchEditor->setKeystrokeCallback(boost::bind(&LLPanelSearchPlaces::onCommitSearch, this, _1)); + + return TRUE; +} + +void LLPanelSearchPlaces::onCommitSearch(LLUICtrl* ctrl) +{ + LLSearchEditor* pSearchEditor = dynamic_cast<LLSearchEditor*>(ctrl); + if (pSearchEditor) + { + std::string text = pSearchEditor->getText(); + LLStringUtil::trim(text); + if (text.length() <= MIN_SEARCH_STRING_SIZE) + LLSearchHistory::getInstance()->addEntry(text); + } + search(); +} + +void LLPanelSearchPlaces::search() +{ + LLDirQuery query; + query.type = SE_PLACES; + query.results_per_page = 100; + query.text = mSearchEditor->getText(); + LLStringUtil::trim(query.text); + + const std::string& category_string = mPlacesCategory->getSelectedValue(); + query.category_char = category_string == "any" ? LLParcel::C_ANY : LLParcel::getCategoryFromString(category_string); + + static LLUICachedControl<bool> inc_pg("ShowPGSims", true); + static LLUICachedControl<bool> inc_mature("ShowMatureSims", false); + static LLUICachedControl<bool> inc_adult("ShowAdultSims", false); + if (!(inc_pg || inc_mature || inc_adult)) + { + LLNotificationsUtil::add("NoContentToSearch"); + return; + } + if (gAgent.wantsPGOnly()) + query.scope |= DFQ_PG_SIMS_ONLY; + if (inc_pg) + query.scope |= DFQ_INC_PG; + if (inc_mature && gAgent.canAccessMature()) + query.scope |= DFQ_INC_MATURE; + if (inc_adult && gAgent.canAccessAdult()) + query.scope |= DFQ_INC_ADULT; + query.scope |= DFQ_DWELL_SORT; + + mFloater->queryDirectory(query, true); +} diff --git a/indra/newview/llpanelsearchplaces.h b/indra/newview/llpanelsearchplaces.h new file mode 100644 index 0000000000000000000000000000000000000000..42e69dd117da94b2a3a9c876d4073563d2dca396 --- /dev/null +++ b/indra/newview/llpanelsearchplaces.h @@ -0,0 +1,53 @@ +/* + * @file llpanelsearchplaces.h + * @brief Groups search panel + * + * Copyright (c) 2014, Cinder Roxley <cinder@sdf.org> + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef LL_PANELSEARCHPLACES_H +#define LL_PANELSEARCHPLACES_H + +#include "llpanelsearchbase.h" + +class LLComboBox; +class LLSearchEditor; + +class LLPanelSearchPlaces : public LLPanelSearch +{ +public: + LLPanelSearchPlaces(); + /*virtual*/ BOOL postBuild() override; + +private: + /*virtual*/ void onCommitSearch(LLUICtrl* ctrl) override; + /*virtual*/ void search() override; + + LLSearchEditor* mSearchEditor; + LLComboBox* mPlacesCategory; +}; + +#endif // LL_PANELSEARCHPLACES_H diff --git a/indra/newview/llpanelsearchweb.cpp b/indra/newview/llpanelsearchweb.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dfd9fedc3efe90eb78d412ddfe9e9463383df564 --- /dev/null +++ b/indra/newview/llpanelsearchweb.cpp @@ -0,0 +1,281 @@ +/* + * @file llpanelsearchweb.cpp + * @brief Web search panel + * + * Copyright (c) 2014, Cinder Roxley <cinder@sdf.org> + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "llviewerprecompiledheaders.h" +#include "llpanelsearchweb.h" + +#include "llagent.h" +#include "llfloaterdirectory.h" +#include "lllogininstance.h" +#include "llmediactrl.h" +#include "llprogressbar.h" +#include "lltextbox.h" +#include "llviewercontrol.h" +#include "llviewernetwork.h" +#include "llviewerregion.h" +#include "llweb.h" + +static LLPanelInjector<LLPanelSearchWeb> t_panel_search_web("panel_search_web"); + +LLPanelSearchWeb::LLPanelSearchWeb() +: LLPanel() +, mStatusBarText(nullptr) +, mStatusBarProgress(nullptr) +, mBtnBack(nullptr) +, mBtnForward(nullptr) +, mBtnReload(nullptr) +, mBtnStop(nullptr) +, mWebBrowser(nullptr) +{ + mSearchType.insert("standard"); + mSearchType.insert("land"); + mSearchType.insert("classified"); + + mCollectionType.insert("events"); + mCollectionType.insert("destinations"); + mCollectionType.insert("places"); + mCollectionType.insert("groups"); + mCollectionType.insert("people"); + + mCategoryPaths = LLSD::emptyMap(); + mCategoryPaths["all"] = "search"; + mCategoryPaths["people"] = "search/people"; + mCategoryPaths["places"] = "search/places"; + mCategoryPaths["events"] = "search/events"; + mCategoryPaths["groups"] = "search/groups"; + mCategoryPaths["wiki"] = "search/wiki"; + mCategoryPaths["destinations"] = "destinations"; + + mCommitCallbackRegistrar.add("WebContent.Back", boost::bind(&LLPanelSearchWeb::onClickBack, this)); + mCommitCallbackRegistrar.add("WebContent.Forward", boost::bind(&LLPanelSearchWeb::onClickForward, this)); + mCommitCallbackRegistrar.add("WebContent.Reload", boost::bind(&LLPanelSearchWeb::onClickReload, this)); + mCommitCallbackRegistrar.add("WebContent.Stop", boost::bind(&LLPanelSearchWeb::onClickStop, this)); +} + +BOOL LLPanelSearchWeb::postBuild() +{ + mWebBrowser = getChild<LLMediaCtrl>("webbrowser"); + if (mWebBrowser) mWebBrowser->addObserver(this); + + mWebBrowser = getChild<LLMediaCtrl>("webbrowser"); + mStatusBarProgress = getChild<LLProgressBar>("statusbarprogress"); + mStatusBarText = getChild<LLTextBox>("statusbartext"); + + mBtnBack = getChild<LLButton>("back"); + mBtnForward = getChild<LLButton>("forward"); + mBtnReload = getChild<LLButton>("reload"); + mBtnStop = getChild<LLButton>("stop"); + + return TRUE; +} + +void LLPanelSearchWeb::loadUrl(const SearchQuery& p) +{ + if (!mWebBrowser || !p.validateBlock()) return; + + mWebBrowser->setTrustedContent(true); + + // work out the subdir to use based on the requested category + LLSD subs; + if (LLGridManager::instance().isInSecondlife()) + { + if (mSearchType.find(p.category.getValue()) != mSearchType.end()) + { + subs["TYPE"] = p.category.getValue(); + } + else + { + subs["TYPE"] = "standard"; + } + + subs["COLLECTION"] = ""; + if (subs["TYPE"] == "standard") + { + if (mCollectionType.find(p.collection) != mCollectionType.end()) + { + subs["COLLECTION"] = "&collection_chosen=" + std::string(p.collection); + } + else + { + std::string collection_args(""); + for (std::set<std::string>::iterator it = mCollectionType.begin(); it != mCollectionType.end(); ++it) + { + collection_args += "&collection_chosen=" + std::string(*it); + } + subs["COLLECTION"] = collection_args; + } + } + } + else + { + subs["CATEGORY"] = (mCategoryPaths.has(p.category.getValue()) + ? mCategoryPaths[p.category.getValue()].asString() + : mCategoryPaths["all"].asString()); + } + + // add the search query string + subs["QUERY"] = LLURI::escape(p.query()); + + // add the user's preferred maturity (can be changed via prefs) + std::string maturity; + if (LLGridManager::instance().isInSecondlife()) + { + if (gAgent.prefersAdult()) + { + maturity = "gma"; // PG,Mature,Adult + } + else if (gAgent.prefersMature()) + { + maturity = "gm"; // PG,Mature + } + else + { + maturity = "g"; // PG + } + } + else + { + if (gAgent.prefersAdult()) + { + maturity = "42"; // PG,Mature,Adult + } + else if (gAgent.prefersMature()) + { + maturity = "21"; // PG,Mature + } + else + { + maturity = "13"; // PG + } + } + subs["MATURITY"] = maturity; + + // add the user's god status + subs["GODLIKE"] = gAgent.isGodlike() ? "1" : "0"; + + // Get the search URL and expand all of the substitutions + // (also adds things like [LANGUAGE], [VERSION], [OS], etc.) + LLViewerRegion* regionp = gAgent.getRegion(); + std::string url = regionp != nullptr ? regionp->getSearchServerURL() + : gSavedSettings.getString(LLGridManager::getInstance()->isInOpenSim() ? "OpenSimSearchURL" : "SearchURL"); + url = LLWeb::expandURLSubstitutions(url, subs); + // Finally, load the URL in the webpanel + mWebBrowser->navigateTo(url, "text/html"); +} + +// virtual +void LLPanelSearchWeb::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) +{ + if(event == MEDIA_EVENT_LOCATION_CHANGED) + { + const std::string url = self->getLocation(); + + if ( url.length() ) + mStatusBarText->setText( url ); + } + else if(event == MEDIA_EVENT_NAVIGATE_BEGIN) + { + // flags are sent with this event + mBtnBack->setEnabled( self->getHistoryBackAvailable() ); + mBtnForward->setEnabled( self->getHistoryForwardAvailable() ); + + // toggle visibility of these buttons based on browser state + mBtnReload->setVisible( false ); + mBtnStop->setVisible( true ); + + // turn "on" progress bar now we're about to start loading + mStatusBarProgress->setVisible( true ); + } + else if(event == MEDIA_EVENT_NAVIGATE_COMPLETE) + { + // flags are sent with this event + mBtnBack->setEnabled( self->getHistoryBackAvailable() ); + mBtnForward->setEnabled( self->getHistoryForwardAvailable() ); + + // toggle visibility of these buttons based on browser state + mBtnReload->setVisible( true ); + mBtnStop->setVisible( false ); + + // turn "off" progress bar now we're loaded + mStatusBarProgress->setVisible( false ); + + // we populate the status bar with URLs as they change so clear it now we're done + const LLStringExplicit end_str(""); + mStatusBarText->setText( end_str ); + } + else if(event == MEDIA_EVENT_STATUS_TEXT_CHANGED ) + { + const std::string text = self->getStatusText(); + if ( text.length() ) + mStatusBarText->setText( text ); + } + else if(event == MEDIA_EVENT_PROGRESS_UPDATED ) + { + int percent = (int)self->getProgressPercent(); + mStatusBarProgress->setValue( percent ); + } + else if(event == MEDIA_EVENT_LINK_HOVERED ) + { + const std::string link = self->getHoverLink(); + mStatusBarText->setText( link ); + } +} + +void LLPanelSearchWeb::onClickForward() const +{ + mWebBrowser->navigateForward(); +} + +void LLPanelSearchWeb::onClickBack() const +{ + mWebBrowser->navigateBack(); +} + +void LLPanelSearchWeb::onClickReload() const +{ + + if( mWebBrowser->getMediaPlugin() ) + { + bool ignore_cache = true; + mWebBrowser->getMediaPlugin()->browse_reload( ignore_cache ); + } +} + +void LLPanelSearchWeb::onClickStop() +{ + if( mWebBrowser->getMediaPlugin() ) + mWebBrowser->getMediaPlugin()->browse_stop(); + + // still should happen when we catch the navigate complete event + // but sometimes (don't know why) that event isn't sent from Qt + // and we ghetto a point where the stop button stays active. + mBtnReload->setVisible( true ); + mBtnStop->setVisible( false ); +} diff --git a/indra/newview/llpanelsearchweb.h b/indra/newview/llpanelsearchweb.h new file mode 100644 index 0000000000000000000000000000000000000000..4877db8bf962381301582b9606d8740674e26647 --- /dev/null +++ b/indra/newview/llpanelsearchweb.h @@ -0,0 +1,70 @@ +/* + * @file llpanelsearchweb.h + * @brief Web search panel + * + * Copyright (c) 2014, Cinder Roxley <cinder@sdf.org> + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef LL_PANELSEARCHWEB_H +#define LL_PANELSEARCHWEB_H + +#include "llpanel.h" +#include "llviewermediaobserver.h" + +class LLMediaCtrl; +class LLProgressBar; +class LLTextBox; +struct SearchQuery; + +class LLPanelSearchWeb : public LLPanel, public LLViewerMediaObserver +{ +public: + LLPanelSearchWeb(); + BOOL postBuild() override; + void loadUrl(const SearchQuery& query); + +private: + void onClickBack() const; + void onClickForward() const; + void onClickReload() const; + void onClickStop(); + /*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) override; + + LLTextBox* mStatusBarText; + LLProgressBar* mStatusBarProgress; + LLButton* mBtnBack; + LLButton* mBtnForward; + LLButton* mBtnReload; + LLButton* mBtnStop; + + std::set<std::string> mSearchType; + std::set<std::string> mCollectionType; + LLSD mCategoryPaths; + //U8 mSearchGodLevel; + LLMediaCtrl* mWebBrowser; +}; + +#endif // LL_PANELSEARCHWEB_H diff --git a/indra/newview/llpickitem.cpp b/indra/newview/llpickitem.cpp new file mode 100644 index 0000000000000000000000000000000000000000..55e59d125511a65783fd9d62e3c044931af89a26 --- /dev/null +++ b/indra/newview/llpickitem.cpp @@ -0,0 +1,155 @@ +/** +* @file llpickitem.cpp +* @brief Widget +* +* $LicenseInfo:firstyear=2009&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2010, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library 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 +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ + +#include "llviewerprecompiledheaders.h" +#include "llpickitem.h" + +#include "lltexturectrl.h" + +LLPickItem::LLPickItem() + : LLPanel() + , mPickID(LLUUID::null) + , mCreatorID(LLUUID::null) + , mParcelID(LLUUID::null) + , mSnapshotID(LLUUID::null) + , mNeedData(true) +{ + buildFromFile("panel_pick_list_item.xml"); +} + +LLPickItem::~LLPickItem() +{ + if (mCreatorID.notNull()) + { + LLAvatarPropertiesProcessor::instance().removeObserver(mCreatorID, this); + } + +} + +LLPickItem* LLPickItem::create() +{ + return new LLPickItem(); +} + +void LLPickItem::init(LLPickData* pick_data) +{ + setPickDesc(pick_data->desc); + setSnapshotId(pick_data->snapshot_id); + mPosGlobal = pick_data->pos_global; + mSimName = pick_data->sim_name; + mPickDescription = pick_data->desc; + mUserName = pick_data->user_name; + mOriginalName = pick_data->original_name; + + LLTextureCtrl* picture = getChild<LLTextureCtrl>("picture"); + picture->setImageAssetID(pick_data->snapshot_id); +} + +void LLPickItem::setPickName(const std::string& name) +{ + mPickName = name; + getChild<LLUICtrl>("picture_name")->setValue(name); + +} + +const std::string& LLPickItem::getPickName() const +{ + return mPickName; +} + +const LLUUID& LLPickItem::getCreatorId() const +{ + return mCreatorID; +} + +const LLUUID& LLPickItem::getSnapshotId() const +{ + return mSnapshotID; +} + +void LLPickItem::setPickDesc(const std::string& descr) +{ + getChild<LLUICtrl>("picture_descr")->setValue(descr); +} + +void LLPickItem::setPickId(const LLUUID& id) +{ + mPickID = id; +} + +const LLUUID& LLPickItem::getPickId() const +{ + return mPickID; +} + +const LLVector3d& LLPickItem::getPosGlobal() const +{ + return mPosGlobal; +} + +const std::string LLPickItem::getDescription() const +{ + return getChild<LLUICtrl>("picture_descr")->getValue().asString(); +} + +void LLPickItem::update() +{ + setNeedData(true); + LLAvatarPropertiesProcessor::instance().sendPickInfoRequest(mCreatorID, mPickID); +} + +void LLPickItem::processProperties(void *data, EAvatarProcessorType type) +{ + if (APT_PICK_INFO != type) + { + return; + } + + LLPickData* pick_data = static_cast<LLPickData *>(data); + if (!pick_data || mPickID != pick_data->pick_id) + { + return; + } + + init(pick_data); + setNeedData(false); + LLAvatarPropertiesProcessor::instance().removeObserver(mCreatorID, this); +} + +BOOL LLPickItem::postBuild() +{ + setMouseEnterCallback(std::bind(&set_child_visible, this, "hovered_icon", true)); + setMouseLeaveCallback(std::bind(&set_child_visible, this, "hovered_icon", false)); + return TRUE; +} + +void LLPickItem::setValue(const LLSD& value) +{ + if (!value.isMap()) return;; + if (!value.has("selected")) return; + getChildView("selected_icon")->setVisible(value["selected"]); +} + diff --git a/indra/newview/llpickitem.h b/indra/newview/llpickitem.h new file mode 100644 index 0000000000000000000000000000000000000000..0ddcbd4bf86490c4e1d176e3ddae09e92c768a62 --- /dev/null +++ b/indra/newview/llpickitem.h @@ -0,0 +1,85 @@ +/** +* @file llpickitem.h +* @brief Widget +* +* $LicenseInfo:firstyear=2009&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2010, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library 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 +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ + +#ifndef LL_PICKITEM_H +#define LL_PICKITEM_H + +#include "llavatarpropertiesprocessor.h" +#include "llpanel.h" + +struct LLPickData; + +static const std::string PICK_ID("pick_id"); +static const std::string PICK_CREATOR_ID("pick_creator_id"); +static const std::string PICK_NAME("pick_name"); + +class LLPickItem final : public LLPanel, public LLAvatarPropertiesObserver +{ +public: + LLPickItem(); + ~LLPickItem(); + BOOL postBuild() override; + + static LLPickItem* create(); + void init(LLPickData* pick_data); + void setPickName(const std::string& name); + void setPickDesc(const std::string& descr); + void setPickId(const LLUUID& id); + void setCreatorId(const LLUUID& id) { mCreatorID = id; }; + void setSnapshotId(const LLUUID& id) { mSnapshotID = id; }; + void setNeedData(bool need) { mNeedData = need; }; + const LLUUID& getPickId() const; + const std::string& getPickName() const; + const LLUUID& getCreatorId() const; + const LLUUID& getSnapshotId() const; + const LLVector3d& getPosGlobal() const; + const std::string getDescription() const; + const std::string& getSimName() const { return mSimName; } + const std::string& getUserName() const { return mUserName; } + const std::string& getOriginalName() const { return mOriginalName; } + const std::string& getPickDesc() const { return mPickDescription; } + void processProperties(void* data, EAvatarProcessorType type) override; + void update(); + + /** setting on/off background icon to indicate selected state */ + void setValue(const LLSD& value) override; + +protected: + LLUUID mPickID; + LLUUID mCreatorID; + LLUUID mParcelID; + LLUUID mSnapshotID; + LLVector3d mPosGlobal; + bool mNeedData; + + std::string mPickName; + std::string mUserName; + std::string mOriginalName; + std::string mPickDescription; + std::string mSimName; +}; + +#endif // LL_PICKITEM_H diff --git a/indra/newview/llprofileimagepicker.cpp b/indra/newview/llprofileimagepicker.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9930b6eea7818ef444207f8cac038dd888bcf372 --- /dev/null +++ b/indra/newview/llprofileimagepicker.cpp @@ -0,0 +1,233 @@ +/** +* @file llprofileimagepicker.cpp +* @brief Specialized profile image filepicker +* +* $LicenseInfo:firstyear=2022&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2022, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library 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 +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ + +#include "llviewerprecompiledheaders.h" +#include "llprofileimagepicker.h" + +#include "llavatariconctrl.h" +#include "llagent.h" +#include "llloadingindicator.h" +#include "llnotificationsutil.h" +#include "llpanel.h" +#include "llviewertexturelist.h" + +static constexpr std::string_view PROFILE_IMAGE_UPLOAD_CAP("UploadAgentProfileImage"); + +static void post_profile_image_coro(std::string cap_url, EProfileImageType type, std::string path_to_image, + LLProfileImagePicker::ugly_picker_cb_t cb); +static LLUUID post_profile_image(std::string cap_url, const LLSD& first_data, std::string path_to_image); +static void setImageUploading(LLPanel* panel, bool loading); + + +LLProfileImagePicker::LLProfileImagePicker(EProfileImageType type, LLHandle<LLPanel>* handle, ugly_picker_cb_t const& cb) +: LLFilePickerThread(LLFilePicker::FFLOAD_IMAGE) +, mHandle(handle) +, mType(type), + mCallback(cb) +{ } + +LLProfileImagePicker::~LLProfileImagePicker() +{ + delete mHandle; +} + +void LLProfileImagePicker::notify(const std::vector<std::string>& filenames) +{ + if (mHandle->isDead()) + { + return; + } + if (filenames.empty()) + { + return; + } + const std::string& file_path = filenames.at(0); + if (file_path.empty()) + { + return; + } + + // generate a temp texture file for coroutine + std::string const& temp_file = gDirUtilp->getTempFilename(); + U32 codec = LLImageBase::getCodecFromExtension(gDirUtilp->getExtension(file_path)); + const S32 MAX_DIM = 256; + if (!LLViewerTextureList::createUploadFile(file_path, temp_file, codec, MAX_DIM)) + { + LLSD notif_args; + notif_args["REASON"] = LLImage::getLastThreadError().c_str(); + LLNotificationsUtil::add("CannotUploadTexture", notif_args); + LL_WARNS("AvatarProperties") << "Failed to upload profile image of type " << (S32)PROFILE_IMAGE_SL << ", failed to open image" << LL_ENDL; + return; + } + + std::string cap_url = gAgent.getRegionCapability(PROFILE_IMAGE_UPLOAD_CAP); + if (cap_url.empty()) + { + LLSD args; + args["CAPABILITY"] = std::string(PROFILE_IMAGE_UPLOAD_CAP); + LLNotificationsUtil::add("RegionCapabilityRequestError", args); + LL_WARNS("AvatarProperties") << "Failed to upload profile image of type " << (S32)PROFILE_IMAGE_SL << ", no cap found" << LL_ENDL; + return; + } + + setImageUploading(mHandle->get(), true); + LLCoros::instance().launch("postAgentUserImageCoro", + [cap_url, this, temp_file] + { + return post_profile_image_coro(cap_url, mType, temp_file, mCallback); + }); +} + +LLUUID post_profile_image(std::string cap_url, const LLSD& first_data, std::string path_to_image) +{ + LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter( + new LLCoreHttpUtil::HttpCoroutineAdapter("post_profile_image_coro", httpPolicy)); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + LLCore::HttpHeaders::ptr_t httpHeaders; + + LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); + httpOpts->setFollowRedirects(true); + + LLSD result = httpAdapter->postAndSuspend(httpRequest, cap_url, first_data, httpOpts, httpHeaders); + + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + if (!status) + { + // todo: notification? + LL_WARNS("AvatarProperties") << "Failed to get uploader cap " << status.toString() << LL_ENDL; + return LLUUID::null; + } + if (!result.has("uploader")) + { + // todo: notification? + LL_WARNS("AvatarProperties") << "Failed to get uploader cap, response contains no data." << LL_ENDL; + return LLUUID::null; + } + std::string uploader_cap = result["uploader"].asString(); + if (uploader_cap.empty()) + { + LL_WARNS("AvatarProperties") << "Failed to get uploader cap, cap invalid." << LL_ENDL; + return LLUUID::null; + } + + // Upload the image + + LLCore::HttpRequest::ptr_t uploaderhttpRequest(new LLCore::HttpRequest); + LLCore::HttpHeaders::ptr_t uploaderhttpHeaders(new LLCore::HttpHeaders); + LLCore::HttpOptions::ptr_t uploaderhttpOpts(new LLCore::HttpOptions); + S64 length; + + { + llifstream instream(path_to_image.c_str(), std::iostream::binary | std::iostream::ate); + if (!instream.is_open()) + { + LL_WARNS("AvatarProperties") << "Failed to open file " << path_to_image << LL_ENDL; + return LLUUID::null; + } + length = instream.tellg(); + } + + uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, "application/jp2"); // optional + uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_LENGTH, llformat("%d", length)); // required! + uploaderhttpOpts->setFollowRedirects(true); + + result = httpAdapter->postFileAndSuspend(uploaderhttpRequest, uploader_cap, path_to_image, uploaderhttpOpts, uploaderhttpHeaders); + + httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + LL_WARNS("AvatarProperties") << result << LL_ENDL; + + if (!status) + { + LL_WARNS("AvatarProperties") << "Failed to upload image " << status.toString() << LL_ENDL; + return LLUUID::null; + } + + if (result["state"].asString() != "complete") + { + if (result.has("message")) + { + LL_WARNS("AvatarProperties") << "Failed to upload image, state " << result["state"] << " message: " << result["message"] << LL_ENDL; + } + else + { + LL_WARNS("AvatarProperties") << "Failed to upload image " << result << LL_ENDL; + } + return LLUUID::null; + } + + return result["new_asset"].asUUID(); +} + +void post_profile_image_coro(std::string cap_url, EProfileImageType type, std::string path_to_image, + LLProfileImagePicker::ugly_picker_cb_t cb) +{ + LLSD data; + switch (type) + { + case PROFILE_IMAGE_SL: + data["profile-image-asset"] = "sl_image_id"; + break; + case PROFILE_IMAGE_FL: + data["profile-image-asset"] = "fl_image_id"; + break; + } + + LLUUID result = post_profile_image(cap_url, data, path_to_image); + + cb(result); + + if (type == PROFILE_IMAGE_SL && result.notNull()) + { + LLAvatarIconIDCache::getInstance()->add(gAgentID, result); + // Should trigger callbacks in icon controls + LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesRequest(gAgentID); + } + + // Cleanup + LLFile::remove(path_to_image); +} + +void setImageUploading(LLPanel* panel, bool loading) +{ + LLLoadingIndicator* indicator = panel->findChild<LLLoadingIndicator>("image_upload_indicator"); + if (indicator) + { + indicator->setVisible(loading); + if (loading) + { + indicator->start(); + } + else + { + indicator->stop(); + } + } +} diff --git a/indra/newview/llprofileimagepicker.h b/indra/newview/llprofileimagepicker.h new file mode 100644 index 0000000000000000000000000000000000000000..a67d0859b08efd4fbc6fb85f39f876ad215c28e3 --- /dev/null +++ b/indra/newview/llprofileimagepicker.h @@ -0,0 +1,53 @@ +/** +* @file llprofileimagepicker.h +* @brief Specialized profile image filepicker +* +* $LicenseInfo:firstyear=2022&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2022, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library 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 +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ + +#ifndef LL_PROFILEIMAGEPICKER_H +#define LL_PROFILEIMAGEPICKER_H + +#include "llviewermenufile.h" + +enum EProfileImageType +{ + PROFILE_IMAGE_SL, + PROFILE_IMAGE_FL, +}; + +class LLProfileImagePicker final : public LLFilePickerThread +{ +public: + typedef std::function<void(LLUUID const&)> ugly_picker_cb_t; + + LLProfileImagePicker(EProfileImageType type, LLHandle<LLPanel>* handle, ugly_picker_cb_t const& cb); + ~LLProfileImagePicker() override; + void notify(const std::vector<std::string>& filenames) override; + +private: + LLHandle<LLPanel>* mHandle; + EProfileImageType mType; + ugly_picker_cb_t mCallback; +}; + +#endif // LL_PROFILEIMAGEPICKER_H diff --git a/indra/newview/llsearchcombobox.h b/indra/newview/llsearchcombobox.h index 891237e92eae314003f39c58d728f32d2b12887f..ff9c74a6a84736edd863b78a9a26ec18ee80a74d 100644 --- a/indra/newview/llsearchcombobox.h +++ b/indra/newview/llsearchcombobox.h @@ -61,11 +61,6 @@ class LLSearchComboBox : public LLComboBox ~LLSearchComboBox(); - /** - * Sets focus to text box - */ - void focusTextEntry(); - protected: LLSearchComboBox(const Params&p); @@ -98,6 +93,11 @@ class LLSearchComboBox : public LLComboBox */ void onSelectionCommit(); + /** + * Sets focus to text box + */ + void focusTextEntry(); + LLButton* mSearchButton; }; diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index f4fe10b4b128f43abcdc04942ee2d4e120c9aa74..5650732f72f5d44bedfbcadfdb109ef10b548db4 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -183,6 +183,7 @@ #include "pipeline.h" #include "llappviewer.h" #include "llfasttimerview.h" +#include "llfloaterdirectory.h" #include "llfloatermap.h" #include "llweb.h" #include "llvoiceclient.h" @@ -220,7 +221,6 @@ #if LL_WINDOWS #include "lldxhardware.h" #endif -#include "fsfloatersearch.h" // // exported globals @@ -2914,12 +2914,13 @@ void register_viewer_callbacks(LLMessageSystem* msg) msg->setHandlerFuncFast(_PREHASH_GroupNoticesListReply, LLPanelGroupNotices::processGroupNoticesListReply); // directory search - msg->setHandlerFuncFast(_PREHASH_DirPeopleReply, FSPanelSearchPeople::processSearchReply); - msg->setHandlerFuncFast(_PREHASH_DirPlacesReply, FSPanelSearchPlaces::processSearchReply); - msg->setHandlerFuncFast(_PREHASH_DirGroupsReply, FSPanelSearchGroups::processSearchReply); - msg->setHandlerFuncFast(_PREHASH_DirEventsReply, FSPanelSearchEvents::processSearchReply); - msg->setHandlerFuncFast(_PREHASH_DirLandReply, FSPanelSearchLand::processSearchReply); - msg->setHandlerFuncFast(_PREHASH_DirClassifiedReply, FSPanelSearchClassifieds::processSearchReply); + msg->setHandlerFunc("DirPeopleReply", LLFloaterDirectory::processSearchPeopleReply); + msg->setHandlerFunc("DirGroupsReply", LLFloaterDirectory::processSearchGroupsReply); + msg->setHandlerFunc("DirPlacesReply", LLFloaterDirectory::processSearchPlacesReply); + msg->setHandlerFunc("DirEventsReply", LLFloaterDirectory::processSearchEventsReply); + msg->setHandlerFunc("DirLandReply", LLFloaterDirectory::processSearchLandReply); + msg->setHandlerFunc("DirClassifiedReply", LLFloaterDirectory::processSearchClassifiedsReply); + msg->setHandlerFuncFast(_PREHASH_AvatarPickerReply, LLFloaterAvatarPicker::processAvatarPickerReply); diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index a3d70aa4ffe01495ecf1c8a30b82e3cf2c9b46c0..721717e68adfa21af6ad1b6e37a82736c14b5d64 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -83,6 +83,7 @@ #include "llfloatercreatelandmark.h" #include "llfloaterdeleteprefpreset.h" #include "llfloaterdestinations.h" +#include "llfloaterdirectory.h" #include "llfloaterdisplayname.h" #include "llfloatereditextdaycycle.h" #include "llfloateremojipicker.h" @@ -144,7 +145,9 @@ #include "llfloaterpreferenceviewadvanced.h" #include "llfloaterpreviewtrash.h" #include "llfloaterprofile.h" +#include "llfloaterprofilelegacy.h" #include "llfloaterprogressview.h" +#include "llfloaterpublishclassified.h" #include "llfloaterregiondebugconsole.h" #include "llfloaterregioninfo.h" #include "llfloaterregionrestarting.h" @@ -192,7 +195,6 @@ #include "llmoveview.h" #include "llfloaterimnearbychat.h" #include "llpanelblockedlist.h" -#include "llpanelprofileclassifieds.h" #include "llpanelemojicomplete.h" #include "llpreviewanim.h" #include "llpreviewgesture.h" @@ -202,12 +204,12 @@ #include "llpreviewtexture.h" #include "llscriptfloater.h" #include "llsyswellwindow.h" -#include "fsfloatersearch.h" #include "bdfloaterposer.h" #include "bdfloaterposecreator.h" // *NOTE: Please add files in alphabetical order to keep merges easy. // [RLVa:KB] - Checked: 2010-03-11 +#include "llfloaterwebprofile.h" #include "rlvfloaters.h" // [/RLVa:KB] // handle secondlife:///app/openfloater/{NAME} URLs @@ -499,7 +501,7 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("preview_sound", "floater_preview_sound.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewSound>, "preview"); LLFloaterReg::add("preview_texture", "floater_preview_texture.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewTexture>, "preview"); LLFloaterReg::add("preview_trash", "floater_preview_trash.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreviewTrash>); - LLFloaterReg::add("publish_classified", "floater_publish_classified.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPublishClassifiedFloater>); + LLFloaterReg::add("publish_classified", "floater_publish_classified.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPublishClassified>); LLFloaterReg::add("save_pref_preset", "floater_save_pref_preset.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSavePrefPreset>); LLFloaterReg::add("save_camera_preset", "floater_save_camera_preset.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSaveCameraPreset>); LLFloaterReg::add("script_colors", "floater_script_ed_prefs.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterScriptEdPrefs>); @@ -543,7 +545,6 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("stop_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterNotRunQueue>); LLFloaterReg::add("snapshot", "floater_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSnapshot>); LLFloaterReg::add("simple_snapshot", "floater_simple_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSimpleSnapshot>); - LLFloaterReg::add("search", "floater_fs_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSFloaterSearch>); //LLFloaterReg::add("search", "floater_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSearch>); // [SL:KB] - Patch: UI-FloaterSearchReplace | Checked: 2010-10-26 (Catznip-2.3) LLFloaterReg::add("search_replace", "floater_search_replace.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSearchReplace>); @@ -576,6 +577,7 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("delete_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterDeleteQueue>); LLFloaterReg::add("generic_text", "floater_generic_text.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterGenericText>); LLFloaterReg::add("group_profile", "floater_group_profile.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterGroupProfile>); + LLFloaterReg::add("legacy_profile", "floater_profile_legacy.xml", (LLFloaterBuildFunc) &LLFloaterReg::build<LLFloaterProfileLegacy>); LLFloaterReg::add("lightbox", "floater_lightbox_settings.xml", (LLFloaterBuildFunc) &LLFloaterReg::build<ALFloaterLightBox>); LLFloaterReg::add("message_builder", "floater_message_builder.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMessageBuilder>); LLFloaterReg::add("message_log", "floater_message_log.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMessageLog>); @@ -588,8 +590,11 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("progress_view", "floater_progress_view.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterProgressView>); LLFloaterReg::add("quick_settings", "floater_quick_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloater>); LLFloaterReg::add("region_tracker", "floater_region_tracker.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<ALFloaterRegionTracker>); + LLFloaterReg::add("search", "floater_directory.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterDirectory>); LLFloaterReg::add("settings_color", "floater_settings_color.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<ALFloaterSettingsColor>); LLFloaterReg::add("sound_explorer", "floater_explore_sounds.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<ALFloaterExploreSounds>); + LLFloaterReg::add("webprofile", "floater_web_profile.xml", (LLFloaterBuildFunc)&LLFloaterWebProfile::create); + LLFloaterReg::registerControlVariables(); // Make sure visibility and rect controls get preserved when saving } diff --git a/indra/newview/llviewerinput.cpp b/indra/newview/llviewerinput.cpp index 74e8c10132132aa4c721b5270955f0ac26996735..9639fb38ed4598cd48052f743ff499743e739427 100644 --- a/indra/newview/llviewerinput.cpp +++ b/indra/newview/llviewerinput.cpp @@ -49,7 +49,6 @@ #include "llfloatercamera.h" #include "llinitparam.h" #include "llselectmgr.h" -#include "fsfloatersearch.h" #include "llfloaterwebcontent.h" // [RLVa:KB] - Checked: 2021-07-29 (RLVa-1.4.4a) #include "rlvactions.h" @@ -709,7 +708,7 @@ bool start_chat( EKeystate s ) bool start_gesture( EKeystate s ) { LLFloater* focused_floater = gFloaterView->getFocusedFloater(); - if (focused_floater && (dynamic_cast<LLFloaterWebContent*>(focused_floater) || dynamic_cast<FSFloaterSearch*>(focused_floater))) + if (focused_floater && dynamic_cast<LLFloaterWebContent*>(focused_floater)) { return true; } diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index adceae2d1913841e39afa1129da1f0e39a3e7bce..91c3df6f3145db7296683810e1989c28c0a3e73d 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -3895,7 +3895,7 @@ void handle_avatar_eject(const LLSD& avatar_id) bool my_profile_visible() { - LLFloater* floaterp = LLAvatarActions::getProfileFloater(gAgentID); + LLFloater* floaterp = LLAvatarActions::findProfileFloater(gAgentID); return floaterp && floaterp->isInVisibleChain(); } @@ -6770,7 +6770,7 @@ class LLAvatarToggleMyProfile : public view_listener_t { bool handleEvent(const LLSD& userdata) { - LLFloater* instance = LLAvatarActions::getProfileFloater(gAgent.getID()); + LLFloater* instance = LLAvatarActions::findProfileFloater(gAgent.getID()); if (LLFloater::isMinimized(instance)) { instance->setMinimized(FALSE); @@ -6796,7 +6796,7 @@ class LLAvatarTogglePicks : public view_listener_t { bool handleEvent(const LLSD& userdata) { - LLFloater * instance = LLAvatarActions::getProfileFloater(gAgent.getID()); + LLFloater * instance = LLAvatarActions::findProfileFloater(gAgent.getID()); if (LLFloater::isMinimized(instance) || (instance && !instance->hasFocus() && !instance->getIsChrome())) { instance->setMinimized(FALSE); diff --git a/indra/newview/skins/alchemy/colors.xml b/indra/newview/skins/alchemy/colors.xml index ac16fb8113a959ea9f16f43749ef701ca0596209..fd72faa3f24bde3049adec7f70f701ab56dce829 100644 --- a/indra/newview/skins/alchemy/colors.xml +++ b/indra/newview/skins/alchemy/colors.xml @@ -1139,6 +1139,9 @@ <color name="StatBarMeanBarColor" reference="Red_80" /> + <color + name="ProfileOnlineIndicatorColor" + reference="Green" /> <color name="FriendChatColor" reference="White" /> diff --git a/indra/newview/skins/alchemy/skin_settings.xml b/indra/newview/skins/alchemy/skin_settings.xml index 03ac8fb0eca54393fbbea459181a0de586e45e0e..1f56287b50d1684ef534e7fe8e54126780c124c1 100644 --- a/indra/newview/skins/alchemy/skin_settings.xml +++ b/indra/newview/skins/alchemy/skin_settings.xml @@ -1,7 +1,20 @@ -<?xml version="1.0" encoding="utf-8"?> +<?xml version="1.0" encoding="utf-8"?> <llsd xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="llsd.xsd"> <map> + <key>LegacyProfile</key> + <map> + <key>Comment</key> + <string>Use Legacy Profiles rather than standard</string> + <key>Persist</key> + <integer>0</integer> + <key>HideFromEditor</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <boolean>0</boolean> + </map> <key>LegacyNotificationWell</key> <map> <key>Comment</key> diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index db03b869897bc89ec65ff828e3d71b3ca9d17f1e..c93686df3d9614c09e2718798c353f3f0ac2856a 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -1039,7 +1039,11 @@ name="PanelNotificationListItem" value="0.3 0.3 0.3 .3" /> - <!-- profiles --> + <color + name="ProfileOnlineIndicatorColor" + reference="Green" /> + + <!-- dildo profiles --> <color name="StatusUserOnline" reference="White" /> diff --git a/indra/newview/skins/default/skin_settings.xml b/indra/newview/skins/default/skin_settings.xml index 03ac8fb0eca54393fbbea459181a0de586e45e0e..1f56287b50d1684ef534e7fe8e54126780c124c1 100644 --- a/indra/newview/skins/default/skin_settings.xml +++ b/indra/newview/skins/default/skin_settings.xml @@ -1,7 +1,20 @@ -<?xml version="1.0" encoding="utf-8"?> +<?xml version="1.0" encoding="utf-8"?> <llsd xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="llsd.xsd"> <map> + <key>LegacyProfile</key> + <map> + <key>Comment</key> + <string>Use Legacy Profiles rather than standard</string> + <key>Persist</key> + <integer>0</integer> + <key>HideFromEditor</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <boolean>0</boolean> + </map> <key>LegacyNotificationWell</key> <map> <key>Comment</key> diff --git a/indra/newview/skins/default/textures/icon_legacy_event.tga b/indra/newview/skins/default/textures/icon_legacy_event.tga deleted file mode 100644 index 7805dbce60eb7c58bb99826157ed222813c27419..0000000000000000000000000000000000000000 Binary files a/indra/newview/skins/default/textures/icon_legacy_event.tga and /dev/null differ diff --git a/indra/newview/skins/default/textures/icon_legacy_event_adult.tga b/indra/newview/skins/default/textures/icon_legacy_event_adult.tga deleted file mode 100644 index c344fb1e78887afe2b20ac4830ffb057772416cd..0000000000000000000000000000000000000000 Binary files a/indra/newview/skins/default/textures/icon_legacy_event_adult.tga and /dev/null differ diff --git a/indra/newview/skins/default/textures/icon_legacy_event_mature.tga b/indra/newview/skins/default/textures/icon_legacy_event_mature.tga deleted file mode 100644 index 61c879bc923c7d1ee625a3995012a3ddecca363d..0000000000000000000000000000000000000000 Binary files a/indra/newview/skins/default/textures/icon_legacy_event_mature.tga and /dev/null differ diff --git a/indra/newview/skins/default/textures/icons/ProgressLarge_1.png b/indra/newview/skins/default/textures/icons/ProgressLarge_1.png deleted file mode 100644 index ff277fc431d6d5f8b13baeb47b478f321e00ab79..0000000000000000000000000000000000000000 Binary files a/indra/newview/skins/default/textures/icons/ProgressLarge_1.png and /dev/null differ diff --git a/indra/newview/skins/default/textures/icons/ProgressLarge_10.png b/indra/newview/skins/default/textures/icons/ProgressLarge_10.png deleted file mode 100644 index 1c94e21d89261478fdde301cf1309dcc3bbe3065..0000000000000000000000000000000000000000 Binary files a/indra/newview/skins/default/textures/icons/ProgressLarge_10.png and /dev/null differ diff --git a/indra/newview/skins/default/textures/icons/ProgressLarge_11.png b/indra/newview/skins/default/textures/icons/ProgressLarge_11.png deleted file mode 100644 index 89bea9b474bbbdb36be8e1024c00d226a22070f9..0000000000000000000000000000000000000000 Binary files a/indra/newview/skins/default/textures/icons/ProgressLarge_11.png and /dev/null differ diff --git a/indra/newview/skins/default/textures/icons/ProgressLarge_12.png b/indra/newview/skins/default/textures/icons/ProgressLarge_12.png deleted file mode 100644 index da38475ba4dc61dfe4bff14a3175837f07d13fa3..0000000000000000000000000000000000000000 Binary files a/indra/newview/skins/default/textures/icons/ProgressLarge_12.png and /dev/null differ diff --git a/indra/newview/skins/default/textures/icons/ProgressLarge_2.png b/indra/newview/skins/default/textures/icons/ProgressLarge_2.png deleted file mode 100644 index c024275ebef799760ab3ae4f1ef9377df066632e..0000000000000000000000000000000000000000 Binary files a/indra/newview/skins/default/textures/icons/ProgressLarge_2.png and /dev/null differ diff --git a/indra/newview/skins/default/textures/icons/ProgressLarge_3.png b/indra/newview/skins/default/textures/icons/ProgressLarge_3.png deleted file mode 100644 index 87b931e72e753c263fc0f07bddd2448ce123d8be..0000000000000000000000000000000000000000 Binary files a/indra/newview/skins/default/textures/icons/ProgressLarge_3.png and /dev/null differ diff --git a/indra/newview/skins/default/textures/icons/ProgressLarge_4.png b/indra/newview/skins/default/textures/icons/ProgressLarge_4.png deleted file mode 100644 index 6dbef74361edb829542a2809fb2a976f03008cac..0000000000000000000000000000000000000000 Binary files a/indra/newview/skins/default/textures/icons/ProgressLarge_4.png and /dev/null differ diff --git a/indra/newview/skins/default/textures/icons/ProgressLarge_5.png b/indra/newview/skins/default/textures/icons/ProgressLarge_5.png deleted file mode 100644 index daccf9b375ffc677a02aa434bd0fc2514c1d614b..0000000000000000000000000000000000000000 Binary files a/indra/newview/skins/default/textures/icons/ProgressLarge_5.png and /dev/null differ diff --git a/indra/newview/skins/default/textures/icons/ProgressLarge_6.png b/indra/newview/skins/default/textures/icons/ProgressLarge_6.png deleted file mode 100644 index cafddcb88dc21d60592ca403c46fd7fc0289adb9..0000000000000000000000000000000000000000 Binary files a/indra/newview/skins/default/textures/icons/ProgressLarge_6.png and /dev/null differ diff --git a/indra/newview/skins/default/textures/icons/ProgressLarge_7.png b/indra/newview/skins/default/textures/icons/ProgressLarge_7.png deleted file mode 100644 index 8acf6472d4d70d6fb758fa7321584c8bf7c6e621..0000000000000000000000000000000000000000 Binary files a/indra/newview/skins/default/textures/icons/ProgressLarge_7.png and /dev/null differ diff --git a/indra/newview/skins/default/textures/icons/ProgressLarge_8.png b/indra/newview/skins/default/textures/icons/ProgressLarge_8.png deleted file mode 100644 index df0e825cef1f053d42c4fffca7efdd0e9f4969cf..0000000000000000000000000000000000000000 Binary files a/indra/newview/skins/default/textures/icons/ProgressLarge_8.png and /dev/null differ diff --git a/indra/newview/skins/default/textures/icons/ProgressLarge_9.png b/indra/newview/skins/default/textures/icons/ProgressLarge_9.png deleted file mode 100644 index 293a7b8f5c6c7983e2e46c56cb661a1994ad3249..0000000000000000000000000000000000000000 Binary files a/indra/newview/skins/default/textures/icons/ProgressLarge_9.png and /dev/null differ diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index c80f637a649b24200d318154bcd5306ddb58f0f2..ec2de431bae5834b7499e475bc302fe50cc515b4 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -990,21 +990,4 @@ with the same filename but different name <texture name="Right_Trigger" file_name="xbox/right_trigger.png" preload="false" /> <texture name="Triggers" file_name="xbox/triggers.png" preload="false" /> <texture name="None" file_name="xbox/none.png" preload="false" /> - - <texture name="Icon_Legacy_Event_PG" file_name="icon_legacy_event.tga" preload="false" /> - <texture name="Icon_Legacy_Event_Mature" file_name="icon_legacy_event_mature.tga" preload="false" /> - <texture name="Icon_Legacy_Event_Adult" file_name="icon_legacy_event_adult.tga" preload="false" /> - - <texture name="ProgressLarge_1" file_name="icons/ProgressLarge_1.png" preload="true" /> - <texture name="ProgressLarge_2" file_name="icons/ProgressLarge_2.png" preload="true" /> - <texture name="ProgressLarge_3" file_name="icons/ProgressLarge_3.png" preload="true" /> - <texture name="ProgressLarge_4" file_name="icons/ProgressLarge_4.png" preload="true" /> - <texture name="ProgressLarge_5" file_name="icons/ProgressLarge_5.png" preload="true" /> - <texture name="ProgressLarge_6" file_name="icons/ProgressLarge_6.png" preload="true" /> - <texture name="ProgressLarge_7" file_name="icons/ProgressLarge_7.png" preload="true" /> - <texture name="ProgressLarge_8" file_name="icons/ProgressLarge_8.png" preload="true" /> - <texture name="ProgressLarge_9" file_name="icons/ProgressLarge_9.png" preload="true" /> - <texture name="ProgressLarge_10" file_name="icons/ProgressLarge_10.png" preload="true" /> - <texture name="ProgressLarge_11" file_name="icons/ProgressLarge_11.png" preload="true" /> - <texture name="ProgressLarge_12" file_name="icons/ProgressLarge_12.png" preload="true" /> </textures> diff --git a/indra/newview/skins/default/xui/en/floater_directory.xml b/indra/newview/skins/default/xui/en/floater_directory.xml new file mode 100644 index 0000000000000000000000000000000000000000..3c6d0cb7fee1f17c5a061f15982c43aef2957e74 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_directory.xml @@ -0,0 +1,291 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + legacy_header_height="18" + single_instance="true" + can_resize="true" + height="590" + min_height="135" + min_width="430" + layout="topleft" + name="search" + save_rect="true" + title="SEARCH" + width="602"> + <floater.string + name="not_found"> +'[TEXT]' not found + </floater.string> + <floater.string + name="no_results"> +No results + </floater.string> + <floater.string + name="result_spillover"> +Over [TOTAL] results Showing [VISIBLE_BEGIN]/[VISIBLE_END] + </floater.string> + <floater.string + name="result_count"> +[TOTAL] results. + </floater.string> + <floater.string + name="searching"> +Searching... + </floater.string> + <floater.string + name="all_categories"> +All Categories + </floater.string> + <floater.string + name="search_banned"> +Some terms in your search query were excluded due to content restrictions as clarified in the Community Standards. + </floater.string> + <floater.string + name="search_short"> +Your search terms were too short so no search was performed. + </floater.string> + <floater.string + name="search_disabled"> +Directory search is disabled in this region. + </floater.string> + <floater.string + name="search_no_date_offset"> +Your search terms were missing the date offset. + </floater.string> + <floater.string + name="search_no_catgory"> +Your search terms were missing a category. + </floater.string> + <floater.string + name="search_no_query"> +Your search terms were missing a query string. + </floater.string> + <tab_container + border="true" + follows="all" + top="16" + left="0" + height="573" + width="602" + name="search_tabs" + tab_min_width="70" + tab_position="top"> + <panel + border="false" + label="People" + filename="panel_search_people.xml" + class="panel_search_people" + name="panel_search_people" + follows="left|top|right" + layout="topleft" + left="0" + top="0" + bottom="-16" /> + <panel + border="false" + label="Groups" + filename="panel_search_groups.xml" + class="panel_search_groups" + name="panel_search_groups" + follows="left|top|right" + layout="topleft" + left="0" + top="0" + bottom="-1" /> + <panel + border="false" + label="Places" + filename="panel_search_places.xml" + class="panel_search_places" + name="panel_search_places" + follows="left|top|right" + layout="topleft" + left="0" + top="0" + bottom="-1" /> + <panel + border="false" + label="Land" + filename="panel_search_landsales.xml" + class="panel_search_landsales" + name="panel_search_landsales" + follows="left|top|right" + layout="topleft" + left="0" + top="0" + bottom="-1" /> + <panel + border="false" + label="Events" + filename="panel_search_events.xml" + class="panel_search_events" + name="panel_search_events" + follows="left|top|right" + layout="topleft" + left="0" + top="0" + bottom="-1" /> + <panel + border="false" + label="Classifieds" + filename="panel_search_classifieds.xml" + class="panel_search_classifieds" + name="panel_search_classifieds" + follows="left|top|right" + layout="topleft" + left="0" + top="0" + bottom="-1" /> + <panel + border="false" + label="AltaVista" + filename="panel_search_web.xml" + class="panel_search_web" + name="panel_search_web" + follows="all" + layout="topleft" + left="0" + top="0" + bottom="-1" /> + </tab_container> + <layout_stack + follows="all" + animate="false" + top="86" + height="480" + left="0" + right="-1" + drag_handle_gap="2" + drag_handle_first_indent="1" + drag_handle_second_indent="1" + layout="topleft" + name="results_stack" + orientation="horizontal" + show_drag_handle="true"> + <layout_panel + border="true" + auto_resize="true" + user_resize="true" + layout="topleft" + top="0" + left="0" + width="300" + bottom="-1" + min_height="10" + name="results_lp"> + <scroll_list + layout="topleft" + top="1" + left="2" + width="300" + bottom="-1" + column_padding="0" + draw_heading="true" + follows="left|right|top|bottom" + multi_select="true" + name="results" + search_column="0" /> + </layout_panel> + <layout_panel + border="true" + auto_resize="true" + user_resize="true" + layout="topleft" + top="0" + bottom="-1" + left="405" + width="313" + min_height="10" + name="detail_lp"> + <panel + follows="all" + name="detail_avatar" + top="0" + bottom="-1" + left="0" + width="313" + class="panel_profile_legacy_sidetray" + filename="panel_profile_legacy_sidetray.xml" /> + <panel + follows="all" + name="detail_group" + top="0" + bottom="-1" + left="0" + width="313" + class="panel_group_info_sidetray" + filename="panel_group_info_sidetray.xml" /> + <panel + follows="all" + name="detail_place" + top="0" + bottom="-1" + left="0" + width="313" + class="panel_places" + filename="panel_places.xml" /> + <panel + follows="all" + name="detail_event" + top="0" + bottom="-1" + left="0" + width="313" + class="panel_event_info" + filename="panel_event_info.xml" /> + <panel + follows="all" + name="detail_classified" + top="0" + bottom="-1" + left="0" + width="313" + class="panel_classified_info" + filename="panel_classified_info.xml" /> + </layout_panel> + </layout_stack> + <text + follows="bottom|left" + height="16" + layout="topleft" + left="4" + name="results_status" + top_pad="3" + value="[TOTAL] results" + width="205" /> + <button + follows="bottom|left" + height="16" + width="16" + image_unselected="Arrow_Left" + image_disabled="Arrow_Left_Off" + image_disabled_selected="Arrow_Left_Off" + image_selected="Arrow_Left" + image_pressed="Arrow_Left" + image_top_pad="0" + layout="topleft" + left_pad="5" + name="PageDn" + top_delta="0" /> + <button + follows="bottom|left" + height="16" + width="16" + image_unselected="Arrow_Right" + image_disabled="Arrow_Right_Off" + image_disabled_selected="Arrow_Right_Off" + image_selected="Arrow_Right" + image_pressed="Arrow_Right" + image_top_pad="0" + layout="topleft" + left_pad="5" + name="PageUp" + top_delta="0" /> + <loading_indicator + follows="bottom|right" + height="16" + layout="topleft" + right="-4" + name="loading" + top_delta="0" + width="16" /> +</floater> diff --git a/indra/newview/skins/default/xui/en/floater_event.xml b/indra/newview/skins/default/xui/en/floater_event.xml index 67eb4931e1be41fde99b944bec80f77a0c2eb551..4b430877762bd213bc1f664b670dc7e612a8c98c 100644 --- a/indra/newview/skins/default/xui/en/floater_event.xml +++ b/indra/newview/skins/default/xui/en/floater_event.xml @@ -1,39 +1,23 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater - height="400" + height="590" can_resize="true" help_topic="event_details" label="Event" layout="topleft" name="Event" - save_rect="true" save_visibility="false" - title="EVENT DETAILS" - width="600"> - <floater.string - name="loading_text"> - Loading... - </floater.string> - <floater.string - name="done_text"> - Done - </floater.string> - <web_browser - trusted_content="true" - follows="left|right|top|bottom" - layout="topleft" - left="10" - name="browser" - height="365" - width="580" - top="0"/> - <text - follows="bottom|left" - height="16" - layout="topleft" - left_delta="0" - name="status_text" - top_pad="10" - width="150" /> + title="EVENT DETAILS" + max_width="320" + width="313"> + <panel + follows="all" + name="event_panel" + top="0" + bottom="590" + left="0" + right="313" + class="panel_event_info" + filename="panel_event_info.xml" /> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_fs_search.xml b/indra/newview/skins/default/xui/en/floater_fs_search.xml deleted file mode 100644 index 67e9d1630db9bec66acf70ce9ae02adabb9c0408..0000000000000000000000000000000000000000 --- a/indra/newview/skins/default/xui/en/floater_fs_search.xml +++ /dev/null @@ -1,337 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<floater - can_resize="true" - default_tab_group="1" - height="590" - help_topic="search" - layout="topleft" - legacy_header_height="0" - min_height="590" - min_width="660" - name="floater_search" - positioning="centered" - save_rect="true" - single_instance="true" - title="SEARCH" - width="780"> - <!-- Strings --> - <floater.string name="string.location"> - Location: [LOCATION] - </floater.string> - <floater.string name="string.traffic"> - Traffic: [DWELL] - </floater.string> - <floater.string name="string.area"> - Area: [AREA] - </floater.string> - <floater.string name="string.members"> - Members: [MEMBER_COUNT] - </floater.string> - <floater.string name="string.founder"> - Founder: [FOUNDER] - </floater.string> - <floater.string name="string.age"> - Age: [AGE] - </floater.string> - <floater.string name="string.partner"> - Partner: [PARTNER] - </floater.string> - <floater.string name="string.listing_price"> - Listing Price: [LISTING_PRICE] - </floater.string> - <floater.string name="string.slurl"> - [SLURL] - </floater.string> - <floater.string name="string.duration"> - Duration: [DURATION] - </floater.string> - <floater.string name="string.covercharge"> - Cover: [COVERCHARGE] - </floater.string> - <!-- Tab time --> - <tab_container - layout="topleft" - follows="all" - top="1" - left="0" - name="ls_tabs" - tab_min_width="90" - tab_position="top" - width="780" - height="585"> - <panel - class="panel_ls_web" - filename="panel_fs_search_legacy_web.xml" - label="Websearch" - layout="topleft" - name="panel_ls_web" /> - <panel - class="panel_ls_people" - filename="panel_fs_search_legacy_people.xml" - label="People" - layout="topleft" - name="panel_ls_people" /> - <panel - class="panel_ls_groups" - filename="panel_fs_search_legacy_groups.xml" - label="Groups" - layout="topleft" - name="panel_ls_groups" /> - <panel - class="panel_ls_places" - filename="panel_fs_search_legacy_places.xml" - label="Places" - layout="topleft" - name="panel_ls_places" /> - <panel - class="panel_ls_land" - filename="panel_fs_search_legacy_land.xml" - label="Land Sales" - layout="topleft" - name="panel_ls_land" /> - <panel - class="panel_ls_events" - filename="panel_fs_search_legacy_events.xml" - label="Events" - layout="topleft" - name="panel_ls_events" /> - <panel - class="panel_ls_classifieds" - filename="panel_fs_search_legacy_classifieds.xml" - label="Classifieds" - layout="topleft" - name="panel_ls_classifieds" /> - </tab_container> - <!-- Details/Action Panes --> - <panel - border="true" - follows="top|right|bottom" - height="508" - layout="topleft" - left="412" - top="80" - width="366" - name="panel_ls_details"> - <text_editor - left="12" - top="5" - height="24" - width="340" - layout="topleft" - follows="left|top|right" - name="title" - bg_visible="false" - border_visible="false" - allow_scroll="false" - h_pad="0" - v_pad="0" - halign="center" - enabled="false" - use_ellipses="true" - font="SansSerifHugeBold" - value="Undefined name" /> - <texture_picker - enabled="false" - fallback_image="Generic_Person_Large" - follows="left|top|right" - height="210" - layout="topleft" - left="78" - name="snapshot" - top_pad="4" - width="210"/> - <texture_picker - enabled="false" - fallback_image="default_land_picture.j2c" - follows="left|top|right" - height="210" - layout="topleft" - left_delta="0" - name="snapshot_parcel" - top_delta="0" - visible="false" - width="280"/> - <text_editor - left="20" - top_pad="2" - height="16" - width="180" - layout="topleft" - follows="left|top|right" - name="aux1" - bg_visible="false" - border_visible="false" - h_pad="0" - v_pad="0" - word_wrap="true" - enabled="false" - max_length="117" - allow_scroll="false" - parse_urls="true" - value="Auxilary info field 1"/> - <text_editor - left_pad="4" - top_delta="0" - height="16" - width="140" - layout="topleft" - follows="left|top|right" - name="aux2" - bg_visible="false" - border_visible="false" - h_pad="0" - v_pad="0" - word_wrap="true" - enabled="false" - max_length="117" - allow_scroll="false" - parse_urls="true" - value="Auxilary info field 2"/> - <icon - follows="top|right" - height="16" - image_name="Unknown_Icon" - layout="topleft" - left="20" - top_pad="2" - name="maturity_icon" - width="18" /> - <text_editor - left_pad="4" - top_delta="0" - height="28" - width="302" - layout="topleft" - follows="left|top|right" - name="location" - bg_visible="false" - border_visible="false" - h_pad="0" - v_pad="0" - word_wrap="true" - enabled="false" - max_length="117" - allow_scroll="false" - parse_urls="true" - value="Location info field"/> - <text_editor - left="20" - top_pad="12" - height="154" - width="324" - layout="topleft" - follows="left|top|right" - name="desc" - bg_visible="false" - border_visible="false" - h_pad="0" - v_pad="0" - word_wrap="true" - parse_urls="true" - enabled="false" - max_length="1000" - trusted_content="false" - value="You unlock this door with the key of imagination. Beyond it is another dimension: a dimension of sound, a dimension of sight, a dimension of mind. You're moving into a land of both shadow and substance, of things and ideas; you've just crossed over into the Twilight Zone. What you are about to see is real; the litigants on the screen are not actors. They are genuine citizens who, having filed their claims in a real small claims court, have been persuaded to drop their suits there and have them settled here, in this forum... the People's Court."/> - <button - layout="topleft" - follows="left|bottom" - height="23" - label="Open Profile" - name="people_profile_btn" - top="484" - left="3" - width="120" /> - <button - layout="topleft" - follows="left|bottom" - height="23" - label="Send Message" - name="people_message_btn" - width="120" - left_pad="1" /> - <button - layout="topleft" - follows="left|bottom" - height="23" - label="Add Friend" - name="people_friend_btn" - width="120" - left_pad="1" /> - <button - layout="topleft" - follows="left|bottom" - height="23" - label="Open Profile" - name="group_profile_btn" - top="484" - left="3" - width="120" /> - <button - layout="topleft" - follows="left|bottom" - height="23" - label="Join Chat" - name="group_message_btn" - width="120" - left_pad="1" /> - <button - layout="topleft" - follows="left|bottom" - height="23" - label="Join Group" - name="group_join_btn" - width="120" - left_pad="1" /> - <button - layout="topleft" - follows="left|bottom" - height="23" - label="Teleport" - name="teleport_btn" - top="484" - left="3" - width="120" /> - <button - layout="topleft" - follows="left|bottom" - height="23" - label="Show on Map" - name="map_btn" - width="120" - left_pad="1" /> - <button - layout="topleft" - follows="left|bottom" - height="23" - label="Remind me" - name="event_reminder_btn" - width="120" - left_pad="1" /> - <loading_indicator - left="134" - top="320" - follows="left|top|right" - mouse_opaque="false" - name="loading" - images_per_sec="1.0" - tab_stop="false" - height="100" - width="100" - visible="false" > - <images> - <image name="ProgressLarge_1"/> - <image name="ProgressLarge_2"/> - <image name="ProgressLarge_3"/> - <image name="ProgressLarge_4"/> - <image name="ProgressLarge_5"/> - <image name="ProgressLarge_6"/> - <image name="ProgressLarge_7"/> - <image name="ProgressLarge_8"/> - <image name="ProgressLarge_9"/> - <image name="ProgressLarge_10"/> - <image name="ProgressLarge_11"/> - <image name="ProgressLarge_12"/> - </images> - </loading_indicator> - </panel> -</floater> diff --git a/indra/newview/skins/default/xui/en/floater_profile_legacy.xml b/indra/newview/skins/default/xui/en/floater_profile_legacy.xml new file mode 100644 index 0000000000000000000000000000000000000000..2a896d10796abe463d06208dd50d4cb6859f77dc --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_profile_legacy.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + positioning="cascading" + can_close="true" + can_resize="true" + height="580" + min_height="350" + min_width="260" + layout="topleft" + name="floater_profile_legacy" + save_rect="true" + title="PROFILE" + width="370"> + <panel + class="panel_profile_legacy_sidetray" + name="panel_profile_legacy_sidetray" + filename="panel_profile_legacy_sidetray.xml" + label="Profile" + font="SansSerifBold" + follows="all" + layout="topleft" + min_height="350" + left="1" + right="-1" + top="0" + bottom="-8"/> +</floater> diff --git a/indra/newview/skins/default/xui/en/menu_profile_legacy.xml b/indra/newview/skins/default/xui/en/menu_profile_legacy.xml new file mode 100644 index 0000000000000000000000000000000000000000..93724bbca1a0e59e67f2f1151d08045ddfd660c1 --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_profile_legacy.xml @@ -0,0 +1,135 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<toggleable_menu + name="menu_profile_legacy" + left="0" bottom="0" visible="false" + mouse_opaque="false"> + <menu_item_call + label="Open Webprofile..." + name="webprofile"> + <menu_item_call.on_click + function="Profile.Action" + parameter="webprofile"/> + </menu_item_call> + <menu_item_separator/> + <!--<menu + label="Upload profile image" + layout="topleft" + name="upload_image_menu"> + <menu_item_call + label="Second Life..." + name="upload_second_life"> + <menu_item_call.on_click + function="Profile.Action" + parameter="upload_sl"/> + <menu_item_call.on_enable + function="Profile.Enable" + parameter="can_upload_pic" /> + </menu_item_call> + <menu_item_call + label="First Life..." + name="upload_first_life"> + <menu_item_call.on_click + function="Profile.Action" + parameter="upload_fl"/> + <menu_item_call.on_enable + function="Profile.Enable" + parameter="can_upload_pic" /> + </menu_item_call> + </menu>--> + <menu_item_call + label="Share..." + name="share"> + <menu_item_call.on_click + function="Profile.Action" + parameter="share"/> + <menu_item_call.on_enable + function="Profile.Enable" + parameter="can_share" /> + </menu_item_call> + <menu_item_call + label="Call Avatar..." + name="call"> + <menu_item_call.on_click + function="Profile.Action" + parameter="call"/> + <menu_item_call.on_enable + function="Profile.Enable" + parameter="can_has_telefono" /> + </menu_item_call> + <menu_item_call + label="Offer teleport..." + name="teleport"> + <menu_item_call.on_click + function="Profile.Action" + parameter="teleport"/> + <menu_item_call.on_enable + function="Profile.Enable" + parameter="can_has_teleport" /> + </menu_item_call> + <menu_item_call + label="Request teleport..." + name="request_teleport"> + <menu_item_call.on_click + function="Profile.Action" + parameter="req_teleport"/> + <menu_item_call.on_enable + function="Profile.Enable" + parameter="can_has_teleport" /> + </menu_item_call> + <menu_item_call + label="Show on map..." + name="map"> + <menu_item_call.on_click + function="Profile.Action" + parameter="map"/> + <menu_item_call.on_enable + function="Profile.Enable" + parameter="can_has_map" /> + </menu_item_call> + <menu_item_call + label="Pay..." + name="pay"> + <menu_item_call.on_click + function="Profile.Action" + parameter="pay"/> + <menu_item_call.on_enable + function="Profile.Enable" + parameter="can_has_pay" /> + </menu_item_call> + <menu_item_call + label="Report Abuse..." + name="report_abuse"> + <menu_item_call.on_click + function="Profile.Action" + parameter="report_abuse"/> + <menu_item_call.on_enable + function="Profile.Enable" + parameter="can_drama" /> + </menu_item_call> + <menu_item_separator /> + <menu_item_call + label="Copy Name" + name="Copy Name"> + <menu_item_call.on_click + function="Avatar.CopyData" + parameter="account_name"/> + <menu_item_call.on_enable + function="RLV.CanShowName" /> + </menu_item_call> + <menu_item_call + label="Copy SLurl" + name="Copy SLurl"> + <menu_item_call.on_click + function="Avatar.CopyData" + parameter="slurl"/> + <menu_item_call.on_enable + function="RLV.CanShowName" /> + </menu_item_call> + <menu_item_call + label="Copy UUID" + name="Copy ID"> + <menu_item_call.on_click + function="Avatar.CopyData" + parameter="id"/> + </menu_item_call> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/panel_classified_info.xml b/indra/newview/skins/default/xui/en/panel_classified_info.xml index 0febf62b4355e3b2f7dabb09bf345bbe73b31934..e3fd1cd5a1fab2799f387eada4da0a9ffdc88a7e 100644 --- a/indra/newview/skins/default/xui/en/panel_classified_info.xml +++ b/indra/newview/skins/default/xui/en/panel_classified_info.xml @@ -38,15 +38,28 @@ name="auto_renew_off"> Disabled </panel.string> + <button + follows="top|left" + height="24" + image_hover_unselected="BackButton_Over" + image_pressed="BackButton_Press" + image_unselected="BackButton_Off" + layout="topleft" + name="back_btn" + left="10" + tab_stop="false" + top="2" + width="30" + use_draw_context_alpha="false" /> <text follows="top|left|right" font="SansSerifHugeBold" height="26" layout="topleft" - left="12" + left_pad="4" name="title" text_color="LtGray" - top="2" + top="0" value="Classified Info" use_ellipses="true" width="275" /> @@ -407,7 +420,7 @@ height="23" label="Teleport" layout="topleft" - left="2" + left="0" name="teleport_btn" top="0" width="101" /> @@ -430,6 +443,24 @@ top="0" width="100" /> </layout_panel> + + <layout_panel + follows="bottom|left|right" + height="23" + layout="bottomleft" + left_pad="3" + name="edit_btn_lp" + auto_resize="true" + width="101"> + <button + follows="bottom|left|right" + height="23" + label="Edit" + layout="topleft" + name="edit_btn" + top="0" + width="101" /> + </layout_panel> </layout_stack> </panel> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_edit_pick.xml b/indra/newview/skins/default/xui/en/panel_edit_pick.xml new file mode 100644 index 0000000000000000000000000000000000000000..39f1817705dfece84146b65b9b4c6e3aa55afa16 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_edit_pick.xml @@ -0,0 +1,238 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + background_visible="true" + bevel_style="in" + follows="left|top|right|bottom" + height="569" + label="Edit Pick" + layout="topleft" + left="0" + min_height="350" + name="panel_edit_pick" + help_topic="profile_edit_pick" + top="0" + width="333"> + <panel.string + name="location_notice"> + (will update after save) + </panel.string> + <button + follows="top|left" + height="24" + image_hover_unselected="BackButton_Over" + image_pressed="BackButton_Press" + image_unselected="BackButton_Off" + layout="topleft" + name="back_btn" + left="10" + tab_stop="false" + top="2" + width="30" + use_draw_context_alpha="false" /> + <text + type="string" + length="1" + follows="top" + font="SansSerifHugeBold" + height="26" + layout="topleft" + left_pad="4" + name="title" + text_color="LtGray" + top="2" + width="250"> + Edit Pick + </text> + <scroll_container + color="PanelDefaultBackgroundColor" + follows="all" + height="502" + layout="topleft" + left="8" + top_pad="10" + name="profile_scroll" + opaque="true" + width="312"> + <panel + name="scroll_content_panel" + follows="left|top|right" + min_height="300" + layout="topleft" + top="0" + background_visible="false" + height="500" + left="0" + width="285"> + <texture_picker + fallback_image="default_land_picture.j2c" + follows="left|top|right" + height="197" + width="272" + layout="topleft" + no_commit_on_selection="true" + top="10" + left="11" + name="pick_snapshot" /> + <icon + height="197" + image_name="spacer24.tga" + layout="topleft" + name="edit_icon" + label="" + tool_tip="Click to select an image" + top="10" + left="11" + width="286" /> + <text + type="string" + length="1" + follows="left|top|right" + height="15" + font="SansSerifSmall" + font.style="BOLD" + layout="topleft" + left="10" + top="215" + name="Name:" + text_color="white" + width="280"> + Title: + </text> + <line_editor + follows="left|top|right" + font="SansSerif" + height="20" + layout="topleft" + left="10" + top_pad="2" + max_length_bytes="63" + name="pick_name" + width="273" /> + <text + type="string" + length="1" + follows="left|top|right" + height="15" + font="SansSerifSmall" + font.style="BOLD" + layout="topleft" + left="10" + top_pad="20" + name="description_label" + text_color="white" + width="280"> + Description: + </text> + <text_editor + follows="left|top|right" + height="100" + width="273" + hide_scrollbar="false" + layout="topleft" + left="10" + top_pad="2" + max_length="1023" + name="pick_desc" + spellcheck="true" + word_wrap="true" + show_emoji_helper="true" /> + <text + type="string" + length="1" + font="SansSerifSmall" + font.style="BOLD" + follows="left|top|right" + height="15" + layout="topleft" + left="10" + name="location_label" + text_color="white" + top_pad="20" + width="280"> + Location: + </text> + <text + type="string" + length="1" + follows="left|top|right" + height="50" + layout="topleft" + left="10" + name="pick_location" + top_pad="2" + width="280" + word_wrap="true"> + loading... + </text> + <button + follows="left|top" + height="23" + label="Set to Current Location" + layout="topleft" + left="8" + top_pad="0" + name="set_to_curr_location_btn" + width="200" /> + </panel> + </scroll_container> + <panel + follows="left|right|bottom" + height="23" + label="bottom_panel" + layout="topleft" + left="8" + name="bottom_panel" + top_pad="5" + width="315"> + + <layout_stack + follows="bottom|left|right" + height="23" + layout="topleft" + name="layout_stack1" + left="0" + orientation="horizontal" + top_pad="0" + width="313"> + + <layout_panel + follows="bottom|left|right" + height="23" + layout="topleft" + left="0" + name="layout_panel1" + auto_resize="true" + width="150"> + <button + follows="bottom|left|right" + height="23" + label="Save Pick" + layout="topleft" + name="save_changes_btn" + top="0" + left="1" + width="149" /> + </layout_panel> + + <layout_panel + follows="bottom|left|right" + height="23" + layout="topleft" + left_pad="4" + name="layout_panel2" + auto_resize="true" + width="146"> + <button + follows="bottom|left|right" + height="23" + label="Cancel" + layout="topleft" + name="cancel_btn" + top="0" + left="1" + width="145" /> + </layout_panel> + </layout_stack> + + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_event_info.xml b/indra/newview/skins/default/xui/en/panel_event_info.xml new file mode 100644 index 0000000000000000000000000000000000000000..b065f493c12e4bc0935a2152adcb63aaa4e6e284 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_event_info.xml @@ -0,0 +1,456 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + background_visible="true" + follows="all" + height="570" + layout="topleft" + left="0" + min_height="350" + name="event_info" + class="event_info" + top="20" + width="333"> + <panel.string name="free"> + FREE + </panel.string> + <panel.string name="hours"> + hours + </panel.string> + <panel.string name="minutes"> + minutes + </panel.string> + <panel.string name="type_mature"> + Moderate + </panel.string> + <panel.string name="type_pg"> + General Content + </panel.string> + <panel.string name="reminder"> + Remind + </panel.string> + <panel.string name="no_reminder"> + Don't remind + </panel.string> + <button + follows="top|left" + height="24" + image_hover_unselected="BackButton_Over" + image_pressed="BackButton_Press" + image_unselected="BackButton_Off" + layout="topleft" + name="back_btn" + left="10" + tab_stop="false" + top="2" + width="30" + use_draw_context_alpha="false" /> + <text + follows="top|left|right" + font="SansSerifHugeBold" + height="26" + layout="topleft" + left_pad="4" + name="title" + text_color="LtGray" + top="0" + value="Event Info" + use_ellipses="true" + width="275" /> + <scroll_container + color="PanelDefaultBackgroundColor" + opaque="true" + follows="all" + height="502" + layout="topleft" + left="10" + top_pad="10" + name="profile_scroll" + reserve_scroll_corner="false" + width="312"> + <panel + name="scroll_content_panel" + follows="left|top" + min_height="300" + layout="topleft" + top="0" + background_visible="false" + height="610" + left="0" + width="285"> + <panel + name="snapshot_panel" + layout="topleft" + follows="left|top|right" + height="197" + left="10" + top="10" + width="275"> + <texture_picker + fallback_image="default_land_picture.j2c" + enabled="false" + follows="left|top|right" + height="197" + layout="topleft" + left="0" + name="snapshot" + top="0" + width="275" /> + </panel> + <text_editor + allow_scroll="false" + bg_visible="false" + follows="left|top|right" + h_pad="0" + height="35" + width="290" + layout="topleft" + font="SansSerifBig" + font.style="BOLD" + left="10" + top_pad="10" + name="name" + read_only="true" + text_color="white" + v_pad="0" + value="[name]" + use_ellipses="true" /> + <text + follows="left|top" + font.style="BOLD" + height="10" + layout="topleft" + left="10" + name="event_location_label" + text_color="white" + top_pad="5" + value="Location:" + width="250" /> + <text_editor + parse_urls="true" + allow_scroll="false" + bg_visible="false" + follows="left|top" + h_pad="0" + height="30" + layout="topleft" + left="10" + name="location" + read_only="true" + top_pad="5" + width="290" + word_wrap="true" + v_pad="0" + value="[loading...]" /> + <text + follows="left|top" + font.style="BOLD" + height="10" + layout="topleft" + left="10" + name="content_type_label" + text_color="white" + top_pad="10" + value="Content Type:" + width="140" /> + <icon + follows="top|left" + height="16" + image_name="Parcel_M_Light" + layout="topleft" + left_pad="0" + name="content_type_moderate" + top_pad="-11" + width="18" /> + <icon + follows="top|left" + height="16" + image_name="Parcel_PG_Light" + layout="topleft" + left_delta="0" + name="content_type_general" + top_delta="0" + width="18" /> + <text_editor + allow_scroll="false" + bg_visible="false" + follows="left|top|right" + h_pad="0" + height="18" + layout="topleft" + left_pad="2" + name="content_type" + read_only="true" + width="130" + top_delta="1" + v_pad="0" + value="[content type]" /> + <text + follows="left|top" + font.style="BOLD" + height="10" + layout="topleft" + left="10" + name="time_label" + text_color="white" + top_pad="0" + value="Time:" + width="140" /> + <text_editor + allow_scroll="false" + bg_visible="false" + follows="left|top|right" + h_pad="0" + height="18" + layout="topleft" + left_pad="0" + name="time" + read_only="true" + width="150" + top_pad="-10" + v_pad="0" + value="[time]" /> + <text + follows="left|top" + font.style="BOLD" + height="10" + layout="topleft" + left="10" + name="duration_label" + text_color="white" + top_pad="0" + value="Duration:" + width="140" /> + <text_editor + allow_scroll="false" + bg_visible="false" + follows="left|top" + h_pad="0" + halign="left" + height="16" + layout="topleft" + left_pad="0" + name="duration" + read_only="true" + top_pad="-10" + v_pad="0" + value="[duration] hours" + width="150" /> + <layout_stack + animate="false" + name="descr_stack" + layout="topleft" + follows="all" + orientation="vertical" + left="10" + top_pad="5" + width="290" + height="215"> + <layout_panel + auto_resize="false" + name="host_layout_panel" + layout="topleft" + follows="all" + left="0" + top="0" + width="290" + height="16"> + <text + follows="left|top" + font.style="BOLD" + height="10" + layout="topleft" + left="0" + name="host_label" + text_color="white" + top_pad="0" + value="Host:" + width="140" /> + <text_editor + allow_scroll="false" + bg_visible="false" + follows="left|top" + h_pad="0" + halign="left" + height="16" + layout="topleft" + left_pad="0" + parse_urls="true" + name="host" + read_only="true" + top_pad="-10" + v_pad="0" + value="secondlife:///app/agent/00000000-0000-0000-0000-000000000000/inspect" + width="150" /> + </layout_panel> + <layout_panel + auto_resize="false" + name="category_panel" + layout="topleft" + follows="all" + left="0" + top="0" + width="290" + height="16"> + <text + follows="left|top" + font.style="BOLD" + height="10" + layout="topleft" + left="0" + name="category_label" + text_color="white" + top="0" + value="Category:" + width="140" /> + <text + height="16" + layout="topleft" + follows="top|left" + left_pad="0" + name="category" + top_pad="-10" + value="[category]" + width="150" /> + </layout_panel> + <layout_panel + auto_resize="false" + name="cover_panel" + layout="topleft" + follows="all" + left="0" + top="0" + width="290" + height="16"> + <text + follows="left|top" + font.style="BOLD" + height="10" + layout="topleft" + left="0" + name="cover_label" + text_color="white" + top="0" + value="Cover:" + width="140" /> + <text + height="16" + layout="topleft" + follows="top|left" + left_pad="0" + name="cover" + top_pad="-10" + value="L$[cover]" + width="150" /> + </layout_panel> + <layout_panel + name="descr_layout_panel" + layout="topleft" + follows="all" + left="0" + top="0" + width="290" + height="215"> + <text + auto_resize="false" + follows="left|top" + font.style="BOLD" + height="10" + layout="topleft" + left="0" + name="desc_label" + text_color="white" + top="0" + value="Description:" + width="250" /> + <text_editor + parse_urls="true" + allow_scroll="true" + bg_visible="false" + follows="all" + h_pad="0" + height="200" + layout="topleft" + left="0" + max_length="1023" + name="desc" + read_only="true" + top_pad="7" + width="280" + v_pad="0" + value="[description]" + word_wrap="true" /> + </layout_panel> + </layout_stack> + </panel> +</scroll_container> +<panel + follows="left|right|bottom" + height="35" + layout="topleft" + top_pad="5" + left="9" + name="buttons"> + <layout_stack + follows="bottom|left|right" + height="23" + layout="topleft" + name="layout_stack1" + left="0" + orientation="horizontal" + top_pad="0" + width="309"> + <layout_panel + follows="bottom|left|right" + height="23" + layout="bottomleft" + left="0" + name="layout_panel1" + auto_resize="true" + width="101"> + <button + follows="bottom|left|right" + height="23" + label="Teleport" + layout="topleft" + left="0" + name="teleport_btn" + top="0" + width="101" /> + </layout_panel> + <layout_panel + follows="bottom|left|right" + height="23" + layout="bottomleft" + left_pad="3" + name="show_on_map_btn_lp" + auto_resize="true" + width="100"> + <button + follows="bottom|left|right" + height="23" + label="Map" + layout="topleft" + name="show_on_map_btn" + top="0" + width="100" /> + </layout_panel> + <layout_panel + follows="bottom|left|right" + height="23" + layout="bottomleft" + left_pad="3" + name="remind_btn_lp" + auto_resize="true" + width="101"> + <button + follows="bottom|left|right" + height="23" + label="Remind" + layout="topleft" + name="remind_btn" + top="0" + width="101" /> + </layout_panel> + </layout_stack> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_fs_search_legacy_classifieds.xml b/indra/newview/skins/default/xui/en/panel_fs_search_legacy_classifieds.xml deleted file mode 100644 index 66c35558b10d93e30f6027ecaa2ac34ce6264715..0000000000000000000000000000000000000000 --- a/indra/newview/skins/default/xui/en/panel_fs_search_legacy_classifieds.xml +++ /dev/null @@ -1,169 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel - border="false" - follows="all" - height="566" - layout="topleft" - left="1" - width="780" - label="Classifieds" - name="panel_ls_classifieds"> - <panel - border="false" - follows="top|left|right" - height="53" - layout="topleft" - left="0" - width="780" - name="panel_ls_input"> - <text - type="string" - length="1" - follows="left|top" - top_pad="5" - layout="topleft" - left="6" - name="search_text" - top="12" - height="16" - width="156"> - Enter search terms: - </text> - <search_combo_box - layout="topleft" - follows="left|top|right" - height="23" - left_delta="0" - name="classifieds_edit" - top="29" - width="651" /> - <combo_box - follows="right|top" - layout="topleft" - height="23" - allow_text_entry="false" - top_delta="0" - left_pad="2" - name="classifieds_category" - width="122"> - <combo_box.commit_callback - function="CommitSearch" /> - </combo_box> - <check_box - control_name="ShowPGClassifieds" - follows="right|top" - height="16" - label="" - layout="topleft" - left="660" - name="pg_all" - top="12" - width="15"> - <check_box.commit_callback - function="CommitSearch" /> - </check_box> - <icon - follows="right|top" - height="16" - image_name="Parcel_PG_Dark" - layout="topleft" - left_pad="2" - name="rating_icon_general" - top_delta="-1" - width="18"/> - <check_box - control_name="ShowMatureClassifieds" - follows="right|top" - height="16" - label="" - layout="topleft" - left_pad="2" - name="mature_all" - top_delta="1" - width="15"> - <check_box.commit_callback - function="CommitSearch" /> - </check_box> - <icon - follows="right|top" - height="16" - image_name="Parcel_M_Dark" - layout="topleft" - left_pad="2" - name="rating_icon_moderate" - top_delta="-1" - width="18"/> - <check_box - control_name="ShowAdultClassifieds" - follows="right|top" - height="16" - label="" - layout="topleft" - left_pad="2" - name="adult_all" - top_delta="1" - width="15"> - <check_box.commit_callback - function="CommitSearch" /> - </check_box> - <icon - follows="right|top" - height="16" - image_name="Parcel_R_Dark" - layout="topleft" - left_pad="2" - name="rating_icon_adult" - top_delta="-1" - width="18"/> - </panel> - <!-- Search Pane --> - <panel - border="true" - follows="all" - height="510" - layout="topleft" - left="1" - width="410" - top_pad="1" - name="panel_ls_scrolllist"> - <scroll_list - draw_heading="true" - follows="all" - height="485" - layout="topleft" - left="0" - name="search_results_classifieds" - top="0" - width="410"> - <columns - label="" - name="icon" - width="20" /> - <columns - label="Name" - name="classified_name" - relwidth="0.70" /> - <columns - label="Listing Price" - name="price" - relwidth="0.3"/> - </scroll_list> - <button - layout="topleft" - follows="left|bottom" - height="23" - label="Back" - name="classifieds_back" - top_pad="2" - left="3" - width="100" /> - <button - layout="topleft" - follows="left|bottom" - height="23" - label="Next" - name="classifieds_next" - width="100" - left_pad="1" /> - </panel> -</panel> diff --git a/indra/newview/skins/default/xui/en/panel_fs_search_legacy_events.xml b/indra/newview/skins/default/xui/en/panel_fs_search_legacy_events.xml deleted file mode 100644 index 57cb4990e408332b97d4607b70899c09ce43c7ed..0000000000000000000000000000000000000000 --- a/indra/newview/skins/default/xui/en/panel_fs_search_legacy_events.xml +++ /dev/null @@ -1,258 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel - border="false" - follows="all" - height="566" - layout="topleft" - left="1" - width="780" - label="Events" - name="panel_ls_events"> - <panel - border="false" - follows="top|left|right" - height="53" - layout="topleft" - left="0" - width="780" - name="panel_ls_input"> - <text - type="string" - length="1" - follows="left|top" - top_pad="5" - layout="topleft" - left="6" - name="search_text" - top="12" - height="16" - width="156"> - Enter search terms: - </text> - <radio_group - left_pad="20" - height="16" - width="300" - layout="topleft" - name="events_search_mode"> - <radio_item - height="16" - label="Ongoing and Upcoming" - layout="topleft" - name="current" - value="current" - top_pad="0" - width="120" /> - <radio_item - height="16" - label="By Date" - layout="topleft" - name="date" - value="date" - left_pad="70" - width="120" /> - <radio_group.commit_callback - function="CommitSearch" /> - </radio_group> - <text - type="string" - length="1" - follows="left|top" - top_delta="0" - layout="topleft" - left_pad="5" - name="events_date" - font.style="BOLD" - height="16" - width="80"> - 4/20 - </text> - <search_combo_box - layout="topleft" - follows="left|top|right" - height="23" - left="6" - name="events_edit" - top="29" - width="651" /> - <combo_box - follows="right|top" - layout="topleft" - height="23" - top_delta="0" - left_pad="2" - name="events_category" - width="122"> - <combo_box.item label="Any Category" name="any" value="0" /> - <combo_box.item label="" value="filter_separator" enabled="false" /> - <combo_box.item label="Discussion" name="discussion" value="18" /> - <combo_box.item label="Sports" name="sports" value="19" /> - <combo_box.item label="Live DJ" name="dj" value="30" /> - <combo_box.item label="Live Music" name="music" value="20" /> - <!-- <combo_box.item label="???" name="mystery_category" value="21" /> --> - <combo_box.item label="Commercial" name="commercial" value="22" /> - <combo_box.item label="Nightlife/Entertainment" name="nightlife" value="23" /> - <combo_box.item label="Games/Contests" name="games" value="24" /> - <combo_box.item label="Pageants" name="pageants" value="25" /> - <combo_box.item label="Education" name="education" value="26" /> - <combo_box.item label="Arts and Culture" name="arts" value="27" /> - <combo_box.item label="Charity/Support Groups" name="charity" value="28" /> - <combo_box.item label="Miscellaneous" name="misc" value="29" /> - <combo_box.commit_callback - function="CommitSearch" /> - </combo_box> - <check_box - control_name="ShowPGEvents" - follows="right|top" - height="16" - label="" - layout="topleft" - left="660" - name="pg_all" - top="12" - width="15" > - <check_box.commit_callback - function="CommitSearch" /> - </check_box> - <icon - follows="right|top" - height="16" - image_name="Parcel_PG_Dark" - layout="topleft" - left_pad="2" - name="rating_icon_general" - top_delta="-1" - width="18"/> - <check_box - control_name="ShowMatureEvents" - follows="right|top" - height="16" - label="" - layout="topleft" - left_pad="2" - name="mature_all" - top_delta="1" - width="15"> - <check_box.commit_callback - function="CommitSearch" /> - </check_box> - <icon - follows="right|top" - height="16" - image_name="Parcel_M_Dark" - layout="topleft" - left_pad="2" - name="rating_icon_moderate" - top_delta="-1" - width="18"/> - <check_box - control_name="ShowAdultEvents" - follows="right|top" - height="16" - label="" - layout="topleft" - left_pad="2" - name="adult_all" - top_delta="1" - width="15"> - <check_box.commit_callback - function="CommitSearch" /> - </check_box> - <icon - follows="right|top" - height="16" - image_name="Parcel_R_Dark" - layout="topleft" - left_pad="2" - name="rating_icon_adult" - top_delta="-1" - width="18"/> - </panel> - <!-- Search Pane --> - <panel - border="true" - follows="all" - height="510" - layout="topleft" - left="1" - width="410" - top_pad="1" - name="panel_ls_scrolllist"> - <scroll_list - draw_heading="true" - follows="all" - height="485" - layout="topleft" - left="0" - name="search_results_events" - sort_ascending="true" - sort_column="3" - top="0" - width="410"> - <columns - label="" - name="icon" - width="20" /> - <columns - label="Event Name" - name="name" - relwidth="0.72" /> - <columns - label="Date/Time" - name="date" - sort_column="time" - relwidth="0.28" /> - <columns - label="Time" - name="time" - width="0"/> - </scroll_list> - <button - layout="topleft" - follows="left|bottom" - height="23" - label="Yesterday" - name="events_yesterday" - top_pad="2" - left="3" - width="100" /> - <button - layout="topleft" - follows="left|bottom" - height="23" - label="Today" - name="events_today" - width="100" - left_pad="1" /> - <button - layout="topleft" - follows="left|bottom" - height="23" - label="Tomorrow" - name="events_tomorrow" - width="100" - left_pad="1" /> - <button - layout="topleft" - follows="left|bottom" - height="23" - image_bottom_pad="2" - image_overlay="Arrow_Left_Off" - image_overlay_alignment="left" - label="Back" - name="events_back" - width="25" - left_pad="1" /> - <button - layout="topleft" - follows="left|bottom" - height="23" - image_bottom_pad="2" - image_overlay="Arrow_Right_Off" - image_overlay_alignment="left" - label="Next" - name="events_next" - width="25" - left_pad="1" /> - </panel> -</panel> diff --git a/indra/newview/skins/default/xui/en/panel_fs_search_legacy_groups.xml b/indra/newview/skins/default/xui/en/panel_fs_search_legacy_groups.xml deleted file mode 100644 index 90001952f7c38528926e77ddb32302e2e0b23bbc..0000000000000000000000000000000000000000 --- a/indra/newview/skins/default/xui/en/panel_fs_search_legacy_groups.xml +++ /dev/null @@ -1,159 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel - border="false" - follows="all" - height="566" - layout="topleft" - left="1" - width="780" - label="Groups" - name="panel_ls_groups"> - <panel - border="false" - follows="top|left|right" - height="53" - layout="topleft" - left="0" - width="780" - name="panel_ls_input"> - <text - type="string" - length="1" - follows="left|top" - top_pad="5" - layout="topleft" - left="6" - name="search_text" - top="12" - height="16" - width="156"> - Enter search terms: - </text> - <search_combo_box - layout="topleft" - follows="left|top|right" - height="23" - left_delta="0" - name="groups_edit" - top="29" - width="770"> - </search_combo_box> - <check_box - control_name="ShowPGGroups" - follows="right|top" - height="16" - label="" - layout="topleft" - left="660" - name="pg_all" - top="12" - width="15" - visible="false"/> - <icon - follows="right|top" - height="16" - image_name="Parcel_PG_Dark" - layout="topleft" - left_pad="2" - name="rating_icon_general" - top_delta="-1" - width="18" - visible="false"/> - <check_box - control_name="ShowMatureGroups" - follows="right|top" - height="16" - label="" - layout="topleft" - left_pad="2" - name="mature_all" - top_delta="1" - width="15" - visible="false"/> - <icon - follows="right|top" - height="16" - image_name="Parcel_M_Dark" - layout="topleft" - left_pad="2" - name="rating_icon_moderate" - top_delta="-1" - width="18" - visible="false"/> - <check_box - control_name="ShowAdultGroups" - follows="right|top" - height="16" - label="" - layout="topleft" - left_pad="2" - name="adult_all" - top_delta="1" - width="15" - visible="false"/> - <icon - follows="right|top" - height="16" - image_name="Parcel_R_Dark" - layout="topleft" - left_pad="2" - name="rating_icon_adult" - top_delta="-1" - width="18" - visible="false"/> - </panel> - <!-- Search Pane --> - <panel - border="true" - follows="all" - height="510" - layout="topleft" - left="1" - width="410" - top_pad="1" - name="panel_ls_scrolllist"> - <scroll_list - draw_heading="true" - follows="all" - height="485" - layout="topleft" - left="0" - name="search_results_groups" - top="0" - width="410"> - <columns - label="" - name="icon" - width="20" /> - <columns - label="Group Name" - name="group_name" - relwidth="0.72" /> - <columns - label="Members" - name="members" - relwidth="0.25" /> - <columns - label="Score" - name="score" - width="0" /> - </scroll_list> - <button - layout="topleft" - follows="left|bottom" - height="23" - label="Back" - name="groups_back" - top_pad="2" - left="3" - width="100" /> - <button - layout="topleft" - follows="left|bottom" - height="23" - label="Next" - name="groups_next" - width="100" - left_pad="1" /> - </panel> -</panel> diff --git a/indra/newview/skins/default/xui/en/panel_fs_search_legacy_land.xml b/indra/newview/skins/default/xui/en/panel_fs_search_legacy_land.xml deleted file mode 100644 index bb03a1e9995b765a5386002da4a82bba89cb7c77..0000000000000000000000000000000000000000 --- a/indra/newview/skins/default/xui/en/panel_fs_search_legacy_land.xml +++ /dev/null @@ -1,281 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel - border="false" - follows="all" - height="566" - layout="topleft" - left="1" - width="780" - label="Land Sales" - name="panel_ls_land"> - <panel - border="false" - follows="top|left|right" - height="53" - layout="topleft" - left="0" - width="780" - name="panel_ls_input"> - <check_box - control_name="ShowPGLand" - follows="right|top" - height="16" - label="" - layout="topleft" - left="660" - name="pg_all" - top="12" - width="15"> - <check_box.commit_callback - function="CommitSearch" /> - </check_box> - <icon - follows="right|top" - height="16" - image_name="Parcel_PG_Dark" - layout="topleft" - left_pad="2" - name="rating_icon_general" - top_delta="-1" - width="18"/> - <check_box - control_name="ShowMatureLand" - follows="right|top" - height="16" - label="" - layout="topleft" - left_pad="2" - name="mature_all" - top_delta="1" - width="15"> - <check_box.commit_callback - function="CommitSearch" /> - </check_box> - <icon - follows="right|top" - height="16" - image_name="Parcel_M_Dark" - layout="topleft" - left_pad="2" - name="rating_icon_moderate" - top_delta="-1" - width="18"/> - <check_box - control_name="ShowAdultLand" - follows="right|top" - height="16" - label="" - layout="topleft" - left_pad="2" - name="adult_all" - top_delta="1" - width="15"> - <check_box.commit_callback - function="CommitSearch" /> - </check_box> - <icon - follows="right|top" - height="16" - image_name="Parcel_R_Dark" - layout="topleft" - left_pad="2" - name="rating_icon_adult" - top_delta="-1" - width="18"/> - <text - type="string" - length="1" - follows="left|top" - layout="topleft" - left="6" - name="search_text" - top="12" - height="16" - width="256"> - Enter search terms: - </text> - <combo_box - control_name="FindLandType" - follows="left|top" - layout="topleft" - height="23" - allow_text_entry="false" - top_pad="2" - left="6" - name="land_category" - width="122"> - <combo_box.item label="All Categories" name="All" value="All"/> - <combo_box.item label="Auction" name="Auction" value="Auction"/> - <combo_box.item label="Mainland Sales" name="Mainland" value="Mainland"/> - <combo_box.item label="Estate Sales" name="Estate" value="Estate"/> - <combo_box.commit_callback - function="CommitSearch" /> - </combo_box> - <check_box - control_name="FindLandPrice" - follows="left|top" - height="16" - label="Price <" - layout="topleft" - left_pad="3" - name="price_check" - top_delta="3" - width="40" > - <check_box.commit_callback - function="CommitSearch" /> - </check_box> - <line_editor - enabled_control="FindLandPrice" - bevel_style="none" - border_style="line" - border.border_thickness="0" - commit_on_focus_lost="false" - follows="left|top" - height="18" - left_pad="20" - name="edit_price" - top_delta="-1" - width="40" > - <line_editor.commit_callback - function="CommitSearch" /> - </line_editor> - <check_box - control_name="FindLandArea" - follows="left|top" - height="16" - label="Area >" - layout="topleft" - left_pad="3" - name="area_check" - top_delta="1" - width="40" > - <check_box.commit_callback - function="CommitSearch" /> - </check_box> - <line_editor - enabled_control="FindLandArea" - bevel_style="none" - border_style="line" - border.border_thickness="0" - commit_on_focus_lost="false" - follows="left|top" - height="18" - left_pad="20" - name="edit_area" - top_delta="-1" - width="40" > - <line_editor.commit_callback - function="CommitSearch" /> - </line_editor> - <text - type="string" - length="1" - follows="left|top" - layout="topleft" - left="365" - name="sort_text" - top="12" - height="16" - width="98"> - Sort results by: - </text> - <check_box - follows="left|top" - height="16" - label="Ascending" - layout="topleft" - left_pad="3" - name="ascending_check" - width="100" > - <check_box.commit_callback - function="CommitSearch" /> - </check_box> - <combo_box - follows="left|top" - layout="topleft" - height="23" - allow_text_entry="false" - left_delta="-102" - top_pad="1" - name="land_sort_combo" - width="118"> - <combo_box.item label="Name" name="Name_item" value="Name"/> - <combo_box.item label="Price" name="Price_item" value="Price"/> - <combo_box.item label="Price per meter" name="PPM_item" value="PPM"/> - <combo_box.item label="Area" name="Area_item" value="Area"/> - <combo_box.commit_callback - function="CommitSearch" /> - </combo_box> - <button - follows="top|right" - height="23" - label="Search" - layout="topleft" - left="678" - top_delta="0" - name="land_find" - width="100" /> - </panel> - <!-- Search Pane --> - <panel - border="true" - follows="all" - height="510" - layout="topleft" - left="1" - width="410" - top_pad="1" - name="panel_ls_scrolllist"> - <scroll_list - draw_heading="true" - follows="all" - height="485" - layout="topleft" - left="0" - name="search_results_land" - top="0" - width="410"> - <columns - label="" - name="icon" - width="20" /> - <columns - label="Name" - name="land_name" - relwidth="0.45" /> - <columns - label="Price" - name="price" - relwidth="0.1" /> - <columns - label="Area" - name="area" - relwidth="0.1" /> - <columns - label="L$/m" - name="ppm" - relwidth="0.1" /> - <columns - label="Type" - name="land_type" - relwidth="0.2" /> - </scroll_list> - <button - layout="topleft" - follows="left|bottom" - height="23" - label="Back" - name="land_back" - top_pad="2" - left="3" - width="100" /> - <button - layout="topleft" - follows="left|bottom" - height="23" - label="Next" - name="land_next" - width="100" - left_pad="1" /> - </panel> -</panel> diff --git a/indra/newview/skins/default/xui/en/panel_fs_search_legacy_people.xml b/indra/newview/skins/default/xui/en/panel_fs_search_legacy_people.xml deleted file mode 100644 index 28df02a7e3ced559795525a87414e0945231b539..0000000000000000000000000000000000000000 --- a/indra/newview/skins/default/xui/en/panel_fs_search_legacy_people.xml +++ /dev/null @@ -1,89 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel - border="false" - follows="all" - height="566" - layout="topleft" - left="1" - width="780" - label="People" - name="panel_ls_people"> - <panel - border="false" - follows="top|left|right" - height="53" - layout="topleft" - left="0" - width="780" - name="panel_ls_input"> - <text - type="string" - length="1" - follows="left|top" - top_pad="5" - layout="topleft" - left="6" - name="search_text" - top="12" - height="16" - width="156"> - Enter search terms: - </text> - <search_combo_box - layout="topleft" - follows="left|top|right" - height="23" - left_delta="0" - name="people_edit" - top="29" - width="770"> - </search_combo_box> - </panel> - <!-- Search Pane --> - <panel - border="true" - follows="all" - height="510" - layout="topleft" - left="1" - width="410" - top_pad="1" - name="panel_ls_scrolllist"> - <scroll_list - content_type="Agents" - draw_heading="true" - follows="all" - height="485" - layout="topleft" - left="0" - name="search_results_people" - top="0" - width="410"> - <columns - label="" - name="icon" - width="20" /> - <columns - label="Name" - name="username" - relwidth="1" /> - </scroll_list> - <button - layout="topleft" - follows="left|bottom" - height="23" - label="Back" - name="people_back" - top_pad="2" - left="3" - width="100" /> - <button - layout="topleft" - follows="left|bottom" - height="23" - label="Next" - name="people_next" - width="100" - left_pad="1" /> - </panel> -</panel> \ No newline at end of file diff --git a/indra/newview/skins/default/xui/en/panel_fs_search_legacy_places.xml b/indra/newview/skins/default/xui/en/panel_fs_search_legacy_places.xml deleted file mode 100644 index 09c142b8fc18688df44226384e6e7ae8a28a72ca..0000000000000000000000000000000000000000 --- a/indra/newview/skins/default/xui/en/panel_fs_search_legacy_places.xml +++ /dev/null @@ -1,169 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel - border="false" - follows="all" - height="566" - layout="topleft" - left="1" - width="780" - label="Places" - name="panel_ls_places"> - <panel - border="false" - follows="top|left|right" - height="53" - layout="topleft" - left="0" - width="780" - name="panel_ls_input"> - <text - type="string" - length="1" - follows="left|top" - top_pad="5" - layout="topleft" - left="6" - name="search_text" - top="12" - height="16" - width="156"> - Enter search terms: - </text> - <search_combo_box - layout="topleft" - follows="left|top|right" - height="23" - left_delta="0" - name="places_edit" - top="29" - width="651" /> - <combo_box - follows="right|top" - layout="topleft" - height="23" - allow_text_entry="false" - top_delta="0" - left_pad="2" - name="places_category" - width="122"> - <combo_box.commit_callback - function="CommitSearch" /> - </combo_box> - <check_box - control_name="ShowPGSims" - follows="right|top" - height="16" - label="" - layout="topleft" - left="660" - name="pg_all" - top="12" - width="15"> - <check_box.commit_callback - function="CommitSearch" /> - </check_box> - <icon - follows="right|top" - height="16" - image_name="Parcel_PG_Dark" - layout="topleft" - left_pad="2" - name="rating_icon_general" - top_delta="-1" - width="18"/> - <check_box - control_name="ShowMatureSims" - follows="right|top" - height="16" - label="" - layout="topleft" - left_pad="2" - name="mature_all" - top_delta="1" - width="15"> - <check_box.commit_callback - function="CommitSearch" /> - </check_box> - <icon - follows="right|top" - height="16" - image_name="Parcel_M_Dark" - layout="topleft" - left_pad="2" - name="rating_icon_moderate" - top_delta="-1" - width="18"/> - <check_box - control_name="ShowAdultSims" - follows="right|top" - height="16" - label="" - layout="topleft" - left_pad="2" - name="adult_all" - top_delta="1" - width="15"> - <check_box.commit_callback - function="CommitSearch" /> - </check_box> - <icon - follows="right|top" - height="16" - image_name="Parcel_R_Dark" - layout="topleft" - left_pad="2" - name="rating_icon_adult" - top_delta="-1" - width="18"/> - </panel> - <!-- Search Pane --> - <panel - border="true" - follows="all" - height="510" - layout="topleft" - left="1" - width="410" - top_pad="1" - name="panel_ls_scrolllist"> - <scroll_list - draw_heading="true" - follows="all" - height="485" - layout="topleft" - left="0" - name="search_results_places" - top="0" - width="410"> - <columns - label="" - name="icon" - width="20" /> - <columns - label="Name" - name="place_name" - relwidth="0.81" /> - <columns - label="Traffic" - name="dwell" - relwidth="0.16" /> - </scroll_list> - <button - layout="topleft" - follows="left|bottom" - height="23" - label="Back" - name="places_back" - top_pad="2" - left="3" - width="100" /> - <button - layout="topleft" - follows="left|bottom" - height="23" - label="Next" - name="places_next" - width="100" - left_pad="1" /> - </panel> -</panel> diff --git a/indra/newview/skins/default/xui/en/panel_fs_search_legacy_web.xml b/indra/newview/skins/default/xui/en/panel_fs_search_legacy_web.xml deleted file mode 100644 index 382a5e8945eafd325fbbb81c5225acdb8c52edc9..0000000000000000000000000000000000000000 --- a/indra/newview/skins/default/xui/en/panel_fs_search_legacy_web.xml +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel -border="false" -follows="all" -height="566" -layout="topleft" -left="1" -width="780" -label="Websearch" -name="panel_ls_web"> - <web_browser - top="5" - bottom="-1" - left="5" - right="-5" - layout="topleft" - follows="all" - name="search_browser" - trusted_content="true" - start_url="about:blank" /> -</panel> \ No newline at end of file diff --git a/indra/newview/skins/default/xui/en/panel_pick_info.xml b/indra/newview/skins/default/xui/en/panel_pick_info.xml new file mode 100644 index 0000000000000000000000000000000000000000..06ac5450355ecd17dfee5382f556351dfcd38590 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_pick_info.xml @@ -0,0 +1,190 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + background_visible="true" + follows="all" + height="570" + layout="topleft" + left="0" + min_height="350" + name="panel_pick_info" + help_topic="profile_pick_info" + top="0" + width="333"> + <button + follows="top|left" + height="24" + image_hover_unselected="BackButton_Over" + image_pressed="BackButton_Press" + image_unselected="BackButton_Off" + layout="topleft" + name="back_btn" + left="10" + tab_stop="false" + top="2" + width="30" + use_draw_context_alpha="false" /> + <text + follows="top|left|right" + font="SansSerifHugeBold" + height="26" + layout="topleft" + left_pad="4" + name="title" + text_color="LtGray" + top="2" + value="Pick Info" + use_ellipses="true" + width="275" /> + <scroll_container + color="PanelDefaultBackgroundColor" + opaque="true" + follows="all" + height="503" + layout="topleft" + left="8" + top_pad="10" + name="profile_scroll" + width="312"> + <panel + name="scroll_content_panel" + follows="left|top|right" + min_height="300" + layout="topleft" + top="0" + background_visible="false" + height="400" + left="0" + width="285"> + <texture_picker + fallback_image="default_land_picture.j2c" + enabled="false" + follows="left|top|right" + height="197" + layout="topleft" + left="11" + name="pick_snapshot" + top="10" + width="272" /> + <text_editor + allow_scroll="false" + bg_visible="false" + follows="left|top|right" + h_pad="0" + height="35" + width="280" + layout="topleft" + font="SansSerifBig" + font.style="BOLD" + left="10" + top_pad="10" + name="pick_name" + read_only="true" + text_color="white" + v_pad="0" + value="[name]" + use_ellipses="true" /> + <text_editor + allow_scroll="false" + bg_visible="false" + follows="left|top|right" + h_pad="0" + height="25" + layout="topleft" + left="10" + name="pick_location" + read_only="true" + width="280" + word_wrap="true" + v_pad="0" + value="[loading...]" /> + <text_editor + bg_readonly_color="DkGray2" + follows="all" + height="100" + width="280" + parse_urls="true" + layout="topleft" + left="10" + top_pad="2" + max_length="1023" + name="pick_desc" + read_only="true" + text_readonly_color="white" + value="[description]" + wrap="true" /> + </panel> + </scroll_container> + <panel + follows="left|right|bottom" + height="23" + layout="topleft" + top_pad="5" + left="8" + name="buttons"> + + <layout_stack + follows="bottom|left|right" + height="23" + layout="topleft" + name="layout_stack1" + left="0" + orientation="horizontal" + top_pad="0" + width="312"> + + <layout_panel + follows="bottom|left|right" + height="23" + layout="bottomleft" + left="0" + name="layout_panel1" + auto_resize="true" + width="101"> + <button + follows="bottom|left|right" + height="23" + label="Teleport" + layout="topleft" + name="teleport_btn" + top="0" + width="101" /> + </layout_panel> + + <layout_panel + follows="bottom|left|right" + height="23" + layout="bottomleft" + left_pad="3" + name="show_on_map_btn_lp" + auto_resize="true" + width="100"> + <button + follows="bottom|left|right" + height="23" + label="Map" + layout="topleft" + name="show_on_map_btn" + top_pad="0" + width="100" /> + </layout_panel> + + <layout_panel + follows="bottom|left|right" + height="23" + layout="bottomleft" + left_pad="3" + name="edit_btn_lp" + auto_resize="true" + width="101"> + <button + follows="bottom|left|right" + height="23" + label="Edit" + layout="topleft" + name="edit_btn" + top_pad="0" + width="101" /> + </layout_panel> + </layout_stack> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_profile_legacy_firstlife.xml b/indra/newview/skins/default/xui/en/panel_profile_legacy_firstlife.xml new file mode 100644 index 0000000000000000000000000000000000000000..8e32d3e70191945d8b61f5506f63186aa9ea727f --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_profile_legacy_firstlife.xml @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + label="First Life" + height="360" + width="304" + name="avatar_firstlife_tab"> + <panel + name="avatar_info_top" + follows="top|left|right" + top="0" + left="0" + height="129" + width="304" + layout="topleft"> + <texture_picker + default_image_name="Generic_Person_Large" + fallback_image="Generic_Person_Large" + follows="left|top" + height="143" + label="" + layout="topleft" + left="5" + name="fl_profile_pic" + no_commit_on_selection="true" + tool_tip="Click to choose a picture" + top="6" + width="120" /> + </panel> + <text_editor + type="string" + follows="all" + left="3" + height="200" + layout="topleft" + max_length="65000" + name="fl_about" + top="134" + right="-4" + bg_readonly_color="DkGray2" + text_readonly_color="White" + commit_on_focus_lost="true" + word_wrap="true" + show_emoji_helper="true" /> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_profile_legacy_group_list_item.xml b/indra/newview/skins/default/xui/en/panel_profile_legacy_group_list_item.xml new file mode 100644 index 0000000000000000000000000000000000000000..ed0b4a8825ed949560b73303ee90184e9eebd7c3 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_profile_legacy_group_list_item.xml @@ -0,0 +1,81 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + bevel_style="none" + follows="top|left|right" + height="85" + layout="topleft" + left="0" + name="panel_group_item" + top="0" + width="313"> + <icon + follows="all" + height="85" + image_name="ListItem_Over" + right="-2" + mouse_opaque="false" + name="hovered_icon" + top="1" + scale_image="true" + visible="false" + width="308"/> + <icon + follows="all" + height="85" + image_name="ListItem_Select" + right="-2" + mouse_opaque="false" + name="selected_icon" + top="1" + scale_image="true" + visible="false" + width="308"/> + <texture_picker + allow_no_texture="true" + fallback_image="Generic_Group_Large" + enabled="false" + follows="left|top" + height="80" + layout="topleft" + left="10" + mouse_opaque="false" + name="picture" + tab_stop="false" + top="10" + top_pad="10" + width="90" /> + <text + follows="top|left|right" + font="SansSerifSmall" + height="15" + layout="topleft" + left="110" + name="name" + text_color="white" + top="9" + use_ellipses="true" + width="193" + word_wrap="false" /> + <expandable_text + follows="top|left|right" + font="SansSerifSmall" + height="55" + layout="topleft" + left="103" + name="description" + textbox.max_length="1024" + textbox.show_context_menu="false" + textbox.word_wrap="true" + top_pad="0" + width="178" /> + <button + follows="right" + height="20" + image_overlay="ForwardArrow_Off" + layout="topleft" + left_pad="5" + right="-8" + name="info_chevron" + top_delta="24" + width="20" /> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_profile_legacy_groups.xml b/indra/newview/skins/default/xui/en/panel_profile_legacy_groups.xml new file mode 100644 index 0000000000000000000000000000000000000000..b09eaa02455a50b3f59ce5087bfb0b54ff63c22e --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_profile_legacy_groups.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + bg_opaque_color="PanelDefaultBackgroundColor" + background_visible="true" + background_opaque="true" + follows="all" + height="360" + label="Groups" + layout="topleft" + left="0" + name="panel_profile_groups" + top_pad="0" + width="304"> + <text + type="string" + follows="all" + height="35" + layout="topleft" + left="6" + right="-6" + name="groups_panel_text" + wrap="true" + top="10"> + No Groups + </text> + <flat_list_view + color="PanelDefaultBackgroundColor" + follows="all" + layout="topleft" + left="0" + right="-1" + name="groups_detail_list" + opaque="true" + top="0" + height="360" /> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_profile_legacy_interests.xml b/indra/newview/skins/default/xui/en/panel_profile_legacy_interests.xml new file mode 100644 index 0000000000000000000000000000000000000000..a99e004b599838c74ea628b56ef6f4782972eebe --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_profile_legacy_interests.xml @@ -0,0 +1,254 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + label="Interests" + height="360" + width="304" + name="avatar_interests_tab"> + <text + font="SansSerifSmall" + text_color="White_50" + width="190" + follows="top|left|right" + layout="topleft" + mouse_opaque="false" + type="string" + height="16" + length="1" + left="3" + name="i_want_label" + top="2"> + I want to: + </text> + <check_box + height="16" + initial_value="false" + label="Build" + layout="topleft" + top_pad="4" + left="25" + name="wanna_build" + width="140"> + <check_box.commit_callback + function="Profile.CommitInterest" /> + </check_box> + <check_box + height="16" + initial_value="false" + label="Explore" + layout="topleft" + top_delta="0" + left_pad="4" + name="wanna_explore" + width="140"> + <check_box.commit_callback + function="Profile.CommitInterest" /> + </check_box> + <check_box + height="16" + initial_value="false" + label="Meet" + layout="topleft" + top_pad="4" + left="25" + name="wanna_yiff" + width="140"> + <check_box.commit_callback + function="Profile.CommitInterest" /> + </check_box> + <check_box + height="16" + initial_value="false" + label="Be Hired" + layout="topleft" + top_delta="0" + left_pad="4" + name="wanna_work" + width="140"> + <check_box.commit_callback + function="Profile.CommitInterest" /> + </check_box> + <check_box + height="16" + initial_value="false" + label="Group" + layout="topleft" + top_pad="4" + left="25" + name="wanna_group" + width="140"> + <check_box.commit_callback + function="Profile.CommitInterest" /> + </check_box> + <check_box + height="16" + initial_value="false" + label="Buy" + layout="topleft" + top_delta="0" + left_pad="4" + name="wanna_buy" + width="140"> + <check_box.commit_callback + function="Profile.CommitInterest" /> + </check_box> + <check_box + height="16" + initial_value="false" + label="Sell" + layout="topleft" + top_pad="4" + left="25" + name="wanna_sell" + width="140"> + <check_box.commit_callback + function="Profile.CommitInterest" /> + </check_box> + <check_box + height="16" + initial_value="false" + label="Hire" + layout="topleft" + top_delta="0" + left_pad="4" + name="wanna_hire" + width="140"> + <check_box.commit_callback + function="Profile.CommitInterest" /> + </check_box> + <line_editor + top_pad="4" + follows="left|top|right" + height="20" + left="25" + text_pad_left="5" + name="wanna_something" + right="-40"> + <line_editor.commit_callback + function="Profile.CommitInterest" /> + </line_editor> + + <text + font="SansSerifSmall" + text_color="White_50" + width="190" + follows="top|left|right" + layout="topleft" + mouse_opaque="false" + type="string" + height="16" + length="1" + left="3" + name="skills_label" + top_pad="8"> + Skills: + </text> + <check_box + height="16" + initial_value="false" + label="Textures" + layout="topleft" + top_pad="4" + left="25" + name="can_texture" + width="140"> + <check_box.commit_callback + function="Profile.CommitInterest" /> + </check_box> + <check_box + height="16" + initial_value="false" + label="Architecture" + layout="topleft" + top_delta="0" + left_pad="4" + name="can_architect" + width="140"> + <check_box.commit_callback + function="Profile.CommitInterest" /> + </check_box> + <check_box + height="16" + initial_value="false" + label="Modeling" + layout="topleft" + top_pad="4" + left="25" + name="can_model" + width="140"> + <check_box.commit_callback + function="Profile.CommitInterest" /> + </check_box> + <check_box + height="16" + initial_value="false" + label="Event Planning" + layout="topleft" + top_delta="0" + left_pad="4" + name="can_event" + width="140"> + <check_box.commit_callback + function="Profile.CommitInterest" /> + </check_box> + <check_box + height="16" + initial_value="false" + label="Scripting" + layout="topleft" + top_pad="4" + left="25" + name="can_script" + width="140"> + <check_box.commit_callback + function="Profile.CommitInterest" /> + </check_box> + <check_box + height="16" + initial_value="false" + label="Custom Characters" + layout="topleft" + top_delta="0" + left_pad="4" + name="can_characters" + width="140"> + <check_box.commit_callback + function="Profile.CommitInterest" /> + </check_box> + <line_editor + top_pad="4" + follows="left|top|right" + height="20" + left="25" + text_pad_left="5" + name="can_something" + right="-40"> + <line_editor.commit_callback + function="Profile.CommitInterest" /> + </line_editor> + <text + top_pad="8" + font="SansSerifSmall" + text_color="White_50" + width="190" + follows="top|left|right" + layout="topleft" + mouse_opaque="false" + type="string" + height="16" + length="1" + left="3" + name="language_label" > + Languages: + </text> + <line_editor + top_pad="4" + follows="left|top|right" + height="20" + left="25" + text_pad_left="5" + name="languages" + right="-40"> + <line_editor.commit_callback + function="Profile.CommitInterest" /> + </line_editor> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_profile_legacy_notes.xml b/indra/newview/skins/default/xui/en/panel_profile_legacy_notes.xml new file mode 100644 index 0000000000000000000000000000000000000000..295e001f138c3bb28006b30422e2f745694aaaa8 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_profile_legacy_notes.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + label="Notes" + height="360" + width="304" + name="avatar_notes_tab"> + <text + font="SansSerifSmall" + text_color="White_50" + width="190" + follows="top|left|right" + layout="topleft" + mouse_opaque="false" + type="string" + height="16" + length="1" + left="3" + name="notes_label" + top="2"> + Private notes: + </text> + <text_editor + type="string" + follows="all" + left="3" + height="320" + layout="topleft" + max_length="65530" + name="notes" + top_pad="4" + right="-4" + bg_readonly_color="DkGray2" + text_readonly_color="White" + commit_on_focus_lost="true" + word_wrap="true" + show_emoji_helper="true" /> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_profile_legacy_picks.xml b/indra/newview/skins/default/xui/en/panel_profile_legacy_picks.xml new file mode 100644 index 0000000000000000000000000000000000000000..3cd7d825d781e3e66f4581e4939d8ab878c56131 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_profile_legacy_picks.xml @@ -0,0 +1,150 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + bg_opaque_color="PanelDefaultBackgroundColor" + background_visible="true" + background_opaque="true" + follows="all" + height="360" + label="Picks" + layout="topleft" + left="0" + name="panel_profile_picks" + top="0" + width="304"> + <text + type="string" + follows="all" + height="35" + layout="topleft" + left="6" + right="-6" + name="picks_panel_text" + wrap="true" + top="10"> + No Picks + </text> + <accordion + fit_parent="true" + follows="all" + height="332" + layout="topleft" + left="0" + right="-1" + name="accordion" + top="0" + single_expansion="true"> + <accordion_tab + layout="topleft" + height="101" + min_height="150" + name="tab_picks" + title="Picks" + visible="true"> + <flat_list_view + color="PanelDefaultBackgroundColor" + follows="all" + layout="topleft" + left="0" + name="picks_list" + opaque="true" + top="0" + width="313" /> + </accordion_tab> + <accordion_tab + layout="topleft" + height="101" + name="tab_classifieds" + title="Classifieds" + visible="true"> + <flat_list_view + color="PanelDefaultBackgroundColor" + follows="all" + layout="topleft" + left="0" + name="classifieds_list" + opaque="true" + top="0" + width="313" /> + </accordion_tab> + </accordion> + <panel + bg_opaque_color="PanelDefaultBackgroundColor" + background_visible="true" + background_opaque="true" + follows="bottom|left|right" + layout="topleft" + left="0" + height="30" + name="buttons_cucks" + top_pad="0" + width="304"> + <layout_stack + follows="bottom|left|right" + height="28" + layout="topleft" + left="2" + name="buttons_cucks_ls" + orientation="horizontal" + top="0" + width="304"> + <layout_panel + follows="bottom|left|right" + height="28" + layout="topleft" + left="0" + name="info_btn_lp" + auto_resize="true" + top="0" + width="95"> + <button + enabled="false" + follows="top|left|right" + height="23" + label="Info" + layout="topleft" + name="info_btn" + tab_stop="false" + tool_tip="Show pick information" + width="95" /> + </layout_panel> + <layout_panel + follows="bottom|left|right" + height="28" + layout="bottomleft" + left_pad="2" + name="teleport_btn_lp" + auto_resize="true" + width="117"> + <button + enabled="false" + follows="top|left|right" + height="23" + label="Teleport" + layout="topleft" + name="teleport_btn" + tab_stop="false" + tool_tip="Teleport to the corresponding area" + width="117" /> + </layout_panel> + <layout_panel + follows="bottom|left|right" + height="28" + layout="bottomleft" + name="show_on_map_btn_lp" + auto_resize="true" + left_pad="2" + width="90"> + <button + enabled="false" + follows="top|left|right" + height="23" + label="Map" + layout="topleft" + name="show_on_map_btn" + tab_stop="false" + tool_tip="Show the corresponding area on the World Map" + width="88" /> + </layout_panel> + </layout_stack> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_profile_legacy_secondlife.xml b/indra/newview/skins/default/xui/en/panel_profile_legacy_secondlife.xml new file mode 100644 index 0000000000000000000000000000000000000000..13560cd0f10c755a59075e040c7d2c6ab7318f48 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_profile_legacy_secondlife.xml @@ -0,0 +1,308 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + follows="all" + label="Second Life" + height="360" + width="304" + class="panel_avatar_secondlife" + name="avatar_secondlife_tab"> + <layout_stack + follows="all" + animate="false" + top="0" + height="360" + left="0" + width="304" + layout="topleft" + orientation="vertical" + show_drag_handle="false"> + <layout_panel + name="avatar_info_top" + follows="top|left|right" + top="0" + left="0" + height="125" + right="-1" + auto_resize="false" + layout="topleft"> + <texture_picker + default_image_name="Generic_Person_Large" + fallback_image="Generic_Person_Large" + follows="left|top" + height="143" + label="" + layout="topleft" + left="5" + name="sl_profile_pic" + no_commit_on_selection="true" + tool_tip="Click to choose a picture" + top="0" + width="120" /> + <text + font="SansSerifSmall" + text_color="White_50" + width="87" + follows="top|left" + layout="topleft" + mouse_opaque="false" + type="string" + height="16" + length="1" + left="129" + name="rezday_label" + top_delta="0"> + Born: + </text> + <icon + height="16" + width="16" + visible="false" + image_name="Cake" + tool_tip="Happy rezday" + mouse_opaque="true" + name="cake" + left_pad="2" /> + <text + font="SansSerifSmall" + text_color="ProfileOnlineIndicatorColor" + width="57" + follows="right|top" + layout="topleft" + mouse_opaque="false" + type="string" + height="16" + length="1" + right="-15" + name="online" + top_delta="0" > + Online + </text> + <icon + follows="right|top" + height="14" + visible="false" + image_name="AccountLevel_Internal" + layout="topleft" + right="-1" + top_delta="0" + mouse_opaque="false" + name="account_type_internal" + width="14" /> + <icon + follows="right|top" + height="14" + visible="false" + image_name="AccountLevel_Premium" + layout="topleft" + right="-1" + top_delta="0" + mouse_opaque="false" + name="account_type_premium" + width="14" /> + <icon + follows="right|top" + height="14" + visible="false" + image_name="AccountLevel_Plus" + layout="topleft" + right="-1" + top_delta="0" + mouse_opaque="false" + name="account_type_plus" + width="14" /> + <text + font="SansSerifSmall" + text_color="White_50" + width="175" + follows="top|left|right" + layout="topleft" + mouse_opaque="false" + type="string" + height="16" + length="1" + left="129" + name="rezday" + top_pad="0" > + (Unknown) + </text> + <text + font="SansSerifSmall" + text_color="White_50" + width="175" + follows="top|left|right" + layout="topleft" + mouse_opaque="false" + type="string" + height="48" + length="1" + left_delta="0" + name="account_info" + top_pad="2" /> + <text + font="SansSerifSmall" + text_color="White_50" + width="175" + follows="top|left|right" + layout="topleft" + mouse_opaque="false" + type="string" + height="16" + length="1" + left_delta="0" + name="partner_label" + top_pad="2"> + Partner: + </text> + <text + font="SansSerifSmall" + text_color="White_50" + width="175" + follows="top|left|right" + layout="topleft" + mouse_opaque="false" + type="string" + height="16" + length="1" + left_delta="0" + name="partner_info" + top_pad="2"> + secondlife:///app/agent/00000000-0000-0000-0000-000000000000/inspect + </text> + </layout_panel> + <layout_panel + name="avatar_desc" + follows="top|left|right" + top_pad="1" + left="0" + height="125" + width="304" + auto_resize="true" + layout="topleft"> + <text_editor + type="string" + follows="all" + left="3" + layout="topleft" + max_length="65000" + name="sl_about" + top="0" + bottom="-20" + right="-4" + bg_readonly_color="DkGray2" + text_readonly_color="White" + commit_on_focus_lost="true" + word_wrap="true" + show_emoji_helper="true" /> + <text + font="SansSerifSmall" + text_color="White_50" + follows="bottom|left|right" + layout="topleft" + mouse_opaque="false" + type="string" + height="16" + length="1" + left="3" + right="-4" + name="www" + top_pad="2" /> + <line_editor + top_delta="-2" + follows="left|bottom|right" + layout="topleft" + height="20" + max_length_chars="254" + left="2" + right="-4" + text_pad_left="5" + tool_tip="Website link" + name="www_edit"> + <line_editor.commit_callback + function="Profile.CommitProperties" /> + </line_editor> + </layout_panel> + <layout_panel + visible="true" + name="avatar_perm" + follows="top|left|right" + top_pad="1" + left="0" + height="74" + width="304" + auto_resize="false" + layout="topleft"> + <text + font="SansSerifSmall" + text_color="White_50" + width="190" + follows="top|left" + layout="topleft" + mouse_opaque="false" + type="string" + height="16" + length="1" + left="3" + name="permissions_label" + top_pad="2"> + Allow this avatar to: + </text> + <check_box + height="16" + initial_value="false" + label="See when I am online" + layout="topleft" + top_pad="4" + left="5" + name="allow_show_online" + width="150"> + <check_box.commit_callback + function="Profile.CommitRights" /> + </check_box> + <check_box + height="16" + initial_value="false" + label="Find me on the world map" + layout="topleft" + top_pad="2" + name="allow_mapping" + width="150"> + <check_box.commit_callback + function="Profile.CommitRights" /> + </check_box> + <check_box + height="16" + initial_value="false" + label="Edit, delete, or take my objects" + layout="topleft" + top_pad="2" + name="allow_object_perms" + width="150"> + <check_box.commit_callback + function="Profile.CommitModifyObjectRights" /> + </check_box> + </layout_panel> + <layout_panel + visible="false" + name="avatar_in_search" + follows="top|left|right" + top_pad="1" + left="0" + height="18" + width="304" + auto_resize="false" + layout="topleft"> + <check_box + height="16" + initial_value="true" + label="Show in search" + layout="topleft" + top_pad="0" + left="5" + name="allow_publish" + width="150"> + <check_box.commit_callback + function="Profile.CommitProperties" /> + </check_box> + </layout_panel> + </layout_stack> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_profile_legacy_sidetray.xml b/indra/newview/skins/default/xui/en/panel_profile_legacy_sidetray.xml new file mode 100644 index 0000000000000000000000000000000000000000..8d4a3a2e504acf80ff2ace8a320d6f6e3e3db52f --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_profile_legacy_sidetray.xml @@ -0,0 +1,311 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + bg_opaque_color="PanelDefaultBackgroundColor" + background_opaque="true" + background_visible="true" + follows="all" + height="570" + label="Profile" + layout="topleft" + min_height="350" + left="0" + top="20" + name="Avatar Profile" + width="313"> + <panel.string + name="account_info_fmt"> +[ACCOUNT_TYPE] +[PAYMENT_INFO] +[AGE_VERIFIED] + </panel.string> + <panel.string + name="age_verified"> +Age Verified + </panel.string> + <panel.string + name="rezday_fmt"> +[REZDAY] ([AGE]) + </panel.string> + <panel.string + name="add_friend"> +Add Friend + </panel.string> + <panel.string + name="remove_friend"> +Remove Friend + </panel.string> + <panel + name="avatar_info_top" + bg_opaque_color="PanelDefaultBackgroundColor" + background_visible="true" + background_opaque="true" + follows="top|left|right" + top="0" + left="0" + height="29" + width="313" + layout="topleft"> + <button + follows="top|left" + height="24" + image_hover_unselected="BackButton_Over" + image_pressed="BackButton_Press" + image_unselected="BackButton_Off" + layout="topleft" + name="back" + left="7" + tab_stop="false" + top="2" + width="30" + use_draw_context_alpha="false" /> + <text_editor + allow_scroll="false" + bg_visible="false" + read_only="true" + layout="topleft" + name="avatar_name" + v_pad="0" + value="(Loading...)" + font="SansSerifHugeBold" + h_pad="0" + height="26" + left_pad="8" + text_color="LtGray" + top="1" + use_ellipses="true" + width="268" + follows="top|left|right" + word_wrap="false" + mouse_opaque="false"/> + <loading_indicator + height="25" + follows="top|right" + layout="topleft" + left_pad="-32" + name="progress_indicator" + top_delta="1" + width="25" /> + </panel> + <layout_stack + name="layout" + orientation="vertical" + follows="all" + left="6" + top_pad="0" + height="506" + width="302" + border_size="0"> + <layout_panel + bg_opaque_color="PanelDefaultBackgroundColor" + background_visible="true" + background_opaque="true" + name="avatar_accordions" + follows="all" + layout="topleft" + auto_resize="true" + user_resize="true" + height="513" + width="313"> + <accordion + left="0" + top="0" + single_expansion="true" + fit_parent="true" + follows="all" + layout="topleft" + name="avatar_accordion" + height="513" + width="313"> + <accordion_tab + expanded="true" + layout="topleft" + name="avatar_secondlife_tab" + title="Second Life" + fit_panel="true"> + <panel + border="false" + filename="panel_profile_legacy_secondlife.xml" + layout="topleft" + left="0" + follows="all" + name="avatar_secondlife_tab_panel" + top="0" /> + </accordion_tab> + <accordion_tab + expanded="false" + layout="topleft" + name="avatar_groups_tab" + title="Groups" + fit_panel="true"> + <panel + border="false" + class="panel_profile_legacy_groups" + filename="panel_profile_legacy_groups.xml" + follows="all" + layout="topleft" + left="0" + name="avatar_groups_tab_panel" + top="0" /> + </accordion_tab> + <accordion_tab + expanded="false" + layout="topleft" + name="avatar_picks_tab" + title="Picks" + fit_panel="true"> + <panel + border="false" + class="panel_profile_legacy_picks" + filename="panel_profile_legacy_picks.xml" + follows="all" + layout="topleft" + left="0" + name="avatar_picks_tab_panel" + top="0" /> + </accordion_tab> + <accordion_tab + expanded="false" + layout="topleft" + name="avatar_firstlife_tab" + title="First Life" + fit_panel="true"> + <panel + border="false" + filename="panel_profile_legacy_firstlife.xml" + follows="left|top|right" + layout="topleft" + left="0" + name="avatar_firstlife_tab_panel" + top="0" /> + </accordion_tab> + <accordion_tab + expanded="false" + layout="topleft" + name="avatar_notes_tab" + title="Notes" + fit_panel="true"> + <panel + border="false" + filename="panel_profile_legacy_notes.xml" + follows="all" + layout="topleft" + left="0" + name="avatar_notes_tab_panel" + top="0" /> + </accordion_tab> + </accordion> + </layout_panel> + </layout_stack> + + <layout_stack + follows="bottom|left|right" + height="25" + layout="topleft" + name="button_row_ls" + left="6" + orientation="horizontal" + top_pad="5" + width="299"> + <layout_panel + follows="bottom|left|right" + height="23" + layout="bottomleft" + left="0" + name="btn_chat_lp" + auto_resize="true" + width="91"> + <button + follows="bottom|left|right" + left="1" + height="23" + name="btn_chat" + label="Chat" + layout="topleft" + tool_tip="Send an instant message" + top="0" + width="90"> + <button.commit_callback + function="Profile.Action" + parameter="chat" /> + </button> + </layout_panel> + <layout_panel + follows="bottom|left|right" + height="23" + layout="bottomleft" + left_pad="3" + name="btn_friend_lp" + auto_resize="true" + width="91"> + <button + follows="bottom|left|right" + left="1" + height="23" + name="btn_friend" + label="Add Friend" + layout="topleft" + top="0" + width="90"> + <button.commit_callback + function="Profile.Action" + parameter="friend" /> + </button> + </layout_panel> + <layout_panel + follows="bottom|left|right" + height="23" + layout="bottomleft" + left_pad="3" + name="btn_block_lp" + auto_resize="true" + width="91"> + <button + follows="bottom|left|right" + left="1" + height="23" + name="btn_block" + label="Block" + layout="topleft" + tool_tip="Block this avatar" + top="0" + width="90"> + <button.commit_callback + function="Profile.Action" + parameter="block" /> + </button> + </layout_panel> + <layout_panel + follows="bottom|left|right" + height="23" + layout="bottomleft" + left_pad="3" + name="btn_menu_lp" + auto_resize="false" + width="30"> + <menu_button + follows="bottom|left|right" + height="23" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="OptionsMenu_Off" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + menu_filename="menu_profile_legacy.xml" + menu_position="bottomleft" + tool_tip="Actions on this avatar" + layout="topleft" + left="1" + top="0" + name="btn_menu" + width="30" /> + </layout_panel> + </layout_stack> + <drop_target + top="0" + bottom="-1" + left="0" + right="-1" + layout="topleft" + follows="all" + name="drop_target" + mouse_opaque="false" /> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_search_classifieds.xml b/indra/newview/skins/default/xui/en/panel_search_classifieds.xml new file mode 100644 index 0000000000000000000000000000000000000000..a865121b618f1e72219ca92d89f24058d41cd9cd --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_search_classifieds.xml @@ -0,0 +1,113 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + height="70" + layout="topleft" + name="panel_search_classifieds" + width="602" + default_tab_group="2"> + <text + follows="left|top|right" + height="16" + layout="topleft" + left="4" + name="search_title" + top="4" + value="Enter search terms:" + width="255" /> + <check_box + control_name="ShowPGClassifieds" + follows="right|top" + height="16" + label="" + layout="topleft" + left="489" + name="pg_all" + top="4" + width="15"> + <check_box.commit_callback + function="Search.query" /> + </check_box> + <icon + follows="right|top" + height="16" + image_name="Parcel_PG_Dark" + layout="topleft" + left_pad="2" + name="rating_icon_general" + top_delta="-1" + width="18"/> + <check_box + control_name="ShowMatureClassifieds" + follows="right|top" + height="16" + label="" + layout="topleft" + left_pad="2" + name="mature_all" + top_delta="1" + width="15"> + <check_box.commit_callback + function="Search.query" /> + </check_box> + <icon + follows="right|top" + height="16" + image_name="Parcel_M_Dark" + layout="topleft" + left_pad="2" + name="rating_icon_moderate" + top_delta="-1" + width="18"/> + <check_box + control_name="ShowAdultClassifieds" + follows="right|top" + height="16" + label="" + layout="topleft" + left_pad="2" + name="adult_all" + top_delta="1" + width="15"> + <check_box.commit_callback + function="Search.query" /> + </check_box> + <icon + follows="right|top" + height="16" + image_name="Parcel_R_Dark" + layout="topleft" + left_pad="2" + name="rating_icon_adult" + top_delta="-1" + width="18"/> + <search_editor + tab_group="2" + follows="top|left|right" + search_button_visible="true" + height="22" + text_readonly_color="DkGray" + label="Search" + layout="topleft" + top_pad="1" + left="4" + right="-128" + name="search_bar" + select_on_focus="true" + commit_on_focus_lost="false" + tool_tip="Enter search terms"> + <search_editor.commit_callback + function="Search.query" /> + </search_editor> + <combo_box + follows="right|top" + layout="topleft" + height="23" + allow_text_entry="false" + top_delta="0" + left_pad="2" + name="classifieds_category" + width="122"> + <combo_box.commit_callback + function="Search.query" /> + </combo_box> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_search_events.xml b/indra/newview/skins/default/xui/en/panel_search_events.xml new file mode 100644 index 0000000000000000000000000000000000000000..407eaf6486a0fc4d24a03b249002f89c7274f1fe --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_search_events.xml @@ -0,0 +1,198 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + height="70" + layout="topleft" + name="panel_search_events" + width="602" + default_tab_group="2"> + <text + follows="left|top" + height="16" + layout="topleft" + left="4" + name="search_title" + top="4" + value="Enter search terms:" + width="128" /> + <radio_group + top_delta="0" + left="130" + height="16" + width="230" + layout="topleft" + initial_value="current" + name="events_search_mode"> + <radio_item + height="16" + label="Ongoing and Upcoming" + layout="topleft" + name="current" + value="current" + top_pad="0" + width="120" /> + <radio_item + height="16" + label="By Date" + layout="topleft" + name="date" + value="date" + left_pad="40" + width="120" /> + <radio_group.commit_callback + function="Search.query" /> + </radio_group> + <button + follows="top|left" + height="16" + width="16" + image_unselected="MinusItem_Off" + image_disabled="MinusItem_Disabled" + image_selected="MinusItem_Press" + image_pressed="MinusItem_Press" + image_top_pad="0" + layout="topleft" + left_pad="14" + name="minus_day" + top_delta="0"> + <button.commit_callback + function="Search.MinusDay" /> + </button> + <text + type="string" + length="1" + follows="left|top" + top_delta="0" + layout="topleft" + left_pad="5" + name="events_date" + font.style="BOLD" + height="16" + width="40" + value="4/20" /> + <button + follows="top|left" + height="16" + width="16" + image_unselected="AddItem_Off" + image_disabled="AddItem_Disabled" + image_selected="AddItem_Press" + image_pressed="AddItem_Press" + image_top_pad="0" + layout="topleft" + left_pad="5" + name="plus_day" + top_delta="0"> + <button.commit_callback + function="Search.AddDay" /> + </button> + <check_box + control_name="ShowPGEvents" + follows="right|top" + height="16" + label="" + layout="topleft" + left="489" + name="pg_all" + top="4" + width="15"> + <check_box.commit_callback + function="Search.query" /> + </check_box> + <icon + follows="right|top" + height="16" + image_name="Parcel_PG_Dark" + layout="topleft" + left_pad="2" + name="rating_icon_general" + top_delta="-1" + width="18"/> + <check_box + control_name="ShowMatureEvents" + follows="right|top" + height="16" + label="" + layout="topleft" + left_pad="2" + name="mature_all" + top_delta="1" + width="15"> + <check_box.commit_callback + function="Search.query" /> + </check_box> + <icon + follows="right|top" + height="16" + image_name="Parcel_M_Dark" + layout="topleft" + left_pad="2" + name="rating_icon_moderate" + top_delta="-1" + width="18"/> + <check_box + control_name="ShowAdultEvents" + follows="right|top" + height="16" + label="" + layout="topleft" + left_pad="2" + name="adult_all" + top_delta="1" + width="15"> + <check_box.commit_callback + function="Search.query" /> + </check_box> + <icon + follows="right|top" + height="16" + image_name="Parcel_R_Dark" + layout="topleft" + left_pad="2" + name="rating_icon_adult" + top_delta="-1" + width="18"/> + <search_editor + tab_group="2" + follows="top|left|right" + search_button_visible="true" + height="22" + text_readonly_color="DkGray" + label="Search" + layout="topleft" + top_pad="1" + left="4" + right="-128" + name="search_bar" + select_on_focus="true" + commit_on_focus_lost="false" + tool_tip="Enter search terms"> + <search_editor.commit_callback + function="Search.query" /> + </search_editor> + <combo_box + follows="right|top" + layout="topleft" + height="23" + allow_text_entry="false" + top_delta="0" + left_pad="2" + name="events_category" + width="122"> + <combo_box.item label="Any Category" name="any" value="0" /> + <combo_box.item label="" value="filter_separator" enabled="false" /> + <combo_box.item label="Discussion" name="discussion" value="18" /> + <combo_box.item label="Sports" name="sports" value="19" /> + <combo_box.item label="Live Music" name="music" value="20" /> + <!-- <combo_box.item label="???" name="mystery_category" value="21" /> --> + <combo_box.item label="Commercial" name="commercial" value="22" /> + <combo_box.item label="Nightlife/Entertainment" name="nightlife" value="23" /> + <combo_box.item label="Games/Contests" name="games" value="24" /> + <combo_box.item label="Pageants" name="pageants" value="25" /> + <combo_box.item label="Education" name="education" value="26" /> + <combo_box.item label="Arts and Culture" name="arts" value="27" /> + <combo_box.item label="Charity/Support Groups" name="charity" value="28" /> + <combo_box.item label="Miscellaneous" name="misc" value="29" /> + <combo_box.commit_callback + function="Search.query" /> + </combo_box> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_search_groups.xml b/indra/newview/skins/default/xui/en/panel_search_groups.xml new file mode 100644 index 0000000000000000000000000000000000000000..78e531ca2fc354161acaa5df8039b58f59b9fb58 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_search_groups.xml @@ -0,0 +1,101 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + height="70" + layout="topleft" + name="panel_search_groups" + width="602" + default_tab_group="2"> + <text + follows="left|top|right" + height="16" + layout="topleft" + left="4" + name="search_title" + top="4" + value="Enter search terms:" + width="255" /> + <check_box + control_name="ShowPGGroups" + follows="right|top" + height="16" + label="" + layout="topleft" + left="489" + name="pg_all" + top="4" + width="15"> + <check_box.commit_callback + function="Search.query" /> + </check_box> + <icon + follows="right|top" + height="16" + image_name="Parcel_PG_Dark" + layout="topleft" + left_pad="2" + name="rating_icon_general" + top_delta="-1" + width="18"/> + <check_box + control_name="ShowMatureGroups" + follows="right|top" + height="16" + label="" + layout="topleft" + left_pad="2" + name="mature_all" + top_delta="1" + width="15"> + <check_box.commit_callback + function="Search.query" /> + </check_box> + <icon + follows="right|top" + height="16" + image_name="Parcel_M_Dark" + layout="topleft" + left_pad="2" + name="rating_icon_moderate" + top_delta="-1" + width="18"/> + <check_box + control_name="ShowAdultGroups" + follows="right|top" + height="16" + label="" + layout="topleft" + left_pad="2" + name="adult_all" + top_delta="1" + width="15"> + <check_box.commit_callback + function="Search.query" /> + </check_box> + <icon + follows="right|top" + height="16" + image_name="Parcel_R_Dark" + layout="topleft" + left_pad="2" + name="rating_icon_adult" + top_delta="-1" + width="18"/> + <search_editor + tab_group="2" + follows="top|left|right" + search_button_visible="true" + height="22" + text_readonly_color="DkGray" + label="Search" + layout="topleft" + top_pad="1" + left="4" + right="-4" + name="search_bar" + select_on_focus="true" + commit_on_focus_lost="false" + tool_tip="Enter search terms"> + <search_editor.commit_callback + function="Search.query" /> + </search_editor> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_search_landsales.xml b/indra/newview/skins/default/xui/en/panel_search_landsales.xml new file mode 100644 index 0000000000000000000000000000000000000000..982fcdefc9db9a7f7b13f0dcce8582965dc748ab --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_search_landsales.xml @@ -0,0 +1,181 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + height="70" + layout="topleft" + name="panel_search_landsales" + width="602"> + <text + follows="left|top|right" + height="16" + layout="topleft" + left="4" + name="search_title" + top="4" + value="Enter search terms:" + width="255" /> + <check_box + control_name="ShowPGLand" + follows="right|top" + height="16" + label="" + layout="topleft" + left="489" + name="pg_all" + top="4" + width="15"> + <check_box.commit_callback + function="Search.query" /> + </check_box> + <icon + follows="right|top" + height="16" + image_name="Parcel_PG_Dark" + layout="topleft" + left_pad="2" + name="rating_icon_general" + top_delta="-1" + width="18"/> + <check_box + control_name="ShowMatureLand" + follows="right|top" + height="16" + label="" + layout="topleft" + left_pad="2" + name="mature_all" + top_delta="1" + width="15"> + <check_box.commit_callback + function="Search.query" /> + </check_box> + <icon + follows="right|top" + height="16" + image_name="Parcel_M_Dark" + layout="topleft" + left_pad="2" + name="rating_icon_moderate" + top_delta="-1" + width="18"/> + <check_box + control_name="ShowAdultLand" + follows="right|top" + height="16" + label="" + layout="topleft" + left_pad="2" + name="adult_all" + top_delta="1" + width="15"> + <check_box.commit_callback + function="Search.query" /> + </check_box> + <icon + follows="right|top" + height="16" + image_name="Parcel_R_Dark" + layout="topleft" + left_pad="2" + name="rating_icon_adult" + top_delta="-1" + width="18"/> + <check_box + control_name="FindLandPrice" + follows="left|top" + height="16" + label="Price <" + layout="topleft" + left="4" + name="price_check" + top_pad="6" + width="40" > + <check_box.commit_callback + function="Search.query" /> + </check_box> + <line_editor + enabled_control="FindLandPrice" + commit_on_focus_lost="false" + follows="left|top" + height="16" + left_pad="20" + name="edit_price" + layout="topleft" + top_delta="-1" + width="40" > + <line_editor.commit_callback + function="Search.query" /> + </line_editor> + <check_box + control_name="FindLandArea" + follows="left|top" + height="16" + label="Area >" + layout="topleft" + left_pad="3" + name="area_check" + top_delta="1" + width="40" > + <check_box.commit_callback + function="Search.query" /> + </check_box> + <line_editor + enabled_control="FindLandArea" + commit_on_focus_lost="false" + follows="left|top" + layout="topleft" + height="16" + left_pad="18" + name="edit_area" + top_delta="-1" + width="40" > + <line_editor.commit_callback + function="Search.query" /> + </line_editor> + <combo_box + control_name="FindLandType" + follows="right|top" + layout="topleft" + height="22" + allow_text_entry="false" + left_pad="90" + top_delta="-1" + name="land_type" + width="110"> + <combo_box.item label="All Categories" name="All" value="All"/> + <combo_box.item label="Auction" name="Auction" value="Auction"/> + <combo_box.item label="Mainland Sales" name="Mainland" value="Mainland"/> + <combo_box.item label="Estate Sales" name="Estate" value="Estate"/> + <combo_box.commit_callback + function="Search.query" /> + </combo_box> + <combo_box + control_name="FindLandSort" + follows="right|top" + layout="topleft" + height="22" + allow_text_entry="false" + left_pad="2" + top_delta="0" + name="land_sort" + width="110"> + <combo_box.item label="Sort by Name" name="Name_item" value="Name"/> + <combo_box.item label="Sort by Price" name="Price_item" value="Price"/> + <combo_box.item label="Sort by Price per meter" name="PPM_item" value="PPM"/> + <combo_box.item label="Sort by Area" name="Area_item" value="Area"/> + <combo_box.commit_callback + function="Search.query" /> + </combo_box> + <check_box + control_name="FindLandSortAscending" + follows="right|top" + height="16" + label="Ascending" + layout="topleft" + left_pad="3" + name="ascending" + top_delta="5" + width="40" > + <check_box.commit_callback + function="Search.query" /> + </check_box> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_search_people.xml b/indra/newview/skins/default/xui/en/panel_search_people.xml new file mode 100644 index 0000000000000000000000000000000000000000..98387dbd9a2f18aada111dbf62fa904008499c05 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_search_people.xml @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + height="70" + class="panel_search_people" + name="panel_search_people" + width="602" + default_tab_group="2"> + <panel.string name="SeachFilteredOnShortWordsEmpty"> + Your search terms were too short so no search was performed. + </panel.string> + <text + follows="left|top|right" + height="16" + layout="topleft" + left="4" + name="search_title" + top="4" + value="Enter search terms:" + width="255" /> + <search_editor + tab_group="2" + follows="top|left|right" + search_button_visible="true" + height="22" + text_readonly_color="DkGray" + label="Search" + layout="topleft" + top_pad="1" + left="4" + right="-4" + name="search_bar" + select_on_focus="true" + commit_on_focus_lost="false" + tool_tip="Enter search terms"> + <search_editor.commit_callback + function="Search.query" /> + </search_editor> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_search_places.xml b/indra/newview/skins/default/xui/en/panel_search_places.xml new file mode 100644 index 0000000000000000000000000000000000000000..94ae80a1576933b64eeae4bd6547b57632c96921 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_search_places.xml @@ -0,0 +1,113 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + height="70" + layout="topleft" + name="panel_search_places" + width="602" + default_tab_group="2"> + <text + follows="left|top|right" + height="16" + layout="topleft" + left="4" + name="search_title" + top="4" + value="Enter search terms:" + width="255" /> + <check_box + control_name="ShowPGSims" + follows="right|top" + height="16" + label="" + layout="topleft" + left="489" + name="pg_all" + top="4" + width="15"> + <check_box.commit_callback + function="Search.query" /> + </check_box> + <icon + follows="right|top" + height="16" + image_name="Parcel_PG_Dark" + layout="topleft" + left_pad="2" + name="rating_icon_general" + top_delta="-1" + width="18"/> + <check_box + control_name="ShowMatureSims" + follows="right|top" + height="16" + label="" + layout="topleft" + left_pad="2" + name="mature_all" + top_delta="1" + width="15"> + <check_box.commit_callback + function="Search.query" /> + </check_box> + <icon + follows="right|top" + height="16" + image_name="Parcel_M_Dark" + layout="topleft" + left_pad="2" + name="rating_icon_moderate" + top_delta="-1" + width="18"/> + <check_box + control_name="ShowAdultSims" + follows="right|top" + height="16" + label="" + layout="topleft" + left_pad="2" + name="adult_all" + top_delta="1" + width="15"> + <check_box.commit_callback + function="Search.query" /> + </check_box> + <icon + follows="right|top" + height="16" + image_name="Parcel_R_Dark" + layout="topleft" + left_pad="2" + name="rating_icon_adult" + top_delta="-1" + width="18"/> + <search_editor + tab_group="2" + follows="top|left|right" + search_button_visible="true" + height="22" + text_readonly_color="DkGray" + label="Search" + layout="topleft" + top_pad="1" + left="4" + right="-128" + name="search_bar" + select_on_focus="true" + commit_on_focus_lost="false" + tool_tip="Enter search terms"> + <search_editor.commit_callback + function="Search.query" /> + </search_editor> + <combo_box + follows="right|top" + layout="topleft" + height="23" + allow_text_entry="false" + top_delta="0" + left_pad="2" + name="places_category" + width="122"> + <combo_box.commit_callback + function="Search.query" /> + </combo_box> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_search_web.xml b/indra/newview/skins/default/xui/en/panel_search_web.xml new file mode 100644 index 0000000000000000000000000000000000000000..81cb9067db204685ce625dbfae92b9b87c36d1b9 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_search_web.xml @@ -0,0 +1,138 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + height="775" + layout="topleft" + follows="all" + name="panel_search_web" + width="780" + default_tab_group="2"> + <layout_stack + bottom="775" + follows="all" + layout="topleft" + left="5" + animate="false" + name="stack1" + orientation="vertical" + top="4" + width="770"> + <layout_panel + height="40" + follows="all" + layout="topleft" + left_delta="0" + name="external_controls" + top_delta="0" + auto_resize="true" + width="585"> + <web_browser + tab_group="2" + bottom="-2" + follows="all" + layout="topleft" + left="0" + name="webbrowser" + top="0"/> + </layout_panel> + <layout_panel + name="status_bar" + height="23" + auto_resize="false"> + <button + image_overlay="Arrow_Left_Off" + image_disabled="PushButton_Disabled" + image_disabled_selected="PushButton_Disabled" + image_selected="PushButton_Selected" + image_unselected="PushButton_Off" + chrome="true" + hover_glow_amount="0.15" + tool_tip="Navigate back" + follows="left|top" + height="22" + layout="topleft" + left="1" + name="back" + top="0" + width="22"> + <button.commit_callback + function="WebContent.Back" /> + </button> + <button + image_overlay="Arrow_Right_Off" + image_disabled="PushButton_Disabled" + image_disabled_selected="PushButton_Disabled" + image_selected="PushButton_Selected" + image_unselected="PushButton_Off" + chrome="true" + tool_tip="Navigate forward" + follows="left|top" + height="22" + layout="topleft" + left="27" + name="forward" + top_delta="0" + width="22"> + <button.commit_callback + function="WebContent.Forward" /> + </button> + <button + image_overlay="Stop_Off" + image_disabled="PushButton_Disabled" + image_disabled_selected="PushButton_Disabled" + image_selected="PushButton_Selected" + image_unselected="PushButton_Off" + chrome="true" + tool_tip="Stop navigation" + enabled="true" + follows="left|top" + height="22" + layout="topleft" + left="51" + name="stop" + top_delta="0" + width="22"> + <button.commit_callback + function="WebContent.Stop" /> + </button> + <button + image_overlay="Refresh_Off" + image_disabled="PushButton_Disabled" + image_disabled_selected="PushButton_Disabled" + image_selected="PushButton_Selected" + image_unselected="PushButton_Off" + chrome="true" + tool_tip="Reload page" + follows="left|top" + height="22" + layout="topleft" + left="51" + name="reload" + top_delta="0" + width="22"> + <button.commit_callback + function="WebContent.Reload" /> + </button> + <text + type="string" + length="200" + follows="bottom|left" + height="20" + layout="topleft" + left_pad="3" + name="statusbartext" + parse_urls="false" + text_color="0.4 0.4 0.4 1" + top_delta="1" + width="441"/> + <progress_bar + color_bar="0.3 1.0 0.3 1" + follows="bottom|right" + height="16" + top_delta="1" + left_pad="3" + layout="topleft" + name="statusbarprogress" + width="64"/> + </layout_panel> + </layout_stack> +</panel> diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 1ac155b9e6fc1aeb9bf3f551aedf822b042f3234..6830a39a2aa9f423d2505d3da6323157b5134c49 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -2995,13 +2995,13 @@ Expected .wav, .tga, .bmp, .jpg, .jpeg, or .anim <string name="None">None</string> <string name="Linden Location">Linden Location</string> <string name="Adult">Adult</string> - <string name="Arts and Culture">Arts & Culture</string> + <string name="Arts&Culture">Arts & Culture</string> <string name="Business">Business</string> <string name="Educational">Educational</string> <string name="Gaming">Gaming</string> <string name="Hangout">Hangout</string> <string name="Newcomer Friendly">Newcomer Friendly</string> - <string name="Parks and Nature">Parks & Nature</string> + <string name="Parks&Nature">Parks & Nature</string> <string name="Residential">Residential</string> <!--<string name="Shopping">Shopping</string> --> <string name="Stage">Stage</string> @@ -4470,13 +4470,6 @@ and report the problem. <string name="outfit_photo_load_codec_error">Invalid image format. Please use another image</string> <!-- Alchemy Strings --> - <string name="not_found">'[TEXT]' not found</string> - <string name="no_results">No results</string> - <string name="searching">Searching...</string> - <string name="all_categories">All Categories</string> - <string name="search_banned">Some terms in your search query were excluded due to content restrictions as clarified in the Community Standards.</string> - <string name="search_short">Your search terms were too short so no search was performed.</string> - <string name="search_disabled">Legacy Search has been disabled in this region.</string> <string name="NotifyIncomingMessage">Incoming message from [NAME]...</string> <string name="NearbyChatTitleChannel">Nearby chat (on channel [CHANNEL])</string> <string name="AvatarTyping">Typing</string> diff --git a/indra/newview/skins/heretic/colors.xml b/indra/newview/skins/heretic/colors.xml index f97407cd628562e4a1b51bd195da644ac8157b60..19b8501e24888ff799b145df1dae0067da4482a6 100644 --- a/indra/newview/skins/heretic/colors.xml +++ b/indra/newview/skins/heretic/colors.xml @@ -1155,6 +1155,9 @@ <color name="StatBarMeanBarColor" reference="Red_80" /> + <color + name="ProfileOnlineIndicatorColor" + reference="Green" /> <color name="MusicTickerGridColor" reference="White_50"/>