Skip to content

Commit 5517a49

Browse files
committed
#2922 Add 'Create Landmark' to the chat context menu
1 parent 16437af commit 5517a49

18 files changed

+326
-92
lines changed

indra/llcorehttp/httpcommon.cpp

Lines changed: 11 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ std::string HttpStatus::toHex() const
6262

6363
std::string HttpStatus::toString() const
6464
{
65-
static const char * llcore_errors[] =
65+
static const std::vector<std::string> llcore_errors =
6666
{
6767
"",
6868
"HTTP error reply status",
@@ -76,16 +76,9 @@ std::string HttpStatus::toString() const
7676
"Invalid HTTP status code received from server",
7777
"Could not allocate required resource"
7878
};
79-
static const int llcore_errors_count(sizeof(llcore_errors) / sizeof(llcore_errors[0]));
8079

81-
static const struct
82-
{
83-
type_enum_t mCode;
84-
const char * mText;
85-
}
86-
http_errors[] =
80+
static const std::map<type_enum_t, std::string> http_errors =
8781
{
88-
// Keep sorted by mCode, we binary search this list.
8982
{ 100, "Continue" },
9083
{ 101, "Switching Protocols" },
9184
{ 200, "OK" },
@@ -128,12 +121,12 @@ std::string HttpStatus::toString() const
128121
{ 504, "Gateway Time-out" },
129122
{ 505, "HTTP Version not supported" }
130123
};
131-
static const int http_errors_count(sizeof(http_errors) / sizeof(http_errors[0]));
132124

133125
if (*this)
134126
{
135-
return std::string("");
127+
return LLStringUtil::null;
136128
}
129+
137130
switch (getType())
138131
{
139132
case EXT_CURL_EASY:
@@ -143,9 +136,9 @@ std::string HttpStatus::toString() const
143136
return std::string(curl_multi_strerror(CURLMcode(getStatus())));
144137

145138
case LLCORE:
146-
if (getStatus() >= 0 && getStatus() < llcore_errors_count)
139+
if (getStatus() >= 0 && std::size_t(getStatus()) < llcore_errors.size())
147140
{
148-
return std::string(llcore_errors[getStatus()]);
141+
return llcore_errors[getStatus()];
149142
}
150143
break;
151144

@@ -156,32 +149,16 @@ std::string HttpStatus::toString() const
156149
if ((getType() == 499) && (!getMessage().empty()))
157150
return getMessage();
158151

159-
// Binary search for the error code and string
160-
int bottom(0), top(http_errors_count);
161-
while (true)
152+
auto it = http_errors.find(getType());
153+
if (it != http_errors.end())
162154
{
163-
int at((bottom + top) / 2);
164-
if (getType() == http_errors[at].mCode)
165-
{
166-
return std::string(http_errors[at].mText);
167-
}
168-
if (at == bottom)
169-
{
170-
break;
171-
}
172-
else if (getType() < http_errors[at].mCode)
173-
{
174-
top = at;
175-
}
176-
else
177-
{
178-
bottom = at;
179-
}
155+
return it->second;
180156
}
181157
}
182158
break;
183159
}
184-
return std::string("Unknown error");
160+
161+
return "Unknown error";
185162
}
186163

187164

indra/llmessage/llcorehttputil.cpp

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ const F32 HTTP_REQUEST_EXPIRY_SECS = 60.0f;
5050

5151
namespace
5252
{
53+
static const char* const LOG_CORE("CoreHttp");
54+
5355
const std::string HTTP_LOGBODY_KEY("HTTPLogBodyOnError");
5456

5557
BoolSettingQuery_t mBoolSettingGet;
@@ -78,12 +80,12 @@ void setPropertyMethods(BoolSettingQuery_t queryfn, BoolSettingUpdate_t updatefn
7880

7981
void logMessageSuccess(std::string logAuth, std::string url, std::string message)
8082
{
81-
LL_INFOS() << logAuth << " Success '" << message << "' for " << url << LL_ENDL;
83+
LL_INFOS(LOG_CORE) << logAuth << " Success '" << message << "' for " << url << LL_ENDL;
8284
}
8385

8486
void logMessageFail(std::string logAuth, std::string url, std::string message)
8587
{
86-
LL_INFOS("CoreHTTP") << logAuth << " Possible failure '" << message << "' for " << url << LL_ENDL;
88+
LL_INFOS(LOG_CORE) << logAuth << " Possible failure '" << message << "' for " << url << LL_ENDL;
8789
}
8890

8991
//=========================================================================
@@ -259,6 +261,7 @@ void HttpCoroHandler::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRespons
259261
LLSD result;
260262

261263
LLCore::HttpStatus status = response->getStatus();
264+
LL_INFOS(LOG_CORE) << "status: " << !!status << ", " << status.toHex() << " '" << status.toString() << "'" << LL_ENDL;
262265

263266
if (status == LLCore::HttpStatus(LLCore::HttpStatus::LLCORE, LLCore::HE_HANDLE_NOT_FOUND))
264267
{ // A response came in for a canceled request and we have not processed the
@@ -272,10 +275,11 @@ void HttpCoroHandler::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRespons
272275
result = LLSD::emptyMap();
273276
LLCore::HttpStatus::type_enum_t errType = status.getType();
274277

275-
LL_INFOS()
276-
<< "Possible failure [" << status.toTerseString() << "] cannot "<< response->getRequestMethod()
277-
<< " url '" << response->getRequestURL()
278-
<< "' because " << status.toString()
278+
LL_INFOS(LOG_CORE)
279+
<< "Possible failure [" << status.toTerseString() << "]"
280+
<< " cannot " << response->getRequestMethod()
281+
<< " url '" << response->getRequestURL() << "'"
282+
<< " because " << errType << " '" << status.toString() << "'"
279283
<< LL_ENDL;
280284
if ((errType >= 400) && (errType < 500))
281285
{
@@ -314,7 +318,7 @@ void HttpCoroHandler::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRespons
314318
if (getBoolSetting(HTTP_LOGBODY_KEY))
315319
{
316320
// commenting out, but keeping since this can be useful for debugging
317-
LL_WARNS("CoreHTTP") << "Returned body=" << std::endl << httpStatus["error_body"].asString() << LL_ENDL;
321+
LL_WARNS(LOG_CORE) << "Returned body=" << std::endl << httpStatus["error_body"].asString() << LL_ENDL;
318322
}
319323
}
320324

@@ -414,7 +418,7 @@ LLSD HttpCoroLLSDHandler::handleSuccess(LLCore::HttpResponse * response, LLCore:
414418
if (contentType && (HTTP_CONTENT_LLSD_XML == *contentType))
415419
{
416420
std::string thebody = LLCoreHttpUtil::responseToString(response);
417-
LL_WARNS("CoreHTTP") << "Failed to deserialize . " << response->getRequestURL() << " [status:" << response->getStatus().toString() << "] "
421+
LL_WARNS(LOG_CORE) << "Failed to deserialize . " << response->getRequestURL() << " [status:" << response->getStatus().toString() << "] "
418422
<< " body: " << thebody << LL_ENDL;
419423

420424
// Replace the status with a new one indicating the failure.
@@ -433,7 +437,7 @@ LLSD HttpCoroLLSDHandler::handleSuccess(LLCore::HttpResponse * response, LLCore:
433437
if (contentType && (HTTP_CONTENT_LLSD_XML == *contentType))
434438
{
435439
std::string thebody = LLCoreHttpUtil::responseToString(response);
436-
LL_WARNS("CoreHTTP") << "Failed to deserialize . " << response->getRequestURL() << " [status:" << response->getStatus().toString() << "] "
440+
LL_WARNS(LOG_CORE) << "Failed to deserialize . " << response->getRequestURL() << " [status:" << response->getStatus().toString() << "] "
437441
<< " body: " << thebody << LL_ENDL;
438442

439443
// Replace the status with a new one indicating the failure.
@@ -1194,7 +1198,7 @@ LLSD HttpCoroutineAdapter::buildImmediateErrorResult(const LLCore::HttpRequest::
11941198
const std::string &url)
11951199
{
11961200
LLCore::HttpStatus status = request->getStatus();
1197-
LL_WARNS("CoreHTTP") << "Error posting to " << url << " Status=" << status.getStatus() <<
1201+
LL_WARNS(LOG_CORE) << "Error posting to " << url << " Status=" << status.getStatus() <<
11981202
" message = " << status.getMessage() << LL_ENDL;
11991203

12001204
// Mimic the status results returned from an http error that we had

indra/llui/lltextbase.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2104,7 +2104,7 @@ LLTextSegmentPtr LLTextBase::getSegmentAtLocalPos(S32 x, S32 y, bool hit_past_en
21042104
return LLTextSegmentPtr();
21052105
}
21062106

2107-
void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url)
2107+
void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url, const std::string &text)
21082108
{
21092109
// work out the XUI menu file to use for this url
21102110
LLUrlMatch match;
@@ -2123,6 +2123,8 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url)
21232123
// set up the callbacks for all of the potential menu items, N.B. we
21242124
// don't use const ref strings in callbacks in case url goes out of scope
21252125
ScopedRegistrarHelper registrar;
2126+
LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
2127+
21262128
registrar.add("Url.Open", boost::bind(&LLUrlAction::openURL, url));
21272129
registrar.add("Url.OpenInternal", boost::bind(&LLUrlAction::openURLInternal, url));
21282130
registrar.add("Url.OpenExternal", boost::bind(&LLUrlAction::openURLExternal, url));
@@ -2138,6 +2140,8 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url)
21382140
registrar.add("Url.ShowOnMap", boost::bind(&LLUrlAction::showLocationOnMap, url));
21392141
registrar.add("Url.CopyLabel", boost::bind(&LLUrlAction::copyLabelToClipboard, url));
21402142
registrar.add("Url.CopyUrl", boost::bind(&LLUrlAction::copyURLToClipboard, url));
2143+
registrar.add("Url.CreateLandmark", boost::bind(&LLUrlAction::showFloaterCreateLandmark, in_url, text));
2144+
enable_registrar.add("Url.CanCreateLandmark", boost::bind(&LLUrlAction::canCreateLandmark, in_url));
21412145

21422146
// create and return the context menu from the XUI file
21432147

@@ -3563,9 +3567,11 @@ bool LLNormalTextSegment::handleRightMouseDown(S32 x, S32 y, MASK mask)
35633567
if (getStyle() && getStyle()->isLink())
35643568
{
35653569
// Only process the click if it's actually in this segment, not to the right of the end-of-line.
3566-
if(mEditor.getSegmentAtLocalPos(x, y, false) == this)
3570+
if (mEditor.getSegmentAtLocalPos(x, y, false) == this)
35673571
{
3568-
mEditor.createUrlContextMenu(x, y, getStyle()->getLinkHREF());
3572+
const std::string url = getStyle()->getLinkHREF();
3573+
const std::string text = wstring_to_utf8str(mEditor.getWText().substr((U64)llmax(0, mStart), (U64)llmax(0, mEnd - mStart)));
3574+
mEditor.createUrlContextMenu(x, y, url, text);
35693575
return true;
35703576
}
35713577
}

indra/llui/lltextbase.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,7 @@ class LLTextBase
447447
void setContentTrusted(bool trusted_content) { mTrustedContent = trusted_content; }
448448

449449
// TODO: move into LLTextSegment?
450-
void createUrlContextMenu(S32 x, S32 y, const std::string &url); // create a popup context menu for the given Url
450+
void createUrlContextMenu(S32 x, S32 y, const std::string &url, const std::string& text); // create a popup context menu for the given Url
451451

452452
// Text accessors
453453
// TODO: add optional style parameter

indra/llui/llurlaction.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
LLUrlAction::url_callback_t LLUrlAction::sOpenURLCallback;
3737
LLUrlAction::url_callback_t LLUrlAction::sOpenURLInternalCallback;
3838
LLUrlAction::url_callback_t LLUrlAction::sOpenURLExternalCallback;
39+
LLUrlAction::url_title_callback_t LLUrlAction::sCreateLandmarkCallback;
40+
LLUrlAction::check_url_callback_t LLUrlAction::sCanCreateLandmarkCallback;
3941
LLUrlAction::execute_url_callback_t LLUrlAction::sExecuteSLURLCallback;
4042

4143

@@ -54,6 +56,16 @@ void LLUrlAction::setOpenURLExternalCallback(url_callback_t cb)
5456
sOpenURLExternalCallback = cb;
5557
}
5658

59+
void LLUrlAction::setCreateLandmarkCallback(url_title_callback_t cb)
60+
{
61+
sCreateLandmarkCallback = cb;
62+
}
63+
64+
void LLUrlAction::setCanCreateLandmarkCallback(check_url_callback_t cb)
65+
{
66+
sCanCreateLandmarkCallback = cb;
67+
}
68+
5769
void LLUrlAction::setExecuteSLURLCallback(execute_url_callback_t cb)
5870
{
5971
sExecuteSLURLCallback = cb;
@@ -142,6 +154,24 @@ void LLUrlAction::copyLabelToClipboard(std::string url)
142154
}
143155
}
144156

157+
void LLUrlAction::showFloaterCreateLandmark(std::string url, std::string title)
158+
{
159+
if (sCreateLandmarkCallback)
160+
{
161+
sCreateLandmarkCallback(url, title);
162+
}
163+
}
164+
165+
bool LLUrlAction::canCreateLandmark(std::string url)
166+
{
167+
if (sCanCreateLandmarkCallback)
168+
{
169+
return sCanCreateLandmarkCallback(url);
170+
}
171+
172+
return false;
173+
}
174+
145175
void LLUrlAction::showProfile(std::string url)
146176
{
147177
// Get id from 'secondlife:///app/{cmd}/{id}/{action}'

indra/llui/llurlaction.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,12 @@ class LLUrlAction
7272
/// copy a Url to the clipboard
7373
static void copyURLToClipboard(std::string url);
7474

75+
/// open the "add_landmark" floater
76+
static void showFloaterCreateLandmark(std::string url, std::string title);
77+
78+
/// make the "Create Landmark" menu item visible
79+
static bool canCreateLandmark(std::string url);
80+
7581
/// if the Url specifies an SL command in the form like 'app/{cmd}/{id}/*', show its profile
7682
static void showProfile(std::string url);
7783
static std::string getUserID(std::string url);
@@ -85,19 +91,25 @@ class LLUrlAction
8591
static void unblockObject(std::string url);
8692

8793
/// specify the callbacks to enable this class's functionality
88-
typedef boost::function<void (const std::string&)> url_callback_t;
94+
typedef boost::function<void(const std::string&)> url_callback_t;
95+
typedef boost::function<void(const std::string&, const std::string&)> url_title_callback_t;
96+
typedef boost::function<bool(const std::string&)> check_url_callback_t;
8997
typedef boost::function<bool(const std::string& url, bool trusted_content)> execute_url_callback_t;
9098

9199
static void setOpenURLCallback(url_callback_t cb);
92100
static void setOpenURLInternalCallback(url_callback_t cb);
93101
static void setOpenURLExternalCallback(url_callback_t cb);
102+
static void setCreateLandmarkCallback(url_title_callback_t cb);
103+
static void setCanCreateLandmarkCallback(check_url_callback_t cb);
94104
static void setExecuteSLURLCallback(execute_url_callback_t cb);
95105

96106
private:
97107
// callbacks for operations we can perform on Urls
98108
static url_callback_t sOpenURLCallback;
99109
static url_callback_t sOpenURLInternalCallback;
100110
static url_callback_t sOpenURLExternalCallback;
111+
static url_title_callback_t sCreateLandmarkCallback;
112+
static check_url_callback_t sCanCreateLandmarkCallback;
101113

102114
static execute_url_callback_t sExecuteSLURLCallback;
103115
};

indra/llui/llurlentry.cpp

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -435,8 +435,18 @@ bool LLUrlEntryInvalidSLURL::isSLURLvalid(const std::string &url) const
435435
LLUrlEntrySLURL::LLUrlEntrySLURL()
436436
{
437437
// see http://slurl.com/about.php for details on the SLURL format
438-
mPattern = boost::regex("https?://(maps.secondlife.com|slurl.com)/secondlife/[^ /]+(/\\d+){0,3}(/?(\\?title|\\?img|\\?msg)=\\S*)?/?",
439-
boost::regex::perl|boost::regex::icase);
438+
std::string pattern =
439+
"("
440+
"secondlife://(Agni|Aditi|Mitra|Damballah)/secondlife"
441+
"|"
442+
"https?://"
443+
"("
444+
"(maps.secondlife.com|slurl.com)/secondlife"
445+
"|"
446+
"util.(agni|aditi|mitra|damballah).lindenlab.com/region"
447+
")"
448+
")/[^/]+(/\\d+){0,3}(/?(\\?title|\\?img|\\?msg)=\\S*)?/?";
449+
mPattern = boost::regex(pattern, boost::regex::perl|boost::regex::icase);
440450
mIcon = "Hand";
441451
mMenuName = "menu_url_slurl.xml";
442452
mTooltip = LLTrans::getString("TooltipSLURL");
@@ -446,6 +456,10 @@ std::string LLUrlEntrySLURL::getLabel(const std::string &url, const LLUrlLabelCa
446456
{
447457
//
448458
// we handle SLURLs in the following formats:
459+
// - https://util.agni.lindenlab.com/region/Place/X/Y/Z
460+
// - https://util.agni.lindenlab.com/region/Place/X/Y
461+
// - https://util.agni.lindenlab.com/region/Place/X
462+
// - https://util.agni.lindenlab.com/region/Place
449463
// - http://slurl.com/secondlife/Place/X/Y/Z
450464
// - http://slurl.com/secondlife/Place/X/Y
451465
// - http://slurl.com/secondlife/Place/X
@@ -616,7 +630,7 @@ void LLUrlEntryAgent::onAvatarNameCache(const LLUUID& id,
616630
callObservers(id.asString(), label, mIcon);
617631
}
618632

619-
LLUUID LLUrlEntryAgent::getID(const std::string &string) const
633+
LLUUID LLUrlEntryAgent::getID(const std::string &string) const
620634
{
621635
return LLUUID(getIDStringFromUrl(string));
622636
}

indra/newview/llagent.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1282,17 +1282,16 @@ const LLVector3 &LLAgent::getPositionAgent()
12821282
{
12831283
if (isAgentAvatarValid())
12841284
{
1285-
if(gAgentAvatarp->mDrawable.isNull())
1285+
if (gAgentAvatarp->mDrawable.isNull())
12861286
{
12871287
mFrameAgent.setOrigin(gAgentAvatarp->getPositionAgent());
12881288
}
12891289
else
1290-
{
1291-
mFrameAgent.setOrigin(gAgentAvatarp->getRenderPosition());
1292-
}
1290+
{
1291+
mFrameAgent.setOrigin(gAgentAvatarp->getRenderPosition());
1292+
}
12931293
}
12941294

1295-
12961295
return mFrameAgent.getOrigin();
12971296
}
12981297

indra/newview/llappviewer.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
#include "llviewerstats.h"
5454
#include "llviewerstatsrecorder.h"
5555
#include "llkeyconflict.h" // for legacy keybinding support, remove later
56+
#include "lllandmarkactions.h"
5657
#include "llmarketplacefunctions.h"
5758
#include "llmarketplacenotifications.h"
5859
#include "llmd5.h"
@@ -871,6 +872,8 @@ bool LLAppViewer::init()
871872
LLUrlAction::setOpenURLCallback(boost::bind(&LLWeb::loadURL, _1, LLStringUtil::null, LLStringUtil::null));
872873
LLUrlAction::setOpenURLInternalCallback(boost::bind(&LLWeb::loadURLInternal, _1, LLStringUtil::null, LLStringUtil::null, false));
873874
LLUrlAction::setOpenURLExternalCallback(boost::bind(&LLWeb::loadURLExternal, _1, true, LLStringUtil::null));
875+
LLUrlAction::setCreateLandmarkCallback(&LLLandmarkActions::showFloaterCreateLandmarkForUrl);
876+
LLUrlAction::setCanCreateLandmarkCallback(&LLLandmarkActions::canCreateLandmarkForUrl);
874877
LLUrlAction::setExecuteSLURLCallback(&LLURLDispatcher::dispatchFromTextEditor);
875878

876879
// Let code in llui access the viewer help floater

0 commit comments

Comments
 (0)