PageRenderTime 62ms CodeModel.GetById 32ms app.highlight 26ms RepoModel.GetById 2ms app.codeStats 0ms

/indra/newview/llpanelprofile.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 433 lines | 339 code | 53 blank | 41 comment | 73 complexity | 56c9b8f06fe92c759795cfbb35033ffd MD5 | raw file
  1/** 
  2* @file llpanelprofile.cpp
  3* @brief Profile panel implementation
  4*
  5* $LicenseInfo:firstyear=2009&license=viewerlgpl$
  6* Second Life Viewer Source Code
  7* Copyright (C) 2010, Linden Research, Inc.
  8* 
  9* This library is free software; you can redistribute it and/or
 10* modify it under the terms of the GNU Lesser General Public
 11* License as published by the Free Software Foundation;
 12* version 2.1 of the License only.
 13* 
 14* This library is distributed in the hope that it will be useful,
 15* but WITHOUT ANY WARRANTY; without even the implied warranty of
 16* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 17* Lesser General Public License for more details.
 18* 
 19* You should have received a copy of the GNU Lesser General Public
 20* License along with this library; if not, write to the Free Software
 21* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 22* 
 23* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 24* $/LicenseInfo$
 25*/
 26
 27#include "llviewerprecompiledheaders.h"
 28#include "llpanelprofile.h"
 29
 30#include "llagent.h"
 31#include "llavataractions.h"
 32#include "llfloaterreg.h"
 33#include "llcommandhandler.h"
 34#include "llnotificationsutil.h"
 35#include "llpanelpicks.h"
 36#include "lltabcontainer.h"
 37#include "llviewercontrol.h"
 38#include "llviewernetwork.h"
 39
 40static const std::string PANEL_PICKS = "panel_picks";
 41
 42std::string getProfileURL(const std::string& agent_name)
 43{
 44	std::string url;
 45
 46	if (LLGridManager::getInstance()->isInProductionGrid())
 47	{
 48		url = gSavedSettings.getString("WebProfileURL");
 49	}
 50	else
 51	{
 52		url = gSavedSettings.getString("WebProfileNonProductionURL");
 53	}
 54	LLSD subs;
 55	subs["AGENT_NAME"] = agent_name;
 56	url = LLWeb::expandURLSubstitutions(url,subs);
 57	LLStringUtil::toLower(url);
 58	return url;
 59}
 60
 61class LLProfileHandler : public LLCommandHandler
 62{
 63public:
 64	// requires trusted browser to trigger
 65	LLProfileHandler() : LLCommandHandler("profile", UNTRUSTED_THROTTLE) { }
 66
 67	bool handle(const LLSD& params, const LLSD& query_map,
 68		LLMediaCtrl* web)
 69	{
 70		if (params.size() < 1) return false;
 71		std::string agent_name = params[0];
 72		llinfos << "Profile, agent_name " << agent_name << llendl;
 73		std::string url = getProfileURL(agent_name);
 74		LLWeb::loadURLInternal(url);
 75
 76		return true;
 77	}
 78};
 79LLProfileHandler gProfileHandler;
 80
 81class LLAgentHandler : public LLCommandHandler
 82{
 83public:
 84	// requires trusted browser to trigger
 85	LLAgentHandler() : LLCommandHandler("agent", UNTRUSTED_THROTTLE) { }
 86
 87	bool handle(const LLSD& params, const LLSD& query_map,
 88		LLMediaCtrl* web)
 89	{
 90		if (params.size() < 2) return false;
 91		LLUUID avatar_id;
 92		if (!avatar_id.set(params[0], FALSE))
 93		{
 94			return false;
 95		}
 96
 97		const std::string verb = params[1].asString();
 98		if (verb == "about")
 99		{
100			LLAvatarActions::showProfile(avatar_id);
101			return true;
102		}
103
104		if (verb == "inspect")
105		{
106			LLFloaterReg::showInstance("inspect_avatar", LLSD().with("avatar_id", avatar_id));
107			return true;
108		}
109
110		if (verb == "im")
111		{
112			LLAvatarActions::startIM(avatar_id);
113			return true;
114		}
115
116		if (verb == "pay")
117		{
118			if (!LLUI::sSettingGroups["config"]->getBOOL("EnableAvatarPay"))
119			{
120				LLNotificationsUtil::add("NoAvatarPay", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit"));
121				return true;
122			}
123
124			LLAvatarActions::pay(avatar_id);
125			return true;
126		}
127
128		if (verb == "offerteleport")
129		{
130			LLAvatarActions::offerTeleport(avatar_id);
131			return true;
132		}
133
134		if (verb == "requestfriend")
135		{
136			LLAvatarActions::requestFriendshipDialog(avatar_id);
137			return true;
138		}
139
140		if (verb == "mute")
141		{
142			if (! LLAvatarActions::isBlocked(avatar_id))
143			{
144				LLAvatarActions::toggleBlock(avatar_id);
145			}
146			return true;
147		}
148
149		if (verb == "unmute")
150		{
151			if (LLAvatarActions::isBlocked(avatar_id))
152			{
153				LLAvatarActions::toggleBlock(avatar_id);
154			}
155			return true;
156		}
157
158		return false;
159	}
160};
161LLAgentHandler gAgentHandler;
162
163
164//-- LLPanelProfile::ChildStack begins ----------------------------------------
165LLPanelProfile::ChildStack::ChildStack()
166:	mParent(NULL)
167{
168}
169
170LLPanelProfile::ChildStack::~ChildStack()
171{
172	while (mStack.size() != 0)
173	{
174		view_list_t& top = mStack.back();
175		for (view_list_t::const_iterator it = top.begin(); it != top.end(); ++it)
176		{
177			LLView* viewp = *it;
178			if (viewp)
179			{
180				viewp->die();
181			}
182		}
183		mStack.pop_back();
184	}
185}
186
187void LLPanelProfile::ChildStack::setParent(LLPanel* parent)
188{
189	llassert_always(parent != NULL);
190	mParent = parent;
191}
192
193/// Save current parent's child views and remove them from the child list.
194bool LLPanelProfile::ChildStack::push()
195{
196	view_list_t vlist = *mParent->getChildList();
197
198	for (view_list_t::const_iterator it = vlist.begin(); it != vlist.end(); ++it)
199	{
200		LLView* viewp = *it;
201		mParent->removeChild(viewp);
202	}
203
204	mStack.push_back(vlist);
205	dump();
206	return true;
207}
208
209/// Restore saved children (adding them back to the child list).
210bool LLPanelProfile::ChildStack::pop()
211{
212	if (mStack.size() == 0)
213	{
214		llwarns << "Empty stack" << llendl;
215		llassert(mStack.size() == 0);
216		return false;
217	}
218
219	view_list_t& top = mStack.back();
220	for (view_list_t::const_iterator it = top.begin(); it != top.end(); ++it)
221	{
222		LLView* viewp = *it;
223		mParent->addChild(viewp);
224	}
225
226	mStack.pop_back();
227	dump();
228	return true;
229}
230
231/// Temporarily add all saved children back.
232void LLPanelProfile::ChildStack::preParentReshape()
233{
234	mSavedStack = mStack;
235	while(mStack.size() > 0)
236	{
237		pop();
238	}
239}
240
241/// Add the temporarily saved children back.
242void LLPanelProfile::ChildStack::postParentReshape()
243{
244	mStack = mSavedStack;
245	mSavedStack = stack_t();
246
247	for (stack_t::const_iterator stack_it = mStack.begin(); stack_it != mStack.end(); ++stack_it)
248	{
249		const view_list_t& vlist = (*stack_it);
250		for (view_list_t::const_iterator list_it = vlist.begin(); list_it != vlist.end(); ++list_it)
251		{
252			LLView* viewp = *list_it;
253			lldebugs << "removing " << viewp->getName() << llendl;
254			mParent->removeChild(viewp);
255		}
256	}
257}
258
259void LLPanelProfile::ChildStack::dump()
260{
261	unsigned lvl = 0;
262	lldebugs << "child stack dump:" << llendl;
263	for (stack_t::const_iterator stack_it = mStack.begin(); stack_it != mStack.end(); ++stack_it, ++lvl)
264	{
265		std::ostringstream dbg_line;
266		dbg_line << "lvl #" << lvl << ":";
267		const view_list_t& vlist = (*stack_it);
268		for (view_list_t::const_iterator list_it = vlist.begin(); list_it != vlist.end(); ++list_it)
269		{
270			dbg_line << " " << (*list_it)->getName();
271		}
272		lldebugs << dbg_line.str() << llendl;
273	}
274}
275
276//-- LLPanelProfile::ChildStack ends ------------------------------------------
277
278LLPanelProfile::LLPanelProfile()
279 : LLPanel()
280 , mAvatarId(LLUUID::null)
281{
282	mChildStack.setParent(this);
283}
284
285BOOL LLPanelProfile::postBuild()
286{
287	LLPanelPicks* panel_picks = findChild<LLPanelPicks>(PANEL_PICKS);
288	panel_picks->setProfilePanel(this);
289
290	getTabContainer()[PANEL_PICKS] = panel_picks;
291
292	return TRUE;
293}
294
295// virtual
296void LLPanelProfile::reshape(S32 width, S32 height, BOOL called_from_parent)
297{
298	// Temporarily add saved children back and reshape them.
299	mChildStack.preParentReshape();
300	LLPanel::reshape(width, height, called_from_parent);
301	mChildStack.postParentReshape();
302}
303
304void LLPanelProfile::onOpen(const LLSD& key)
305{
306	getTabContainer()[PANEL_PICKS]->onOpen(getAvatarId());
307
308	// support commands to open further pieces of UI
309	if (key.has("show_tab_panel"))
310	{
311		std::string panel = key["show_tab_panel"].asString();
312		if (panel == "create_classified")
313		{
314			LLPanelPicks* picks = dynamic_cast<LLPanelPicks *>(getTabContainer()[PANEL_PICKS]);
315			if (picks)
316			{
317				picks->createNewClassified();
318			}
319		}
320		else if (panel == "classified_details")
321		{
322			LLPanelPicks* picks = dynamic_cast<LLPanelPicks *>(getTabContainer()[PANEL_PICKS]);
323			if (picks)
324			{
325				LLSD params = key;
326				params.erase("show_tab_panel");
327				params.erase("open_tab_name");
328				picks->openClassifiedInfo(params);
329			}
330		}
331		else if (panel == "edit_classified")
332		{
333			LLPanelPicks* picks = dynamic_cast<LLPanelPicks *>(getTabContainer()[PANEL_PICKS]);
334			if (picks)
335			{
336				LLSD params = key;
337				params.erase("show_tab_panel");
338				params.erase("open_tab_name");
339				picks->openClassifiedEdit(params);
340			}
341		}
342		else if (panel == "create_pick")
343		{
344			LLPanelPicks* picks = dynamic_cast<LLPanelPicks *>(getTabContainer()[PANEL_PICKS]);
345			if (picks)
346			{
347				picks->createNewPick();
348			}
349		}
350		else if (panel == "edit_pick")
351		{
352			LLPanelPicks* picks = dynamic_cast<LLPanelPicks *>(getTabContainer()[PANEL_PICKS]);
353			if (picks)
354			{
355				LLSD params = key;
356				params.erase("show_tab_panel");
357				params.erase("open_tab_name");
358				picks->openPickEdit(params);
359			}
360		}
361	}
362}
363
364void LLPanelProfile::onTabSelected(const LLSD& param)
365{
366	std::string tab_name = param.asString();
367	if (NULL != getTabContainer()[tab_name])
368	{
369		getTabContainer()[tab_name]->onOpen(getAvatarId());
370	}
371}
372
373void LLPanelProfile::openPanel(LLPanel* panel, const LLSD& params)
374{
375	// Hide currently visible panel (STORM-690).
376	mChildStack.push();
377
378	// Add the panel or bring it to front.
379	if (panel->getParent() != this)
380	{
381		addChild(panel);
382	}
383	else
384	{
385		sendChildToFront(panel);
386	}
387
388	panel->setVisible(TRUE);
389	panel->setFocus(TRUE); // prevent losing focus by the floater
390	panel->onOpen(params);
391
392	LLRect new_rect = getRect();
393	panel->reshape(new_rect.getWidth(), new_rect.getHeight());
394	new_rect.setLeftTopAndSize(0, new_rect.getHeight(), new_rect.getWidth(), new_rect.getHeight());
395	panel->setRect(new_rect);
396}
397
398void LLPanelProfile::closePanel(LLPanel* panel)
399{
400	panel->setVisible(FALSE);
401
402	if (panel->getParent() == this) 
403	{
404		removeChild(panel);
405
406		// Make the underlying panel visible.
407		mChildStack.pop();
408
409		// Prevent losing focus by the floater
410		const child_list_t* child_list = getChildList();
411		if (child_list->size() > 0)
412		{
413			child_list->front()->setFocus(TRUE);
414		}
415		else
416		{
417			llwarns << "No underlying panel to focus." << llendl;
418		}
419	}
420}
421
422S32 LLPanelProfile::notifyParent(const LLSD& info)
423{
424	std::string action = info["action"];
425	// lets update Picks list after Pick was saved
426	if("save_new_pick" == action)
427	{
428		onOpen(info);
429		return 1;
430	}
431
432	return LLPanel::notifyParent(info);
433}