llpaneldirfind.cpp

Go to the documentation of this file.
00001 
00032 #include "llviewerprecompiledheaders.h"
00033 
00034 #include "llpaneldirfind.h"
00035 
00036 // linden library includes
00037 #include "llclassifiedflags.h"
00038 #include "llfontgl.h"
00039 #include "llparcel.h"
00040 #include "llqueryflags.h"
00041 #include "message.h"
00042 
00043 // viewer project includes
00044 #include "llagent.h"
00045 #include "llbutton.h"
00046 #include "llcheckboxctrl.h"
00047 #include "lllineeditor.h"
00048 #include "llcombobox.h"
00049 #include "llviewercontrol.h"
00050 #include "llmenucommands.h"
00051 #include "llmenugl.h"
00052 #include "lltextbox.h"
00053 #include "lluiconstants.h"
00054 #include "llviewerimagelist.h"
00055 #include "llviewermessage.h"
00056 #include "llfloateravatarinfo.h"
00057 #include "lldir.h"
00058 #include "llviewercontrol.h"
00059 #include "llviewerregion.h"             // for region name for search urls
00060 #include "llvieweruictrlfactory.h"
00061 #include "llfloaterdirectory.h"
00062 #include "llpaneldirbrowser.h"
00063 
00064 #include <boost/tokenizer.hpp>
00065 
00066 //---------------------------------------------------------------------------
00067 // LLPanelDirFindAll - Google search appliance based search
00068 //---------------------------------------------------------------------------
00069 
00070 class LLPanelDirFindAll
00071 :       public LLPanelDirBrowser,
00072         public LLWebBrowserCtrlObserver
00073 {
00074 public:
00075         LLPanelDirFindAll(const std::string& name, LLFloaterDirectory* floater);
00076         /*virtual*/ ~LLPanelDirFindAll();
00077 
00078         /*virtual*/ BOOL postBuild();
00079         /*virtual*/ void draw();
00080 
00081         void search(const std::string& search_text);
00082         void focus();
00083         void navigateToDefaultPage();
00084 
00085 private:
00086         static void onClickBack( void* data );
00087         static void onClickForward( void* data );
00088         static void onClickHome( void* data );
00089         static void onClickSearch( void* data );
00090         static void onCommitSearch(LLUICtrl*, void* data);
00091 
00092         static std::string getSearchURLSuffix(bool mature);
00093 
00094         /*virtual*/ void onNavigateBegin( const EventType& eventIn );
00095         /*virtual*/ void onNavigateComplete( const EventType& eventIn );
00096                 // Used to update progress indicator
00097         /*virtual*/ void onLocationChange( const EventType& eventIn );
00098                 // Debugging info to console
00099 
00100 private:
00101 #if LL_LIBXUL_ENABLED
00102         LLWebBrowserCtrl* mWebBrowser;
00103 #endif // LL_LIBXUL_ENABLED
00104 };
00105 
00106 
00107 LLPanelDirFindAll::LLPanelDirFindAll(const std::string& name, LLFloaterDirectory* floater)
00108 :       LLPanelDirBrowser(name, floater)
00109 #if LL_LIBXUL_ENABLED
00110         ,mWebBrowser(NULL)
00111 #endif // LL_LIBXUL_ENABLED
00112 {
00113         mMinSearchChars = 3;
00114 }
00115 
00116 BOOL LLPanelDirFindAll::postBuild()
00117 {
00118         LLPanelDirBrowser::postBuild();
00119 
00120         childSetAction("back_btn", onClickBack, this);
00121         childSetAction("home_btn", onClickHome, this);
00122         childSetAction("forward_btn", onClickForward, this);
00123         childSetCommitCallback("search_editor", onCommitSearch, this);
00124         childSetAction("search_btn", onClickSearch, this);
00125 
00126         if (gAgent.isTeen())
00127         {
00128                 childSetVisible("mature_check", false);
00129                 childSetValue("mature_check", false);
00130         }
00131 
00132 #if LL_LIBXUL_ENABLED
00133         mWebBrowser = LLViewerUICtrlFactory::getWebBrowserByName(this, "find_browser");
00134         if (mWebBrowser)
00135         {
00136                 // new pages appear in same window as the results page now
00137                 mWebBrowser->setOpenInInternalBrowser( false );
00138                 mWebBrowser->setOpenInExternalBrowser( false ); 
00139 
00140                 // redirect 404 pages from S3 somewhere else
00141                 mWebBrowser->set404RedirectUrl( childGetText("redirect_404_url") );
00142                 
00143                 // Track updates for progress display.
00144                 mWebBrowser->addObserver(this);
00145 
00146                 navigateToDefaultPage();
00147         }
00148 #endif // LL_LIBXUL_ENABLED
00149 
00150         return TRUE;
00151 }
00152 
00153 LLPanelDirFindAll::~LLPanelDirFindAll()
00154 {
00155 #if LL_LIBXUL_ENABLED
00156         if (mWebBrowser) mWebBrowser->remObserver(this);
00157 #endif // LL_LIBXUL_ENABLED
00158 }
00159 
00160 // virtual
00161 void LLPanelDirFindAll::draw()
00162 {
00163         // enable/disable buttons depending on state
00164 #if LL_LIBXUL_ENABLED
00165         if ( mWebBrowser )
00166         {
00167                 bool enable_back = mWebBrowser->canNavigateBack();      
00168                 childSetEnabled( "back_btn", enable_back );
00169 
00170                 bool enable_forward = mWebBrowser->canNavigateForward();        
00171                 childSetEnabled( "forward_btn", enable_forward );
00172         }
00173 #endif // LL_LIBXUL_ENABLED
00174 
00175         LLPanelDirBrowser::draw();
00176 }
00177 
00178 void LLPanelDirFindAll::search(const std::string& search_text)
00179 {
00180         if (!search_text.empty())
00181         {
00182                 // Replace spaces with "+" for use by Google search appliance
00183                 // Yes, this actually works for double-spaces
00184                 // " foo  bar" becomes "+foo++bar" and works fine. JC
00185 
00186                 // Since we are already iterating over the query,
00187                 // do our own custom escaping here.
00188 
00189                 // Our own special set of allowed chars (RFC1738 http://www.ietf.org/rfc/rfc1738.txt)
00190                 const char* allowed =   
00191                         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
00192                         "0123456789"
00193                         "-._~$+!*'()";
00194 
00195                 std::string query;
00196                 std::string::const_iterator it = search_text.begin();
00197                 for ( ; it != search_text.end(); ++it )
00198                 {
00199                         if ( std::isspace( *it ) )
00200                         {
00201                                 query += '+';
00202                         }
00203                         else if(strchr(allowed,*it))
00204                         {
00205                                 // The character is in the allowed set, just copy it
00206                                 query += *it;
00207                         }
00208                         else
00209                         {
00210                                 // Do escaping
00211                                 query += llformat("%%%02X", *it);
00212                         }
00213                 }
00214 
00215                 std::string url = gSavedSettings.getString("SearchURLQuery");
00216                 std::string substring = "[QUERY]";
00217                 url.replace(url.find(substring), substring.length(), query);
00218 
00219                 // replace the collection name with the one selected from the combo box
00220                 std::string selected_collection = childGetValue( "Category" ).asString();
00221                 substring = "[COLLECTION]";
00222                 url.replace(url.find(substring), substring.length(), selected_collection);
00223 
00224                 // Add common parameters (mature, teen, location)
00225                 bool mature = childGetValue( "mature_check" ).asBoolean();
00226                 url += getSearchURLSuffix(mature);
00227 
00228                 llinfos << "url " << url << llendl;
00229 
00230 #if LL_LIBXUL_ENABLED
00231                 if (mWebBrowser)
00232                 {
00233                         mWebBrowser->navigateTo(url);
00234                 }
00235 #endif // LL_LIBXUL_ENABLED
00236         }
00237         else
00238         {
00239                 // empty search text
00240                 navigateToDefaultPage();
00241         }
00242 
00243         childSetText("search_editor", search_text);
00244 }
00245 
00246 void LLPanelDirFindAll::focus()
00247 {
00248         childSetFocus("search_editor");
00249 }
00250 
00251 void LLPanelDirFindAll::navigateToDefaultPage()
00252 {
00253         std::string start_url = gSavedSettings.getString("SearchURLDefault");
00254         bool mature = childGetValue( "mature_check" ).asBoolean();
00255         start_url += getSearchURLSuffix( mature );
00256 
00257         llinfos << "default url: "  << start_url << llendl;
00258 
00259 #if LL_LIBXUL_ENABLED
00260         if (mWebBrowser)
00261         {
00262                 mWebBrowser->navigateTo( start_url );
00263         }
00264 #endif //LL_LIBXUL_ENABLED
00265 }
00266 
00267 // static
00268 std::string LLPanelDirFindAll::getSearchURLSuffix(bool mature_in)
00269 {
00270         bool mature = mature_in;
00271         // Teens never get mature results.  Explicitly override because 
00272         // Lindens/testers have multiple accounts and shared settings sometimes 
00273         // result in teen=Y and mature=Y simultaneously.  JC
00274         if (gAgent.isTeen())
00275         {
00276                 mature = false;
00277         }
00278 
00279         std::string url = gSavedSettings.getString("SearchURLSuffix");
00280 
00281         // if the mature checkbox is unchecked, modify query to remove 
00282         // terms with given phrase from the result set
00283         std::string substring = "[MATURE]";
00284         const char* mature_flag = (mature ? "Y" : "N");
00285         url.replace(url.find(substring), substring.length(), mature_flag);
00286 
00287         substring = "[TEEN]";
00288         const char* teen_flag = (gAgent.isTeen() ? "Y" : "N");
00289         url.replace(url.find(substring), substring.length(), teen_flag);
00290 
00291         // Include region and x/y position, not for the GSA, but
00292         // just to get logs on the web server for search_proxy.php
00293         // showing where people were standing when they searched.
00294         std::string region_name;
00295         LLViewerRegion* region = gAgent.getRegion();
00296         if (region)
00297         {
00298                 region_name = region->getName();
00299         }
00300         // take care of spaces in names
00301         region_name = LLURI::escape(region_name);
00302         substring = "[REGION]";
00303         url.replace(url.find(substring), substring.length(), region_name);
00304 
00305         LLVector3 pos_region = gAgent.getPositionAgent();
00306 
00307         std::string x = llformat("%.0f", pos_region.mV[VX]);
00308         substring = "[X]";
00309         url.replace(url.find(substring), substring.length(), x);
00310         std::string y = llformat("%.0f", pos_region.mV[VY]);
00311         substring = "[Y]";
00312         url.replace(url.find(substring), substring.length(), y);
00313         std::string z = llformat("%.0f", pos_region.mV[VZ]);
00314         substring = "[Z]";
00315         url.replace(url.find(substring), substring.length(), z);
00316 
00317         return url;
00318 }
00319 
00320 
00321 // static
00322 void LLPanelDirFindAll::onClickBack( void* data )
00323 {
00324 #if LL_LIBXUL_ENABLED
00325         LLPanelDirFindAll* self = ( LLPanelDirFindAll* )data;
00326         if ( self->mWebBrowser )
00327         {
00328                 self->mWebBrowser->navigateBack();
00329         }
00330 #endif // LL_LIBXUL_ENABLED
00331 }
00332 
00333 // static
00334 void LLPanelDirFindAll::onClickForward( void* data )
00335 {
00336 #if LL_LIBXUL_ENABLED
00337         LLPanelDirFindAll* self = ( LLPanelDirFindAll* )data;
00338         if ( self->mWebBrowser )
00339         {
00340                 self->mWebBrowser->navigateForward();
00341         }
00342 #endif // LL_LIBXUL_ENABLED
00343 }
00344 
00345 // static
00346 void LLPanelDirFindAll::onClickHome( void* data )
00347 {
00348 #if LL_LIBXUL_ENABLED
00349         LLPanelDirFindAll* self = ( LLPanelDirFindAll* )data;
00350         if ( self->mWebBrowser )
00351         {
00352                 self->mWebBrowser->navigateHome();
00353         }
00354 #endif // LL_LIBXUL_ENABLED
00355 }
00356 
00357 // static
00358 void LLPanelDirFindAll::onCommitSearch(LLUICtrl*, void* data)
00359 {
00360         onClickSearch(data);
00361 }
00362 
00363 // static
00364 void LLPanelDirFindAll::onClickSearch(void* data)
00365 {
00366         LLPanelDirFindAll* self = ( LLPanelDirFindAll* )data;
00367         LLString search_text = self->childGetText("search_editor");
00368         self->search(search_text);
00369 }
00370 
00371 void LLPanelDirFindAll::onNavigateBegin( const EventType& eventIn )
00372 {
00373         childSetText("status_text", childGetText("loading_text"));
00374 }
00375 
00376 void LLPanelDirFindAll::onNavigateComplete( const EventType& eventIn )
00377 {
00378         childSetText("status_text", childGetText("done_text"));
00379 }
00380 
00381 void LLPanelDirFindAll::onLocationChange( const EventType& eventIn )
00382 {
00383         llinfos << eventIn.getStringValue() << llendl;
00384 }
00385 
00386 //---------------------------------------------------------------------------
00387 // LLPanelDirFindAllInterface
00388 //---------------------------------------------------------------------------
00389 
00390 // static
00391 LLPanelDirFindAll* LLPanelDirFindAllInterface::create(LLFloaterDirectory* floater)
00392 {
00393         return new LLPanelDirFindAll("find_all_panel", floater);
00394 }
00395 
00396 // static
00397 void LLPanelDirFindAllInterface::search(LLPanelDirFindAll* panel,
00398                                                                                 const std::string& search_text)
00399 {
00400         panel->search(search_text);
00401 }
00402 
00403 // static
00404 void LLPanelDirFindAllInterface::focus(LLPanelDirFindAll* panel)
00405 {
00406         panel->focus();
00407 }
00408 
00409 //---------------------------------------------------------------------------
00410 // LLPanelDirFindAllOld - deprecated if new Google search works out. JC
00411 //---------------------------------------------------------------------------
00412 
00413 LLPanelDirFindAllOld::LLPanelDirFindAllOld(const std::string& name, LLFloaterDirectory* floater)
00414         :       LLPanelDirBrowser(name, floater)
00415 {
00416         mMinSearchChars = 3;
00417 }
00418 
00419 BOOL LLPanelDirFindAllOld::postBuild()
00420 {
00421         LLPanelDirBrowser::postBuild();
00422 
00423         childSetKeystrokeCallback("name", &LLPanelDirBrowser::onKeystrokeName, this);
00424 
00425         childSetAction("Search", onClickSearch, this);
00426         childDisable("Search");
00427         setDefaultBtn( "Search" );
00428 
00429         return TRUE;
00430 }
00431 
00432 LLPanelDirFindAllOld::~LLPanelDirFindAllOld()
00433 {
00434         // Children all cleaned up by default view destructor.
00435 }
00436 
00437 // virtual
00438 void LLPanelDirFindAllOld::draw()
00439 {
00440         // You only have a choice if you are mature
00441         childSetVisible("incmature", !gAgent.isTeen());
00442         childSetValue("incmature", gSavedSettings.getBOOL("ShowMatureFindAll"));
00443 
00444         LLPanelDirBrowser::draw();
00445 }
00446 
00447 // static
00448 void LLPanelDirFindAllOld::onCommitScope(LLUICtrl* ctrl, void* data)
00449 {
00450         LLPanelDirFindAllOld* self = (LLPanelDirFindAllOld*)data;
00451         self->setFocus(TRUE);
00452 }
00453 
00454 // static
00455 void LLPanelDirFindAllOld::onClickSearch(void *userdata)
00456 {
00457         LLPanelDirFindAllOld *self = (LLPanelDirFindAllOld *)userdata;
00458 
00459         if (self->childGetValue("name").asString().length() < self->mMinSearchChars)
00460         {
00461                 return;
00462         };
00463 
00464         self->setupNewSearch();
00465 
00466         // Figure out scope
00467         U32 scope = 0x0;
00468         scope |= DFQ_PEOPLE;    // people (not just online = 0x01 | 0x02)
00469         // places handled below
00470         scope |= DFQ_EVENTS;    // events
00471         scope |= DFQ_GROUPS;    // groups
00472 
00473         BOOL filter_mature = (!gSavedSettings.getBOOL("ShowMatureFindAll") || 
00474                  gAgent.isTeen() ||
00475                  !self->childGetValue("incmature").asBoolean() );
00476 
00477         if ( filter_mature )
00478         {
00479                 scope |= DFQ_PG_SIMS_ONLY;
00480                 scope |= DFQ_PG_EVENTS_ONLY;
00481                 scope |= DFQ_FILTER_MATURE;
00482                 scope |= DFQ_PG_PARCELS_ONLY;
00483         }
00484 
00485         // send the message
00486         LLMessageSystem *msg = gMessageSystem;
00487         S32 start_row = 0;
00488         sendDirFindQuery(msg, self->mSearchID, self->childGetValue("name").asString(), scope, start_row);
00489 
00490         // Also look up classified ads. JC 12/2005
00491         BOOL filter_auto_renew = FALSE;
00492         U32 classified_flags = pack_classified_flags(filter_mature, filter_auto_renew);
00493         msg->newMessage("DirClassifiedQuery");
00494         msg->nextBlock("AgentData");
00495         msg->addUUID("AgentID", gAgent.getID());
00496         msg->addUUID("SessionID", gAgent.getSessionID());
00497         msg->nextBlock("QueryData");
00498         msg->addUUID("QueryID", self->mSearchID);
00499         msg->addString("QueryText", self->childGetValue("name").asString());
00500         msg->addU32("QueryFlags", classified_flags);
00501         msg->addU32("Category", 0);     // all categories
00502         msg->addS32("QueryStart", 0);
00503         gAgent.sendReliableMessage();
00504 
00505         // Need to use separate find places query because places are
00506         // sent using the more compact DirPlacesReply message.
00507         U32 query_flags = DFQ_DWELL_SORT;
00508         if ( filter_mature )
00509         {
00510         query_flags |= DFQ_PG_SIMS_ONLY;
00511                 query_flags |= DFQ_PG_PARCELS_ONLY;     // FWIW, currently DFQ_PG_PARCELS_ONLY is only supported
00512                 query_flags |= DFQ_FILTER_MATURE;
00513         }
00514         msg->newMessage("DirPlacesQuery");
00515         msg->nextBlock("AgentData");
00516         msg->addUUID("AgentID", gAgent.getID() );
00517         msg->addUUID("SessionID", gAgent.getSessionID());
00518         msg->nextBlock("QueryData");
00519         msg->addUUID("QueryID", self->mSearchID );
00520         msg->addString("QueryText", self->childGetValue("name").asString());
00521         msg->addU32("QueryFlags", query_flags );
00522         msg->addS32("QueryStart", 0 ); // Always get the first 100 when using find ALL
00523         msg->addS8("Category", LLParcel::C_ANY);
00524         msg->addString("SimName", NULL);
00525         gAgent.sendReliableMessage();
00526 }

Generated on Thu Jul 1 06:08:56 2010 for Second Life Viewer by  doxygen 1.4.7