diff options
author | McCabe Maxsted | 2010-09-07 00:46:37 -0700 |
---|---|---|
committer | McCabe Maxsted | 2010-09-07 00:46:37 -0700 |
commit | 43cd306e901c444b997614c8e3d16ef79c3aa044 (patch) | |
tree | 8c07a54e874a137ba936e4dca2b8330f991a4446 /linden/indra/newview/llfloaterteleporthistory.cpp | |
parent | Use solid circles instead of asterisks for password fields. (diff) | |
download | meta-impy-43cd306e901c444b997614c8e3d16ef79c3aa044.zip meta-impy-43cd306e901c444b997614c8e3d16ef79c3aa044.tar.gz meta-impy-43cd306e901c444b997614c8e3d16ef79c3aa044.tar.bz2 meta-impy-43cd306e901c444b997614c8e3d16ef79c3aa044.tar.xz |
Applied #472: teleport history from Emerald, patch by Ansariel Hiler, feature originally by Zi Ree
Diffstat (limited to 'linden/indra/newview/llfloaterteleporthistory.cpp')
-rw-r--r-- | linden/indra/newview/llfloaterteleporthistory.cpp | 348 |
1 files changed, 348 insertions, 0 deletions
diff --git a/linden/indra/newview/llfloaterteleporthistory.cpp b/linden/indra/newview/llfloaterteleporthistory.cpp new file mode 100644 index 0000000..70a2d71 --- /dev/null +++ b/linden/indra/newview/llfloaterteleporthistory.cpp | |||
@@ -0,0 +1,348 @@ | |||
1 | /** | ||
2 | * @file llfloaterteleporthistory.cpp | ||
3 | * @author Zi Ree | ||
4 | * @brief LLFloaterTeleportHistory class implementation | ||
5 | * | ||
6 | * $LicenseInfo:firstyear=2001&license=viewergpl$ | ||
7 | * | ||
8 | * Copyright (c) 2008, Linden Research, Inc. | ||
9 | * | ||
10 | * Second Life Viewer Source Code | ||
11 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
12 | * to you under the terms of the GNU General Public License, version 2.0 | ||
13 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
14 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
15 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
16 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 | ||
17 | * | ||
18 | * There are special exceptions to the terms and conditions of the GPL as | ||
19 | * it is applied to this Source Code. View the full text of the exception | ||
20 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
21 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception | ||
22 | * | ||
23 | * By copying, modifying or distributing this software, you acknowledge | ||
24 | * that you have read and understood your obligations described above, | ||
25 | * and agree to abide by those obligations. | ||
26 | * | ||
27 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
28 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
29 | * COMPLETENESS OR PERFORMANCE. | ||
30 | * $/LicenseInfo$ | ||
31 | */ | ||
32 | |||
33 | #include "llviewerprecompiledheaders.h" | ||
34 | |||
35 | #include "linden_common.h" | ||
36 | |||
37 | #include "llfloaterteleporthistory.h" | ||
38 | #include "llfloaterworldmap.h" | ||
39 | #include "lltimer.h" | ||
40 | #include "lluictrlfactory.h" | ||
41 | #include "llurldispatcher.h" | ||
42 | #include "llurlsimstring.h" | ||
43 | #include "llviewercontrol.h" // gSavedSettings | ||
44 | #include "llviewerwindow.h" | ||
45 | #include "llweb.h" | ||
46 | |||
47 | #include "apr_time.h" | ||
48 | |||
49 | // [RLVa:KB] - Emerald specific | ||
50 | #include "rlvhandler.h" | ||
51 | #include "llsdserialize.h" | ||
52 | // [/RLVa:KB] | ||
53 | |||
54 | // globals | ||
55 | LLFloaterTeleportHistory* gFloaterTeleportHistory; | ||
56 | |||
57 | LLFloaterTeleportHistory::LLFloaterTeleportHistory() | ||
58 | : LLFloater(std::string("teleporthistory")), | ||
59 | mPlacesInList(NULL), | ||
60 | mPlacesOutList(NULL), | ||
61 | pItem(NULL), | ||
62 | id(0) | ||
63 | { | ||
64 | LLUICtrlFactory::getInstance()->buildFloater(this, "floater_teleport_history.xml", NULL); | ||
65 | } | ||
66 | |||
67 | // virtual | ||
68 | LLFloaterTeleportHistory::~LLFloaterTeleportHistory() | ||
69 | { | ||
70 | } | ||
71 | |||
72 | // virtual | ||
73 | void LLFloaterTeleportHistory::onFocusReceived() | ||
74 | { | ||
75 | // take care to enable or disable buttons depending on the selection in the places list | ||
76 | if(pItem) | ||
77 | { | ||
78 | setButtonsEnabled(TRUE); | ||
79 | } | ||
80 | else | ||
81 | { | ||
82 | setButtonsEnabled(FALSE); | ||
83 | } | ||
84 | LLFloater::onFocusReceived(); | ||
85 | } | ||
86 | |||
87 | BOOL LLFloaterTeleportHistory::postBuild() | ||
88 | { | ||
89 | // make sure the cached pointer to the scroll list is valid | ||
90 | mPlacesInList=getChild<LLScrollListCtrl>("places_list_in"); | ||
91 | if(!mPlacesInList) | ||
92 | { | ||
93 | llwarns << "coud not get pointer to places list in" << llendl; | ||
94 | return FALSE; | ||
95 | } | ||
96 | mPlacesOutList=getChild<LLScrollListCtrl>("places_list_out"); | ||
97 | if(!mPlacesOutList) | ||
98 | { | ||
99 | llwarns << "coud not get pointer to places list out" << llendl; | ||
100 | return FALSE; | ||
101 | } | ||
102 | |||
103 | // setup callbacks for the scroll list | ||
104 | mPlacesInList->setDoubleClickCallback(onTeleport); | ||
105 | mPlacesOutList->setDoubleClickCallback(onTeleport); | ||
106 | childSetCommitCallback("places_list_in", onInPlacesSelected, this); | ||
107 | childSetCommitCallback("places_list_out", onOutPlacesSelected, this); | ||
108 | childSetAction("teleport", onTeleport, this); | ||
109 | childSetAction("show_on_map", onShowOnMap, this); | ||
110 | childSetAction("copy_slurl", onCopySLURL, this); | ||
111 | loadEntrys(); | ||
112 | |||
113 | return TRUE; | ||
114 | } | ||
115 | void LLFloaterTeleportHistory::saveEntry(LLSD toSave) | ||
116 | { | ||
117 | tpList.append(toSave); | ||
118 | std::string filename=getFileName(); | ||
119 | llofstream file; | ||
120 | file.open(filename.c_str()); | ||
121 | LLSDSerialize::toPrettyXML(tpList, file); | ||
122 | file.close(); | ||
123 | } | ||
124 | |||
125 | std::string LLFloaterTeleportHistory::getFileName() | ||
126 | { | ||
127 | std::string path=gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, ""); | ||
128 | |||
129 | if (!path.empty()) | ||
130 | { | ||
131 | path = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "teleport_history.xml"); | ||
132 | } | ||
133 | return path; | ||
134 | } | ||
135 | void LLFloaterTeleportHistory::loadEntrys() | ||
136 | { | ||
137 | std::string filename=getFileName(); | ||
138 | if (filename.empty()) | ||
139 | { | ||
140 | llinfos << "no valid user directory." << llendl; | ||
141 | return; | ||
142 | } | ||
143 | llifstream file; | ||
144 | file.open(filename.c_str()); | ||
145 | if (file.is_open()) | ||
146 | LLSDSerialize::fromXML(tpList, file); | ||
147 | file.close(); | ||
148 | |||
149 | for(int i = 0;i<(int)tpList.size();i++) | ||
150 | { | ||
151 | LLSD data = tpList[i]; | ||
152 | LLScrollListCtrl* pItemPointer; | ||
153 | if(data["out"].asBoolean()) | ||
154 | pItemPointer=mPlacesOutList; | ||
155 | else | ||
156 | pItemPointer=mPlacesInList; | ||
157 | |||
158 | pItemPointer->addElement(data, ADD_TOP); | ||
159 | pItemPointer->deselectAllItems(TRUE); | ||
160 | setButtonsEnabled(FALSE); | ||
161 | id++; | ||
162 | } | ||
163 | } | ||
164 | void LLFloaterTeleportHistory::addEntry(std::string regionName, S16 x, S16 y, S16 z,bool outList) | ||
165 | { | ||
166 | LLScrollListCtrl* pItemPointer; | ||
167 | if(outList) | ||
168 | pItemPointer=mPlacesOutList; | ||
169 | else | ||
170 | pItemPointer=mPlacesInList; | ||
171 | // only if the cached scroll list pointer is valid | ||
172 | if(pItemPointer) | ||
173 | { | ||
174 | // prepare display of position | ||
175 | std::string position=llformat("%d, %d, %d", x, y, z); | ||
176 | // prepare simstring for later parsing | ||
177 | std::string simString = regionName + llformat("/%d/%d/%d", x, y, z); | ||
178 | simString = LLWeb::escapeURL(simString); | ||
179 | |||
180 | // check if we are in daylight savings time | ||
181 | std::string timeZone = "PST"; | ||
182 | if(is_daylight_savings()) timeZone = "PDT"; | ||
183 | |||
184 | // do all time related stuff as closely together as possible, because every other operation | ||
185 | // might change the internal tm* buffer | ||
186 | struct tm* internal_time; | ||
187 | internal_time = utc_to_pacific_time(time_corrected(), is_daylight_savings()); | ||
188 | std::string timeString=llformat("%02d/%02d/%04d - %02d:%02d:%02d ",internal_time->tm_mon+1,internal_time->tm_mday,internal_time->tm_year+1900,internal_time->tm_hour, internal_time->tm_min, internal_time->tm_sec)+timeZone; | ||
189 | |||
190 | // build the list entry | ||
191 | LLSD value; | ||
192 | value["id"] = id; | ||
193 | value["columns"][0]["column"] = "region"; | ||
194 | value["columns"][0]["value"] = regionName; | ||
195 | value["columns"][1]["column"] = "position"; | ||
196 | value["columns"][1]["value"] = position; | ||
197 | value["columns"][2]["column"] = "visited"; | ||
198 | value["columns"][2]["value"] = timeString; | ||
199 | |||
200 | // these columns are hidden and serve as data storage for simstring and SLURL | ||
201 | value["columns"][3]["column"] = "slurl"; | ||
202 | value["columns"][3]["value"] = LLURLDispatcher::buildSLURL(regionName, x, y, z); | ||
203 | value["columns"][4]["column"] = "simstring"; | ||
204 | value["columns"][4]["value"] = simString; | ||
205 | value["out"]=outList; | ||
206 | |||
207 | // [RLVa:KB] - Alternate: Emerald-370 | ||
208 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) | ||
209 | { | ||
210 | // TODO: This is the original code from Emerald. It | ||
211 | // uses the class RlvStrings, defined in rlvcommon.cpp | ||
212 | // to load localized strings. For Imprudence we use the | ||
213 | // old fashioned way via RlvHandler with English | ||
214 | // strings only! | ||
215 | // value["columns"][0]["value"] = RlvStrings::getString(RLV_STRING_HIDDEN_REGION); | ||
216 | // value["columns"][1]["value"] = RlvStrings::getString(RLV_STRING_HIDDEN); | ||
217 | // value["columns"][3]["value"] = RlvStrings::getString(RLV_STRING_HIDDEN); | ||
218 | // value["columns"][4]["value"] = RlvStrings::getString(RLV_STRING_HIDDEN); | ||
219 | |||
220 | value["columns"][0]["value"] = RlvHandler::cstrHiddenRegion; | ||
221 | value["columns"][1]["value"] = RlvHandler::cstrHidden; | ||
222 | value["columns"][3]["value"] = RlvHandler::cstrHidden; | ||
223 | value["columns"][4]["value"] = RlvHandler::cstrHidden; | ||
224 | } | ||
225 | // [/RLVa:KB] | ||
226 | saveEntry(value); | ||
227 | // add the new list entry on top of the list, deselect all and disable the buttons | ||
228 | pItemPointer->addElement(value, ADD_TOP); | ||
229 | pItemPointer->deselectAllItems(TRUE); | ||
230 | setButtonsEnabled(FALSE); | ||
231 | id++; | ||
232 | } | ||
233 | else | ||
234 | { | ||
235 | llwarns << "pointer to places list is NULL" << llendl; | ||
236 | } | ||
237 | } | ||
238 | |||
239 | void LLFloaterTeleportHistory::setButtonsEnabled(BOOL on) | ||
240 | { | ||
241 | // [RLVa:KB] - Alternate: Emerald-370 | ||
242 | if (rlv_handler_t::isEnabled()) | ||
243 | { | ||
244 | // TODO: This is the original code from Emerald. It | ||
245 | // uses the class RlvStrings, defined in rlvcommon.cpp | ||
246 | // to load localized strings. For Imprudence we use the | ||
247 | // old fashioned way via RlvHandler with English | ||
248 | // strings only! | ||
249 | //if ( (pItem) && (pItem->getColumn(4)) && (RlvStrings::getString(RLV_STRING_HIDDEN) == pItem->getColumn(4)->getValue().asString()) ) | ||
250 | if ( (pItem) && (pItem->getColumn(4)) && (RlvHandler::cstrHidden == pItem->getColumn(4)->getValue().asString()) ) | ||
251 | { | ||
252 | on = FALSE; | ||
253 | } | ||
254 | } | ||
255 | // [/RLVa:K] | ||
256 | |||
257 | // enable or disable buttons | ||
258 | childSetEnabled("teleport", on); | ||
259 | childSetEnabled("show_on_map", on); | ||
260 | childSetEnabled("copy_slurl", on); | ||
261 | } | ||
262 | |||
263 | // virtual | ||
264 | void LLFloaterTeleportHistory::onClose(bool app_quitting) | ||
265 | { | ||
266 | LLFloater::setVisible(FALSE); | ||
267 | } | ||
268 | |||
269 | // virtual | ||
270 | BOOL LLFloaterTeleportHistory::canClose() | ||
271 | { | ||
272 | return !LLApp::isExiting(); | ||
273 | } | ||
274 | |||
275 | // callbacks | ||
276 | |||
277 | // static | ||
278 | void LLFloaterTeleportHistory::onInPlacesSelected(LLUICtrl* /* ctrl */, void* data) | ||
279 | { | ||
280 | LLFloaterTeleportHistory* self = (LLFloaterTeleportHistory*) data; | ||
281 | self->mPlacesOutList->deselectAllItems(); | ||
282 | self->pItem = self->mPlacesInList->getFirstSelected(); | ||
283 | // on selection change check if we need to enable or disable buttons | ||
284 | if(self->pItem) | ||
285 | { | ||
286 | self->setButtonsEnabled(TRUE); | ||
287 | } | ||
288 | else | ||
289 | { | ||
290 | self->setButtonsEnabled(FALSE); | ||
291 | } | ||
292 | } | ||
293 | |||
294 | // static | ||
295 | void LLFloaterTeleportHistory::onOutPlacesSelected(LLUICtrl* /* ctrl */, void* data) | ||
296 | { | ||
297 | LLFloaterTeleportHistory* self = (LLFloaterTeleportHistory*) data; | ||
298 | self->mPlacesInList->deselectAllItems(); | ||
299 | self->pItem = self->mPlacesOutList->getFirstSelected(); | ||
300 | // on selection change check if we need to enable or disable buttons | ||
301 | if(self->pItem) | ||
302 | { | ||
303 | self->setButtonsEnabled(TRUE); | ||
304 | } | ||
305 | else | ||
306 | { | ||
307 | self->setButtonsEnabled(FALSE); | ||
308 | } | ||
309 | } | ||
310 | |||
311 | // static | ||
312 | void LLFloaterTeleportHistory::onTeleport(void* data) | ||
313 | { | ||
314 | LLFloaterTeleportHistory* self = (LLFloaterTeleportHistory*) data; | ||
315 | |||
316 | // build secondlife::/app link from simstring for instant teleport to destination | ||
317 | std::string slapp="secondlife:///app/teleport/" + self->pItem->getColumn(4)->getValue().asString(); | ||
318 | LLURLDispatcher::dispatch(slapp, NULL, true); | ||
319 | } | ||
320 | |||
321 | // static | ||
322 | void LLFloaterTeleportHistory::onShowOnMap(void* data) | ||
323 | { | ||
324 | LLFloaterTeleportHistory* self = (LLFloaterTeleportHistory*) data; | ||
325 | |||
326 | // get simstring from selected entry and parse it for its components | ||
327 | std::string simString = self->pItem->getColumn(4)->getValue().asString(); | ||
328 | std::string region = ""; | ||
329 | S32 x = 128; | ||
330 | S32 y = 128; | ||
331 | S32 z = 20; | ||
332 | |||
333 | LLURLSimString::parse(simString, ®ion, &x, &y, &z); | ||
334 | |||
335 | // point world map at position | ||
336 | gFloaterWorldMap->trackURL(region, x, y, z); | ||
337 | LLFloaterWorldMap::show(NULL, TRUE); | ||
338 | } | ||
339 | |||
340 | // static | ||
341 | void LLFloaterTeleportHistory::onCopySLURL(void* data) | ||
342 | { | ||
343 | LLFloaterTeleportHistory* self = (LLFloaterTeleportHistory*) data; | ||
344 | |||
345 | // get SLURL of the selected entry and copy it to the clipboard | ||
346 | std::string SLURL=self->pItem->getColumn(3)->getValue().asString(); | ||
347 | gViewerWindow->mWindow->copyTextToClipboard(utf8str_to_wstring(SLURL)); | ||
348 | } | ||