From 69bd05651a2cb7dfb69959a52e00aa6dfa6258c5 Mon Sep 17 00:00:00 2001 From: Cinder Roxley <cinder@sdf.org> Date: Wed, 18 Dec 2024 14:47:00 -0600 Subject: [PATCH] Revert "Merge pull request #25 from AlchemyViewer/RyeMutt/issue17" like a boss. This reverts commit 20fb5ad099f84daa3903ce0bae9feb72d691f227, reversing changes made to 0dcc5ce285905e2a3c03c722016ba5c8f05582e1. --- indra/llmessage/llclassifiedflags.h | 1 + indra/newview/CMakeLists.txt | 41 +- indra/newview/alavataractions.cpp | 21 + indra/newview/alavataractions.h | 3 + indra/newview/fsfloatersearch.cpp | 3155 ----------------- indra/newview/fsfloatersearch.h | 404 --- indra/newview/llagenthandler.cpp | 188 + indra/newview/llavataractions.cpp | 161 +- indra/newview/llavataractions.h | 4 +- indra/newview/llclassifieditem.cpp | 119 + indra/newview/llclassifieditem.h | 83 + indra/newview/lleventnotifier.cpp | 62 +- indra/newview/lleventnotifier.h | 11 +- indra/newview/llfloaterdirectory.cpp | 1219 +++++++ indra/newview/llfloaterdirectory.h | 134 + indra/newview/llfloaterevent.cpp | 88 +- indra/newview/llfloaterevent.h | 29 +- indra/newview/llfloaterjoystick.cpp | 26 +- indra/newview/llfloaterjoystick.h | 2 +- indra/newview/llfloaterprofilelegacy.cpp | 81 + indra/newview/llfloaterprofilelegacy.h | 58 + indra/newview/llfloaterpublishclassified.cpp | 63 + indra/newview/llfloaterpublishclassified.h | 48 + indra/newview/llfloaterwebprofile.cpp | 81 + indra/newview/llfloaterwebprofile.h | 56 + indra/newview/llhudeffectresetskeleton.h | 32 +- indra/newview/llpanelavatarlegacy.cpp | 109 + indra/newview/llpanelavatarlegacy.h | 105 + indra/newview/llpanelclassified.cpp | 599 +++- indra/newview/llpanelclassified.h | 124 +- indra/newview/llpaneleventinfo.cpp | 158 + indra/newview/llpaneleventinfo.h | 59 + indra/newview/llpanellandmarks.cpp | 6 +- indra/newview/llpanelpick.cpp | 612 ++++ indra/newview/llpanelpick.h | 255 ++ indra/newview/llpanelplaceinfo.cpp | 6 +- indra/newview/llpanelprofile.cpp | 260 +- indra/newview/llpanelprofile.h | 1 + indra/newview/llpanelprofileclassifieds.cpp | 57 +- indra/newview/llpanelprofileclassifieds.h | 27 +- indra/newview/llpanelprofilelegacy.cpp | 1668 +++++++++ indra/newview/llpanelprofilelegacy.h | 230 ++ indra/newview/llpanelsearchbase.cpp | 44 + indra/newview/llpanelsearchbase.h | 55 + indra/newview/llpanelsearchclassifieds.cpp | 110 + indra/newview/llpanelsearchclassifieds.h | 53 + indra/newview/llpanelsearchevents.cpp | 135 + indra/newview/llpanelsearchevents.h | 56 + indra/newview/llpanelsearchgroups.cpp | 99 + indra/newview/llpanelsearchgroups.h | 51 + indra/newview/llpanelsearchlandsales.cpp | 118 + indra/newview/llpanelsearchlandsales.h | 47 + indra/newview/llpanelsearchpeople.cpp | 87 + indra/newview/llpanelsearchpeople.h | 51 + indra/newview/llpanelsearchplaces.cpp | 113 + indra/newview/llpanelsearchplaces.h | 53 + indra/newview/llpanelsearchweb.cpp | 281 ++ indra/newview/llpanelsearchweb.h | 70 + indra/newview/llpickitem.cpp | 155 + indra/newview/llpickitem.h | 85 + indra/newview/llprofileimagepicker.cpp | 233 ++ indra/newview/llprofileimagepicker.h | 53 + indra/newview/llsearchcombobox.h | 10 +- indra/newview/llstartup.cpp | 15 +- indra/newview/llviewerfloaterreg.cpp | 13 +- indra/newview/llviewerinput.cpp | 3 +- indra/newview/llviewermenu.cpp | 6 +- indra/newview/skins/alchemy/colors.xml | 3 + indra/newview/skins/alchemy/skin_settings.xml | 15 +- indra/newview/skins/default/colors.xml | 6 +- indra/newview/skins/default/skin_settings.xml | 15 +- .../default/textures/icon_legacy_event.tga | Bin 1068 -> 0 bytes .../textures/icon_legacy_event_adult.tga | Bin 648 -> 0 bytes .../textures/icon_legacy_event_mature.tga | Bin 1068 -> 0 bytes .../textures/icons/ProgressLarge_1.png | Bin 6163 -> 0 bytes .../textures/icons/ProgressLarge_10.png | Bin 6310 -> 0 bytes .../textures/icons/ProgressLarge_11.png | Bin 6169 -> 0 bytes .../textures/icons/ProgressLarge_12.png | Bin 6197 -> 0 bytes .../textures/icons/ProgressLarge_2.png | Bin 6227 -> 0 bytes .../textures/icons/ProgressLarge_3.png | Bin 6090 -> 0 bytes .../textures/icons/ProgressLarge_4.png | Bin 6295 -> 0 bytes .../textures/icons/ProgressLarge_5.png | Bin 6158 -> 0 bytes .../textures/icons/ProgressLarge_6.png | Bin 6220 -> 0 bytes .../textures/icons/ProgressLarge_7.png | Bin 6100 -> 0 bytes .../textures/icons/ProgressLarge_8.png | Bin 6223 -> 0 bytes .../textures/icons/ProgressLarge_9.png | Bin 6034 -> 0 bytes .../skins/default/textures/textures.xml | 17 - .../default/xui/en/floater_directory.xml | 291 ++ .../skins/default/xui/en/floater_event.xml | 42 +- .../default/xui/en/floater_fs_search.xml | 337 -- .../default/xui/en/floater_profile_legacy.xml | 27 + .../default/xui/en/menu_profile_legacy.xml | 135 + .../default/xui/en/panel_classified_info.xml | 37 +- .../skins/default/xui/en/panel_edit_pick.xml | 238 ++ .../skins/default/xui/en/panel_event_info.xml | 456 +++ .../en/panel_fs_search_legacy_classifieds.xml | 169 - .../xui/en/panel_fs_search_legacy_events.xml | 258 -- .../xui/en/panel_fs_search_legacy_groups.xml | 159 - .../xui/en/panel_fs_search_legacy_land.xml | 281 -- .../xui/en/panel_fs_search_legacy_people.xml | 89 - .../xui/en/panel_fs_search_legacy_places.xml | 169 - .../xui/en/panel_fs_search_legacy_web.xml | 21 - .../skins/default/xui/en/panel_pick_info.xml | 190 + .../xui/en/panel_profile_legacy_firstlife.xml | 44 + .../panel_profile_legacy_group_list_item.xml | 81 + .../xui/en/panel_profile_legacy_groups.xml | 36 + .../xui/en/panel_profile_legacy_interests.xml | 254 ++ .../xui/en/panel_profile_legacy_notes.xml | 37 + .../xui/en/panel_profile_legacy_picks.xml | 150 + .../en/panel_profile_legacy_secondlife.xml | 308 ++ .../xui/en/panel_profile_legacy_sidetray.xml | 311 ++ .../xui/en/panel_search_classifieds.xml | 113 + .../default/xui/en/panel_search_events.xml | 198 ++ .../default/xui/en/panel_search_groups.xml | 101 + .../default/xui/en/panel_search_landsales.xml | 181 + .../default/xui/en/panel_search_people.xml | 38 + .../default/xui/en/panel_search_places.xml | 113 + .../skins/default/xui/en/panel_search_web.xml | 138 + .../newview/skins/default/xui/en/strings.xml | 11 +- indra/newview/skins/heretic/colors.xml | 3 + 120 files changed, 11832 insertions(+), 5682 deletions(-) delete mode 100644 indra/newview/fsfloatersearch.cpp delete mode 100644 indra/newview/fsfloatersearch.h create mode 100644 indra/newview/llagenthandler.cpp create mode 100644 indra/newview/llclassifieditem.cpp create mode 100644 indra/newview/llclassifieditem.h create mode 100644 indra/newview/llfloaterdirectory.cpp create mode 100644 indra/newview/llfloaterdirectory.h create mode 100644 indra/newview/llfloaterprofilelegacy.cpp create mode 100644 indra/newview/llfloaterprofilelegacy.h create mode 100644 indra/newview/llfloaterpublishclassified.cpp create mode 100644 indra/newview/llfloaterpublishclassified.h create mode 100644 indra/newview/llfloaterwebprofile.cpp create mode 100644 indra/newview/llfloaterwebprofile.h create mode 100644 indra/newview/llpanelavatarlegacy.cpp create mode 100644 indra/newview/llpanelavatarlegacy.h create mode 100644 indra/newview/llpaneleventinfo.cpp create mode 100644 indra/newview/llpaneleventinfo.h create mode 100644 indra/newview/llpanelpick.cpp create mode 100644 indra/newview/llpanelpick.h create mode 100644 indra/newview/llpanelprofilelegacy.cpp create mode 100644 indra/newview/llpanelprofilelegacy.h create mode 100644 indra/newview/llpanelsearchbase.cpp create mode 100644 indra/newview/llpanelsearchbase.h create mode 100644 indra/newview/llpanelsearchclassifieds.cpp create mode 100644 indra/newview/llpanelsearchclassifieds.h create mode 100644 indra/newview/llpanelsearchevents.cpp create mode 100644 indra/newview/llpanelsearchevents.h create mode 100644 indra/newview/llpanelsearchgroups.cpp create mode 100644 indra/newview/llpanelsearchgroups.h create mode 100644 indra/newview/llpanelsearchlandsales.cpp create mode 100644 indra/newview/llpanelsearchlandsales.h create mode 100644 indra/newview/llpanelsearchpeople.cpp create mode 100644 indra/newview/llpanelsearchpeople.h create mode 100644 indra/newview/llpanelsearchplaces.cpp create mode 100644 indra/newview/llpanelsearchplaces.h create mode 100644 indra/newview/llpanelsearchweb.cpp create mode 100644 indra/newview/llpanelsearchweb.h create mode 100644 indra/newview/llpickitem.cpp create mode 100644 indra/newview/llpickitem.h create mode 100644 indra/newview/llprofileimagepicker.cpp create mode 100644 indra/newview/llprofileimagepicker.h delete mode 100644 indra/newview/skins/default/textures/icon_legacy_event.tga delete mode 100644 indra/newview/skins/default/textures/icon_legacy_event_adult.tga delete mode 100644 indra/newview/skins/default/textures/icon_legacy_event_mature.tga delete mode 100644 indra/newview/skins/default/textures/icons/ProgressLarge_1.png delete mode 100644 indra/newview/skins/default/textures/icons/ProgressLarge_10.png delete mode 100644 indra/newview/skins/default/textures/icons/ProgressLarge_11.png delete mode 100644 indra/newview/skins/default/textures/icons/ProgressLarge_12.png delete mode 100644 indra/newview/skins/default/textures/icons/ProgressLarge_2.png delete mode 100644 indra/newview/skins/default/textures/icons/ProgressLarge_3.png delete mode 100644 indra/newview/skins/default/textures/icons/ProgressLarge_4.png delete mode 100644 indra/newview/skins/default/textures/icons/ProgressLarge_5.png delete mode 100644 indra/newview/skins/default/textures/icons/ProgressLarge_6.png delete mode 100644 indra/newview/skins/default/textures/icons/ProgressLarge_7.png delete mode 100644 indra/newview/skins/default/textures/icons/ProgressLarge_8.png delete mode 100644 indra/newview/skins/default/textures/icons/ProgressLarge_9.png create mode 100644 indra/newview/skins/default/xui/en/floater_directory.xml delete mode 100644 indra/newview/skins/default/xui/en/floater_fs_search.xml create mode 100644 indra/newview/skins/default/xui/en/floater_profile_legacy.xml create mode 100644 indra/newview/skins/default/xui/en/menu_profile_legacy.xml create mode 100644 indra/newview/skins/default/xui/en/panel_edit_pick.xml create mode 100644 indra/newview/skins/default/xui/en/panel_event_info.xml delete mode 100644 indra/newview/skins/default/xui/en/panel_fs_search_legacy_classifieds.xml delete mode 100644 indra/newview/skins/default/xui/en/panel_fs_search_legacy_events.xml delete mode 100644 indra/newview/skins/default/xui/en/panel_fs_search_legacy_groups.xml delete mode 100644 indra/newview/skins/default/xui/en/panel_fs_search_legacy_land.xml delete mode 100644 indra/newview/skins/default/xui/en/panel_fs_search_legacy_people.xml delete mode 100644 indra/newview/skins/default/xui/en/panel_fs_search_legacy_places.xml delete mode 100644 indra/newview/skins/default/xui/en/panel_fs_search_legacy_web.xml create mode 100644 indra/newview/skins/default/xui/en/panel_pick_info.xml create mode 100644 indra/newview/skins/default/xui/en/panel_profile_legacy_firstlife.xml create mode 100644 indra/newview/skins/default/xui/en/panel_profile_legacy_group_list_item.xml create mode 100644 indra/newview/skins/default/xui/en/panel_profile_legacy_groups.xml create mode 100644 indra/newview/skins/default/xui/en/panel_profile_legacy_interests.xml create mode 100644 indra/newview/skins/default/xui/en/panel_profile_legacy_notes.xml create mode 100644 indra/newview/skins/default/xui/en/panel_profile_legacy_picks.xml create mode 100644 indra/newview/skins/default/xui/en/panel_profile_legacy_secondlife.xml create mode 100644 indra/newview/skins/default/xui/en/panel_profile_legacy_sidetray.xml create mode 100644 indra/newview/skins/default/xui/en/panel_search_classifieds.xml create mode 100644 indra/newview/skins/default/xui/en/panel_search_events.xml create mode 100644 indra/newview/skins/default/xui/en/panel_search_groups.xml create mode 100644 indra/newview/skins/default/xui/en/panel_search_landsales.xml create mode 100644 indra/newview/skins/default/xui/en/panel_search_people.xml create mode 100644 indra/newview/skins/default/xui/en/panel_search_places.xml create mode 100644 indra/newview/skins/default/xui/en/panel_search_web.xml diff --git a/indra/llmessage/llclassifiedflags.h b/indra/llmessage/llclassifiedflags.h index 9c6c268b397..dafd0ceb625 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 ce8b7dcf041..48a6c314a66 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 b9bdbc2b137..7668577325a 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 d6bb2f1792f..03dfe49e516 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 286bcdf2fe8..00000000000 --- 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 61cef8bab98..00000000000 --- 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 00000000000..688aa2b6aee --- /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 927618a0865..51e5dcd8d96 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 2493ec2b503..f69954bfe43 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 00000000000..0f0f6924e0b --- /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 00000000000..212a53ee0c6 --- /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 04aad5aa0f4..4bc481b21ec 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 f30039f51b0..14ced4908d8 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 00000000000..1df46a66fdb --- /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 00000000000..0817f223ab4 --- /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 b07f2963b27..92d762fa9cb 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 169ce246ecb..50eb86e07cb 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 c3bc8e2f2b3..03e587e38ee 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 ebc1a26190c..5aa0dbd0104 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 00000000000..78df15de899 --- /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 00000000000..59c9381fd86 --- /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 00000000000..b19cc8f97e2 --- /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 00000000000..f5d79656119 --- /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 00000000000..05ec0028548 --- /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 00000000000..df9ebc89285 --- /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 39a61370548..ddac84165f3 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 00000000000..c0a943b6757 --- /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 00000000000..ef442b16bc5 --- /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 11d12394592..b8b95fc711a 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 88346df6c33..e742328df25 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 00000000000..d9ffc02e42d --- /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 00000000000..3852dba91ed --- /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 f05f9270671..95bc7896f44 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 00000000000..113f9b0b9e4 --- /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 00000000000..21f2b7d7024 --- /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 3f12deb36ad..f1445ad4386 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 68fbfa3fb0a..f6d19dfe9bd 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 a2f0fbbfe1d..1f7435eaa82 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 23266a2279f..e2768ff8074 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 5f029b22f4a..e6aa761ff02 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 00000000000..de616798401 --- /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 00000000000..9c30519ab5c --- /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 00000000000..ba11c8a0096 --- /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 00000000000..3e54edce0ee --- /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 00000000000..4834c63adf1 --- /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 00000000000..64992be6bb9 --- /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 00000000000..425d5a157bc --- /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 00000000000..1f2af30622f --- /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 00000000000..b4fbea45d86 --- /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 00000000000..f3e80c6b171 --- /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 00000000000..a2def0f36a6 --- /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 00000000000..f0f27407719 --- /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 00000000000..69b2c3fc5c4 --- /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 00000000000..e55645f7f62 --- /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 00000000000..97b758dea42 --- /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 00000000000..42e69dd117d --- /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 00000000000..dfd9fedc3ef --- /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 00000000000..4877db8bf96 --- /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 00000000000..55e59d12551 --- /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 00000000000..0ddcbd4bf86 --- /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 00000000000..9930b6eea78 --- /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 00000000000..a67d0859b08 --- /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 891237e92ea..ff9c74a6a84 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 f4fe10b4b12..5650732f72f 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 a3d70aa4ffe..721717e68ad 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 74e8c101321..9639fb38ed4 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 adceae2d191..91c3df6f314 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 ac16fb8113a..fd72faa3f24 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 03ac8fb0eca..1f56287b50d 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 db03b869897..c93686df3d9 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 03ac8fb0eca..1f56287b50d 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 GIT binary patch literal 0 HcmV?d00001 literal 1068 zcmb7?&q~8U5XPtW(4M5=#iK9K-g*-cg$O~h(0_VtFVce`?LiS=$Oj9#^%ZtH-!|Wp zuA7Jp!zMG|@0;0dL@tDDAOpGSPws97VM{yG@xffYvkq-sL#~w42X&@_F8CHw_<9qs zKdSn!!KW)-MbH;Dcj+|6V;<ynYaXBHKHz-LYE5k5Urqa61$+>Ew^|#Ib7NNB*BG*v zLk$}AiX*VQs3&>MVYQS8X7YX4ruj(prUz=KftKe8>|2fdsy&mf=S)iv@c!O#cZ^NN z<GUl^fgJ0$ALQU?03V0f;VkTJ&+h7U@3A)ij^Q5BtK!{t^FNc~g9rHM_B(IoZ3fr- me{Xv7tb9-H<A?0mzeL?%JXo&9Y?-a{c|Ls_zTD@J*+`CFKhviG 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 GIT binary patch literal 0 HcmV?d00001 literal 648 zcmZ9JOG*Pl5Qb|e2E<j4;01K&N*6(hFc=hkA(BOKB_duRWYO)Iv&36@ld`_QXOfs+ z%vAl4s_JU9BkRw|Ms|Fd#+MgDJXL1?O{xgc#qLP_{jKN<fg^$Ki32zHpS9;@9g0C@ z_B(qi=~kO*7Nj{c4*%@Sh1Weo3+eQ!cf~E53fq5?y2GvDY(r}1id5G?p{^QIQ4)qi z+F`dF>HT#c^DQ)DQeni34v65mBNO7&s5J7=kB|kc>NQsB<1b{;JG(`eWoFh_wh%Qi zWSm1;soJ&cO)Y)5H&OHj)-sG%vU!kzJ6zAL7l5QDl+Zn@JaVB{luRfU+1dHENiIy0 YF#2#F?j9#k&3$uwbMk!EOed%I2Uv>&3jhEB 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 GIT binary patch literal 0 HcmV?d00001 literal 1068 zcmbW0Jqp4=5QW#+Smp>`KszffM2HZK3jQHtAyy*d1tj;;(i_?46l>nFZyA<If`MVO zGw*vdS<#rt@QF=qx}EW4WDw<JTP|1&GyBknJ=E;=B0(KBJhT6ke?9Hzc(CtzCebcE z5vb{?;xP+#=<>)&XofXp?iFV6=-Z<3JkIoFJ>+-}d7Q~;U+Q(n9pQeo&gKu{k#!wf z&B`3y{rTi|WXb6>z6T6EJbS-cJ%@W&)xcv{u)>$Wn{^@c_#N2ag|3G@eV9e7Sn+V4 z)G+IN;5&M<4?Wzj>^I5U1Mf{3t?~RHv*`nmy4i!_O#Z)QbgtvU^4YAm$u3=|%SCTL IO|ztLzMf}`#Q*>R 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 GIT binary patch literal 0 HcmV?d00001 literal 6163 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 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 GIT binary patch literal 0 HcmV?d00001 literal 6310 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 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 GIT binary patch literal 0 HcmV?d00001 literal 6169 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 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 GIT binary patch literal 0 HcmV?d00001 literal 6197 zcmV-57|Q2~P)<h;3K|Lk000e1NJLTq0077U0077c1ONa42T^7f0000WV@Og>004R= z004l4008;_004mL004C`008P>0026e000+nl3&F}00002VoOIv0RM-N%)bBt010qN zS#tmY3ljhU3ljkVnw%H_02i%EL_t(|+U=ctj9k@y$3J%-yE`-c@(WyO6Sf4Jwo$2F zQvrddiRrpFtf`tvsgO|B28n?BKru!QAiN89tMZUYglH&KZA20YHI0P5@yZ6PrD_W; z##U0mn3u85%QiOa$L@M(cINhvyR$owd!F~)JG0c^{bzU2ow?`S?>*=DJHOxW{C=L# zIkXc}t?s}%)FT71v(>%e43}}S>4(neR=zm<dyz+Yw$-B$<1`m?T6vYvEFlXNPjY?D zUsrJ>W3BE|bhOEm<(qe8dmSCn&vw?fdK}TwCWLs*n0;Vd=)>R6%2tmgD%ymQPChWX zd~L(*n8%ZJwt6hl&?barILRsf%dZo*te~saV~K_~AtXha*Yz*|SlDuksaB6A>XT>- z_~d!tWR8f()6?p)L>)kzAO$9KM1%sjw0b1bpF>-~(H!y4%@C(uaWF@wTRo2GPoYiV zOpYvQBw;$~=QcWkB9AdHyD*p|zuoF*0+8owt^%E2yG8tj4D*-t&;GuV?=URBv^qz6 zlN*0H*75@u&;6z7wOhoyWPO3>*fd86^s|ZWs_wj&)YwH>%k~;Ns=dxe`N|&c2OTFN z-TZ*nA;aA!{)kVGPbkIMDJ52fzA|gMC(4)J&sohY<0RxJE(`tt^{kh5Xp$o_c1nRP z{~&1DP&aFgFv7js%3pkhbn<m!+cOlzAI$I}Epsg2!wNx5fm`jqa@0rw#YadNUy`(L z6gPG730`d7lA^!{No%*wSB^1cbbWk;RHQ!3JH$;MB|eF*TT<L1o4Gby&N0>*ej+|X z<YvACTSZN2ruZ<nZb`6`yQS^Mo)&XD;w0oO&r92fSQXyjljB%y-ICyOg=%}o?CWgk zh?9_Mp0<4e8BTFLwvGv~Ui5;@VuHUj`8qo~;#GT}Vvn?arAW6=F_omX0-(S%iYp%G zg#Opr(h)BqXOzB)4dFu6r;C#@b}R&UDBAb1S^vxI>4@8OvYXw~_JZg^bZ{ie{klq= z!!7#Vi9$#G=J(qa?RSR<?xdJ9i$jS9l{i<uST%@7NBo4mB(q!rSso8>@U^W!k)aaj zC4IMWR63GyP_1V|+P*6Madh!f>|FzN#Q7G5ax#bLbR^?3d`QtAx?m)x`l`hFgtGs$ za6v~hggmI2BcbYVLaMJ?oIkAS{Vd$jkqjXdJgm4P#H5#y>Z=mxn(FTTj_61#$YHZ$ z6%Ms*C7}AM#JQ%rJIcMzx|9qdYCUC$%bU9vv+AoB=i7AD-BCjWyBtY{0jV|l$D02Y zv+BE1(LN#bY*sPil#V3hvQ(3QRrBy;R()0am4<e;*?Blha)j(*i{gqV$8M~u?^dZZ z3gAK2SBx>@yjw{|E<U7GAR88u7**d@%9Z8@Rd4TSo$0wR4J1j3dW+Sth{UG)3Jo@M z*e&*G1{iUuS=A!h*k08l(4_vxr25{YJd3C>ijKq<%9t!66WpM<qCx$QN%h^JXy3+5 zvgT)Ej4Vw$`hBaZ`Wu7ls}ko5b$5h6h~?1)Nd7p2%0tqi{yJBE)#6+#>Ec_g0whm} z%0tqi{$@DkGD=G=&ZUyh{l23StvIlw@{rVNTPdbpMro<VxkTN)KZborBh-ZC8DyBd z>_d%1pi+Np9J@X_j=GEWRf%(nx;w(Xru&Yb*&hSQ3F&8;!|Y%aTR6-P1|2;Xm4~Em zVM$S>Qr|914j^k&iF1h&^j_1&>MnNh{_Kyzlamp09S7JnH#71KvcnN6Y7a?`V>iti z4%fGy;<WJRl;k^A;#}aYonamKn~ZOe=h(vF+zc6H2ix?H{CGZsd|3ry=;SCjMYd>U zc~P;N@8OE-p0LaeU#<;4?~ugVPE)kJ;{@l2&)j=W=on;!;H6b6Xg=Z@;&G?&bJueq zva+G}kkmMKGnDvQZCg<?L&E9s*rF8Y0%z@rJ{|pRldK_kNe^gLJ1UqVSxzX<L+s*# zh^gpaQu^zDwR&*f;}ip|us=7_txV`vGb3v;#HijK`nkR4cxyPG;1-#FBAX%SDYNRV zW(PY$&JgND<stbGmdtlG$A^^d?=`{K6w7RAZ`SG3G0cIw<E`QNL#4@INXU((HM%j# za||oHA%e_9GR_Fs@SnB+>WXr%%I9AgU_?kts7G^1FK6Ij!&zf7G!Em6maGfduYH7T z-1;1Mfg_>s%m|M(KDrq?`CYBIM2dc%3Q2xe;)-VdN=uZl=1wEMvtQ;<kS$p%2~vNP zO+06%4u^S2c5*Glv4v!fGsK#vH!wuq)lhW%88#gE^J+_}h!CH>Mgz5#DD`%uU94dZ zyNtiZ3_DrFP#xt>uf;mmV%0w@HO%m|`kbPOkZEo<9;l5(nfH*4Gs3lrr4SxvV9qer zWW7?-alMuZZ^T}nQePzA7zQaO%rVYQx~j=6-eDk2YShD#45`Oz9$<>A>;I{sL%i`* zJ(sVjRvjNXA+VZnTPe0XdD!4xU(NaaNOe&xgoHp!N4QF$11;-@nh>bZ=Ht8z`bdTl z2^~5czi?=;88R(v9>WY6E<phT1B=Z7S_TOndK<rHj5A{P{B#^tfvRY(`}DJk1C~>~ z1rXAqzwv9tC<CS{yspP^C)Y~$xnju8ZEXYr9fQ^eqGsh<3u+lsi<pI)4Drg4P&({K zYp!Vmx-z8xMs|yr8<Tx(2%#g`_}S56C^hO~9^_!Zc-b0QVnr#84!ezC_31=1{MbdE z4A<;)O|Y6BJj>VYyXzW0n;YrKv4?F|WH>SW*oFa(Gi+(-xK`~GNDdy4xOpbd3_nrg zvUXYN5!?8F^lrPtea$fuQ~ajhx!W3yFyKl;rT}u}$dM;!p2m07aPiVQCYB8L@mC^q zt>(#ez`47?^MQW^phAk}^iniG0HE)tu?~%Ot@i#me=5!pT+mEb7Co+@4s*7wyJr9N z>EQw{pxcI&>v>8;6m}ag2eWWX$OO0Zr0jzA$`iWweo`Uk%I4+f{x!{h-seIaQbrlz zc7@AEc}y$`_#9z{DjV5Wc1vSo9Ggz((IC{b6ezNvmw1C|y6G~J`YO#!c}y%Bc>ES0 z3BtE(AdZQ#G>YgU<at*~*~2Rw1@d%~CZ!kfEYrMHCqoj#eR^lI!ee5>eew?B`5<uT z&oE7vZu(hDH(5HFrc6aA7$?kkuq~Q?<wl0=<NN%r?!}EUG2?tk<=2dcIiW6!ukff) zW|~g2^st0}3UpGU)EJE(hI-T7gk4_fdAJ}%s#%4h_NZ-aQez%U<D!p8hHg^KaEw=Z znOE4)5g<pN44!Nmt2acdqTLffkta<{VN{dm*lmHWAe|wNs8FIrCj}PM$zr<6GL0_} z@f>Coud*WQ>E`G&<Zl>Oi}FTX$xrwvz8$Uax-hO5ouZR2DoiqtM<@L(VG&vKRGJUf zR58qtNVm2mNPtu3bifN-lx&$XV_QkEjAeidNBM|6Sr)N`esXve!^Hj@Ne)O1%bKhS zSAC06gDOQA!C{(l-lN-O89N6dA{PZq1KH4Jtjr8P<yO@KS)g!Ir7e6J3wAF#renyN z^XY}-vU#=3*au|kVKGbT#gBZjd4@s)af_`-EOiWnWvt8$$M}Fgmg^c`B&aaO`Fu9{ zCzLQ^D=g`g0@8Fc&0F{mB*_%t<<A(f{=B7@l`s-0y_#`!lL9As)PR!4Q=SW>%5D<1 za2=sSp8+L9O%<0GMj7b^L`apA$M_R|O>w32$W7a#k&rmb!~0CQ${tgpk25^U=lOj; zBe<r-4e`+7QHW(zRkya*60({*xiW?up5ao{3TI+eDA2{vd7VEOEL~gTnjHn+i0VWL z#S1(zA6_?a?X^3=riVV)5;et1%AwLkn6M-|dSk2(u#T~Mf5>$)(s9~-Y1;~Yq<NGB zO)Z+$C2Zg;({tEkJJ$uj1ca=ykJfG#!YLUuDW=w57-bDq3Hes5dt-xUO2$~%4vrUF zd<&|C<XhbrJ5(uo2XI&8re(-Om5{^=qPa$eK2rQWQ|w&mbj-4_pf-kKD6@<SHuCSS z?ua7<Gh|t-yI~8T4&V^`_zixi)t!loWl$yL*;e<(4n7^Ec$Fh8;w+agbV{CuDk1kR zJhgY8j$^Yr$tPUOH7&^u?F6IT2US8&>n2ZYA2iYd@CjewS6baMJB%?DY&+*)DDCuu z#^{N|B-e@8KnK7$pO4Sc>&0Sv1sI)I5o@)qAqKf>?yoH0)Jy%V#2KAXV14+re#keQ z=zt=NxulxP)HN!6=*YNO;(Ika*#D}Hrk911<{iCk4$beuQswg=M<~(}(w-s3E{?jo zT`k<1-^)yfk4?T0nWXIyNRHR|kX$GoP$I_~cEmx6@6L%J#)8@y&I@w!V(u|TjzM;D z#K9dsD(+3yQY;`s!t|;zcubM!8h%bG@|x?B;!vUoBioh`ACIoO6DVm)8gu}7OyiTq zk32k|3<DgD(Gk*!wk0G@nM0Io^zsbje5`4h_L!ke#X-pTG#P%G6O9EkVnf>!l46E~ z6l*%@lOdn*iVhxSDl7%wcdNY%(6)s5Ko{u-DUdWB)w@oyh&;y`k3Dd_Z3$^N6v=P_ z=W&`M6HLZ7Th0-pjWT6Y^pj?WX--n+WDN7AjR|ST!v_^Al<?@_7w|csGfZ%jio^Mm z1R<A_W}o@T+9X_|vpFc(r%V}0(MLbaD07<Ajt(Zp?>-o2KmTlIru69~!+r-FyU4hb zcloNQu|kO=DLPorXSsyWu!Ky+M;b37K?-8{_4xu{YWU=t;7y9HKb@H6QI_*#dFJ5? zWzOQ`(Z_{+j*D4N!FuU2N*rK>#?%^`5uQGICV7RE^vE+sNRg)GVuo3y)=1%zrHIdj zv3xPl+pCYptha^Q`nEE3ahg{+Locn`b=35^wot2P=HamU(rxgV;~*qFSNh$`I)Vh6 z)d!rU&}uRO?r6xLYLI!@uahqqaWTs^-Hoo7ELnQ)-CQpJaGGiMQ*`i_I9Re)@}fW$ z*;#vhKnETvvQ#+5ajBWo{gNe5&%H{PG0UfuEc=;&)(dlh$Ay}qacL)?GG{5#%K#TC zW{SHRGRU18RRjb{Fn#iz<^zu7<{gPVLss#U;tH!Im>yYRoJmfE2zz%kBq&OuQ`BK& z*gpf!Y9EJ4wSMOT4dugyW46d;?^C2iAHT>YEDL@3(FrlDBM_=<wUK5O;2s?Xgdmr_ zah`ae5@*S9VJIn42{ElBP-xCf>d{7;Re%i!*IJf#D$kPgIhL_>_6MR7V)cG7#2?T9 z5d=%W%yD|!g^nD14a)^smv$<1mMj-=;p`9C6JlO=w2J5E#d<);TkWG+Vf{?3OFNaB zp8K)Ad3B*O$2dd$9zPELsK!_wrOQEb8fTc|GOL0$LA@%w$|E%}C&X@{YAPV78`RSh z*cPmDP%O}l5c`Fyp@3Xl(*aQm)<i58XhMkXLe-S@w(aSd@3&oAas7Q+6LblQvQRa= zX$ypo0QQOZZE9zuM~MAG6;cXlLD3N)s3J6O@ySi*#R7F|;o2=!p{0O=0MFMJ5*-jo z6gx3*Y+#WSvf8o=te}9LPns-;`KX?b)!gXjxy1^5F&`}Vi}Ws*5we!&ECiFVfSga7 zE)H<GaU=W$KWtH5>3&}3e+;g-uT*$F`}Hmq6SC4OKajA1TtLS@4wJ3F>3RmRT5TgD zFp93^a>KeNwv|qo>D3n!`9nH+ffa_glz7s7(sb}Hhscnr-IdqZLvvR3Oz97)FJWe0 zs?4t3{a5%`S@S-`Go;Iq4r$rqfR2M4BwJ5MqkqI!xi&+yi9<60qi(#z7A1)PNNutc z5mGTYqcSe9kL;5n%R%0ygLFL|VX-KYjSo_U8v(TfFha&{T94|hYCCdt2UUYnq!B)8 zG92ZdW;&YVI;syXlJP+Tkt<EdLl_RTjpGuvLsUeFN2i<aq{woJ*XU}dV<mSBKi1DS z{*5nMJ|<|)Ht#VcRpD1js}{<kzi~XSKGG##vQ)9oniICbdmIR(Ll)N&;7c60en_OK z)RxL9uvMYLt9m1U7J3`UpQx1w5g`+bGF~HUk>=yk%|{#}8%BrvoxIOJB}17k19;3- zDVg9w#Ya|}#2<%1y>Tq@L$%vS90nvV(5n?F7HC$7IW(Jlp#fQ5R0z^NTp^sL9g+og zx>{-~$H%-)s!ECaj&3r{4zfXDDp3|@mZ`lk5i0()_o^u}9OP{XqeCaI;}*%Hc?a(c zf9CYIBHg6tqn}FLqPU}W{IL`wxjGtJIW*+CiSbjeW#?RijY&?3j3QykbDX#7BpXIY zK^fPvo86MuUV4N-z153+QWR>X=x(+t?rNw0HX{)8CuX1BBqtbRNbdxa{20S7cCnam z(m|2$aaJ$;iBF0=M|nM5lml#3=;Nxl`K(S`nH+ufRiW2&MtbKgkE`O3H8IXG575P5 z0N>Spa-egh?F4^q)|V6+KH_z}#$EY5R7=B_*$SJH;4woFSt_;5z{52sKEkkyRnoa> zf=MRL?Q=04M=0<i|4S-db^vTu?pGgj(~~k?^wq2Wo0U{YQGXr4IU#wDa8M*W04`@p z@fA0?%JxzrOKx8E1s%~IRsD?!hlB+Cj$^zw>lYN@F~!&H)-zM<z+;9S+4?whwP-g9 zBy|plgrvxDfY<TFixsR_ZU=93IlMBx<QnZ2>lHJw;O><$heJa0oZwB6(NW+T#g}YT zp35*og)BYwix#Mhi4Qr_wJhL_kgB4am01TiD!ydG(0iu=pT5RLOGmV;7S`C{h>$$T zcul70g3eCZk#<#!GWpv5dH}U(U*-PQ(1Q~~s&sV7ZD)5V)m@bV&;mZ``u%!<-OAm@ zGlqu}9Kiu0nsms#9|4@HyR|5jr7x^!w<t{+ss%O{L?%R&4)uo1p}JcOj}kp}HqVhg zN@Jf3Q=>5=5~5AV<;kkM^$-+)RY|OtsK1d2(WXPKwK!IHYf+|?UP{dY9~0c5_~=js z$F3zJ5Mn@wYC9N%x?2mMUNT`xV74knd*YTYYeEd@P;UoS8?}g-p{IGj9zZ496Sr(x z5@JAyT3gu@ck#gr*+#4H{JmA8eM7S9uN5Iibf~ozwF2q@LdTC<v?r=<SrB4Khsyh* z-l91`In00(KrPx`Id-*ROo$;JD({Edh~Wffy66!lsZ@z}`?y967!qPghg#ir;;dDp zLMD8_9zeBdMu}@Qgb^Xebf^Y05r;W348r|-0JUgOO#L+=q>H0wbaX4HdW^NUn~{-4 zbf{j8#MEDHLb{kzxt|(wlQK3j!CKqG{dxekXy3r%B>JgINC(IGS$I&W2%UUgaYZ8P z?mUG1^#Cf-Uf|XwdZ|H(PX}e*V%jX*TNhuFwkM+Q)<Uvh51@KM+?32yKuJiDLg@`= z=ra3e`5CN))ZO|H3HR#(RHA*F1fU=!2<X|zQ9+S9={L*LZziPfHbN1o`H)n}&^f{s z8B#)mnwp0i5BlrjEYC}a-U3MW>j7k^V*F$(gGmWVljc=Eu(PgB^R%!n7H6#*(*1gX z&FmGlcs!9rAEktNOmZC0)+GFtU~r?Y3Pe*%5h(EuLCbcICDBL8vrbdu4OM853}^U8 z$ibB{Wo&P3@F>zpUOq?m&R1@(>-BZX^ilEhN8BjvWq{F|vk~Krgbp_`l*zM9RS9Q| zb#=!|6797@?MO$ht~Acj?2#WR@|acDDW{lWDaR<u2R_CxarJB|^MreyL=7tABR_Fs zh8)W{q#F1nJKbbmF-80}sM-!QEF~9vfk<0?`Up{O-)6{ho`Wj6@!-=&h}QOPhDGuX zVhizUBV<Cy-CCxTg4h(_QheG7(Ml^-A<c4V%Q><z30W#^=_RNBxJQwGmb6PP(K;+l zLVhZ2*(*&dFoy~$dfTS}Kn)fqA!EW!L^tbsEj&tL$3fcw3zHBSVl3pp>rA{XsdGZz zDb_X2l5y6Bk|c!RmP=L}*Hc&GW^SEJ0$Ah`o^5r9T)=C`x8(mb7VeVuDaHQ*Mcgm^ T#5UU&00000NkvXXu0mjfu^GjJ 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 GIT binary patch literal 0 HcmV?d00001 literal 6227 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 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 GIT binary patch literal 0 HcmV?d00001 literal 6090 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 Q9{>OV07*qoM6N<$g2zO3LI3~& 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 GIT binary patch literal 0 HcmV?d00001 literal 6295 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 N002ovPDHLkV1lAq*!lnf 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 GIT binary patch literal 0 HcmV?d00001 literal 6158 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 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 GIT binary patch literal 0 HcmV?d00001 literal 6220 zcmV-S7_;YzP)<h;3K|Lk000e1NJLTq0077U0077c1ONa42T^7f0000WV@Og>004R= z004l4008;_004mL004C`008P>0026e000+nl3&F}00002VoOIv0RM-N%)bBt010qN zS#tmY3ljhU3ljkVnw%H_02jnbL_t(|+U=cdY+T26$A5RpB_*yNlw^^VZ9OQ}*28IH z(^6n34h%#t4Lv9WZGaSM4YY_+#X-;pk!&=vRZ)S}0Ja4rMd8LsQnYZI!l)a>5<@|< zg~m>k7_ce<ZG*%vQU`JUNMy;B#3i}hS3lfcavyi*%-lQo?$Ys}Ur5f~yEFHHXU>^( z&Ya_wc^~bBRI5AiKI+j4u(j2_Ajev+CujGee(vX^mEULiD$lig6e<)+a}#Nb!gYtJ z5VAn=P4?FO^$|YB$yRqMI@)H*^6>0FFkVLo^fJz_R*xb&+J=x4R_euxz=uE1P^-rg z6>UOD2NUGYJF}}{cFg0Obhmme(a<)8Op_&TI!pE_TW(=dtH%-zZ9+(jB5zYR?an*O zmMcuRdMr_&L|dRt7w<Abmz^XD8qd;Jk0t5=+5{=!*XDCXg$(;!J(B3pp)KHOj(G3S z5T{*nFh?x6`|XA{BE*>-S<pzrbkfUb=>leXf(hM){v7Eg)p|;LxPy;?Nw3`^enLk1 z3wkTRKfu=*RbN`2BP*D(HKe%3F22pmxxa*7yG6W9)(3c=!*g^%FNYbIy7M;0)~=+x z7_XtD+Us=K+j*49Q8s+V;vD%BzRk{n;hs=`q)eJDGjzn*EdjR#zB0RbINa?#iWIn> zPD)1C$4SV&d?@h$d)cS!P@b!Fwn~bm`Ie&PK;5h{Mu`IJ*?=c{L#pGC3*CHD+4d|M z^#?sJlW)}=d6-)iEg9|)bHgcCv58rVEnl)0ai^yB0d-RcS>x_IMur2L)+P2goT85{ z%vg*kK0-=d)wCYeb*acyYi7tn-ORP$a!#?Dn<!JTc)j8yL~rKHa9sVtJeONBLxy-r z+ivM;@#!crYc-bm2$|spZTkq@gB!|pa@EFN<qA&<s_mrB&BD<UCm}hW4*LK)nC42- zi`G8X3sOOrzcasCSUTcWd!OQ*wtYyY+o#AgoviAc;aTB|V_Y)5S$I0)C1g_cO&kao zqGdXnPIl2cD72sB5z|{mp(Ae7$yv^7+cT;M(ZS^;_v?~4hyCQuZWWD=_|5O171|#P z4&3oIt;7hC#JTih%^@ls@e}g0&T<8$c~aF>h`DQXki>c3)GZvHjwBpZ`^akBw+BCt z4lXAnMPzY)R8USTa6v~h9>d3l_P_-rG1XTR=UK7;fGawZA>=V(js&W|38}uaI6o%z z9*;7U^f{p;8A7rg6Rrp_=_RE4O5)r=-7QgIkj+l$NGizT5n&Y$v}`4y`by$lRChhf zOtF$1zzH2m5hCj;BkXAITFk1iEY45p)m@JwdDgI*8S;+Ip-F9qWljExpnt}y`aU4E zXLX)UfD(Du@&QU#26jD?vrb5R-R;f8k6HDV^ea)j%CeS0rXA9eBq8TGDqPXz*o{^7 zJ+5^|0X(K|@-?dg){=MZ-AvNy@VKNvHZCGDs=nJ95w5sL-CK_$IR@E`=S+6Yk2yKW zTdamfBsSGoW3Z{<tlFdLQDm0&Y{HdhRf}ZZa*qk^P3mt<s_(<%Swy8#)T2P2^=u&L ze0D(6gk-r#xS~P*jY;)AAhe(0<=_U7B1QVyXc5?Bhol|X$L-Z$=c=zH&Xww}zgVqf zt5sl+9g+{Cl{_R3>aTOvR~F|=NmnAz2G++&M=J=CJR}Y3ZwJ#{br+;Bi*tpf^C)wL zwQPuOvGUQ1FmuU6Qm1XDC~(Ey1CYgept|cTx;Jp0^L<AnWI}ovW|S|53pG|iQh#e4 zyJgZ`A?Hf4OX56G-Sx<mV*?vW*=bfwD?b*{6Vl5luXBpS9OZRRG3@54h#r!Lg{45L z{xRs11L)c$aUN&{^_T@VvEEM6{Sv2mqw-_%<aC7W;WZA=&5Ry~Ipv5H*+Wv}*zF+4 zyY(jzuW(iQb47DcNt_2bYyG|WW(LWbFIK}m&rycwX2>w7IAM0=$19`Amz7b5PL6SJ z<WqNPUJ_RGbKF)nN0unDh2>0FA4r!b&Njzv$ZyQj-#Bx9*|CX1^ElFB4k%vQBhtaR zL#Stn$Aikx?d7$|XYOPVNsVK-g95Kpnzw4rYGz0<9UezTael0sjyyAL<a$vHsi2n= znl<E0+5;NZ?^Mi?G?#?)5NCLl(`Nlt;APQYx0Rn)AI&tY*hJazU|18DXb(p~-Hfb$ z=PYHmu!@4oV%5v%YmT=D;~VVPSxR*?q)*JMvy)St3OGY(4#`9E@2sl+>g!sw;kEQE zpAeSW{f%@KD6@?LGevil*XoY92IKcdlfQC=pEA-jhk2e+u^TGrJR}nw;bZ)$_Frkd z@P_y@|H>dol%zCxH2uYD3w>ne^RvSZXN}cZD!);xCF@#VF+RdI5&9f=hF=H1Ge`Jp z<D)B*X0t&eNddh)6_ETa&uz8(mB%a|>$sMJ^a||cK`Xtpm&@u#-I66qkoqq<%=4kt z;UEvmY3^b)w%iF5jBt08>^s^>N0}`QQqW7RUPdj){Q@)6B`QM7oVOZiScy_^H#)=J z+|3#5yV&70cQaB)dChC#)3J@!OzIY^-ip+)!_)FPMHL}A?z0|f7>P3PA(`L^cSY3O z%rV9wM=HP9Sg+>kn9_ZEuaO9E#Ce{QFH&y|{S*`SnBZQ<tUmF-3<gP!dN`6H_1MXy zOmoNF!!V&kz44Qt%g3cv=MZ{AU?*P;rP!Y4n8mxklYYJ<T@(u;bugeKSS2ulk#$2R z1nRT-IPZcv;wD6-!(`(Z4C6IJr)AA!ltIfS$cJxW2{V8eK%~QL<JXJ{j@UgvldZ3> zD%$Hly&UGXkW)NS2y~cl{2DRFpsfmTYKu6{U7CHa8hUeETR=<4aA*TjvvO?&8{<&e z#mn~w^oD$1F+)Q~_?Ibo`)LF_YhBpI%Z<rC1}N$9H-6!kTT7`?4}0@z_{A%%fh9&1 z@q*|GxACh!ok)hCaQ5ucntiSfc5;g6_(b^by2dPP>940_G3P=quucp=VI2$;jD|FH z+$H-2l7UBo6xTG{`@%dEXNI3Baam_V=@BRR$LQUT4v!qOtfRAWt2xchrXJfl9AVIv zgiHZ+&;3|OKaE)~Ug9yaWZ;n{!&cTpkcr*sWO@aT-32LNE_~=s@+`6?#cuJk8ETA} zVL4k^s|pL1j!je%gS)^hLrs@btYRgL$=lnE_VSd0C|qK_98}=amQ|#{jjYv$sO}R_ z=!W-`DiL7IDsh4T;SCD*GsR@_x+g3hE>WbLAy#r#=PQ?vO^msd8ubVe>b0b#ZKS@m zcxjG_B?XTHMQ$VmlDAwP6BE)XVg|+Y_DT6aE(2YpNtp&w>NGFuWJv7rHLJBOCf^t> z+>GFum<UD@GiWA2iFf!Fukr?$DdVw-4l`QD0t0T8$HbCCRkK=0$xIS8o*K3`rHATe zy--)7lWvx>lx{jHQZ$JltoN>E!{mjoMO2~gkt4$vmUGp(QUOQ!tGVADJKTa`=AZ(g zK$f@p1;6AiCh()3h51r%h?Jt;V@H`1*Rq@|n7n`$RFmd}+X9Dz;S8xqC(G$zIo))U zm*Q<lIm}PF#Wabe3Q=ds4C`30h{V?5cD~C$@Wp6-H^rP!J#7BW9+t3_4!S7oma!Y@ z;Ac@g8<mi0HnE<p{aCw`D>D|ce0PaSCix91mXl!#U3e6NiVVM+)PQvGD9M^t5E8EX z7WsH<i4qsNXt#{L4<($PH!g4yc&A|*E4RMh+5&^)DsA=4SO$;oFm|!uV#HE5Z+;o; zW+}_)K{Ql|DA2{?sH)lmK&*8P3lzxm8&*a+YEwa(6d5)rS>v%KNTAYZNmKsZ4i`vq zBkvkq=}~OZsS4)%^Ohos(yI>fA{bEOpDkZhr|Fg2p`fb)78oH_N-k>-V*0UGTUlNw zamu9R<4bLT1xE<HNSWWEtnl~EhrZ?NQYSPoV(p1WLgFY7Unc8zwfG^wU>oZK&rcTd z*s2Jdj!1_`CKg8PPSDp9vXck7J%%rw<VL#+XENU8P447|0BMqABmJ(w&PRq<qdE}+ z@e>}M50scEB-{Zu6BwM%4ucmcHwpLxJ*<vPR-{-H%YBC#W;Z9RU*cm=Y;?fYxYU~$ zd6gA)|Cy$bp12Z}m&NoP;W5r0{}-Q-yW@6D#)W!HrdY%ENt<U~VT`+>O2`*l-J9^3 zr(}xNY%?yC-G=xARAop{tNRiKF9K_Mi*;;uR8*x!=z;1CSqM8O4PN9w*~&WNNd284 zW}r1$Nn^m{JVuTStttBL6h0xVTiuOl7-yKp{23)KFXT6DHB<?CuGM{sf^l{Mu#wME zT*#C>2USA8yinENc{%_F`5c|hEKE5v#+RW=$W=zFJH>^CS~>s**~7(FcPb1{GU9JL z=jZqC*k;MnxL(;tIsiV*^<ko~OyI?0dIcC`clFm=<KhUzd}QvgG@mg`{VQTJj+mfc zz7s$Pr1=<s&qfDM<0h1N%aL(0&(~|5H9xM6rq@L-_BhfaotxkFDT+$`Ge6`y_msFZ zzZZj(sz{NG+N5f&#CYJ`s3OH5QQ}7o5Ixofy!p4X9FJAM9t+T8sHelny?FdL%OZc5 zpK81-!O<-^LQLoY_+!Q?Mjl>@6hGq)dgw?fL}GyvVoC?V5~d?-C1uilkQ8r{CY=Z+ zZA?fvUuY<TaEC?Ws-mM>I0e$&OdtQnjHV=mJG3z&i}>qScL6`ftHkxB_$gDQ>5MtP ztBnmmr5HV?Ht;Ah$!c!r1{PD`D!CXBTeR^EX)okRa|7$RM3zY|F-@5+I-Jj!_X#mZ zo;)e~Ns}YXC30M1l04nDdzHv&V?tsJR*8TTIc7-FLoa1=OmLBR$umU<op=tE<0J?P zb?DQhzdZz8)1gm~G6f1iiarLIBG0>A<SKclBhQ!k$2`g_{EPjDpv>8JNIiEuzvK^8 zjU{H7qJzZ@^1JNdgAB5m4yMS3jwFtk5I+Sm+%#X{%M9E23fHyX(Uj(I8Q>Xxve+U8 zCMnU$HQdAyL)^q_Iw>(p!8#}@!Z~#Tjj1*I%~LaN;~9NEdIJ>s0lBCva){I#9e8w; zBhMu7ROCyFE~7W!BDID!8nfPJYU|tTahn4=oFG$IsMRp@aL|0|1E!cUI>QwQA;G!Q z9}?>bR-VFr?Lh||Y!G6`nTI_}6v@rWmk)6(H!(ntDUlS{OO~#}##weq1L@~HE1j6T zBQIG)yrfV?PS+kEkWnT@2i+98!0TL~%p%2h(*2U9PtUzw%1Bz~KNv{V`=G&-O3l!+ zw3DwUPm-gLTN$E{9FxijeRqVI6m@u3r^#;PD_rZWI}x#6s6u+!HkZ9enJH%I<5q5F zBi&>JPu;sA#IGY@VjF)z)v%3c_)909ae#*M;fgU^=d!Po($5DNVl!O<q(mpgu8x30 z*J>Nh%E!ZI3J5#x3vqaqnPHM{Ze$0W=_bn*(@Zn%w?`D}X4!gcaiUq0WcV7Nj`j$f z5J{*{S{Vr@_?lE>E*NRLxWe0%D)Zt`iAIQR+0iQgq%r&ZTaGlVT7)KKF+b*J>rdGi z3#_2CrpE8b2)|_6mmRI*`Nkdl_uEIa@)72lgs#R@V7hL}3P;G^5M@WfPmK9{JX8Cx z@%bpq_P{hB3RSSiQE4Z8LP7{KK#}#<CW<6Mge_R(pje=t4C&?bp=O4{G#4iw4vdRo zWn^fHGK}2}3A<1!vfj4o?5OW|xU}Nt`?4mO5)x&h3QW-7_H_6NpLjn^?QF~l39nHp zO93qqI(!7@vNwUXfyJyAZn%X?Sqi9gVbKA8A&zij-rB&TCuC>HDzMs8K!+RY*vY4& zJ+DL%zAl}=+^;aZSf^!$EpV?b1vJ_`-HZy{+rmi8>g5bYK5TX4VIB-6t}oCh-&!|A zhC<OH6p;H~GadUFB-Cmf5x!A$h#i)7<HA-tU2RrhNHs&c`3bjJex>M13z!|5x>HGK zc+^$(8exXi8%6C)m4z#J|8f3J*Q}c%i!A9dC|f)lq#M-xN5U%Cc4#(n7zbd~j5kc} z>_3$E;Hnw2lsAkI0UMd01L?@{>i|P{XmfTg6f-2)=bz`cO6e9`40FIjhq}lH-8n_u zoq90*0&)}ji|z^5oDT;29eOz&x^%W4Dp#6`hcFm+8^=|0l&Ojk&*-?2VRuIPUeLdX zcu4t?UQX}>J{s~d0n~?bdW>jQc*%#ZgZaksq8!MmBBUhdy*Dl(cSyCbd{T(`y)#;t zjJjlI8IB9es?;0(voPB@epgl=RD@)OGG4|7<aX6WW7a`_C%??kLq8%qxD{`nlB`(Y zcE~pVxB>FUG0#8Arxny2!;Dh=SOkh4@>AS2Bh5=fAi+6qQ_j*Z&4QYnul#k9m*}Xz zbMiM@#UCr77V}4>ot9pxX9LBbRej`96&)sV9s4zl=E1oF*UdjQD(tG-qs)2s3*TrF zf2@H@u8sv(4sC)?%lbZdae6Mn#uS%Sru1O!Rof)%!<d6`R$Cl+8B3KvHR&75tf(!N zca{^vw;IMDi}1z#rOLCL;u0f_m{p_E8+*=hhLwDVE@t^UGd9^zcIig{fDmRQz0EUb zZ60g*Rc+foA;2filT!S#Ato5*Q5Ny%z~9(BIoZc~Da>*4z516?S{jaq+@>|5pPsp> zCjgGAbc_nNvt20MZH_6X?Co>0oDVsqr{lO7hW5Cto}}roukQJXNOctT*8yT6WS9OW z+`))&gL@q4I&)ZFpMy~r?NQa=h;UBGF2?oi;1j|P&YGF2P0`EZ`n(IWXqOa@SmBtE zLy{9^pST_TtlJ)~Vp-!^jD5lk%(#6e?BJA;z3P2Ob*Rq@w>ZJeu7|jq>Bg<ER7`xt zk**a24hh*Mt_AATAr)jTy>~`f!{SDpo-Ep>g*7%fBgDV~FYkn%X;-ya(VTir7VYBk zySU(p5TkgAgQB`C8303}VZZL<thn2Fwl#?)oDgC}htB)q!>PJE505oLM=bY?rVMF; zjRg(}F^m?HHe8O?-CFdswAnLsPBiwpFg02uG9iX^>_}SOtwkqYK{?<giPaMIHzFa% zv2>Ew5`(%s50AcP)fckdBYbcqf@3!%A`xOthqN7xMcu8%8oGn#$Z=7$CvMq_K!`CN z@^(<#s71z#=KZ=4Nwg<!*$PdFMc}Wbt(@bL_y;-=>_m}8`+;QD-;jh@#bHa@imZS- zz#>)9pe))G)wV(rVnv7K{gAh4PH=6b)wc>+w7YWb8X*KBR&+?-57~&}2x(TUin2<g zJ$zha2v`$hd1ypZcbz$FWeli`7E6m}l(<GqSQ27Mhcu9EJm$n;1n$>;$f7+l_1B6J z%NpNH#HoHP9_v*w6#I1_(u<Lp`fEYRYTM%w_lmKJ38=gCQ0&)z$fErKE0gG@F(G?+ z#qQ4Cd{Vd~5p}l~iv79|NwjCUKZ!mX6EbFcjI@eH+^KC(NZqZ4a=-3FdO_Tj%oAWp z$oK8<tS|qOn7Uh!0bS6eB-(Q%00Tlg!=+G4X^+GusP5Kck^Ye1<60#niHb)igd7f+ zcVUJXv_o$Rl>2obx>GUbWD5R>gd7j6@8x(}*%p(tR)%K3?&A^8D_T6hkwg!*gm_#h z#(iq=lwxpWtqepPXbyO&MP8YWbDRrF^iNAjhO<#B#!T|*fP*V1qi`G@1FX<1Q|AK( z=1KM>)4!CyaUfb=`11@hR&zFDf+MX?vDnE*?eP-eB)hp(^LL`X*2YDbxf->E_yi-B zBR??96K)gCgu@1Y!K~gib&|E*Q7L7faIcf7K^5xAPkczRiSv@JaEjBevaZ<n?za#d zSeCTa#u)ECLJYQVDK_bKtrp_FMu_3|ZN1LS*iyXL2+5kcTRT{(HpRCT?=?b<D;jTu zwwxmilaOnaEz4MJc8g`KucW_kFDy(#)ZT#e(ynhFebz-Elfc3x<fPJ@e4n}3qMzkD zcU6n9FbRPXP6qsUw~d#jvn>bTj(sx2?uJ=1!R|nklqj`fdGNNbr!L|??w?BnILlXg quGJlK0k0k3lHX=5+$HNhivI^hMks8cfYo&X0000<MNUMnLSTaMo!J`z 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 GIT binary patch literal 0 HcmV?d00001 literal 6100 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 a#s34K^jh37hlkq$0000<MNUMnLSTZWqovaT 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 GIT binary patch literal 0 HcmV?d00001 literal 6223 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 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 GIT binary patch literal 0 HcmV?d00001 literal 6034 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 M07*qoM6N<$f*xC6aR2}S diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index c80f637a649..ec2de431bae 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 00000000000..3c6d0cb7fee --- /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 67eb4931e1b..4b430877762 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 67e9d1630db..00000000000 --- 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 00000000000..2a896d10796 --- /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 00000000000..93724bbca1a --- /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 0febf62b435..e3fd1cd5a1f 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 00000000000..39f1817705d --- /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 00000000000..b065f493c12 --- /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 66c35558b10..00000000000 --- 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 57cb4990e40..00000000000 --- 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 90001952f7c..00000000000 --- 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 bb03a1e9995..00000000000 --- 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 28df02a7e3c..00000000000 --- 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 09c142b8fc1..00000000000 --- 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 382a5e8945e..00000000000 --- 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 00000000000..06ac5450355 --- /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 00000000000..8e32d3e7019 --- /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 00000000000..ed0b4a8825e --- /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 00000000000..b09eaa02455 --- /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 00000000000..a99e004b599 --- /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 00000000000..295e001f138 --- /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 00000000000..3cd7d825d78 --- /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 00000000000..13560cd0f10 --- /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 00000000000..8d4a3a2e504 --- /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 00000000000..a865121b618 --- /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 00000000000..407eaf6486a --- /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 00000000000..78e531ca2fc --- /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 00000000000..982fcdefc9d --- /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 00000000000..98387dbd9a2 --- /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 00000000000..94ae80a1576 --- /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 00000000000..81cb9067db2 --- /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 1ac155b9e6f..6830a39a2aa 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 f97407cd628..19b8501e248 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"/> -- GitLab