PageRenderTime 107ms CodeModel.GetById 30ms app.highlight 60ms RepoModel.GetById 11ms app.codeStats 0ms

/indra/newview/llpanellandmarkinfo.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 510 lines | 360 code | 79 blank | 71 comment | 39 complexity | 843437fc8e22c0e300b85ce4915354d5 MD5 | raw file
  1/**
  2 * @file llpanellandmarkinfo.cpp
  3 * @brief Displays landmark info in Side Tray.
  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
 29#include "llpanellandmarkinfo.h"
 30
 31#include "llcombobox.h"
 32#include "lliconctrl.h"
 33#include "llinventoryfunctions.h"
 34#include "lllineeditor.h"
 35#include "lltextbox.h"
 36#include "lltexteditor.h"
 37#include "lltrans.h"
 38
 39#include "llagent.h"
 40#include "llagentui.h"
 41#include "lllandmarkactions.h"
 42#include "llslurl.h"
 43#include "llviewerinventory.h"
 44#include "llviewerparcelmgr.h"
 45#include "llviewerregion.h"
 46
 47//----------------------------------------------------------------------------
 48// Aux types and methods
 49//----------------------------------------------------------------------------
 50
 51typedef std::pair<LLUUID, std::string> folder_pair_t;
 52
 53static bool cmp_folders(const folder_pair_t& left, const folder_pair_t& right);
 54static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats);
 55
 56static LLRegisterPanelClassWrapper<LLPanelLandmarkInfo> t_landmark_info("panel_landmark_info");
 57
 58// Statics for textures filenames
 59static std::string icon_pg;
 60static std::string icon_m;
 61static std::string icon_r;
 62
 63LLPanelLandmarkInfo::LLPanelLandmarkInfo()
 64:	LLPanelPlaceInfo()
 65{}
 66
 67// virtual
 68LLPanelLandmarkInfo::~LLPanelLandmarkInfo()
 69{}
 70
 71// virtual
 72BOOL LLPanelLandmarkInfo::postBuild()
 73{
 74	LLPanelPlaceInfo::postBuild();
 75
 76	mOwner = getChild<LLTextBox>("owner");
 77	mCreator = getChild<LLTextBox>("creator");
 78	mCreated = getChild<LLTextBox>("created");
 79
 80	mLandmarkTitle = getChild<LLTextBox>("title_value");
 81	mLandmarkTitleEditor = getChild<LLLineEditor>("title_editor");
 82	mNotesEditor = getChild<LLTextEditor>("notes_editor");
 83	mFolderCombo = getChild<LLComboBox>("folder_combo");
 84
 85	icon_pg = getString("icon_PG");
 86	icon_m = getString("icon_M");
 87	icon_r = getString("icon_R");
 88
 89	return TRUE;
 90}
 91
 92// virtual
 93void LLPanelLandmarkInfo::resetLocation()
 94{
 95	LLPanelPlaceInfo::resetLocation();
 96
 97	std::string loading = LLTrans::getString("LoadingData");
 98	mCreator->setText(loading);
 99	mOwner->setText(loading);
100	mCreated->setText(loading);
101	mLandmarkTitle->setText(LLStringUtil::null);
102	mLandmarkTitleEditor->setText(LLStringUtil::null);
103	mNotesEditor->setText(LLStringUtil::null);
104}
105
106// virtual
107void LLPanelLandmarkInfo::setInfoType(EInfoType type)
108{
109	LLPanel* landmark_info_panel = getChild<LLPanel>("landmark_info_panel");
110
111	bool is_info_type_create_landmark = type == CREATE_LANDMARK;
112
113	landmark_info_panel->setVisible(type == LANDMARK);
114
115	getChild<LLTextBox>("folder_label")->setVisible(is_info_type_create_landmark);
116	mFolderCombo->setVisible(is_info_type_create_landmark);
117
118	switch(type)
119	{
120		case CREATE_LANDMARK:
121		{
122			mCurrentTitle = getString("title_create_landmark");
123
124			mLandmarkTitle->setVisible(FALSE);
125			mLandmarkTitleEditor->setVisible(TRUE);
126			mNotesEditor->setEnabled(TRUE);
127
128			LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance();
129			std::string name = parcel_mgr->getAgentParcelName();
130			LLVector3 agent_pos = gAgent.getPositionAgent();
131
132			if (name.empty())
133			{
134				S32 region_x = llround(agent_pos.mV[VX]);
135				S32 region_y = llround(agent_pos.mV[VY]);
136				S32 region_z = llround(agent_pos.mV[VZ]);
137
138				std::string region_name;
139				LLViewerRegion* region = parcel_mgr->getSelectionRegion();
140				if (region)
141				{
142					region_name = region->getName();
143				}
144				else
145				{
146					region_name = getString("unknown");
147				}
148
149				mLandmarkTitleEditor->setText(llformat("%s (%d, %d, %d)",
150									  region_name.c_str(), region_x, region_y, region_z));
151			}
152			else
153			{
154				mLandmarkTitleEditor->setText(name);
155			}
156
157			std::string desc;
158			LLAgentUI::buildLocationString(desc, LLAgentUI::LOCATION_FORMAT_FULL, agent_pos);
159			mNotesEditor->setText(desc);
160
161			// Moved landmark creation here from LLPanelLandmarkInfo::processParcelInfo()
162			// because we use only agent's current coordinates instead of waiting for
163			// remote parcel request to complete.
164			if (!LLLandmarkActions::landmarkAlreadyExists())
165			{
166				createLandmark(LLUUID());
167			}
168		}
169		break;
170
171		case LANDMARK:
172		default:
173			mCurrentTitle = getString("title_landmark");
174
175			mLandmarkTitle->setVisible(TRUE);
176			mLandmarkTitleEditor->setVisible(FALSE);
177			mNotesEditor->setEnabled(FALSE);
178		break;
179	}
180
181	populateFoldersList();
182
183	// Prevent the floater from losing focus (if the sidepanel is undocked).
184	setFocus(TRUE);
185
186	LLPanelPlaceInfo::setInfoType(type);
187}
188
189// virtual
190void LLPanelLandmarkInfo::processParcelInfo(const LLParcelData& parcel_data)
191{
192	LLPanelPlaceInfo::processParcelInfo(parcel_data);
193
194	// HACK: Flag 0x2 == adult region,
195	// Flag 0x1 == mature region, otherwise assume PG
196	if (parcel_data.flags & 0x2)
197	{
198		mMaturityRatingIcon->setValue(icon_r);
199		mMaturityRatingText->setText(LLViewerRegion::accessToString(SIM_ACCESS_ADULT));
200	}
201	else if (parcel_data.flags & 0x1)
202	{
203		mMaturityRatingIcon->setValue(icon_m);
204		mMaturityRatingText->setText(LLViewerRegion::accessToString(SIM_ACCESS_MATURE));
205	}
206	else
207	{
208		mMaturityRatingIcon->setValue(icon_pg);
209		mMaturityRatingText->setText(LLViewerRegion::accessToString(SIM_ACCESS_PG));
210	}
211
212	S32 region_x;
213	S32 region_y;
214	S32 region_z;
215
216	// If the region position is zero, grab position from the global
217	if(mPosRegion.isExactlyZero())
218	{
219		region_x = llround(parcel_data.global_x) % REGION_WIDTH_UNITS;
220		region_y = llround(parcel_data.global_y) % REGION_WIDTH_UNITS;
221		region_z = llround(parcel_data.global_z);
222	}
223	else
224	{
225		region_x = llround(mPosRegion.mV[VX]);
226		region_y = llround(mPosRegion.mV[VY]);
227		region_z = llround(mPosRegion.mV[VZ]);
228	}
229
230	LLSD info;
231	info["update_verbs"] = true;
232	info["global_x"] = parcel_data.global_x;
233	info["global_y"] = parcel_data.global_y;
234	info["global_z"] = parcel_data.global_z;
235	notifyParent(info);
236}
237
238void LLPanelLandmarkInfo::displayItemInfo(const LLInventoryItem* pItem)
239{
240	if (!pItem)
241		return;
242
243	if(!gCacheName)
244		return;
245
246	const LLPermissions& perm = pItem->getPermissions();
247
248	//////////////////
249	// CREATOR NAME //
250	//////////////////
251	if (pItem->getCreatorUUID().notNull())
252	{
253		// IDEVO
254		LLUUID creator_id = pItem->getCreatorUUID();
255		std::string name =
256			LLSLURL("agent", creator_id, "inspect").getSLURLString();
257		mCreator->setText(name);
258	}
259	else
260	{
261		mCreator->setText(getString("unknown"));
262	}
263
264	////////////////
265	// OWNER NAME //
266	////////////////
267	if(perm.isOwned())
268	{
269		std::string name;
270		if (perm.isGroupOwned())
271		{
272			LLUUID group_id = perm.getGroup();
273			name = LLSLURL("group", group_id, "inspect").getSLURLString();
274		}
275		else
276		{
277			LLUUID owner_id = perm.getOwner();
278			name = LLSLURL("agent", owner_id, "inspect").getSLURLString();
279		}
280		mOwner->setText(name);
281	}
282	else
283	{
284		mOwner->setText(getString("public"));
285	}
286
287	//////////////////
288	// ACQUIRE DATE //
289	//////////////////
290	time_t time_utc = pItem->getCreationDate();
291	if (0 == time_utc)
292	{
293		mCreated->setText(getString("unknown"));
294	}
295	else
296	{
297		std::string timeStr = getString("acquired_date");
298		LLSD substitution;
299		substitution["datetime"] = (S32) time_utc;
300		LLStringUtil::format (timeStr, substitution);
301		mCreated->setText(timeStr);
302	}
303
304	mLandmarkTitle->setText(pItem->getName());
305	mLandmarkTitleEditor->setText(pItem->getName());
306	mNotesEditor->setText(pItem->getDescription());
307}
308
309void LLPanelLandmarkInfo::toggleLandmarkEditMode(BOOL enabled)
310{
311	// If switching to edit mode while creating landmark
312	// the "Create Landmark" title remains.
313	if (enabled && mInfoType != CREATE_LANDMARK)
314	{
315		mTitle->setText(getString("title_edit_landmark"));
316	}
317	else
318	{
319		mTitle->setText(mCurrentTitle);
320
321		mLandmarkTitle->setText(mLandmarkTitleEditor->getText());
322	}
323
324	if (mNotesEditor->getReadOnly() ==  (enabled == TRUE))
325	{
326		mLandmarkTitle->setVisible(!enabled);
327		mLandmarkTitleEditor->setVisible(enabled);
328		mNotesEditor->setReadOnly(!enabled);
329		mFolderCombo->setVisible(enabled);
330		getChild<LLTextBox>("folder_label")->setVisible(enabled);
331
332		// HACK: To change the text color in a text editor
333		// when it was enabled/disabled we set the text once again.
334		mNotesEditor->setText(mNotesEditor->getText());
335	}
336
337	// Prevent the floater from losing focus (if the sidepanel is undocked).
338	setFocus(TRUE);
339}
340
341const std::string& LLPanelLandmarkInfo::getLandmarkTitle() const
342{
343	return mLandmarkTitleEditor->getText();
344}
345
346const std::string LLPanelLandmarkInfo::getLandmarkNotes() const
347{
348	return mNotesEditor->getText();
349}
350
351const LLUUID LLPanelLandmarkInfo::getLandmarkFolder() const
352{
353	return mFolderCombo->getValue().asUUID();
354}
355
356BOOL LLPanelLandmarkInfo::setLandmarkFolder(const LLUUID& id)
357{
358	return mFolderCombo->setCurrentByID(id);
359}
360
361void LLPanelLandmarkInfo::createLandmark(const LLUUID& folder_id)
362{
363	std::string name = mLandmarkTitleEditor->getText();
364	std::string desc = mNotesEditor->getText();
365
366	LLStringUtil::trim(name);
367	LLStringUtil::trim(desc);
368
369	// If typed name is empty use the parcel name instead.
370	if (name.empty())
371	{
372		name = mParcelName->getText();
373
374		// If no parcel exists use the region name instead.
375		if (name.empty())
376		{
377			name = mRegionName->getText();
378		}
379	}
380
381	LLStringUtil::replaceChar(desc, '\n', ' ');
382
383	// If no folder chosen use the "Landmarks" folder.
384	LLLandmarkActions::createLandmarkHere(name, desc,
385		folder_id.notNull() ? folder_id : gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK));
386}
387
388// static
389std::string LLPanelLandmarkInfo::getFullFolderName(const LLViewerInventoryCategory* cat)
390{
391	std::string name;
392	LLUUID parent_id;
393
394	llassert(cat);
395	if (cat)
396	{
397		name = cat->getName();
398		parent_id = cat->getParentUUID();
399		bool is_under_root_category = parent_id == gInventory.getRootFolderID();
400
401		// we don't want "My Inventory" to appear in the name
402		while ((parent_id = cat->getParentUUID()).notNull())
403		{
404			cat = gInventory.getCategory(parent_id);
405			llassert(cat);
406			if (cat)
407			{
408				if (is_under_root_category || cat->getParentUUID() == gInventory.getRootFolderID())
409				{
410					std::string localized_name;
411
412					// Looking for translation only for protected type categories
413					// to avoid warnings about non existent string in strings.xml.
414					bool is_protected_type = LLFolderType::lookupIsProtectedType(cat->getPreferredType());
415
416					if (is_under_root_category)
417					{
418						// translate category name, if it's right below the root
419						bool is_found = is_protected_type && LLTrans::findString(localized_name, "InvFolder " + name);
420						name = is_found ? localized_name : name;
421					}
422					else
423					{
424						bool is_found = is_protected_type && LLTrans::findString(localized_name, "InvFolder " + cat->getName());
425
426						// add translated category name to folder's full name
427						name = (is_found ? localized_name : cat->getName()) + "/" + name;
428					}
429
430					break;
431				}
432				else
433				{
434					name = cat->getName() + "/" + name;
435				}
436			}
437		}
438	}
439
440	return name;
441}
442
443void LLPanelLandmarkInfo::populateFoldersList()
444{
445	// Collect all folders that can contain landmarks.
446	LLInventoryModel::cat_array_t cats;
447	collectLandmarkFolders(cats);
448
449	mFolderCombo->removeall();
450
451	// Put the "Landmarks" folder first in list.
452	LLUUID landmarks_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK);
453	const LLViewerInventoryCategory* lmcat = gInventory.getCategory(landmarks_id);
454	if (!lmcat)
455	{
456		llwarns << "Cannot find the landmarks folder" << llendl;
457	}
458	else
459	{
460		std::string cat_full_name = getFullFolderName(lmcat);
461		mFolderCombo->add(cat_full_name, lmcat->getUUID());
462	}
463
464	typedef std::vector<folder_pair_t> folder_vec_t;
465	folder_vec_t folders;
466	// Sort the folders by their full name.
467	for (S32 i = 0; i < cats.count(); i++)
468	{
469		const LLViewerInventoryCategory* cat = cats.get(i);
470		std::string cat_full_name = getFullFolderName(cat);
471		folders.push_back(folder_pair_t(cat->getUUID(), cat_full_name));
472	}
473	sort(folders.begin(), folders.end(), cmp_folders);
474
475	// Finally, populate the combobox.
476	for (folder_vec_t::const_iterator it = folders.begin(); it != folders.end(); it++)
477		mFolderCombo->add(it->second, LLSD(it->first));
478}
479
480static bool cmp_folders(const folder_pair_t& left, const folder_pair_t& right)
481{
482	return left.second < right.second;
483}
484
485static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats)
486{
487	LLUUID landmarks_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK);
488
489	// Add descendent folders of the "Landmarks" category.
490	LLInventoryModel::item_array_t items; // unused
491	LLIsType is_category(LLAssetType::AT_CATEGORY);
492	gInventory.collectDescendentsIf(
493		landmarks_id,
494		cats,
495		items,
496		LLInventoryModel::EXCLUDE_TRASH,
497		is_category);
498
499	// Add the "My Favorites" category.
500	LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
501	LLViewerInventoryCategory* favorites_cat = gInventory.getCategory(favorites_id);
502	if (!favorites_cat)
503	{
504		llwarns << "Cannot find the favorites folder" << llendl;
505	}
506	else
507	{
508		cats.put(favorites_cat);
509	}
510}