123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971 |
- /**
- * @file hbfloatersearch.cpp
- * @brief The "Search" floater and its Web tab implementation.
- *
- * $LicenseInfo:firstyear=2002&license=viewergpl$
- *
- * Copyright (c) 2002-2009, Linden Research, Inc. (c) 2009-2021, Henri Beauchamp.
- *
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- *
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- *
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- *
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
- // This used to be LL's v1 viewer "Directory" floater (llfloaterdirectory.cpp),
- // and was modified/expanded by Henri Beauchamp to add web search, showcase and
- // Marketplace when LL added them to their own v2+ viewers, as well as support
- // for OpenSim grids (optional) web search.
- #include "llviewerprecompiledheaders.h"
- #include "hbfloatersearch.h"
- #include "llbutton.h"
- #include "llkeyboard.h"
- #include "lldir.h"
- #include "llpluginclassmedia.h"
- #include "llradiogroup.h"
- #include "llresizehandle.h"
- #include "llscrollcontainer.h"
- #include "llscrollbar.h"
- #include "lltabcontainer.h"
- #include "lluictrlfactory.h"
- #include "llagent.h"
- #include "llcommandhandler.h"
- #include "llfloateravatarinfo.h"
- #include "llgridmanager.h" // For gIsInSecondLife
- #include "llmediactrl.h"
- #include "llpanelavatar.h"
- #include "llpanelevent.h"
- #include "llpanelclassified.h"
- #include "llpaneldirclassified.h"
- #include "llpaneldirevents.h"
- #include "llpaneldirfind.h"
- #include "llpaneldirgroups.h"
- #include "llpaneldirland.h"
- #include "llpaneldirpeople.h"
- #include "llpaneldirplaces.h"
- #include "llpanelgroup.h"
- #include "llpanelpick.h"
- #include "llpanelplace.h"
- #include "llviewercontrol.h"
- #include "llviewerparcelmgr.h"
- #include "llweb.h"
- ///////////////////////////////////////////////////////////////////////////////
- // Command handler for search SLURLs
- ///////////////////////////////////////////////////////////////////////////////
- // Support secondlife:///app/search/{CATEGORY}/{QUERY} SLapps
- class LLSearchHandler final : public LLCommandHandler
- {
- public:
- LLSearchHandler()
- : LLCommandHandler("search", UNTRUSTED_THROTTLE)
- {
- }
- bool handle(const LLSD& tokens, const LLSD&, LLMediaCtrl*) override
- {
- const size_t parts = tokens.size();
- #if 0 // The category is now (11-2021) ignored since not possible to pass
- // "as is" to the newest SL web-based search
- // Get the (optional) category for the search
- std::string category = "all";
- if (parts > 0)
- {
- category = tokens[0].asString();
- }
- #endif
- // Get the (optional) search string
- std::string search_text;
- if (parts > 1)
- {
- search_text = tokens[1].asString();
- }
- HBFloaterSearch::showFindAll(search_text);
- return true;
- }
- };
- LLSearchHandler gSearchHandler;
- ///////////////////////////////////////////////////////////////////////////////
- // HBPanelWebSearch class, for the Web search panel. Implemented in this module
- // since no other module is using it... This tab merely displays a web browser.
- ///////////////////////////////////////////////////////////////////////////////
- class HBPanelWebSearch : public LLPanelDirBrowser, public LLViewerMediaObserver
- {
- protected:
- LOG_CLASS(HBPanelWebSearch);
- public:
- HBPanelWebSearch(const std::string& name, HBFloaterSearch* floater);
- ~HBPanelWebSearch() override;
- bool postBuild() override;
- void draw() override;
- void onVisibilityChange(bool new_visibility) override;
- void reshape(S32 width, S32 height, bool call_from_parent = true) override;
- void search(const std::string& text = LLStringUtil::null);
- LL_INLINE static void setOSSearchURL(const std::string& url)
- {
- sOSSearchURL = url;
- }
- LL_INLINE static std::string getOSSearchURL()
- {
- return sOSSearchURL;
- }
- protected:
- static void onClickBack(void* data);
- static void onClickForward(void* data);
- static void onClickReload(void* data);
- static void onCommitSelectionRadio(LLUICtrl* ctrl, void* data);
- // Inherited from LLViewerMediaObserver
- void handleMediaEvent(LLPluginClassMedia*, EMediaEvent event) override;
- protected:
- LLMediaCtrl* mWebBrowser;
- LLButton* mBackButton;
- LLButton* mForwardButton;
- LLButton* mReloadButton;
- LLRadioGroup* mSelectionRadio;
- bool mReloading;
- static std::string sOSSearchURL;
- };
- //static
- std::string HBPanelWebSearch::sOSSearchURL;
- HBPanelWebSearch::HBPanelWebSearch(const std::string& name,
- HBFloaterSearch* floater)
- : LLPanelDirBrowser(name, floater),
- // NOTE: a reshape() event occurs before mWebBrowser is created, so we must
- // check for NULL whenever reshape() is called...
- mWebBrowser(NULL),
- mReloading(false)
- {
- }
- bool HBPanelWebSearch::postBuild()
- {
- LLPanelDirBrowser::postBuild();
- mBackButton = getChild<LLButton>("back_btn");
- mBackButton->setClickedCallback(onClickBack, this);
- mForwardButton = getChild<LLButton>("forward_btn");
- mForwardButton->setClickedCallback(onClickForward, this);
- mReloadButton = getChild<LLButton>("reload_btn");
- mReloadButton->setClickedCallback(onClickReload, this);
- mSelectionRadio = getChild<LLRadioGroup>("web_site");
- if (gIsInSecondLife)
- {
- U32 selection = gSavedSettings.getU32("WebSearchSiteSelection");
- mSelectionRadio->selectNthItem(selection);
- mSelectionRadio->setCommitCallback(onCommitSelectionRadio);
- mSelectionRadio->setCallbackUserData(this);
- }
- else
- {
- mSelectionRadio->setVisible(false);
- }
- mWebBrowser = getChild<LLMediaCtrl>("find_browser");
- mWebBrowser->addObserver(this);
- // We need to handle secondlife:///app/ URLs for direct teleports
- mWebBrowser->setTrusted(true);
- // Redirect 404 pages from S3 somewhere else
- mWebBrowser->setErrorPageURL(getString("redirect_404_url"));
- search();
- return true;
- }
- HBPanelWebSearch::~HBPanelWebSearch()
- {
- if (mWebBrowser)
- {
- mWebBrowser->remObserver(this);
- }
- }
- //virtual
- void HBPanelWebSearch::draw()
- {
- if (mWebBrowser)
- {
- // Enable/disable buttons depending on state
- mBackButton->setEnabled(mWebBrowser->canNavigateBack());
- mForwardButton->setEnabled(mWebBrowser->canNavigateForward());
- }
- LLPanelDirBrowser::draw();
- }
- //virtual
- void HBPanelWebSearch::reshape(S32 width, S32 height, bool called_from_parent)
- {
- #if 0
- handleMediaEvent(NULL, MEDIA_EVENT_NAVIGATE_BEGIN);
- #endif
- if (mWebBrowser)
- {
- mWebBrowser->navigateTo(mWebBrowser->getCurrentNavUrl());
- }
- LLUICtrl::reshape(width, height, called_from_parent);
- }
- // When we show any web browser-based view, we want to hide all the right-side
- // XUI detail panels.
- //virtual
- void HBPanelWebSearch::onVisibilityChange(bool new_visibility)
- {
- if (new_visibility)
- {
- mFloaterSearch->hideAllDetailPanels();
- }
- LLPanel::onVisibilityChange(new_visibility);
- }
- // Note: we actually do not use any more the search_text in the viewer code
- // calling this method (which is now limited to this panel code). This is
- // because LL broke simple category/query searches in its latest (Nov 2021) web
- // search engine version... Searches from the status bar (which was the only
- // consumer of this method outside this module) are now done via the old (but
- // universal and stable for the past 15 years) non-web interface. HB
- void HBPanelWebSearch::search(const std::string& search_text)
- {
- std::string url;
- if (gIsInSecondLife)
- {
- S32 selection = mSelectionRadio->getSelectedIndex();
- if (selection == 1)
- {
- url = getString("showcase_url");
- mWebBrowser->navigateTo(url);
- }
- else if (selection == 2)
- {
- url = getString("marketplace_url");
- }
- else
- {
- url = gSavedSettings.getString("SearchURL");
- }
- }
- else
- {
- url = sOSSearchURL;
- }
- if (url.empty())
- {
- // This happens when the panel is created while logged in an OpenSim
- // grid without a search URL.
- return;
- }
- LLStringUtil::format_map_t subs;
- #if 0 // Not used: see the note above. HB
- if (!search_text.empty() || url.find("[QUERY]" != std::string::npos))
- {
- if (!gIsInSecondLife)
- {
- // By default, do a standard search in places...
- subs["[SEARCH_TYPE]"] = "standard";
- subs["[COLLECTION]"] = "places";
- }
- else if (url.find("[QUERY]") == std::string::npos)
- {
- // Missing query field in the search url (seen in Speculoos), let's
- // add one (assumption is made that that field is "q=<querry>",
- // which is reasonnable enough):
- llwarns_sparse << "Missing query field in the search URL... Using SL's OLD search engine query format..."
- << llendl;
- if (url.find('?') == std::string::npos)
- {
- url += "?";
- }
- else if (url.rfind('&') != url.length() - 1)
- {
- url += "&";
- }
- url += "q=[QUERY]";
- }
- subs["[QUERY]"] = LLURI::escape(search_text);
- }
- #else // Make any query parameter a no-operation
- if (!gIsInSecondLife && url.find("[QUERY]") != std::string::npos)
- {
- // Make sure we will not search for "[QUERY]" in OpenSim grids !
- subs["[QUERY]"] = LLStringUtil::null;
- }
- #endif
- if (!gIsInSecondLife && url.find("[CATEGORY]") != std::string::npos)
- {
- subs["[CATEGORY]"] = "search"; // Means "everything"
- // Warn when not in SL, since we do not have a documented list of
- // allowed categories in search queries...
- llwarns_sparse << "There is a category field in the search URL, but valid categories for this grid are unknown: using SL's old search engine global category..."
- << llendl;
- }
- if (url.find("[MATURITY]") != std::string::npos)
- {
- std::string maturity;
- if (gAgent.prefersAdult())
- {
- maturity = gIsInSecondLife ? "gma" : "42"; // PG, Mature, Adult
- }
- else if (gAgent.prefersMature())
- {
- maturity = gIsInSecondLife ? "gm" : "21"; // PG, Mature
- }
- else
- {
- maturity = gIsInSecondLife ? "g" : "13"; // PG
- }
- // Add the user's maturity preferences/ranking
- subs["[MATURITY]"] = maturity;
- // Warn when not in SL, since we do not have a documented way to encode
- // the maturity rating in search queries...
- if (!gIsInSecondLife)
- {
- llwarns_sparse << "There is a maturity field in the search URL, but its encoding for this grid is unknown: using SL's old search engine encoding conventions..."
- << llendl;
- }
- }
- if (url.find("[TEEN]") != std::string::npos)
- {
- // Add the agent's teen status
- subs["[TEEN]"] = gAgent.isTeen() ? "y" : "n";
- }
- // Expand all our substitutions and also [LANGUAGE], [VERSION], etc...
- url = LLWeb::expandURLSubstitutions(url, subs);
- handleMediaEvent(NULL, MEDIA_EVENT_NAVIGATE_BEGIN);
- mWebBrowser->navigateTo(url);
- }
- //static
- void HBPanelWebSearch::onClickBack(void* data)
- {
- HBPanelWebSearch* self = (HBPanelWebSearch*)data;
- if (self)
- {
- self->handleMediaEvent(NULL, MEDIA_EVENT_NAVIGATE_BEGIN);
- self->mWebBrowser->navigateBack();
- }
- }
- //static
- void HBPanelWebSearch::onClickForward(void* data)
- {
- HBPanelWebSearch* self = (HBPanelWebSearch*)data;
- if (self)
- {
- self->handleMediaEvent(NULL, MEDIA_EVENT_NAVIGATE_BEGIN);
- self->mWebBrowser->navigateForward();
- }
- }
- //static
- void HBPanelWebSearch::onClickReload(void* data)
- {
- HBPanelWebSearch* self = (HBPanelWebSearch*)data;
- if (self)
- {
- std::string url = self->mWebBrowser->getCurrentNavUrl();
- self->mReloading = true;
- self->mWebBrowser->navigateTo("about:blank");
- self->mWebBrowser->navigateTo(url);
- self->handleMediaEvent(NULL, MEDIA_EVENT_NAVIGATE_BEGIN);
- }
- }
- //static
- void HBPanelWebSearch::onCommitSelectionRadio(LLUICtrl* ctrl, void* data)
- {
- HBPanelWebSearch* self = (HBPanelWebSearch*)data;
- if (self)
- {
- S32 selection = self->mSelectionRadio->getSelectedIndex();
- if (selection >= 0)
- {
- gSavedSettings.setU32("WebSearchSiteSelection", selection);
- }
- self->search();
- }
- }
- //virtual
- void HBPanelWebSearch::handleMediaEvent(LLPluginClassMedia*,
- EMediaEvent event)
- {
- switch (event)
- {
- case MEDIA_EVENT_NAVIGATE_BEGIN:
- {
- mReloadButton->setEnabled(false);
- childSetText("status_text", getString("loading_text"));
- break;
- }
- case MEDIA_EVENT_NAVIGATE_COMPLETE:
- {
- std::string url = mWebBrowser->getCurrentNavUrl();
- if (!mReloading || url != "about:blank")
- {
- mReloading = false;
- mReloadButton->setEnabled(true);
- childSetText("status_text", getString("done_text"));
- }
- break;
- }
- default: // Let's ignore other events
- break;
- }
- }
- ///////////////////////////////////////////////////////////////////////////////
- // HBFloaterSearch class proper
- ///////////////////////////////////////////////////////////////////////////////
- //static
- bool HBFloaterSearch::sSearchURLSetOnLogin = false;
- HBFloaterSearch::HBFloaterSearch(const LLSD&)
- : mSearchWebPanel(NULL),
- mFindAllPanel(NULL),
- mEventsPanel(NULL),
- mLandPanel(NULL),
- mPanelAvatarp(NULL),
- mPanelEventp(NULL),
- mPanelGroupp(NULL),
- mPanelGroupHolderp(NULL),
- mPanelPlacep(NULL),
- mPanelPlaceSmallp(NULL),
- mPanelClassifiedp(NULL)
- {
- // Build the floater with our tab panel classes
- LLCallbackMap::map_t factory_map;
- factory_map["find_all_panel"] = LLCallbackMap(createFindAll, this);
- factory_map["classified_panel"] = LLCallbackMap(createClassified, this);
- factory_map["events_panel"] = LLCallbackMap(createEvents, this);
- factory_map["places_panel"] = LLCallbackMap(createPlaces, this);
- factory_map["land_sales_panel"] = LLCallbackMap(createLand, this);
- factory_map["people_panel"] = LLCallbackMap(createPeople, this);
- factory_map["groups_panel"] = LLCallbackMap(createGroups, this);
- factory_map["web_search_panel"] = LLCallbackMap(createWebSearch, this);
- factory_map["classified_details_panel"] =
- LLCallbackMap(createClassifiedDetail, this);
- factory_map["event_details_panel"] =
- LLCallbackMap(createEventDetail, this);
- factory_map["group_details_panel"] =
- LLCallbackMap(createGroupDetail, this);
- factory_map["group_details_panel_holder"] =
- LLCallbackMap(createGroupDetailHolder, this);
- factory_map["place_details_panel"] =
- LLCallbackMap(createPlaceDetail, this);
- factory_map["place_details_small_panel"] =
- LLCallbackMap(createPlaceDetailSmall, this);
- factory_map["Panel Avatar"] = LLCallbackMap(createPanelAvatar, this);
- LLUICtrlFactory::getInstance()->buildFloater(this,
- "floater_directory.xml",
- &factory_map);
- moveResizeHandlesToFront();
- mTabsContainer = getChild<LLTabContainer>("Directory Tabs");
- // There is not always a web search URL in OpenSim drids...
- if (!gIsInSecondLife && mSearchWebPanel &&
- HBPanelWebSearch::getOSSearchURL().empty())
- {
- mTabsContainer->removeTabPanel(mSearchWebPanel);
- delete mSearchWebPanel;
- mSearchWebPanel = NULL;
- }
- if (mPanelAvatarp)
- {
- mPanelAvatarp->selectTab(0);
- }
- childSetTabChangeCallback("Directory Tabs", "find_all_panel",
- onTabChanged, this);
- childSetTabChangeCallback("Directory Tabs", "classified_panel",
- onTabChanged, this);
- childSetTabChangeCallback("Directory Tabs", "events_panel",
- onTabChanged, this);
- childSetTabChangeCallback("Directory Tabs", "places_panel",
- onTabChanged, this);
- childSetTabChangeCallback("Directory Tabs", "land_sales_panel",
- onTabChanged, this);
- childSetTabChangeCallback("Directory Tabs", "people_panel",
- onTabChanged, this);
- childSetTabChangeCallback("Directory Tabs", "groups_panel",
- onTabChanged, this);
- childSetTabChangeCallback("Directory Tabs", "web_search_panel",
- onTabChanged, this);
- mTeleportArrivingConnection =
- gViewerParcelMgr.setTPArrivingCallback(boost::bind(&HBFloaterSearch::onTeleportArriving));
- }
- //virtual
- HBFloaterSearch::~HBFloaterSearch()
- {
- mTeleportArrivingConnection.disconnect();
- // Note: this function is defined in the class LLFloater. However, it
- // causes crash if this line is postponed to ~LLFloater() because it uses
- // some pointers deleted below. That is, those pointers are used again
- // after deleting.
- setMinimized(false);
- delete mPanelAvatarp;
- mPanelAvatarp = NULL;
- delete mPanelEventp;
- mPanelEventp = NULL;
- delete mPanelGroupp;
- mPanelGroupp = NULL;
- delete mPanelGroupHolderp;
- mPanelGroupHolderp = NULL;
- delete mPanelPlacep;
- mPanelPlacep = NULL;
- delete mPanelPlaceSmallp;
- mPanelPlaceSmallp = NULL;
- delete mPanelClassifiedp;
- mPanelClassifiedp = NULL;
- gSavedSettings.setBool("ShowSearch", false);
- }
- //virtual
- void HBFloaterSearch::setVisible(bool visible)
- {
- gSavedSettings.setBool("ShowSearch", visible);
- LLFloater::setVisible(visible);
- }
- void HBFloaterSearch::focusCurrentPanel()
- {
- LLPanel* panel = mTabsContainer->getCurrentPanel();
- if (panel)
- {
- panel->setFocus(true);
- }
- }
- //static
- void* HBFloaterSearch::createFindAll(void* userdata)
- {
- HBFloaterSearch* self = (HBFloaterSearch*)userdata;
- self->mFindAllPanel = new LLPanelDirFind("find_all_panel", self);
- return self->mFindAllPanel;
- }
- //static
- void* HBFloaterSearch::createClassified(void* userdata)
- {
- HBFloaterSearch* self = (HBFloaterSearch*)userdata;
- self->mClassifiedPanel = new LLPanelDirClassified("classified_panel",
- self);
- return self->mClassifiedPanel;
- }
- //static
- void* HBFloaterSearch::createEvents(void* userdata)
- {
- HBFloaterSearch* self = (HBFloaterSearch*)userdata;
- self->mEventsPanel = new LLPanelDirEvents("events_panel", self);
- return self->mEventsPanel;
- }
- //static
- void* HBFloaterSearch::createPlaces(void* userdata)
- {
- HBFloaterSearch* self = (HBFloaterSearch*)userdata;
- return new LLPanelDirPlaces("places_panel", self);
- }
- //static
- void* HBFloaterSearch::createLand(void* userdata)
- {
- HBFloaterSearch* self = (HBFloaterSearch*)userdata;
- self->mLandPanel = new LLPanelDirLand("land_panel", self);
- return self->mLandPanel;
- }
- //static
- void* HBFloaterSearch::createPeople(void* userdata)
- {
- HBFloaterSearch* self = (HBFloaterSearch*)userdata;
- return new LLPanelDirPeople("people_panel", self);
- }
- //static
- void* HBFloaterSearch::createGroups(void* userdata)
- {
- HBFloaterSearch* self = (HBFloaterSearch*)userdata;
- return new LLPanelDirGroups("groups_panel", self);
- }
- //static
- void* HBFloaterSearch::createWebSearch(void* userdata)
- {
- HBFloaterSearch* self = (HBFloaterSearch*)userdata;
- self->mSearchWebPanel = new HBPanelWebSearch("web_search_panel", self);
- return self->mSearchWebPanel;
- }
- //static
- void* HBFloaterSearch::createClassifiedDetail(void* userdata)
- {
- HBFloaterSearch* self = (HBFloaterSearch*)userdata;
- self->mPanelClassifiedp = new LLPanelClassified(true, false);
- self->mPanelClassifiedp->setVisible(false);
- return self->mPanelClassifiedp;
- }
- //static
- void* HBFloaterSearch::createPanelAvatar(void* userdata)
- {
- HBFloaterSearch* self = (HBFloaterSearch*)userdata;
- // Note: false to disallow editing in search context (SL-48632):
- self->mPanelAvatarp = new LLPanelAvatar("Avatar", LLRect(), false);
- self->mPanelAvatarp->setVisible(false);
- return self->mPanelAvatarp;
- }
- //static
- void* HBFloaterSearch::createEventDetail(void* userdata)
- {
- HBFloaterSearch* self = (HBFloaterSearch*)userdata;
- self->mPanelEventp = new LLPanelEvent();
- LLUICtrlFactory::getInstance()->buildPanel(self->mPanelEventp,
- "panel_event.xml");
- self->mPanelEventp->setVisible(false);
- return self->mPanelEventp;
- }
- //static
- void* HBFloaterSearch::createGroupDetail(void* userdata)
- {
- HBFloaterSearch* self = (HBFloaterSearch*)userdata;
- self->mPanelGroupp = new LLPanelGroup("panel_group.xml",
- "PanelGroup",
- gAgent.getGroupID());
- // Gods can always edit panels
- self->mPanelGroupp->setAllowEdit(gAgent.isGodlike());
- self->mPanelGroupp->setVisible(false);
- return self->mPanelGroupp;
- }
- //static
- void* HBFloaterSearch::createGroupDetailHolder(void* userdata)
- {
- HBFloaterSearch* self = (HBFloaterSearch*)userdata;
- self->mPanelGroupHolderp = new LLPanel(std::string("PanelGroupHolder"));
- self->mPanelGroupHolderp->setVisible(false);
- return self->mPanelGroupHolderp;
- }
- //static
- void* HBFloaterSearch::createPlaceDetail(void* userdata)
- {
- HBFloaterSearch* self = (HBFloaterSearch*)userdata;
- self->mPanelPlacep = new LLPanelPlace(false);
- LLUICtrlFactory::getInstance()->buildPanel(self->mPanelPlacep,
- "panel_place.xml");
- self->mPanelPlacep->setVisible(false);
- return self->mPanelPlacep;
- }
- //static
- void* HBFloaterSearch::createPlaceDetailSmall(void* userdata)
- {
- HBFloaterSearch* self = (HBFloaterSearch*)userdata;
- self->mPanelPlaceSmallp = new LLPanelPlace(false);
- LLUICtrlFactory::getInstance()->buildPanel(self->mPanelPlaceSmallp,
- "panel_place_small.xml");
- self->mPanelPlaceSmallp->setVisible(false);
- return self->mPanelPlaceSmallp;
- }
- //static
- void HBFloaterSearch::setSearchURL(const std::string& url, bool on_login)
- {
- sSearchURLSetOnLogin = on_login;
- if (gIsInSecondLife)
- {
- // Nothing else to do: SL got its own, hard-coded search URL...
- return;
- }
- HBPanelWebSearch::setOSSearchURL(url);
- HBFloaterSearch* self = findInstance();
- if (!self)
- {
- // Nothing else to do: the tabs will be created as needed on floater
- // opening...
- return;
- }
- bool url_is_empty = url.empty();
- if (url_is_empty && self->mSearchWebPanel)
- {
- // No web search available... Remove the tab.
- self->mTabsContainer->removeTabPanel(self->mSearchWebPanel);
- delete self->mSearchWebPanel;
- self->mSearchWebPanel = NULL;
- }
- else if (!url_is_empty && !self->mSearchWebPanel)
- {
- // No "Web search" tab while the URL is not empty... We need to destroy
- // the floater in order to get back the tab after the floater will be
- // re-opened...
- self->close();
- }
- }
- //static
- bool HBFloaterSearch::wasSearchURLSetOnLogin()
- {
- return sSearchURLSetOnLogin;
- }
- //static
- void HBFloaterSearch::requestClassifieds()
- {
- HBFloaterSearch* self = findInstance();
- if (self && self->mClassifiedPanel)
- {
- self->mClassifiedPanel->performQuery();
- }
- }
- //static
- void HBFloaterSearch::showFindAll(const std::string& text)
- {
- showPanel("find_all_panel");
- HBFloaterSearch* self = findInstance();
- if (self && self->mFindAllPanel)
- {
- self->mFindAllPanel->search(text);
- }
- }
- //static
- void HBFloaterSearch::showClassified(const LLUUID& classified_id)
- {
- showPanel("classified_panel");
- HBFloaterSearch* self = findInstance();
- if (self && self->mClassifiedPanel)
- {
- self->mClassifiedPanel->selectByUUID(classified_id);
- }
- }
- //static
- void HBFloaterSearch::showEvents(S32 event_id)
- {
- showPanel("events_panel");
- HBFloaterSearch* self = findInstance();
- if (self && self->mEventsPanel)
- {
- if (event_id != 0)
- {
- self->mEventsPanel->selectEventByID(event_id);
- }
- else
- {
- // Force a query for today's events
- self->mEventsPanel->setDay(0);
- self->mEventsPanel->performQuery();
- }
- }
- }
- //static
- void HBFloaterSearch::showLandForSale(const LLUUID& parcel_id)
- {
- showPanel("land_sales_panel");
- HBFloaterSearch* self = findInstance();
- if (self && self->mLandPanel)
- {
- self->mLandPanel->selectByUUID(parcel_id);
- }
- }
- //static
- void HBFloaterSearch::showGroups()
- {
- showPanel("groups_panel");
- }
- //static
- void HBFloaterSearch::refreshGroup(const LLUUID& group_id)
- {
- HBFloaterSearch* self = findInstance();
- if (self && self->mPanelGroupp && self->mPanelGroupp->getID() == group_id)
- {
- self->mPanelGroupp->refreshData();
- }
- }
- //static
- void HBFloaterSearch::showPanel(const std::string& tabname)
- {
- // This function gets called when web browser clicks are processed, so we
- // do not delete the existing panel, which would delete the web browser
- // instance currently handling the click. JC
- // Get current instance or create a new one if none exist yet.
- HBFloaterSearch* self = getInstance();
- if (self) // Paranoia (could happen when out of memory)
- {
- self->open();
- self->childShowTab("Directory Tabs", tabname);
- self->focusCurrentPanel();
- }
- }
- //static
- void HBFloaterSearch::toggle()
- {
- HBFloaterSearch* self = findInstance();
- if (self)
- {
- if (self->getVisible())
- {
- self->setVisible(false);
- }
- else
- {
- self->open();
- self->focusCurrentPanel();
- }
- return;
- }
- std::string panel = gSavedSettings.getString("LastFindPanel");
- // These panels got renamed...
- if (panel == "find_all_old_panel")
- {
- panel = "find_all_panel";
- }
- if (panel == "sl_panel")
- {
- panel = "web_search_panel";
- }
- if (!gIsInSecondLife && panel == "web_search_panel" &&
- HBPanelWebSearch::getOSSearchURL().empty())
- {
- panel = "find_all_panel";
- }
- showPanel(panel); // Creates a new instance
- // *HACK: force query for today's events
- self = findInstance();
- if (self && self->mEventsPanel)
- {
- self->mEventsPanel->setDay(0);
- }
- }
- //static
- void HBFloaterSearch::onTeleportArriving()
- {
- HBFloaterSearch* self = findInstance();
- if (self && !self->isMinimized() &&
- gSavedSettings.getBool("HideFloatersOnTPSuccess"))
- {
- self->setVisible(false);
- }
- }
- //static
- void HBFloaterSearch::onTabChanged(void* data, bool from_click)
- {
- HBFloaterSearch* self = (HBFloaterSearch*)data;
- if (!self) return;
- LLPanel* panel = self->childGetVisibleTab("Directory Tabs");
- if (panel)
- {
- gSavedSettings.setString("LastFindPanel", panel->getName());
- }
- }
- void HBFloaterSearch::hideAllDetailPanels()
- {
- if (mPanelAvatarp)
- {
- mPanelAvatarp->setVisible(false);
- }
- if (mPanelEventp)
- {
- mPanelEventp->setVisible(false);
- }
- if (mPanelGroupp)
- {
- mPanelGroupp->setVisible(false);
- }
- if (mPanelGroupHolderp)
- {
- mPanelGroupHolderp->setVisible(false);
- }
- if (mPanelPlacep)
- {
- mPanelPlacep->setVisible(false);
- }
- if (mPanelPlaceSmallp)
- {
- mPanelPlaceSmallp->setVisible(false);
- }
- if (mPanelClassifiedp)
- {
- mPanelClassifiedp->setVisible(false);
- }
- }
|