diff --git a/etc/message.xml b/etc/message.xml
index ea6fc8146..fd019aa70 100644
--- a/etc/message.xml
+++ b/etc/message.xml
@@ -718,7 +718,14 @@
UploadBakedTexture
true
-
+
+ ObjectMedia
+ false
+
+ ObjectMediaNavigate
+ false
+
+
messageBans
- AudioStreamingVideo
-
- Comment
- Enable streaming video
- Persist
- 1
- Type
- Boolean
- Value
- 0
-
AuditTexture
Comment
@@ -2702,23 +2702,23 @@ This should be as low as possible, but too low may break functionality
Value
0
- PluginAttachDebuggerToPlugins
+ BrowserEnableJSObject
Comment
- Opens a terminal window with a debugger and attach it, every time a new SLPlugin process is started.
+ (WARNING: Advanced feature. Use if you are aware of the implications). Enable or disable the viewer to Javascript bridge object.
Persist
- 1
+ 0
Type
Boolean
Value
- 0
+ 0
BlockAvatarAppearanceMessages
-
- Comment
- Ignores appearance messages (for simulating Ruth)
- Persist
- 1
+
+ Comment
+ Ignores appearance messages (for simulating Ruth)
+ Persist
+ 1
Type
Boolean
Value
@@ -3780,17 +3780,6 @@ This should be as low as possible, but too low may break functionality
- CmdLineRegionURI
-
- Comment
- URL of region to connect to through Agent Domain.
- Persist
- 0
- Type
- String
- Value
-
-
ColorPaletteEntry01
Comment
@@ -5430,6 +5419,17 @@ This should be as low as possible, but too low may break functionality
Value
0
+ DisableExternalBrowser
+
+ Comment
+ Disable opening an external browser.
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 0
+
DisableRendering
Comment
@@ -5441,6 +5441,17 @@ This should be as low as possible, but too low may break functionality
Value
0
+ DisableTextHyperlinkActions
+
+ Comment
+ Disable highlighting and linking of URLs in XUI text boxes
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 0
+
DisableVerticalSync
Comment
@@ -6014,17 +6025,6 @@ This should be as low as possible, but too low may break functionality
Value
1
- FirstLoginThisInstall
-
- Comment
- Specifies that you have not successfully logged in since you installed the latest update
- Persist
- 1
- Type
- Boolean
- Value
- 1
-
FirstName
Comment
@@ -6069,6 +6069,17 @@ This should be as low as possible, but too low may break functionality
Value
1
+ FirstLoginThisInstall
+
+ Comment
+ Specifies that you have not successfully logged in since you installed the latest update
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 1
+
FixedWeather
Comment
@@ -9109,16 +9120,16 @@ This should be as low as possible, but too low may break functionality
Value
0
- LoginLastLocation
+ LoginLocation
Comment
- Login at same location you last logged out
+ Default Login location ('last', 'home') preference
Persist
1
Type
- Boolean
+ String
Value
- 1
+ last
LoginPage
@@ -9435,13 +9446,68 @@ This should be as low as possible, but too low may break functionality
Persist
1
Type
- Boolean
- Value
- 0
-
- MemoryFailurePreventionEnabled
-
- Comment
+ Boolean
+ Value
+ 1
+
+ MediaPerformanceManagerDebug
+
+ Comment
+ Whether to show debug data for the media performance manager in the nearby media list.
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 0
+
+ MediaShowOnOthers
+
+ Comment
+ Whether or not to show media on other avatars
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 0
+
+ MediaShowOutsideParcel
+
+ Comment
+ Whether or not to show media from outside the current parcel
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 1
+
+ MediaShowWithinParcel
+
+ Comment
+ Whether or not to show media within the current parcel
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 1
+
+ MediaTentativeAutoPlay
+
+ Comment
+ This is a tentative flag that may be temporarily set off by the user, until she teleports
+ Persist
+ 0
+ Type
+ Boolean
+ Value
+ 1
+
+ MemoryFailurePreventionEnabled
+
+ Comment
If set, the viewer will quit to avoid crash when memory failure happens
Persist
1
@@ -10426,6 +10492,86 @@ This should be as low as possible, but too low may break functionality
Value
1
+ PluginAttachDebuggerToPlugins
+
+ Comment
+ If true, attach a debugger session to each plugin process as it's launched.
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 0
+
+ PluginInstancesCPULimit
+
+ Comment
+ Amount of total plugin CPU usage before inworld plugins start getting turned down to "slideshow" priority. Set to 0 to disable this check.
+ Persist
+ 1
+ Type
+ F32
+ Value
+ 0.9
+
+
+ PlainTextChatHistory
+
+ Comment
+ Enable/Disable plain text chat history style
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 0
+
+
+ PluginInstancesLow
+
+ Comment
+ Limit on the number of inworld media plugins that will run at "low" priority
+ Persist
+ 1
+ Type
+ U32
+ Value
+ 4
+
+ PluginInstancesNormal
+
+ Comment
+ Limit on the number of inworld media plugins that will run at "normal" or higher priority
+ Persist
+ 1
+ Type
+ U32
+ Value
+ 2
+
+ PluginInstancesTotal
+
+ Comment
+ Hard limit on the number of plugins that will be instantiated at once for inworld media
+ Persist
+ 1
+ Type
+ U32
+ Value
+ 8
+
+
+ PluginUseReadThread
+
+ Comment
+ Use a separate thread to read incoming messages from plugins
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 0
+
PlayTypingSound
Comment
@@ -10629,6 +10775,94 @@ This should be as low as possible, but too low may break functionality
+ PrimMediaMasterEnabled
+
+ Comment
+ Whether or not Media on a Prim is enabled.
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 1
+
+ PrimMediaControlsUseHoverControlSet
+
+ Comment
+ Whether or not hovering over prim media uses minimal "hover" controls or the authored control set.
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 0
+
+ PrimMediaDragNDrop
+
+ Comment
+ Enable drag and drop of URLs onto prim faces
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 1
+
+ PrimMediaMaxRetries
+
+ Comment
+ Maximum number of retries for media queries.
+ Persist
+ 1
+ Type
+ U32
+ Value
+ 4
+
+ PrimMediaRequestQueueDelay
+
+ Comment
+ Timer delay for fetching media from the queue (in seconds).
+ Persist
+ 1
+ Type
+ F32
+ Value
+ 1.0
+
+ PrimMediaRetryTimerDelay
+
+ Comment
+ Timer delay for retrying on media queries (in seconds).
+ Persist
+ 1
+ Type
+ F32
+ Value
+ 5.0
+
+ PrimMediaMaxSortedQueueSize
+
+ Comment
+ Maximum number of objects the viewer will load media for initially
+ Persist
+ 1
+ Type
+ U32
+ Value
+ 100000
+
+ PrimMediaMaxRoundRobinQueueSize
+
+ Comment
+ Maximum number of objects the viewer will continuously update media for
+ Persist
+ 1
+ Type
+ U32
+ Value
+ 100000
+
PreviewAnimRect
Comment
@@ -10937,6 +11171,50 @@ This should be as low as possible, but too low may break functionality
Value
1.0
+ WebContentWindowLimit
+
+ Comment
+ Maximum number of web browser windows that can be open at once in the Web content floater (0 for no limit)
+ Persist
+ 1
+ Type
+ S32
+ Value
+ 5
+
+ MediaRollOffRate
+
+ Comment
+ Multiplier to change rate of media attenuation
+ Persist
+ 1
+ Type
+ F32
+ Value
+ 0.125
+
+ MediaRollOffMin
+
+ Comment
+ Adjusts the distance at which media attentuation starts
+ Persist
+ 1
+ Type
+ F32
+ Value
+ 5.0
+
+ MediaRollOffMax
+
+ Comment
+ Distance at which media volume is set to 0
+ Persist
+ 1
+ Type
+ F32
+ Value
+ 30.0
+
RecentItemsSortOrder
Comment
@@ -16551,6 +16829,28 @@ This should be as low as possible, but too low may break functionality
Boolean
Value
1
+
+ SLURLDragNDrop
+
+ Comment
+ Enable drag and drop of SLURLs onto the viewer
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 1
+
+ SLURLPassToOtherInstance
+
+ Comment
+ Pass execution to prevoius viewer instances if there is a given slurl
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 1
soundsbeacon
@@ -16629,6 +16929,19 @@ This should be as low as possible, but too low may break functionality
Value
180
+
+ SLURLTeleportDirectly
+
+ Comment
+ Clicking on a slurl will teleport you directly instead of opening places panel
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 0
+
+
UseHTTPInventory
Comment
diff --git a/indra/newview/app_settings/settings_sh.xml b/indra/newview/app_settings/settings_sh.xml
index d0f7516a2..732da64bf 100644
--- a/indra/newview/app_settings/settings_sh.xml
+++ b/indra/newview/app_settings/settings_sh.xml
@@ -41,6 +41,17 @@
Value
0
+ SHEnableFMODEXVerboseDebugging
+
+ Comment
+ Enable profiler tool if using FMOD Ex
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 0
+
SHFMODExStreamBufferSize
Comment
diff --git a/indra/newview/chatbar_as_cmdline.cpp b/indra/newview/chatbar_as_cmdline.cpp
index 895f72b04..5b9d7817a 100644
--- a/indra/newview/chatbar_as_cmdline.cpp
+++ b/indra/newview/chatbar_as_cmdline.cpp
@@ -60,6 +60,8 @@
#include "lltooldraganddrop.h"
#include "llinventorymodel.h"
#include "llselectmgr.h"
+#include "llslurl.h"
+#include "llurlaction.h"
#include
@@ -374,7 +376,6 @@ bool cmd_line_chat(std::string revised_text, EChatType type)
S32 agent_y = llround( (F32)fmod( agentPos.mdV[VY], (F64)REGION_WIDTH_METERS ) );
S32 agent_z = llround( (F32)agentPos.mdV[VZ] );
std::string region_name = LLWeb::escapeURL(revised_text.substr(command.length()+1));
- std::string url;
if(!sAscentCmdLineMapToKeepPos)
{
@@ -383,8 +384,8 @@ bool cmd_line_chat(std::string revised_text, EChatType type)
agent_z = 0;
}
- url = llformat("secondlife:///app/teleport/%s/%d/%d/%d",region_name.c_str(),agent_x,agent_y,agent_z);
- LLURLDispatcher::dispatch(url, NULL, true);
+ LLSLURL slurl(region_name,LLVector3(agent_x,agent_y,agent_z));
+ LLUrlAction::teleportToLocation(std::string("secondlife:///app/teleport/")+slurl.getLocationString());
}
return false;
}
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 6021f3676..25e984503 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -57,6 +57,7 @@
#include "llsdmessage.h"
#include "llsdutil.h"
#include "llsky.h"
+#include "llslurl.h"
#include "llsmoothstep.h"
#include "llspeakers.h"
#include "llstartup.h"
@@ -65,6 +66,8 @@
#include "lltoolpie.h"
#include "lltoolmgr.h"
#include "lltrans.h"
+#include "lluictrl.h"
+#include "llurlentry.h"
#include "llviewercontrol.h"
#include "llviewerdisplay.h"
#include "llviewerjoystick.h"
@@ -345,6 +348,7 @@ LLAgent::LLAgent() :
mAgentAccess(new LLAgentAccess(gSavedSettings)),
mGodLevelChangeSignal(),
mCanEditParcel(false),
+ mTeleportSourceSLURL(new LLSLURL),
mTeleportRequest(),
mTeleportFinishedSlot(),
mTeleportFailedSlot(),
@@ -485,6 +489,8 @@ LLAgent::~LLAgent()
mAgentAccess = NULL;
delete mEffectColor;
mEffectColor = NULL;
+ delete mTeleportSourceSLURL;
+ mTeleportSourceSLURL = NULL;
}
// Handle any actions that need to be performed when the main app gains focus
@@ -949,24 +955,6 @@ const LLHost& LLAgent::getRegionHost() const
}
}
-//-----------------------------------------------------------------------------
-// getSLURL()
-// returns empty() if getRegion() == NULL
-//-----------------------------------------------------------------------------
-std::string LLAgent::getSLURL() const
-{
- std::string slurl;
- LLViewerRegion *regionp = getRegion();
- if (regionp)
- {
- LLVector3d agentPos = getPositionGlobal();
- S32 x = llround( (F32)fmod( agentPos.mdV[VX], (F64)REGION_WIDTH_METERS ) );
- S32 y = llround( (F32)fmod( agentPos.mdV[VY], (F64)REGION_WIDTH_METERS ) );
- S32 z = llround( (F32)agentPos.mdV[VZ] );
- slurl = LLURLDispatcher::buildSLURL(regionp->getName(), x, y, z);
- }
- return slurl;
-}
//-----------------------------------------------------------------------------
// inPrelude()
@@ -3916,7 +3904,7 @@ bool LLAgent::teleportCore(bool is_local)
LLFloaterLand::hideInstance();
LLViewerParcelMgr::getInstance()->deselectLand();
- LLViewerMediaFocus::getInstance()->setFocusFace(false, NULL, 0, NULL);
+ LLViewerMediaFocus::getInstance()->clearFocus();
// Close all pie menus, deselect land, etc.
// Don't change the camera until we know teleport succeeded. JC
@@ -4308,7 +4296,7 @@ void LLAgent::setTeleportState(ETeleportState state)
case TELEPORT_MOVING:
// We're outa here. Save "back" slurl.
- mTeleportSourceSLURL = getSLURL();
+ LLAgentUI::buildSLURL(*mTeleportSourceSLURL);
break;
case TELEPORT_ARRIVING:
@@ -4734,6 +4722,10 @@ void LLAgent::parseTeleportMessages(const std::string& xml_filename)
}//end for (all message sets in xml file)
}
+const void LLAgent::getTeleportSourceSLURL(LLSLURL& slurl) const
+{
+ slurl = *mTeleportSourceSLURL;
+}
void LLAgent::sendAgentUpdateUserInfo(bool im_via_email, const std::string& directory_visibility )
{
@@ -4787,14 +4779,13 @@ void LLAgent::renderAutoPilotTarget()
}
}
-void LLAgent::showLureDestination(const std::string fromname, const int global_x, const int global_y, const int x, const int y, const int z, const std::string maturity)
+void LLAgent::showLureDestination(const std::string fromname, U64& handle, U32 x, U32 y, U32 z)
{
- const LLVector3d posglobal = LLVector3d(F64(global_x), F64(global_y), F64(0));
- LLSimInfo* siminfo = LLWorldMap::getInstance()->simInfoFromPosGlobal(posglobal);
+ LLSimInfo* siminfo = LLWorldMap::getInstance()->simInfoFromHandle(handle);
if(mPendingLure)
delete mPendingLure;
- mPendingLure = new SHLureRequest(fromname,posglobal,x,y,z);
+ mPendingLure = new SHLureRequest(fromname,handle,x,y,z);
if(siminfo) //We already have an entry? Go right on to displaying it.
{
@@ -4802,8 +4793,8 @@ void LLAgent::showLureDestination(const std::string fromname, const int global_x
}
else
{
- U16 grid_x = (U16)(global_x / REGION_WIDTH_UNITS);
- U16 grid_y = (U16)(global_y / REGION_WIDTH_UNITS);
+ U32 grid_x, grid_y;
+ grid_from_region_handle(handle,&grid_x,&grid_y);
LLWorldMapMessage::getInstance()->sendMapBlockRequest(grid_x, grid_y, grid_x, grid_y, true); //Will call onFoundLureDestination on response
}
}
@@ -4814,7 +4805,7 @@ void LLAgent::onFoundLureDestination(LLSimInfo *siminfo)
return;
if(!siminfo)
- siminfo = LLWorldMap::getInstance()->simInfoFromPosGlobal(mPendingLure->mPosGlobal);
+ siminfo = LLWorldMap::getInstance()->simInfoFromHandle(mPendingLure->mRegionHandle);
if(siminfo)
{
const std::string sim_name = siminfo->getName();
@@ -4823,7 +4814,7 @@ void LLAgent::onFoundLureDestination(LLSimInfo *siminfo)
llinfos << mPendingLure->mAvatarName << "'s teleport lure is to " << sim_name << " (" << maturity << ")" << llendl;
LLStringUtil::format_map_t args;
args["[NAME]"] = mPendingLure->mAvatarName;
- args["[DESTINATION]"] = LLURLDispatcher::buildSLURL(sim_name, (S32)mPendingLure->mPosLocal[0], (S32)mPendingLure->mPosLocal[1], (S32)mPendingLure->mPosLocal[2] );
+ args["[DESTINATION]"] = LLSLURL(sim_name,mPendingLure->mPosLocal).getSLURLString();
std::string msg = LLTrans::getString("TeleportOfferMaturity", args);
if (!maturity.empty())
{
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index eb039800e..8a01093bf 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -68,6 +68,7 @@ class LLPickInfo;
class LLViewerObject;
class LLAgentDropGroupViewerNode;
class LLAgentAccess;
+class LLSLURL;
class LLSimInfo;
class LLTeleportRequest;
@@ -245,20 +246,18 @@ public:
LLViewerRegion *getRegion() const { return mRegionp; }
const LLHost& getRegionHost() const;
BOOL inPrelude();
- std::string getSLURL() const; //Return uri for current region
-
+
//
struct SHLureRequest
{
- SHLureRequest(const std::string& avatar_name, const LLVector3d& pos_global, const int x, const int y, const int z) :
- mAvatarName(avatar_name), mPosGlobal(pos_global)
- { mPosLocal[0] = x; mPosLocal[1] = y; mPosLocal[2] = z;}
+ SHLureRequest(const std::string& avatar_name, U64& handle, const U32 x, const U32 y, const U32 z) :
+ mAvatarName(avatar_name), mRegionHandle(handle), mPosLocal(x,y,z) {}
const std::string mAvatarName;
- const LLVector3d mPosGlobal;
- int mPosLocal[3];
+ const U64 mRegionHandle;
+ LLVector3 mPosLocal;
};
SHLureRequest *mPendingLure;
- void showLureDestination(const std::string fromname, const int global_x, const int global_y, const int x, const int y, const int z, const std::string maturity);
+ void showLureDestination(const std::string fromname, U64& handle, U32 x, U32 y, U32 z);
void onFoundLureDestination(LLSimInfo *siminfo = NULL);
//
@@ -584,13 +583,14 @@ public:
public:
static void parseTeleportMessages(const std::string& xml_filename);
- const std::string& getTeleportSourceSLURL() const { return mTeleportSourceSLURL; }
+ const void getTeleportSourceSLURL(LLSLURL& slurl) const;
public:
// ! TODO ! Define ERROR and PROGRESS enums here instead of exposing the mappings.
static std::map sTeleportErrorMessages;
static std::map sTeleportProgressMessages;
-public:
- std::string mTeleportSourceSLURL; // SLURL where last TP began.
+private:
+ LLSLURL * mTeleportSourceSLURL; // SLURL where last TP began
+
//--------------------------------------------------------------------
// Teleport Actions
//--------------------------------------------------------------------
diff --git a/indra/newview/llagentui.cpp b/indra/newview/llagentui.cpp
index eb6b1835b..0fcc5fb2b 100644
--- a/indra/newview/llagentui.cpp
+++ b/indra/newview/llagentui.cpp
@@ -37,6 +37,7 @@
#include "llviewerregion.h"
#include "llviewerparcelmgr.h"
#include "llvoavatarself.h"
+#include "llslurl.h"
// [RLVa:KB] - Checked: 2010-04-04 (RLVa-1.2.0d)
#include "rlvhandler.h"
// [/RLVa:KB]
@@ -48,9 +49,8 @@ void LLAgentUI::buildFullname(std::string& name)
name = gAgentAvatarp->getFullname();
}
-/*
//static
-void LLAgentUI::buildSLURL(LLSLURL& slurl, const bool escaped /= true/ )
+void LLAgentUI::buildSLURL(LLSLURL& slurl, const bool escaped /*= true*/)
{
LLSLURL return_slurl;
LLViewerRegion *regionp = gAgent.getRegion();
@@ -59,7 +59,7 @@ void LLAgentUI::buildSLURL(LLSLURL& slurl, const bool escaped /= true/ )
return_slurl = LLSLURL(regionp->getName(), gAgent.getPositionGlobal());
}
slurl = return_slurl;
-}*/
+}
//static
BOOL LLAgentUI::checkAgentDistance(const LLVector3& pole, F32 radius)
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 9b203f7ca..c5917804a 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -56,6 +56,7 @@
#include "llmodaldialog.h"
#include "llpumpio.h"
#include "llmimetypes.h"
+#include "llslurl.h"
#include "llstartup.h"
#include "llfocusmgr.h"
#include "llviewerjoystick.h"
@@ -80,6 +81,7 @@
#include "llvector4a.h"
#include "llvoicechannel.h"
#include "llvoavatarself.h"
+#include "llurlmatch.h"
#include "llprogressview.h"
#include "llvocache.h"
#include "llvopartgroup.h"
@@ -94,6 +96,8 @@
#include "llimagej2c.h"
#include "llmemory.h"
#include "llprimitive.h"
+#include "llurlaction.h"
+#include "llurlentry.h"
#include "llnotifications.h"
#include "llnotificationsutil.h"
#include
@@ -149,7 +153,6 @@
#include "llworld.h"
#include "llhudeffecttrail.h"
#include "llvectorperfoptions.h"
-#include "llurlsimstring.h"
#include "llwatchdog.h"
// Included so that constants/settings might be initialized
@@ -755,9 +758,11 @@ bool LLAppViewer::init()
LLWeb::initClass(); // do this after LLUI
- LLTextEditor::setURLCallbacks(&LLWeb::loadURL,
- &LLURLDispatcher::dispatchFromTextEditor,
- &LLURLDispatcher::dispatchFromTextEditor);
+ // Provide the text fields with callbacks for opening Urls
+ LLUrlAction::setOpenURLCallback(boost::bind(&LLWeb::loadURL, _1, LLStringUtil::null, LLStringUtil::null));
+ LLUrlAction::setOpenURLInternalCallback(boost::bind(&LLWeb::loadURLInternal, _1, LLStringUtil::null, LLStringUtil::null));
+ LLUrlAction::setOpenURLExternalCallback(boost::bind(&LLWeb::loadURLExternal, _1, true, LLStringUtil::null));
+ LLUrlAction::setExecuteSLURLCallback(&LLURLDispatcher::dispatchFromTextEditor);
LLToolMgr::getInstance(); // Initialize tool manager if not already instantiated
@@ -975,6 +980,8 @@ bool LLAppViewer::init()
LLEnvManagerNew::instance().usePrefs();
gGLActive = FALSE;
+ LLViewerMedia::initClass();
+ LL_INFOS("InitInfo") << "Viewer media initialized." << LL_ENDL ;
return true;
}
@@ -1701,8 +1708,7 @@ bool LLAppViewer::cleanup()
if (mPurgeOnExit)
{
llinfos << "Purging all cache files on exit" << llendflush;
- std::string mask = gDirUtilp->getDirDelimiter() + "*.*";
- gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""),mask);
+ gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""),"*.*");
}
removeMarkerFile(); // Any crashes from here on we'll just have to ignore
@@ -1779,7 +1785,6 @@ bool LLAppViewer::cleanup()
//Note:
//LLViewerMedia::cleanupClass() has to be put before gTextureList.shutdown()
//because some new image might be generated during cleaning up media. --bao
- LLViewerMediaFocus::cleanupClass();
LLViewerMedia::cleanupClass();
LLViewerParcelMedia::cleanupClass();
gTextureList.shutdown(); // shutdown again in case a callback added something
@@ -2329,30 +2334,17 @@ bool LLAppViewer::initConfiguration()
// injection and steal passwords. Phoenix. SL-55321
if(clp.hasOption("url"))
{
- std::string slurl = clp.getOption("url")[0];
- if (LLURLDispatcher::isSLURLCommand(slurl))
- {
- LLStartUp::sSLURLCommand = slurl;
- }
- else
- {
- LLURLSimString::setString(slurl);
- }
+ LLStartUp::setStartSLURL(LLSLURL(clp.getOption("url")[0]));
+ if(LLStartUp::getStartSLURL().getType() == LLSLURL::LOCATION)
+ {
+ gHippoGridManager->setCurrentGrid(LLStartUp::getStartSLURL().getGrid());
+
+ }
}
else if(clp.hasOption("slurl"))
{
- std::string slurl = clp.getOption("slurl")[0];
- if(LLURLDispatcher::isSLURL(slurl))
- {
- if (LLURLDispatcher::isSLURLCommand(slurl))
- {
- LLStartUp::sSLURLCommand = slurl;
- }
- else
- {
- LLURLSimString::setString(slurl);
- }
- }
+ LLSLURL start_slurl(clp.getOption("slurl")[0]);
+ LLStartUp::setStartSLURL(start_slurl);
}
const LLControlVariable* skinfolder = gSavedSettings.getControl("SkinCurrent");
@@ -2431,18 +2423,11 @@ bool LLAppViewer::initConfiguration()
// don't call anotherInstanceRunning() when doing URL handoff, as
// it relies on checking a marker file which will not work when running
// out of different directories
- std::string slurl;
- if (!LLStartUp::sSLURLCommand.empty())
+
+ if (LLStartUp::getStartSLURL().isValid() &&
+ (gSavedSettings.getBOOL("SLURLPassToOtherInstance")))
{
- slurl = LLStartUp::sSLURLCommand;
- }
- else if (LLURLSimString::parse())
- {
- slurl = LLURLSimString::getURL();
- }
- if (!slurl.empty())
- {
- if (sendURLToOtherInstance(slurl))
+ if (sendURLToOtherInstance(LLStartUp::getStartSLURL().getSLURLString()))
{
// successfully handed off URL to existing instance, exit
return false;
@@ -2498,9 +2483,10 @@ bool LLAppViewer::initConfiguration()
// need to do this here - need to have initialized global settings first
std::string nextLoginLocation = gSavedSettings.getString( "NextLoginLocation" );
- if ( nextLoginLocation.length() )
+ if ( !nextLoginLocation.empty() )
{
- LLURLSimString::setString( nextLoginLocation );
+ LL_DEBUGS("AppInit")<<"set start from NextLoginLocation: "<getDirDelimiter() + file_mask;
- gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""), mask);
+ gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""), file_mask);
}
void LLAppViewer::writeSystemInfo()
diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp
index 29f8cfe8e..ce64710fa 100644
--- a/indra/newview/llappviewerlinux.cpp
+++ b/indra/newview/llappviewerlinux.cpp
@@ -459,7 +459,7 @@ gboolean viewer_app_api_GoSLURL(ViewerAppAPI *obj, gchar *slurl, gboolean **succ
std::string url = slurl;
LLMediaCtrl* web = NULL;
const bool trusted_browser = false;
- if (LLURLDispatcher::dispatch(url, web, trusted_browser))
+ if (LLURLDispatcher::dispatch(url, "", web, trusted_browser))
{
// bring window to foreground, as it has just been "launched" from a URL
// todo: hmm, how to get there from here?
diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp
index da03fc76e..029b0953e 100644
--- a/indra/newview/llappviewermacosx.cpp
+++ b/indra/newview/llappviewermacosx.cpp
@@ -43,7 +43,6 @@
#include "llviewernetwork.h"
#include "llviewercontrol.h"
#include "llmd5.h"
-#include "llurlsimstring.h"
#include "llfloaterworldmap.h"
#include "llurldispatcher.h"
#include
@@ -476,7 +475,7 @@ OSErr AEGURLHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn)
LLMediaCtrl* web = NULL;
const bool trusted_browser = false;
- LLURLDispatcher::dispatch(url, web, trusted_browser);
+ LLURLDispatcher::dispatch(url, "", web, trusted_browser);
}
return(result);
diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index 0d71bc3f4..5ccb1f7e6 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -488,7 +488,7 @@ bool LLAppViewerWin32::initHardwareTest()
if (OSBTN_NO== button)
{
LL_INFOS("AppInit") << "User quitting after failed DirectX 9 detection" << LL_ENDL;
- LLWeb::loadURLExternal(DIRECTX_9_URL);
+ LLWeb::loadURLExternal(DIRECTX_9_URL, false);
return false;
}
gSavedSettings.setWarning("AboutDirectX9", FALSE);
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 6bfbad3bf..bdb57a10f 100644
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -46,6 +46,7 @@
#include "lltrans.h"
#include "llvoiceclient.h"
#include "llweb.h"
+#include "llslurl.h" // IDEVO
// [RLVa:KB] - Checked: 2011-04-11 (RLVa-1.3.0h) | Added: RLVa-1.3.0h
#include "rlvhandler.h"
// [/RLVa:KB]
@@ -177,7 +178,7 @@ void LLAvatarActions::startIM(const LLUUID& id)
if ( (idSession.notNull()) && (!gIMMgr->hasSession(idSession)) )
{
make_ui_sound("UISndInvalidOp");
- RlvUtil::notifyBlocked(RLV_STRING_BLOCKED_STARTIM, LLSD().with("RECIPIENT", id/*LLSLURL("agent", id, "completename").getSLURLString()*/));
+ RlvUtil::notifyBlocked(RLV_STRING_BLOCKED_STARTIM, LLSD().with("RECIPIENT", LLSLURL("agent", id, "completename").getSLURLString()));
return;
}
}
@@ -231,7 +232,7 @@ void LLAvatarActions::startCall(const LLUUID& id)
if ( (idSession.notNull()) && (!gIMMgr->hasSession(idSession)) )
{
make_ui_sound("UISndInvalidOp");
- RlvUtil::notifyBlocked(RLV_STRING_BLOCKED_STARTIM, LLSD().with("RECIPIENT", id));//LLSLURL("agent", id, "completename").getSLURLString()));
+ RlvUtil::notifyBlocked(RLV_STRING_BLOCKED_STARTIM, LLSD().with("RECIPIENT", LLSLURL("agent", id, "completename").getSLURLString()));
return;
}
}
@@ -258,7 +259,7 @@ void LLAvatarActions::startAdhocCall(const uuid_vec_t& ids)
if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.canStartIM(idAgent)) )
{
make_ui_sound("UISndInvalidOp");
- RlvUtil::notifyBlocked(RLV_STRING_BLOCKED_STARTCONF, LLSD().with("RECIPIENT", idAgent));//LLSLURL("agent", idAgent, "completename").getSLURLString()));
+ RlvUtil::notifyBlocked(RLV_STRING_BLOCKED_STARTCONF, LLSD().with("RECIPIENT", LLSLURL("agent", idAgent, "completename").getSLURLString()));
return;
}
id_array.push_back(idAgent);
@@ -312,7 +313,7 @@ void LLAvatarActions::startConference(const uuid_vec_t& ids)
if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.canStartIM(idAgent)) )
{
make_ui_sound("UISndInvalidOp");
- RlvUtil::notifyBlocked(RLV_STRING_BLOCKED_STARTCONF, LLSD().with("RECIPIENT", idAgent/*LLSLURL("agent", idAgent, "completename").getSLURLString()*/));
+ RlvUtil::notifyBlocked(RLV_STRING_BLOCKED_STARTCONF, LLSD().with("RECIPIENT", LLSLURL("agent", idAgent, "completename").getSLURLString()));
return;
}
// [/RLVa:KB]
diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp
index b8fa0a1bf..50aa2921e 100644
--- a/indra/newview/llchatbar.cpp
+++ b/indra/newview/llchatbar.cpp
@@ -896,7 +896,7 @@ class LLChatHandler : public LLCommandHandler
{
public:
// not allowed from outside the app
- LLChatHandler() : LLCommandHandler("chat", true) { }
+ LLChatHandler() : LLCommandHandler("chat", UNTRUSTED_BLOCK) { }
// Your code here
bool handle(const LLSD& tokens, const LLSD& query_map,
diff --git a/indra/newview/llcommandhandler.cpp b/indra/newview/llcommandhandler.cpp
index a04182a91..679a30891 100644
--- a/indra/newview/llcommandhandler.cpp
+++ b/indra/newview/llcommandhandler.cpp
@@ -4,46 +4,47 @@
* which manipulate user interface. For example, the command
* "agent (uuid) about" will open the UI for an avatar's profile.
*
- * $LicenseInfo:firstyear=2007&license=viewergpl$
- *
- * Copyright (c) 2007-2009, Linden Research, Inc.
- *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * Copyright (C) 2010, Linden Research, Inc.
*
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
*
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llcommandhandler.h"
+#include "llnotificationsutil.h"
+//#include "llcommanddispatcherlistener.h"
+#include "stringize.h"
// system includes
#include
+#define THROTTLE_PERIOD 5 // required seconds between throttled commands
+
+//static LLCommandDispatcherListener sCommandDispatcherListener;
+
//---------------------------------------------------------------------------
// Underlying registry for command handlers, not directly accessible.
//---------------------------------------------------------------------------
struct LLCommandHandlerInfo
{
- bool mRequireTrustedBrowser;
+ LLCommandHandler::EUntrustedAccess mUntrustedBrowserAccess;
LLCommandHandler* mHandler; // safe, all of these are static objects
};
@@ -51,14 +52,18 @@ class LLCommandHandlerRegistry
{
public:
static LLCommandHandlerRegistry& instance();
- void add(const char* cmd, bool require_trusted_browser, LLCommandHandler* handler);
+ void add(const char* cmd,
+ LLCommandHandler::EUntrustedAccess untrusted_access,
+ LLCommandHandler* handler);
bool dispatch(const std::string& cmd,
const LLSD& params,
const LLSD& query_map,
LLMediaCtrl* web,
+ const std::string& nav_type,
bool trusted_browser);
private:
+ friend LLSD LLCommandDispatcher::enumerate();
std::map mMap;
};
@@ -72,10 +77,12 @@ LLCommandHandlerRegistry& LLCommandHandlerRegistry::instance()
return instance;
}
-void LLCommandHandlerRegistry::add(const char* cmd, bool require_trusted_browser, LLCommandHandler* handler)
+void LLCommandHandlerRegistry::add(const char* cmd,
+ LLCommandHandler::EUntrustedAccess untrusted_access,
+ LLCommandHandler* handler)
{
LLCommandHandlerInfo info;
- info.mRequireTrustedBrowser = require_trusted_browser;
+ info.mUntrustedBrowserAccess = untrusted_access;
info.mHandler = handler;
mMap[cmd] = info;
@@ -85,17 +92,60 @@ bool LLCommandHandlerRegistry::dispatch(const std::string& cmd,
const LLSD& params,
const LLSD& query_map,
LLMediaCtrl* web,
+ const std::string& nav_type,
bool trusted_browser)
{
+ static bool slurl_blocked = false;
+ static bool slurl_throttled = false;
+ static F64 last_throttle_time = 0.0;
+ F64 cur_time = 0.0;
std::map::iterator it = mMap.find(cmd);
if (it == mMap.end()) return false;
const LLCommandHandlerInfo& info = it->second;
- if (!trusted_browser && info.mRequireTrustedBrowser)
+ if (!trusted_browser)
{
- // block request from external browser, but report as
- // "handled" because it was well formatted.
- LL_WARNS_ONCE("SLURL") << "Blocked SLURL command from untrusted browser" << LL_ENDL;
- return true;
+ switch (info.mUntrustedBrowserAccess)
+ {
+ case LLCommandHandler::UNTRUSTED_ALLOW:
+ // fall through and let the command be handled
+ break;
+
+ case LLCommandHandler::UNTRUSTED_BLOCK:
+ // block request from external browser, but report as
+ // "handled" because it was well formatted.
+ LL_WARNS_ONCE("SLURL") << "Blocked SLURL command from untrusted browser" << LL_ENDL;
+ if (! slurl_blocked)
+ {
+ LLNotificationsUtil::add("BlockedSLURL");
+ slurl_blocked = true;
+ }
+ return true;
+
+ case LLCommandHandler::UNTRUSTED_THROTTLE:
+ // if users actually click on a link, we don't need to throttle it
+ // (throttling mechanism is used to prevent an avalanche of clicks via
+ // javascript
+ if ( nav_type == "clicked" )
+ {
+ break;
+ }
+
+ cur_time = LLTimer::getElapsedSeconds();
+ if (cur_time < last_throttle_time + THROTTLE_PERIOD)
+ {
+ // block request from external browser if it happened
+ // within THROTTLE_PERIOD seconds of the last command
+ LL_WARNS_ONCE("SLURL") << "Throttled SLURL command from untrusted browser" << LL_ENDL;
+ if (! slurl_throttled)
+ {
+ LLNotificationsUtil::add("ThrottledSLURL");
+ slurl_throttled = true;
+ }
+ return true;
+ }
+ last_throttle_time = cur_time;
+ break;
+ }
}
if (!info.mHandler) return false;
return info.mHandler->handle(params, query_map, web);
@@ -106,10 +156,9 @@ bool LLCommandHandlerRegistry::dispatch(const std::string& cmd,
//---------------------------------------------------------------------------
LLCommandHandler::LLCommandHandler(const char* cmd,
- bool require_trusted_browser)
+ EUntrustedAccess untrusted_access)
{
- LLCommandHandlerRegistry::instance().add(
- cmd, require_trusted_browser, this);
+ LLCommandHandlerRegistry::instance().add(cmd, untrusted_access, this);
}
LLCommandHandler::~LLCommandHandler()
@@ -127,8 +176,62 @@ bool LLCommandDispatcher::dispatch(const std::string& cmd,
const LLSD& params,
const LLSD& query_map,
LLMediaCtrl* web,
+ const std::string& nav_type,
bool trusted_browser)
{
return LLCommandHandlerRegistry::instance().dispatch(
- cmd, params, query_map, web, trusted_browser);
+ cmd, params, query_map, web, nav_type, trusted_browser);
+}
+
+static std::string lookup(LLCommandHandler::EUntrustedAccess value);
+
+LLSD LLCommandDispatcher::enumerate()
+{
+ LLSD response;
+ LLCommandHandlerRegistry& registry(LLCommandHandlerRegistry::instance());
+ for (std::map::const_iterator chi(registry.mMap.begin()),
+ chend(registry.mMap.end());
+ chi != chend; ++chi)
+ {
+ LLSD info;
+ info["untrusted"] = chi->second.mUntrustedBrowserAccess;
+ info["untrusted_str"] = lookup(chi->second.mUntrustedBrowserAccess);
+ response[chi->first] = info;
+ }
+ return response;
+}
+
+/*------------------------------ lookup stuff ------------------------------*/
+struct symbol_info
+{
+ const char* name;
+ LLCommandHandler::EUntrustedAccess value;
+};
+
+#define ent(SYMBOL) \
+ { \
+ #SYMBOL + 28, /* skip "LLCommandHandler::UNTRUSTED_" prefix */ \
+ SYMBOL \
+ }
+
+symbol_info symbols[] =
+{
+ ent(LLCommandHandler::UNTRUSTED_ALLOW), // allow commands from untrusted browsers
+ ent(LLCommandHandler::UNTRUSTED_BLOCK), // ignore commands from untrusted browsers
+ ent(LLCommandHandler::UNTRUSTED_THROTTLE) // allow untrusted, but only a few per min.
+};
+
+#undef ent
+
+static std::string lookup(LLCommandHandler::EUntrustedAccess value)
+{
+ for (symbol_info *sii(symbols), *siend(symbols + (sizeof(symbols)/sizeof(symbols[0])));
+ sii != siend; ++sii)
+ {
+ if (sii->value == value)
+ {
+ return sii->name;
+ }
+ }
+ return STRINGIZE("UNTRUSTED_" << value);
}
diff --git a/indra/newview/llcommandhandler.h b/indra/newview/llcommandhandler.h
index 5cb3ee73d..1e0895565 100644
--- a/indra/newview/llcommandhandler.h
+++ b/indra/newview/llcommandhandler.h
@@ -4,36 +4,32 @@
* which manipulate user interface. For example, the command
* "agent (uuid) about" will open the UI for an avatar's profile.
*
- * $LicenseInfo:firstyear=2007&license=viewergpl$
- *
- * Copyright (c) 2007-2009, Linden Research, Inc.
- *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * Copyright (C) 2010, Linden Research, Inc.
*
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
*
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LLCOMMANDHANDLER_H
#define LLCOMMANDHANDLER_H
+#include "llsd.h"
+
/* Example: secondlife:///app/foo/
Command "foo" that takes one parameter, a UUID.
@@ -43,7 +39,7 @@ public:
// Inform the system you handle commands starting
// with "foo" and they are only allowed from
// "trusted" (pointed at Linden content) browsers
- LLFooHandler() : LLCommandHandler("foo", true) { }
+ LLFooHandler() : LLCommandHandler("foo", UNTRUSTED_BLOCK) { }
// Your code here
bool handle(const LLSD& tokens, const LLSD& query_map,
@@ -65,7 +61,14 @@ class LLMediaCtrl;
class LLCommandHandler
{
public:
- LLCommandHandler(const char* command, bool allow_from_untrusted_browser);
+ enum EUntrustedAccess
+ {
+ UNTRUSTED_ALLOW, // allow commands from untrusted browsers
+ UNTRUSTED_BLOCK, // ignore commands from untrusted browsers
+ UNTRUSTED_THROTTLE // allow untrusted, but only a few per min.
+ };
+
+ LLCommandHandler(const char* command, EUntrustedAccess untrusted_access);
// Automatically registers object to get called when
// command is executed. All commands can be processed
// in links from LLMediaCtrl, but some (like teleport)
@@ -92,10 +95,14 @@ public:
const LLSD& params,
const LLSD& query_map,
LLMediaCtrl* web,
+ const std::string& nav_type,
bool trusted_browser);
// Execute a command registered via the above mechanism,
// passing string parameters.
// Returns true if command was found and executed correctly.
+ /// Return an LLSD::Map of registered LLCommandHandlers and associated
+ /// info (e.g. EUntrustedAccess).
+ static LLSD enumerate();
};
#endif
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index 95245b8f0..5d0371601 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -190,8 +190,9 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp)
mImportanceToCamera = 0.f ;
mBoundingSphereRadius = 0.0f ;
-}
+ mHasMedia = FALSE ;
+}
void LLFace::destroy()
{
@@ -2065,6 +2066,20 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
return TRUE;
}
+//check if the face has a media
+BOOL LLFace::hasMedia() const
+{
+ if(mHasMedia)
+ {
+ return TRUE ;
+ }
+ if(mTexture.notNull())
+ {
+ return mTexture->hasParcelMedia() ; //if has a parcel media
+ }
+
+ return FALSE ; //no media.
+}
const F32 LEAST_IMPORTANCE = 0.05f ;
const F32 LEAST_IMPORTANCE_FOR_LARGE_IMAGE = 0.3f ;
@@ -2134,7 +2149,7 @@ BOOL LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius)
t.load3(camera->getOrigin().mV);
lookAt.setSub(center, t);
F32 dist = lookAt.getLength3().getF32();
- dist = llmax(dist-size.getLength3().getF32(), 0.f);
+ dist = llmax(dist-size.getLength3().getF32(), 0.001f);
lookAt.normalize3fast() ;
//get area of circle around node
@@ -2145,9 +2160,33 @@ BOOL LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius)
x_axis.load3(camera->getXAxis().mV);
cos_angle_to_view_dir = lookAt.dot3(x_axis).getF32();
+ //if has media, check if the face is out of the view frustum.
+ if(hasMedia())
+ {
+ if(!camera->AABBInFrustum(center, size))
+ {
+ mImportanceToCamera = 0.f ;
+ return false ;
+ }
+ if(cos_angle_to_view_dir > camera->getCosHalfFov()) //the center is within the view frustum
+ {
+ cos_angle_to_view_dir = 1.0f ;
+ }
+ else
+ {
+ LLVector4a d;
+ d.setSub(lookAt, x_axis);
+
+ if(dist * dist * d.dot3(d) < size_squared)
+ {
+ cos_angle_to_view_dir = 1.0f ;
+ }
+ }
+ }
+
if(dist < mBoundingSphereRadius) //camera is very close
{
- cos_angle_to_view_dir = 1.0f;
+ cos_angle_to_view_dir = 1.0f ;
mImportanceToCamera = 1.0f;
}
else
diff --git a/indra/newview/llface.h b/indra/newview/llface.h
index b59dff8f0..68cdcadde 100644
--- a/indra/newview/llface.h
+++ b/indra/newview/llface.h
@@ -224,6 +224,9 @@ public:
F32 getTextureVirtualSize() ;
F32 getImportanceToCamera()const {return mImportanceToCamera ;}
+
+ void setHasMedia(bool has_media) { mHasMedia = has_media ;}
+ BOOL hasMedia() const ;
//vertex buffer tracking
void setVertexBuffer(LLVertexBuffer* buffer);
void clearVertexBuffer(); //sets mVertexBuffer and mLastVertexBuffer to NULL
@@ -289,6 +292,7 @@ private:
//based on the distance from the face to the view point and the angle from the face center to the view direction.
F32 mImportanceToCamera ;
F32 mBoundingSphereRadius ;
+ bool mHasMedia ;
protected:
static BOOL sSafeRenderSelect;
diff --git a/indra/newview/llfloaterclassified.cpp b/indra/newview/llfloaterclassified.cpp
index 07603039b..f695da399 100644
--- a/indra/newview/llfloaterclassified.cpp
+++ b/indra/newview/llfloaterclassified.cpp
@@ -55,7 +55,7 @@ class LLClassifiedHandler : public LLCommandHandler
{
public:
// requires trusted browser to trigger
- LLClassifiedHandler() : LLCommandHandler("classified", true) { }
+ LLClassifiedHandler() : LLCommandHandler("classified", UNTRUSTED_THROTTLE) { }
bool handle(const LLSD& tokens, const LLSD& query_map,
LLMediaCtrl* web)
{
diff --git a/indra/newview/llfloaterevent.cpp b/indra/newview/llfloaterevent.cpp
index 0ec2a7637..b526767f8 100644
--- a/indra/newview/llfloaterevent.cpp
+++ b/indra/newview/llfloaterevent.cpp
@@ -56,7 +56,7 @@ class LLEventHandler : public LLCommandHandler
{
public:
// requires trusted browser to trigger
- LLEventHandler() : LLCommandHandler("event", true) { }
+ LLEventHandler() : LLCommandHandler("event", UNTRUSTED_THROTTLE) { }
bool handle(const LLSD& tokens, const LLSD& query_map,
LLMediaCtrl* web)
{
diff --git a/indra/newview/llfloaterhandler.h b/indra/newview/llfloaterhandler.h
index 31ea80c12..cd9d8b537 100644
--- a/indra/newview/llfloaterhandler.h
+++ b/indra/newview/llfloaterhandler.h
@@ -38,7 +38,7 @@ class LLFloaterHandler
: public LLCommandHandler
{
public:
- LLFloaterHandler() : LLCommandHandler("floater", true) { }
+ LLFloaterHandler() : LLCommandHandler("floater", UNTRUSTED_BLOCK) { }
bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web);
};
diff --git a/indra/newview/llfloaterhtmlsimple.cpp b/indra/newview/llfloaterhtmlsimple.cpp
index 8091c1e97..67650be48 100644
--- a/indra/newview/llfloaterhtmlsimple.cpp
+++ b/indra/newview/llfloaterhtmlsimple.cpp
@@ -63,5 +63,5 @@ void LLFloaterHtmlSimple::navigateTo(const std::string &url)
void LLFloaterHtmlSimple::setTrusted(bool trusted)
{
LLMediaCtrl* web = getChild("browser");
- web->setTrusted(trusted);
+ web->setTrustedContent(trusted);
}
diff --git a/indra/newview/llfloaterhud.cpp b/indra/newview/llfloaterhud.cpp
index cb8071588..f2743e0cf 100644
--- a/indra/newview/llfloaterhud.cpp
+++ b/indra/newview/llfloaterhud.cpp
@@ -78,7 +78,7 @@ LLFloaterHUD::LLFloaterHUD()
if (mWebBrowser)
{
// Open links in internal browser
- mWebBrowser->setOpenInExternalBrowser(false);
+ //mWebBrowser->setOpenInExternalBrowser(false);
// This is a "chrome" floater, so we don't want anything to
// take focus (as the user needs to be able to walk with
diff --git a/indra/newview/llfloatermediabrowser.cpp b/indra/newview/llfloatermediabrowser.cpp
deleted file mode 100644
index 43abcb8c0..000000000
--- a/indra/newview/llfloatermediabrowser.cpp
+++ /dev/null
@@ -1,434 +0,0 @@
-/**
- * @file llfloaterhtmlhelp.cpp
- * @brief HTML Help floater - uses embedded web browser control
- *
- * $LicenseInfo:firstyear=2006&license=viewergpl$
- *
- * Copyright (c) 2006-2009, Linden Research, Inc.
- *
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- *
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- *
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- *
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llfloatermediabrowser.h"
-#include "llfloaterhtml.h"
-
-#include "llparcel.h"
-#include "llpluginclassmedia.h"
-#include "lluictrlfactory.h"
-#include "llmediactrl.h"
-#include "llviewerwindow.h"
-#include "llviewercontrol.h"
-#include "llviewerparcelmgr.h"
-#include "llweb.h"
-#include "llui.h"
-#include "roles_constants.h"
-#include "llwindow.h"
-
-#include "llurlhistory.h"
-#include "llmediactrl.h"
-#include "llviewermedia.h"
-#include "llviewerparcelmedia.h"
-#include "llcombobox.h"
-#include "llnotificationsutil.h"
-
-// TEMP
-#include "llsdutil.h"
-
-LLFloaterMediaBrowser::LLFloaterMediaBrowser(const LLSD& media_data)
-{
- LLUICtrlFactory::getInstance()->buildFloater(this, "floater_media_browser.xml");
-
-}
-
-
-void LLFloaterMediaBrowser::geometryChanged(S32 x, S32 y, S32 width, S32 height)
-{
- // Make sure the layout of the browser control is updated, so this calculation is correct.
- LLLayoutStack::updateClass();
-
- // TODO: need to adjust size and constrain position to make sure floaters aren't moved outside the window view, etc.
- LLCoordWindow window_size;
- getWindow()->getSize(&window_size);
-
- // Adjust width and height for the size of the chrome on the Media Browser window.
- width += getRect().getWidth() - mBrowser->getRect().getWidth();
- height += getRect().getHeight() - mBrowser->getRect().getHeight();
-
- LLRect geom;
- geom.setOriginAndSize(x, window_size.mY - (y + height), width, height);
-
- lldebugs << "geometry change: " << geom << llendl;
-
- handleReshape(geom,false);
-}
-
-void LLFloaterMediaBrowser::draw()
-{
- childSetEnabled("go", !mAddressCombo->getValue().asString().empty());
- LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
- if(parcel)
- {
- childSetVisible("parcel_owner_controls", LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_CHANGE_MEDIA));
- childSetEnabled("assign", !mAddressCombo->getValue().asString().empty());
- }
- bool show_time_controls = false;
- bool media_playing = false;
- if(mBrowser)
- {
- LLPluginClassMedia* media_plugin = mBrowser->getMediaPlugin();
- if(media_plugin)
- {
- show_time_controls = media_plugin->pluginSupportsMediaTime();
- media_playing = media_plugin->getStatus() == LLPluginClassMediaOwner::MEDIA_PLAYING;
- }
- }
- childSetVisible("time_controls", show_time_controls);
- childSetVisible("rewind", show_time_controls);
- childSetVisible("play", show_time_controls && ! media_playing);
- childSetVisible("pause", show_time_controls && media_playing);
- childSetVisible("stop", show_time_controls);
- childSetVisible("seek", show_time_controls);
-
- childSetEnabled("play", ! media_playing);
- childSetEnabled("stop", media_playing);
-
- childSetEnabled("back", mBrowser->canNavigateBack());
- childSetEnabled("forward", mBrowser->canNavigateForward());
-
- LLFloater::draw();
-}
-
-BOOL LLFloaterMediaBrowser::postBuild()
-{
- mBrowser = getChild("browser");
- mBrowser->addObserver(this);
-
- mAddressCombo = getChild("address");
- mAddressCombo->setCommitCallback(onEnterAddress);
- mAddressCombo->setCallbackUserData(this);
- mAddressCombo->sortByName();
-
- childSetAction("back", onClickBack, this);
- childSetAction("forward", onClickForward, this);
- childSetAction("reload", onClickRefresh, this);
- childSetAction("rewind", onClickRewind, this);
- childSetAction("play", onClickPlay, this);
- childSetAction("stop", onClickStop, this);
- childSetAction("pause", onClickPlay, this);
- childSetAction("seek", onClickSeek, this);
- childSetAction("go", onClickGo, this);
- childSetAction("open_browser", onClickOpenWebBrowser, this);
- childSetAction("assign", onClickAssign, this);
-
- buildURLHistory();
- return TRUE;
-}
-
-void LLFloaterMediaBrowser::buildURLHistory()
-{
- LLCtrlListInterface* url_list = childGetListInterface("address");
- if (url_list)
- {
- url_list->operateOnAll(LLCtrlListInterface::OP_DELETE);
- }
-
- // Get all of the entries in the "browser" collection
- LLSD browser_history = LLURLHistory::getURLHistory("browser");
-
- LLSD::array_iterator iter_history =
- browser_history.beginArray();
- LLSD::array_iterator end_history =
- browser_history.endArray();
- for(; iter_history != end_history; ++iter_history)
- {
- std::string url = (*iter_history).asString();
- if(! url.empty())
- url_list->addSimpleElement(url);
- }
-
- // initialize URL history in the plugin
- if(mBrowser && mBrowser->getMediaPlugin())
- {
- mBrowser->getMediaPlugin()->initializeUrlHistory(browser_history);
- }
-}
-
-std::string LLFloaterMediaBrowser::getSupportURL()
-{
- return getString("support_page_url");
-}
-void LLFloaterMediaBrowser::onClose(bool app_quitting)
-{
- //setVisible(FALSE);
- destroy();
-}
-
-void LLFloaterMediaBrowser::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
-{
- if(event == MEDIA_EVENT_LOCATION_CHANGED)
- {
- setCurrentURL(self->getLocation());
- }
- else if(event == MEDIA_EVENT_NAVIGATE_COMPLETE)
- {
- // This is the event these flags are sent with.
- childSetEnabled("back", self->getHistoryBackAvailable());
- childSetEnabled("forward", self->getHistoryForwardAvailable());
- }
- else if(event == MEDIA_EVENT_CLOSE_REQUEST)
- {
- // The browser instance wants its window closed.
- close();
- }
- else if(event == MEDIA_EVENT_GEOMETRY_CHANGE)
- {
- geometryChanged(self->getGeometryX(), self->getGeometryY(), self->getGeometryWidth(), self->getGeometryHeight());
- }
-}
-void LLFloaterMediaBrowser::setCurrentURL(const std::string& url)
-{
- mCurrentURL = url;
-
- // redirects will navigate momentarily to about:blank, don't add to history
- if (mCurrentURL != "about:blank")
- {
- mAddressCombo->remove(mCurrentURL);
- mAddressCombo->add(mCurrentURL, ADD_SORTED);
- mAddressCombo->selectByValue(mCurrentURL);
-
- // Serialize url history
- LLURLHistory::removeURL("browser", mCurrentURL);
- LLURLHistory::addURL("browser", mCurrentURL);
- }
- childSetEnabled("back", mBrowser->canNavigateBack());
- childSetEnabled("forward", mBrowser->canNavigateForward());
- childSetEnabled("reload", TRUE);
-}
-
-LLFloaterMediaBrowser* LLFloaterMediaBrowser::showInstance(const LLSD& media_url)
-{
- LLFloaterMediaBrowser* floaterp = LLUISingleton >::showInstance(media_url);
-
- floaterp->openMedia(media_url.asString());
- return floaterp;
-}
-
-//static
-void LLFloaterMediaBrowser::onEnterAddress(LLUICtrl* ctrl, void* user_data)
-{
- LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data;
- self->mBrowser->navigateTo(self->mAddressCombo->getValue().asString());
-}
-
-//static
-void LLFloaterMediaBrowser::onClickRefresh(void* user_data)
-{
- LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data;
-
- self->mAddressCombo->remove(0);
- if( self->mBrowser->getMediaPlugin() && self->mBrowser->getMediaPlugin()->pluginSupportsMediaBrowser())
- {
- bool ignore_cache = true;
- self->mBrowser->getMediaPlugin()->browse_reload( ignore_cache );
- }
- else
- {
- self->mBrowser->navigateTo(self->mCurrentURL);
- }
-}
-
-//static
-void LLFloaterMediaBrowser::onClickForward(void* user_data)
-{
- LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data;
-
- self->mBrowser->navigateForward();
-}
-
-//static
-void LLFloaterMediaBrowser::onClickBack(void* user_data)
-{
- LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data;
-
- self->mBrowser->navigateBack();
-}
-
-//static
-void LLFloaterMediaBrowser::onClickGo(void* user_data)
-{
- LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data;
-
- self->mBrowser->navigateTo(self->mAddressCombo->getValue().asString());
-}
-
-//static
-void LLFloaterMediaBrowser::onClickOpenWebBrowser(void* user_data)
-{
- LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data;
-
- std::string url = self->mCurrentURL.empty() ?
- self->mBrowser->getHomePageUrl() :
- self->mCurrentURL;
- LLWeb::loadURLExternal(url);
-}
-
-void LLFloaterMediaBrowser::onClickAssign(void* user_data)
-{
- LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data;
-
- LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
- if (!parcel)
- {
- return;
- }
- std::string media_url = self->mAddressCombo->getValue().asString();
- LLStringUtil::trim(media_url);
-
- if(parcel->getMediaType() != "text/html")
- {
- parcel->setMediaURL(media_url);
- parcel->setMediaCurrentURL(media_url);
- parcel->setMediaType(std::string("text/html"));
- LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate( parcel, true );
- LLViewerParcelMedia::sendMediaNavigateMessage(media_url);
- LLViewerParcelMedia::stop();
- // LLViewerParcelMedia::update( parcel );
- }
- LLViewerParcelMedia::sendMediaNavigateMessage(media_url);
-}
-//static
-void LLFloaterMediaBrowser::onClickRewind(void* user_data)
-{
- LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data;
-
- if(self->mBrowser->getMediaPlugin())
- self->mBrowser->getMediaPlugin()->start(-2.0f);
-}
-//static
-void LLFloaterMediaBrowser::onClickPlay(void* user_data)
-{
- LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data;
-
- LLPluginClassMedia* plugin = self->mBrowser->getMediaPlugin();
- if(plugin)
- {
- if(plugin->getStatus() == LLPluginClassMediaOwner::MEDIA_PLAYING)
- {
- plugin->pause();
- }
- else
- {
- plugin->start();
- }
- }
-}
-//static
-void LLFloaterMediaBrowser::onClickStop(void* user_data)
-{
- LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data;
-
- if(self->mBrowser->getMediaPlugin())
- self->mBrowser->getMediaPlugin()->stop();
-}
-//static
-void LLFloaterMediaBrowser::onClickSeek(void* user_data)
-{
- LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data;
-
- if(self->mBrowser->getMediaPlugin())
- self->mBrowser->getMediaPlugin()->start(2.0f);
-}
-void LLFloaterMediaBrowser::openMedia(const std::string& media_url)
-{
- mBrowser->setHomePageUrl(media_url);
- mBrowser->navigateTo(media_url);
- setCurrentURL(media_url);
-}
-////////////////////////////////////////////////////////////////////////////////
-//
-
-LLViewerHtmlHelp gViewerHtmlHelp;
-
-
-////////////////////////////////////////////////////////////////////////////////
-//
-LLViewerHtmlHelp::LLViewerHtmlHelp()
-{
-
- LLUI::setHtmlHelp(this);
-}
-
-LLViewerHtmlHelp::~LLViewerHtmlHelp()
-{
-
- LLUI::setHtmlHelp(NULL);
-}
-
-void LLViewerHtmlHelp::show()
-{
- show("");
-}
-
-void LLViewerHtmlHelp::show(std::string url)
-{
- LLFloaterMediaBrowser* floater_html = LLFloaterMediaBrowser::getInstance();
- floater_html->setVisible(FALSE);
-
- if (url.empty())
- {
- url = floater_html->getSupportURL();
- }
-
- if (gSavedSettings.getBOOL("UseExternalBrowser"))
- {
- LLSD notificationData;
- notificationData["url"] = url;
-
- LLNotificationsUtil::add("ClickOpenF1Help", notificationData, LLSD(), onClickF1HelpLoadURL);
- floater_html->close();
- }
- else
- {
- // don't wait, just do it
- floater_html->setVisible(TRUE);
- floater_html->openMedia(url);
- }
-}
-// static
-bool LLViewerHtmlHelp::onClickF1HelpLoadURL(const LLSD& notification, const LLSD& response)
-{
- LLFloaterMediaBrowser* floater_html = LLFloaterMediaBrowser::getInstance();
- floater_html->setVisible(FALSE);
- std::string url = floater_html->getSupportURL();
- S32 option = LLNotification::getSelectedOption(notification, response);
- if (option == 0)
- {
- LLWeb::loadURL(url);
- }
- floater_html->close();
- return false;
-}
-
diff --git a/indra/newview/llfloatermediabrowser.h b/indra/newview/llfloatermediabrowser.h
deleted file mode 100644
index c2203670a..000000000
--- a/indra/newview/llfloatermediabrowser.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/**
- * @file llfloaterhtmlhelp.h
- * @brief HTML Help floater - uses embedded web browser control
- *
- * $LicenseInfo:firstyear=2006&license=viewergpl$
- *
- * Copyright (c) 2006-2009, Linden Research, Inc.
- *
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- *
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- *
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- *
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLFLOATERHTMLHELP_H
-#define LL_LLFLOATERHTMLHELP_H
-
-#include "llhtmlhelp.h"
-#include "llfloater.h"
-#include "llmediactrl.h"
-
-class LLViewerHtmlHelp : public LLHtmlHelp
-{
-public:
- LLViewerHtmlHelp();
- virtual ~LLViewerHtmlHelp();
-
- /*virtual*/ void show();
- /*virtual*/ void show(std::string start_url);
- void show(std::string start_url, std::string title);
-
- static bool onClickF1HelpLoadURL(const LLSD& notification, const LLSD& response);
-
-};
-
-class LLComboBox;
-class LLMediaCtrl;
-
-class LLFloaterMediaBrowser :
- public LLFloater,
- public LLUISingleton >,
- public LLViewerMediaObserver
-{
- friend class LLUISingleton >;
-public:
- LLFloaterMediaBrowser(const LLSD& media_data);
-
-
- void geometryChanged(S32 x, S32 y, S32 width, S32 height);
-
- /*virtual*/ BOOL postBuild();
- /*virtual*/ void onClose(bool app_quitting);
- /*virtual*/ void draw();
-
- // inherited from LLViewerMediaObserver
- /*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event);
-
- void openMedia(const std::string& media_url);
- void buildURLHistory();
- std::string getSupportURL();
- void setCurrentURL(const std::string& url);
-
- static LLFloaterMediaBrowser* showInstance(const LLSD& id);
- static void onEnterAddress(LLUICtrl* ctrl, void* user_data);
- static void onClickRefresh(void* user_data);
- static void onClickBack(void* user_data);
- static void onClickForward(void* user_data);
- static void onClickGo(void* user_data);
- static void onClickOpenWebBrowser(void* user_data);
- static void onClickAssign(void* user_data);
- static void onClickRewind(void* user_data);
- static void onClickPlay(void* user_data);
- static void onClickStop(void* user_data);
- static void onClickSeek(void* user_data);
-
-private:
- LLMediaCtrl* mBrowser;
- LLComboBox* mAddressCombo;
- std::string mCurrentURL;
-};
-
-extern LLViewerHtmlHelp gViewerHtmlHelp;
-
-#endif // LL_LLFLOATERHTMLHELP_H
-
diff --git a/indra/newview/llfloaternotificationsconsole.h b/indra/newview/llfloaternotificationsconsole.h
index 1a436b8bf..037255318 100644
--- a/indra/newview/llfloaternotificationsconsole.h
+++ b/indra/newview/llfloaternotificationsconsole.h
@@ -34,6 +34,7 @@
#define LL_LLFLOATER_NOTIFICATIONS_CONSOLE_H
#include "llfloater.h"
+#include "lllayoutstack.h"
#include "llnotifications.h"
class LLFloaterNotificationConsole :
diff --git a/indra/newview/llfloaterobjectiminfo.cpp b/indra/newview/llfloaterobjectiminfo.cpp
index af4650d0c..5d433bca6 100644
--- a/indra/newview/llfloaterobjectiminfo.cpp
+++ b/indra/newview/llfloaterobjectiminfo.cpp
@@ -42,9 +42,13 @@
#include "llfloatermute.h"
#include "llgroupactions.h"
#include "llmutelist.h"
-#include "llsdutil.h"
+#include "llslurl.h"
+#include "lltrans.h"
+#include "llui.h"
+#include "lluictrl.h"
#include "lluictrlfactory.h"
-#include "llurldispatcher.h"
+#include "llurlaction.h"
+#include "llweb.h"
// [RLVa:KB] - Version: 1.23.4
#include "rlvhandler.h"
@@ -52,34 +56,9 @@
////////////////////////////////////////////////////////////////////////////
// LLFloaterObjectIMInfo
-class LLFloaterObjectIMInfo : public LLFloater, public LLFloaterSingleton
-{
-public:
- LLFloaterObjectIMInfo(const LLSD& sd);
- virtual ~LLFloaterObjectIMInfo() { };
-
- BOOL postBuild(void);
-
- void update(const LLUUID& id, const std::string& name, const std::string& slurl, const LLUUID& owner, bool owner_is_group);
-
- // UI Handlers
- static void onClickMap(void* data);
- static void onClickOwner(void* data);
- static void onClickMute(void* data);
-
- void nameCallback(const LLUUID& id, const std::string& full_name, bool is_group);
-
-private:
- LLUUID mObjectID;
- std::string mObjectName;
- std::string mSlurl;
- LLUUID mOwnerID;
- std::string mOwnerName;
- bool mOwnerIsGroup;
-};
LLFloaterObjectIMInfo::LLFloaterObjectIMInfo(const LLSD& seed)
-: mObjectID(), mObjectName(), mSlurl(), mOwnerID(), mOwnerName(), mOwnerIsGroup(false)
+: mObjectID(), mName(), mSLurl(), mOwnerID(), mGroupOwned(false)
{
LLUICtrlFactory::getInstance()->buildFloater(this, "floater_object_im_info.xml");
@@ -99,34 +78,37 @@ BOOL LLFloaterObjectIMInfo::postBuild(void)
return true;
}
-void LLFloaterObjectIMInfo::update(const LLUUID& object_id, const std::string& name, const std::string& slurl, const LLUUID& owner_id, bool owner_is_group)
+void LLFloaterObjectIMInfo::update(LLSD& data)
{
+ // Extract appropriate object information from input LLSD
+ // (Eventually, it might be nice to query server for details
+ // rather than require caller to pass in the information.)
+ mObjectID = data["object_id"].asUUID();
+ mName = data["name"].asString();
+ mOwnerID = data["owner_id"].asUUID();
+ mGroupOwned = data["group_owned"].asBoolean();
+ mSLurl = data["slurl"].asString();
+
// When talking to an old region we won't have a slurl.
// The object id isn't really the object id either but we don't use it so who cares.
//bool have_slurl = !slurl.empty();
// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-04 (RLVa-1.0.0a) | Added: RLVa-0.2.0g
- bool have_slurl = (!slurl.empty()) && (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC));
+ bool have_slurl = (!mSLurl.empty()) && (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC));
// [/RLVa:KB]
childSetVisible("Unknown_Slurl",!have_slurl);
childSetVisible("Slurl",have_slurl);
- childSetText("ObjectName",name);
- childSetText("Slurl",slurl);
+ childSetText("ObjectName",mName);
+ childSetText("Slurl",mSLurl);
childSetText("OwnerName",std::string(""));
// bool my_object = (owner_id == gAgentID);
// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-08 (RLVa-1.0.0e) | Added: RLVa-0.2.0g
- bool my_object = (owner_id == gAgentID) || ((gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) && (RlvUtil::isNearbyAgent(owner_id)));
+ bool my_object = (mOwnerID == gAgentID) || ((gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) && (RlvUtil::isNearbyAgent(mOwnerID)));
// [/RLVa:KB]
childSetEnabled("Mute",!my_object);
- mObjectID = object_id;
- mObjectName = name;
- mSlurl = slurl;
- mOwnerID = owner_id;
- mOwnerIsGroup = owner_is_group;
-
- if (gCacheName) gCacheName->get(owner_id,owner_is_group,boost::bind(&LLFloaterObjectIMInfo::nameCallback,this,_1,_2,_3));
+ if (gCacheName) gCacheName->get(mOwnerID,mGroupOwned,boost::bind(&LLFloaterObjectIMInfo::nameCallback,this,_1,_2,_3));
}
//static
@@ -134,17 +116,15 @@ void LLFloaterObjectIMInfo::onClickMap(void* data)
{
LLFloaterObjectIMInfo* self = (LLFloaterObjectIMInfo*)data;
- std::ostringstream link;
- link << "secondlife://" << self->mSlurl;
- class LLMediaCtrl* web = NULL;
- LLURLDispatcher::dispatch(link.str(), web, true);
+ std::string url = "secondlife://" + self->mSLurl;
+ LLUrlAction::showLocationOnMap(url);
}
//static
void LLFloaterObjectIMInfo::onClickOwner(void* data)
{
LLFloaterObjectIMInfo* self = (LLFloaterObjectIMInfo*)data;
- if (self->mOwnerIsGroup)
+ if (self->mGroupOwned)
{
LLGroupActions::show(self->mOwnerID);
}
@@ -162,7 +142,7 @@ void LLFloaterObjectIMInfo::onClickMute(void* data)
{
LLFloaterObjectIMInfo* self = (LLFloaterObjectIMInfo*)data;
- LLMute::EType mute_type = (self->mOwnerIsGroup) ? LLMute::GROUP : LLMute::AGENT;
+ LLMute::EType mute_type = (self->mGroupOwned) ? LLMute::GROUP : LLMute::AGENT;
// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-08 (RLVa-1.0.0e) | Added: RLVa-0.2.0g
if ( (LLMute::GROUP != mute_type) && (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) && (RlvUtil::isNearbyAgent(self->mOwnerID)) )
{
@@ -170,7 +150,7 @@ void LLFloaterObjectIMInfo::onClickMute(void* data)
}
// [/RLVa:KB]
- LLMute mute(self->mOwnerID, self->mOwnerName, mute_type);
+ LLMute mute(self->mOwnerID, self->mName, mute_type);
LLMuteList::getInstance()->add(mute);
LLFloaterMute::showInstance();
self->close();
@@ -179,49 +159,50 @@ void LLFloaterObjectIMInfo::onClickMute(void* data)
//static
void LLFloaterObjectIMInfo::nameCallback(const LLUUID& id, const std::string& full_name, bool is_group)
{
- mOwnerName = full_name;
+ mName = full_name;
// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-08 (RLVa-1.0.0e) | Added: RLVa-0.2.0g
if ( (!is_group) && (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) && (RlvUtil::isNearbyAgent(id)) )
{
- mOwnerName = RlvStrings::getAnonym(mOwnerName);
+ mName = RlvStrings::getAnonym(mName);
}
// [/RLVa:KB]
- childSetText("OwnerName", mOwnerName);
-}
-
-////////////////////////////////////////////////////////////////////////////
-// LLObjectIMInfo
-void LLObjectIMInfo::show(const LLUUID &object_id, const std::string &name, const std::string &location, const LLUUID &owner_id, bool owner_is_group)
-{
- LLFloaterObjectIMInfo* im_info_floater = LLFloaterObjectIMInfo::showInstance();
- im_info_floater->update(object_id,name,location,owner_id,owner_is_group);
+ childSetText("OwnerName", mName);
}
////////////////////////////////////////////////////////////////////////////
// LLObjectIMInfoHandler
+//moved to llchathistory.cpp in v2
class LLObjectIMInfoHandler : public LLCommandHandler
{
public:
- LLObjectIMInfoHandler() : LLCommandHandler("objectim", true) { }
+ LLObjectIMInfoHandler() : LLCommandHandler("objectim", UNTRUSTED_THROTTLE) { }
- bool handle(const LLSD& tokens, const LLSD& query_map,
- LLMediaCtrl* web);
+ bool handle(const LLSD& params, const LLSD& query_map,LLMediaCtrl* web)
+ {
+ if (params.size() < 1)
+ {
+ return false;
+ }
+
+ LLUUID object_id;
+ if (!object_id.set(params[0], FALSE))
+ {
+ return false;
+ }
+
+ LLSD payload;
+ payload["object_id"] = object_id;
+ payload["owner_id"] = query_map["owner"];
+ payload["name"] = query_map["name"];
+ payload["slurl"] = LLWeb::escapeURL(query_map["slurl"]);
+ payload["group_owned"] = query_map["groupowned"];
+
+ LLFloaterObjectIMInfo::showInstance()->update(payload);
+
+ return true;
+ }
};
// Creating the object registers with the dispatcher.
LLObjectIMInfoHandler gObjectIMHandler;
-
-// ex. secondlife:///app/objectim/9426adfc-9c17-8765-5f09-fdf19957d003?owner=a112d245-9095-4e9c-ace4-ffa31717f934&groupowned=true&slurl=ahern/123/123/123&name=Object
-bool LLObjectIMInfoHandler::handle(const LLSD &tokens, const LLSD &query_map, LLMediaCtrl* web)
-{
- LLUUID task_id = tokens[0].asUUID();
- std::string name = query_map["name"].asString();
- std::string slurl = query_map["slurl"].asString();
- LLUUID owner = query_map["owner"].asUUID();
- bool group_owned = query_map.has("groupowned");
-
- LLObjectIMInfo::show(task_id,name,slurl,owner,group_owned);
-
- return true;
-}
diff --git a/indra/newview/llfloaterobjectiminfo.h b/indra/newview/llfloaterobjectiminfo.h
index 55f8bba6f..58377c009 100644
--- a/indra/newview/llfloaterobjectiminfo.h
+++ b/indra/newview/llfloaterobjectiminfo.h
@@ -33,14 +33,31 @@
#ifndef LL_LLFLOATEROBJECTIMINFO_H
#define LL_LLFLOATEROBJECTIMINFO_H
-namespace LLObjectIMInfo
+#include "llfloater.h"
+
+class LLFloaterObjectIMInfo : public LLFloater, public LLFloaterSingleton
{
- // Show an LLFloaterObjectIMInfo for this object.
- static void show(const LLUUID& object_id,
- const std::string& name,
- const std::string& location,
- const LLUUID& owner_id,
- bool owner_is_group);
+public:
+ LLFloaterObjectIMInfo(const LLSD& sd);
+ virtual ~LLFloaterObjectIMInfo() { };
+
+ /*virtual*/ BOOL postBuild(void);
+
+ void update(LLSD& payload);
+
+ // UI Handlers
+ static void onClickMap(void* data);
+ static void onClickOwner(void* data);
+ static void onClickMute(void* data);
+
+ void nameCallback(const LLUUID& id, const std::string& full_name, bool is_group);
+
+private:
+ LLUUID mObjectID;
+ LLUUID mOwnerID;
+ std::string mSLurl;
+ std::string mName;
+ bool mGroupOwned;
};
#endif // LL_LLFLOATERURLDISPLAY_H
diff --git a/indra/newview/llfloaterparcel.cpp b/indra/newview/llfloaterparcel.cpp
index a61f3b912..93afb820f 100644
--- a/indra/newview/llfloaterparcel.cpp
+++ b/indra/newview/llfloaterparcel.cpp
@@ -49,11 +49,12 @@
LLMap< const LLUUID, LLFloaterParcelInfo* > gPlaceInfoInstances;
+//moved to llpanelplaces.cpp in v2
class LLParcelHandler : public LLCommandHandler
{
public:
// requires trusted browser to trigger
- LLParcelHandler() : LLCommandHandler("parcel", true) { }
+ LLParcelHandler() : LLCommandHandler("parcel", UNTRUSTED_THROTTLE) { }
bool handle(const LLSD& params, const LLSD& query_map,
LLMediaCtrl* web)
{
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index ed0b07be4..dbbd06f76 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -93,7 +93,7 @@ class LLPreferencesHandler : public LLCommandHandler
{
public:
// requires trusted browser
- LLPreferencesHandler() : LLCommandHandler("preferences", true) { }
+ LLPreferencesHandler() : LLCommandHandler("preferences", UNTRUSTED_BLOCK) { }
bool handle(const LLSD& tokens, const LLSD& query_map,
LLMediaCtrl* web)
{
@@ -469,7 +469,7 @@ void LLFloaterPreference::onBtnOK( void* userdata )
llinfos << "Can't close preferences!" << llendl;
}
- LLPanelLogin::refreshLocation( false );
+ LLPanelLogin::updateLocationSelectorsVisibility();
}
@@ -480,14 +480,14 @@ void LLFloaterPreference::onBtnApply( void* userdata )
if (fp->hasFocus())
{
LLUICtrl* cur_focus = dynamic_cast(gFocusMgr.getKeyboardFocus());
- if (cur_focus->acceptsTextInput())
+ if (cur_focus && cur_focus->acceptsTextInput())
{
cur_focus->onCommit();
}
}
fp->apply();
- LLPanelLogin::refreshLocation( false );
+ LLPanelLogin::updateLocationSelectorsVisibility();
}
diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp
index 83ab8b0e8..d41cbf17a 100644
--- a/indra/newview/llfloaterreporter.cpp
+++ b/indra/newview/llfloaterreporter.cpp
@@ -51,9 +51,11 @@
// viewer project includes
#include "llagent.h"
+#include "llagentui.h"
#include "llbutton.h"
#include "lltexturectrl.h"
#include "llscrolllistctrl.h"
+#include "llslurl.h"
#include "lldispatcher.h"
#include "llviewerobject.h"
#include "llviewerregion.h"
@@ -122,7 +124,9 @@ void LLFloaterReporter::processRegionInfo(LLMessageSystem* msg)
// virtual
BOOL LLFloaterReporter::postBuild()
{
- getChild("abuse_location_edit")->setValue(gAgent.getSLURL());
+ LLSLURL slurl;
+ LLAgentUI::buildSLURL(slurl);
+ getChild("abuse_location_edit")->setValue(slurl.getSLURLString());
enableControls(TRUE);
diff --git a/indra/newview/llfloaterteleporthistory.cpp b/indra/newview/llfloaterteleporthistory.cpp
index bdb089e3c..a4ffe91fa 100644
--- a/indra/newview/llfloaterteleporthistory.cpp
+++ b/indra/newview/llfloaterteleporthistory.cpp
@@ -44,15 +44,17 @@
#include "llappviewer.h"
#include "llfloaterteleporthistory.h"
#include "llfloaterworldmap.h"
+#include "llslurl.h"
#include "lltimer.h"
#include "lluictrlfactory.h"
#include "llurldispatcher.h"
-#include "llurlsimstring.h"
#include "llviewercontrol.h"
#include "llviewerwindow.h"
#include "llwindow.h"
#include "llweb.h"
#include "llsdserialize.h"
+#include "llurlaction.h"
+
// [RLVa:KB]
#include "rlvhandler.h"
// [/RLVa:KB]
@@ -137,12 +139,12 @@ void LLFloaterTeleportHistory::addPendingEntry(std::string regionName, S16 x, S1
// Set pending position
mPendingPosition = llformat("%d, %d, %d", x, y, z);
+ LLSLURL slurl(regionName, LLVector3(x, y, z));
// prepare simstring for later parsing
- mPendingSimString = regionName + llformat("/%d/%d/%d", x, y, z);
- mPendingSimString = LLWeb::escapeURL(mPendingSimString);
+ mPendingSimString = LLWeb::escapeURL(slurl.getLocationString());
// Prepare the SLURL
- mPendingSLURL = LLURLDispatcher::buildSLURL(regionName, x, y, z);
+ mPendingSLURL = slurl.getSLURLString();
}
void LLFloaterTeleportHistory::addEntry(std::string parcelName)
@@ -332,9 +334,8 @@ void LLFloaterTeleportHistory::onTeleport(void* data)
LLFloaterTeleportHistory* self = (LLFloaterTeleportHistory*) data;
// build secondlife::/app link from simstring for instant teleport to destination
- std::string slapp = "secondlife:///app/teleport/" + self->mPlacesList->getFirstSelected()->getColumn(LIST_SIMSTRING)->getValue().asString();
- LLMediaCtrl* web = NULL;
- LLURLDispatcher::dispatch(slapp, web, TRUE);
+ std::string slapp = "secondlife:///app/teleport/" + self->mPlacesList->getFirstSelected()->getColumn(LIST_SLURL)->getValue().asString();
+ LLUrlAction::teleportToLocation(slapp);
}
// static
@@ -344,15 +345,11 @@ void LLFloaterTeleportHistory::onShowOnMap(void* data)
// get simstring from selected entry and parse it for its components
std::string simString = self->mPlacesList->getFirstSelected()->getColumn(LIST_SIMSTRING)->getValue().asString();
- std::string region = "";
- S32 x = 128;
- S32 y = 128;
- S32 z = 20;
- LLURLSimString::parse(simString, ®ion, &x, &y, &z);
+ LLSLURL slurl(simString);
// point world map at position
- gFloaterWorldMap->trackURL(region, x, y, z);
+ gFloaterWorldMap->trackURL(slurl.getRegion(), slurl.getPosition().mV[VX], slurl.getPosition().mV[VY], slurl.getPosition().mV[VZ]);
LLFloaterWorldMap::show(true);
}
diff --git a/indra/newview/llfloaterurlentry.cpp b/indra/newview/llfloaterurlentry.cpp
index dd6ea2864..65171b007 100644
--- a/indra/newview/llfloaterurlentry.cpp
+++ b/indra/newview/llfloaterurlentry.cpp
@@ -32,12 +32,15 @@
#include "llviewerprecompiledheaders.h"
+#include "llhttpclient.h"
+
#include "llfloaterurlentry.h"
#include "llpanellandmedia.h"
+#include "llpanelface.h"
-// project includes
#include "llcombobox.h"
+#include "llmimetypes.h"
#include "llnotificationsutil.h"
#include "llurlhistory.h"
#include "lluictrlfactory.h"
@@ -83,7 +86,7 @@ public:
{
// Set empty type to none/none. Empty string is reserved for legacy parcels
// which have no mime type set.
- std::string resolved_mime_type = ! mime_type.empty() ? mime_type : "none/none";
+ std::string resolved_mime_type = ! mime_type.empty() ? mime_type : LLMIMETypes::getDefaultMimeType();
LLFloaterURLEntry* floater_url_entry = (LLFloaterURLEntry*)mParent.get();
if ( floater_url_entry )
floater_url_entry->headerFetchComplete( status, resolved_mime_type );
@@ -165,6 +168,16 @@ void LLFloaterURLEntry::headerFetchComplete(U32 status, const std::string& mime_
panel_media->setMediaType(mime_type);
panel_media->setMediaURL(mMediaURLEdit->getValue().asString());
}
+ else
+ {
+ LLPanelFace* panel_face = dynamic_cast(mPanelLandMediaHandle.get());
+ if(panel_face)
+ {
+ panel_face->setMediaType(mime_type);
+ panel_face->setMediaURL(mMediaURLEdit->getValue().asString());
+ }
+
+ }
// Decrement the cursor
getWindow()->decBusyCount();
getChildView("loading_label")->setVisible( false);
@@ -172,26 +185,18 @@ void LLFloaterURLEntry::headerFetchComplete(U32 status, const std::string& mime_
}
// static
-LLHandle LLFloaterURLEntry::show(LLHandle parent)
+LLHandle LLFloaterURLEntry::show(LLHandle parent, const std::string media_url)
{
if (!sInstance)
{
sInstance = new LLFloaterURLEntry(parent);
}
sInstance->open();
- sInstance->updateFromLandMediaPanel();
+ sInstance->addURLToCombobox(media_url);
return sInstance->getHandle();
}
-void LLFloaterURLEntry::updateFromLandMediaPanel()
-{
- LLPanelLandMedia* panel_media = (LLPanelLandMedia*)mPanelLandMediaHandle.get();
- if (panel_media)
- {
- std::string media_url = panel_media->getMediaURL();
- addURLToCombobox(media_url);
- }
-}
+
bool LLFloaterURLEntry::addURLToCombobox(const std::string& media_url)
{
diff --git a/indra/newview/llfloaterurlentry.h b/indra/newview/llfloaterurlentry.h
index 0aeca823b..6dd9c8453 100644
--- a/indra/newview/llfloaterurlentry.h
+++ b/indra/newview/llfloaterurlentry.h
@@ -44,10 +44,8 @@ class LLFloaterURLEntry : public LLFloater
public:
// Can only be shown by LLPanelLandMedia, and pushes data back into
// that panel via the handle.
- static LLHandle show(LLHandle panel_land_media_handle);
+ static LLHandle show(LLHandle panel_land_media_handle, const std::string media_url);
/*virtual*/ BOOL postBuild();
- void updateFromLandMediaPanel();
-
void headerFetchComplete(U32 status, const std::string& mime_type);
bool addURLToCombobox(const std::string& media_url);
diff --git a/indra/newview/llfloaterwebcontent.cpp b/indra/newview/llfloaterwebcontent.cpp
new file mode 100644
index 000000000..c47a893ff
--- /dev/null
+++ b/indra/newview/llfloaterwebcontent.cpp
@@ -0,0 +1,517 @@
+/**
+ * @file llfloaterwebcontent.cpp
+ * @brief floater for displaying web content - e.g. profiles and search (eventually)
+ *
+ * $LicenseInfo:firstyear=2006&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llcombobox.h"
+#include "lliconctrl.h"
+#include "lllayoutstack.h"
+#include "llpluginclassmedia.h"
+#include "llprogressbar.h"
+#include "lltextbox.h"
+#include "llurlhistory.h"
+#include "llviewercontrol.h"
+#include "llweb.h"
+#include "llwindow.h"
+#include "lluictrlfactory.h"
+
+#include "llfloaterwebcontent.h"
+
+LLFloaterWebContent::_Params::_Params()
+: url("url"),
+ target("target"),
+ id("id"),
+ window_class("window_class", "web_content"),
+ show_chrome("show_chrome", true),
+ allow_address_entry("allow_address_entry", true),
+ preferred_media_size("preferred_media_size"),
+ trusted_content("trusted_content", false),
+ show_page_title("show_page_title", true)
+{}
+
+LLFloaterWebContent::LLFloaterWebContent( const Params& params )
+: LLFloater( params.id ),
+ LLInstanceTracker(params.id()),
+ mWebBrowser(NULL),
+ mAddressCombo(NULL),
+ mSecureLockIcon(NULL),
+ mStatusBarText(NULL),
+ mStatusBarProgress(NULL),
+ mBtnBack(NULL),
+ mBtnForward(NULL),
+ mBtnReload(NULL),
+ mBtnStop(NULL),
+ mUUID(params.id()),
+ mShowPageTitle(params.show_page_title),
+ mKey(params)
+{
+ mCommitCallbackRegistrar.add( "WebContent.Back", boost::bind( &LLFloaterWebContent::onClickBack, this ));
+ mCommitCallbackRegistrar.add( "WebContent.Forward", boost::bind( &LLFloaterWebContent::onClickForward, this ));
+ mCommitCallbackRegistrar.add( "WebContent.Reload", boost::bind( &LLFloaterWebContent::onClickReload, this ));
+ mCommitCallbackRegistrar.add( "WebContent.Stop", boost::bind( &LLFloaterWebContent::onClickStop, this ));
+ mCommitCallbackRegistrar.add( "WebContent.EnterAddress", boost::bind( &LLFloaterWebContent::onEnterAddress, this ));
+ mCommitCallbackRegistrar.add( "WebContent.PopExternal", boost::bind( &LLFloaterWebContent::onPopExternal, this ));
+ LLUICtrlFactory::getInstance()->buildFloater(this, "floater_web_content.xml");
+ mAgeTimer.reset();
+}
+
+BOOL LLFloaterWebContent::postBuild()
+{
+ // these are used in a bunch of places so cache them
+ mWebBrowser = getChild< LLMediaCtrl >( "webbrowser" );
+ mAddressCombo = getChild< LLComboBox >( "address" );
+ mStatusBarText = getChild< LLTextBox >( "statusbartext" );
+ mStatusBarProgress = getChild("statusbarprogress" );
+
+ mBtnBack = getChildView( "back" );
+ mBtnForward = getChildView( "forward" );
+ mBtnReload = getChildView( "reload" );
+ mBtnStop = getChildView( "stop" );
+
+ // observe browser events
+ mWebBrowser->addObserver( this );
+
+ // these buttons are always enabled
+ mBtnReload->setEnabled( true );
+ getChildView("popexternal")->setEnabled( true );
+
+ // cache image for secure browsing
+ mSecureLockIcon = getChild< LLIconCtrl >("media_secure_lock_flag");
+
+ // initialize the URL history using the system URL History manager
+ initializeURLHistory();
+
+ return TRUE;
+}
+
+void LLFloaterWebContent::initializeURLHistory()
+{
+ // start with an empty list
+ LLCtrlListInterface* url_list = childGetListInterface("address");
+ if (url_list)
+ {
+ url_list->operateOnAll(LLCtrlListInterface::OP_DELETE);
+ }
+
+ // Get all of the entries in the "browser" collection
+ LLSD browser_history = LLURLHistory::getURLHistory("browser");
+ LLSD::array_iterator iter_history = browser_history.beginArray();
+ LLSD::array_iterator end_history = browser_history.endArray();
+ for(; iter_history != end_history; ++iter_history)
+ {
+ std::string url = (*iter_history).asString();
+ if(! url.empty())
+ url_list->addSimpleElement(url);
+ }
+}
+
+bool LLFloaterWebContent::matchesKey(const LLSD& key)
+{
+ Params p(mKey);
+ Params other_p(key);
+ if (!other_p.target().empty() && other_p.target() != "_blank")
+ {
+ return other_p.target() == p.target();
+ }
+ else
+ {
+ return other_p.id() == p.id();
+ }
+}
+
+//static
+void LLFloaterWebContent::showInstance(const std::string& window_class, Params& p)
+{
+ p.window_class(window_class);
+
+ LLSD key = p;
+
+ instance_iter it = beginInstances();
+ for(;it!=endInstances();++it)
+ {
+ if(it->mKey["window_class"].asString() == window_class)
+ {
+ if(it->matchesKey(key))
+ {
+ it->mKey = key;
+ it->setKey(p.id());
+ it->mAgeTimer.reset();
+ it->open();
+ return;
+ }
+ }
+ }
+ LLFloaterWebContent* old_inst = getInstance(p.id());
+ if(old_inst)
+ {
+ llwarns << "Replacing unexpected duplicate floater: " << p.id() << llendl;
+ old_inst->mKey = key;
+ old_inst->mAgeTimer.reset();
+ old_inst->open();
+ }
+ assert(!old_inst);
+
+ if(!old_inst)
+ LLFloaterWebContent::create(p);
+}
+
+//static
+LLFloater* LLFloaterWebContent::create( Params p)
+{
+ preCreate(p);
+ return new LLFloaterWebContent(p);
+}
+
+//static
+void LLFloaterWebContent::closeRequest(const std::string &uuid)
+{
+ LLFloaterWebContent* floaterp = instance_tracker_t::getInstance(uuid);
+ if (floaterp)
+ {
+ floaterp->close();
+ }
+}
+
+//static
+void LLFloaterWebContent::geometryChanged(const std::string &uuid, S32 x, S32 y, S32 width, S32 height)
+{
+ LLFloaterWebContent* floaterp = instance_tracker_t::getInstance(uuid);
+ if (floaterp)
+ {
+ floaterp->geometryChanged(x, y, width, height);
+ }
+}
+
+void LLFloaterWebContent::geometryChanged(S32 x, S32 y, S32 width, S32 height)
+{
+ // Make sure the layout of the browser control is updated, so this calculation is correct.
+ getChild("stack1")->updateLayout();
+
+ // TODO: need to adjust size and constrain position to make sure floaters aren't moved outside the window view, etc.
+ LLCoordWindow window_size;
+ getWindow()->getSize(&window_size);
+
+ // Adjust width and height for the size of the chrome on the web Browser window.
+ LLRect browser_rect;
+ mWebBrowser->localRectToOtherView(mWebBrowser->getLocalRect(), &browser_rect, this);
+
+ S32 requested_browser_bottom = window_size.mY - (y + height);
+ LLRect geom;
+ geom.setOriginAndSize(x - browser_rect.mLeft,
+ requested_browser_bottom - browser_rect.mBottom,
+ width + getRect().getWidth() - browser_rect.getWidth(),
+ height + getRect().getHeight() - browser_rect.getHeight());
+
+ lldebugs << "geometry change: " << geom << llendl;
+
+ LLRect new_rect;
+ getParent()->screenRectToLocal(geom, &new_rect);
+ setShape(new_rect);
+}
+
+// static
+void LLFloaterWebContent::preCreate(LLFloaterWebContent::Params& p)
+{
+ lldebugs << "url = " << p.url() << ", target = " << p.target() << ", uuid = " << p.id() << llendl;
+
+ if (!p.id.isProvided())
+ {
+ p.id = LLUUID::generateNewID().asString();
+ }
+
+ if(p.target().empty() || p.target() == "_blank")
+ {
+ p.target = p.id();
+ }
+
+ S32 browser_window_limit = gSavedSettings.getS32("WebContentWindowLimit");
+ if(browser_window_limit != 0)
+ {
+ // showInstance will open a new window. Figure out how many web browsers are already open,
+ // and close the least recently opened one if this will put us over the limit.
+
+ std::vector instances;
+ instances.reserve(instanceCount());
+ instance_iter it = beginInstances();
+ for(;it!=endInstances();++it)
+ {
+ if(it->mKey["window_class"].asString() == p.window_class.getValue())
+ instances.push_back(&*it);
+ }
+
+ std::sort(instances.begin(), instances.end(), CompareAgeDescending());
+
+ //LLFloaterReg::const_instance_list_t &instances = LLFloaterReg::getFloaterList(p.window_class);
+ lldebugs << "total instance count is " << instances.size() << llendl;
+
+ for(std::vector::const_iterator iter = instances.begin(); iter != instances.end(); iter++)
+ {
+ lldebugs << " " << (*iter)->mKey["target"] << llendl;
+ }
+
+ if(instances.size() >= (size_t)browser_window_limit)
+ {
+ // Destroy the least recently opened instance
+ (*instances.begin())->close();
+ }
+ }
+}
+
+void LLFloaterWebContent::open_media(const Params& p)
+{
+ // Specifying a mime type of text/html here causes the plugin system to skip the MIME type probe and just open a browser plugin.
+ LLViewerMedia::proxyWindowOpened(p.target(), p.id());
+ mWebBrowser->setHomePageUrl(p.url, "text/html");
+ mWebBrowser->setTarget(p.target);
+ mWebBrowser->navigateTo(p.url, "text/html");
+
+ set_current_url(p.url);
+
+ getChild("status_bar")->setVisible(p.show_chrome);
+ getChild("nav_controls")->setVisible(p.show_chrome);
+ bool address_entry_enabled = p.allow_address_entry && !p.trusted_content;
+ getChildView("address")->setEnabled(address_entry_enabled);
+ getChildView("popexternal")->setEnabled(address_entry_enabled);
+
+ if (!address_entry_enabled)
+ {
+ mWebBrowser->setFocus(TRUE);
+ }
+
+ if (!p.show_chrome)
+ {
+ setResizeLimits(100, 100);
+ }
+
+ if (!p.preferred_media_size().isEmpty())
+ {
+ getChild("stack1")->updateLayout();
+ LLRect browser_rect = mWebBrowser->calcScreenRect();
+ LLCoordWindow window_size;
+ getWindow()->getSize(&window_size);
+
+ geometryChanged(browser_rect.mLeft, window_size.mY - browser_rect.mTop, p.preferred_media_size().getWidth(), p.preferred_media_size().getHeight());
+ }
+
+}
+
+void LLFloaterWebContent::onOpen()
+{
+ Params params(mKey);
+
+ if (!params.validateBlock())
+ {
+ close();
+ return;
+ }
+
+ mWebBrowser->setTrustedContent(params.trusted_content);
+
+ // tell the browser instance to load the specified URL
+ open_media(params);
+}
+
+//virtual
+void LLFloaterWebContent::onClose(bool app_quitting)
+{
+ LLViewerMedia::proxyWindowClosed(mUUID);
+ destroy();
+}
+
+// virtual
+void LLFloaterWebContent::draw()
+{
+ // this is asynchronous so we need to keep checking
+ mBtnBack->setEnabled( mWebBrowser->canNavigateBack() );
+ mBtnForward->setEnabled( mWebBrowser->canNavigateForward() );
+
+ LLFloater::draw();
+}
+
+// virtual
+void LLFloaterWebContent::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
+{
+ if(event == MEDIA_EVENT_LOCATION_CHANGED)
+ {
+ const std::string url = self->getLocation();
+
+ if ( url.length() )
+ mStatusBarText->setText( url );
+
+ set_current_url( url );
+ }
+ else if(event == MEDIA_EVENT_NAVIGATE_BEGIN)
+ {
+ // flags are sent with this event
+ mBtnBack->setEnabled( self->getHistoryBackAvailable() );
+ mBtnForward->setEnabled( self->getHistoryForwardAvailable() );
+
+ // toggle visibility of these buttons based on browser state
+ mBtnReload->setVisible( false );
+ mBtnStop->setVisible( true );
+
+ // turn "on" progress bar now we're about to start loading
+ mStatusBarProgress->setVisible( true );
+ }
+ else if(event == MEDIA_EVENT_NAVIGATE_COMPLETE)
+ {
+ // flags are sent with this event
+ mBtnBack->setEnabled( self->getHistoryBackAvailable() );
+ mBtnForward->setEnabled( self->getHistoryForwardAvailable() );
+
+ // toggle visibility of these buttons based on browser state
+ mBtnReload->setVisible( true );
+ mBtnStop->setVisible( false );
+
+ // turn "off" progress bar now we're loaded
+ mStatusBarProgress->setVisible( false );
+
+ // we populate the status bar with URLs as they change so clear it now we're done
+ const std::string end_str = "";
+ mStatusBarText->setText( end_str );
+
+ // decide if secure browsing icon should be displayed
+ std::string prefix = std::string("https://");
+ std::string test_prefix = mCurrentURL.substr(0, prefix.length());
+ LLStringUtil::toLower(test_prefix);
+ if(test_prefix == prefix)
+ {
+ mSecureLockIcon->setVisible(true);
+ }
+ else
+ {
+ mSecureLockIcon->setVisible(false);
+ }
+ }
+ else if(event == MEDIA_EVENT_CLOSE_REQUEST)
+ {
+ // The browser instance wants its window closed.
+ close();
+ }
+ else if(event == MEDIA_EVENT_GEOMETRY_CHANGE)
+ {
+ geometryChanged(self->getGeometryX(), self->getGeometryY(), self->getGeometryWidth(), self->getGeometryHeight());
+ }
+ else if(event == MEDIA_EVENT_STATUS_TEXT_CHANGED )
+ {
+ const std::string text = self->getStatusText();
+ if ( text.length() )
+ mStatusBarText->setText( text );
+ }
+ else if(event == MEDIA_EVENT_PROGRESS_UPDATED )
+ {
+ int percent = (int)self->getProgressPercent();
+ mStatusBarProgress->setPercent( percent );
+ }
+ else if(event == MEDIA_EVENT_NAME_CHANGED )
+ {
+ std::string page_title = self->getMediaName();
+ // simulate browser behavior - title is empty, use the current URL
+ if (mShowPageTitle)
+ {
+ if ( page_title.length() > 0 )
+ setTitle( page_title );
+ else
+ setTitle( mCurrentURL );
+ }
+ }
+ else if(event == MEDIA_EVENT_LINK_HOVERED )
+ {
+ const std::string link = self->getHoverLink();
+ mStatusBarText->setText( link );
+ }
+}
+
+void LLFloaterWebContent::set_current_url(const std::string& url)
+{
+ mCurrentURL = url;
+
+ // serialize url history into the system URL History manager
+ LLURLHistory::removeURL("browser", mCurrentURL);
+ LLURLHistory::addURL("browser", mCurrentURL);
+
+ mAddressCombo->remove( mCurrentURL );
+ mAddressCombo->add( mCurrentURL );
+ mAddressCombo->selectByValue( mCurrentURL );
+}
+
+void LLFloaterWebContent::onClickForward()
+{
+ mWebBrowser->navigateForward();
+}
+
+void LLFloaterWebContent::onClickBack()
+{
+ mWebBrowser->navigateBack();
+}
+
+void LLFloaterWebContent::onClickReload()
+{
+
+ if( mWebBrowser->getMediaPlugin() )
+ {
+ bool ignore_cache = true;
+ mWebBrowser->getMediaPlugin()->browse_reload( ignore_cache );
+ }
+ else
+ {
+ mWebBrowser->navigateTo(mCurrentURL);
+ }
+}
+
+void LLFloaterWebContent::onClickStop()
+{
+ if( mWebBrowser->getMediaPlugin() )
+ mWebBrowser->getMediaPlugin()->browse_stop();
+
+ // still should happen when we catch the navigate complete event
+ // but sometimes (don't know why) that event isn't sent from Qt
+ // and we ghetto a point where the stop button stays active.
+ mBtnReload->setVisible( true );
+ mBtnStop->setVisible( false );
+}
+
+void LLFloaterWebContent::onEnterAddress()
+{
+ // make sure there is at least something there.
+ // (perhaps this test should be for minimum length of a URL)
+ std::string url = mAddressCombo->getValue().asString();
+ if ( url.length() > 0 )
+ {
+ mWebBrowser->navigateTo( url, "text/html");
+ };
+}
+
+void LLFloaterWebContent::onPopExternal()
+{
+ // make sure there is at least something there.
+ // (perhaps this test should be for minimum length of a URL)
+ std::string url = mAddressCombo->getValue().asString();
+ if ( url.length() > 0 )
+ {
+ LLWeb::loadURLExternal( url );
+ };
+}
diff --git a/indra/newview/llfloaterwebcontent.h b/indra/newview/llfloaterwebcontent.h
new file mode 100644
index 000000000..00d8c9532
--- /dev/null
+++ b/indra/newview/llfloaterwebcontent.h
@@ -0,0 +1,125 @@
+/**
+ * @file llfloaterwebcontent.h
+ * @brief floater for displaying web content - e.g. profiles and search (eventually)
+ *
+ * $LicenseInfo:firstyear=2006&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFLOATERWEBCONTENT_H
+#define LL_LLFLOATERWEBCONTENT_H
+
+#include "llfloater.h"
+#include "llmediactrl.h"
+#include "llsdparam.h"
+
+class LLMediaCtrl;
+class LLComboBox;
+class LLTextBox;
+class LLProgressBar;
+class LLIconCtrl;
+
+class LLFloaterWebContent :
+ public LLFloater,
+ public LLViewerMediaObserver,
+ public LLInstanceTracker
+{
+public:
+ typedef LLInstanceTracker instance_tracker_t;
+ LOG_CLASS(LLFloaterWebContent);
+
+ struct _Params : public LLInitParam::Block<_Params>
+ {
+ Optional url,
+ target,
+ window_class,
+ id;
+ Optional show_chrome,
+ allow_address_entry,
+ trusted_content,
+ show_page_title;
+ Optional preferred_media_size;
+
+ _Params();
+ };
+
+ typedef LLSDParamAdapter<_Params> Params;
+
+ LLFloaterWebContent(const Params& params);
+
+ void initializeURLHistory();
+
+ static LLFloater* create(Params);
+
+ static void showInstance(const std::string& window_class, Params& p);
+ static void closeRequest(const std::string &uuid);
+ static void geometryChanged(const std::string &uuid, S32 x, S32 y, S32 width, S32 height);
+ void geometryChanged(S32 x, S32 y, S32 width, S32 height);
+
+ /* virtual */ BOOL postBuild();
+ /* virtual */ void onOpen();
+ /* virtual */ bool matchesKey(const LLSD& key);
+ /* virtual */ void onClose(bool app_quitting);
+ /* virtual */ void draw();
+
+protected:
+ // inherited from LLViewerMediaObserver
+ /*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event);
+
+ void onClickBack();
+ void onClickForward();
+ void onClickReload();
+ void onClickStop();
+ void onEnterAddress();
+ void onPopExternal();
+
+ static void preCreate(Params& p);
+ void open_media(const Params& );
+ void set_current_url(const std::string& url);
+
+ LLMediaCtrl* mWebBrowser;
+ LLComboBox* mAddressCombo;
+ LLIconCtrl* mSecureLockIcon;
+ LLTextBox* mStatusBarText;
+ LLProgressBar* mStatusBarProgress;
+
+ LLView* mBtnBack;
+ LLView* mBtnForward;
+ LLView* mBtnReload;
+ LLView* mBtnStop;
+
+ std::string mCurrentURL;
+ std::string mUUID;
+ bool mShowPageTitle;
+
+ LLSD mKey;
+ LLTimer mAgeTimer;
+
+ struct CompareAgeDescending
+ {
+ bool operator()(const LLFloaterWebContent* const& lhs, const LLFloaterWebContent* const& rhs)
+ {
+ return lhs->mAgeTimer.getElapsedTimeF64() > lhs->mAgeTimer.getElapsedTimeF64();
+ }
+ };
+};
+
+#endif // LL_LLFLOATERWEBCONTENT_H
diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp
index e3532cfe8..0f6eb2cdf 100644
--- a/indra/newview/llfloaterworldmap.cpp
+++ b/indra/newview/llfloaterworldmap.cpp
@@ -75,6 +75,7 @@
#include "llmapimagetype.h"
#include "llweb.h"
#include "llwindow.h" // copyTextToClipboard()
+#include "llslurl.h"
// [RLVa:KB]
@@ -728,7 +729,7 @@ void LLFloaterWorldMap::updateLocation()
// Figure out where user is
// Set the current SLURL
- mSLURL = LLURLDispatcher::buildSLURL(agent_sim_name, x, y, z);
+ mSLURL = LLSLURL(agent_sim_name, LLVector3(x, y, z)).getSLURLString();
// [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a)
if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC))
@@ -774,7 +775,7 @@ void LLFloaterWorldMap::updateLocation()
S32 x = llround( (F32)fmod( (F32)coord_pos[VX], (F32)REGION_WIDTH_METERS ) );
S32 y = llround( (F32)fmod( (F32)coord_pos[VY], (F32)REGION_WIDTH_METERS ) );
S32 z = llround( (F32)coord_pos[VZ] );
- mSLURL = LLURLDispatcher::buildSLURL(sim_name, x, y, z);
+ mSLURL = LLSLURL(sim_name, LLVector3(x, y, z)).getSLURLString();
}
else
{ // Empty SLURL will disable the "Copy SLURL to clipboard" button
diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp
index 5efe05ccc..d5d9ecad4 100644
--- a/indra/newview/llgroupactions.cpp
+++ b/indra/newview/llgroupactions.cpp
@@ -42,7 +42,7 @@
#include "groupchatlistener.h"
#include "hippolimits.h" // for getMaxAgentGroups
// [RLVa:KB] - Checked: 2011-03-28 (RLVa-1.3.0f)
-//#include "llslurl.h"
+#include "llslurl.h"
#include "rlvhandler.h"
// [/RLVa:KB]
@@ -55,7 +55,7 @@ class LLGroupHandler : public LLCommandHandler
{
public:
// requires trusted browser to trigger
- LLGroupHandler() : LLCommandHandler("group", true/*UNTRUSTED_THROTTLE*/) { }
+ LLGroupHandler() : LLCommandHandler("group", UNTRUSTED_THROTTLE) { }
bool handle(const LLSD& tokens, const LLSD& query_map,
LLMediaCtrl* web)
{
@@ -402,7 +402,7 @@ LLUUID LLGroupActions::startIM(const LLUUID& group_id)
if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.canStartIM(group_id)) && (!gIMMgr->hasSession(group_id)) )
{
make_ui_sound("UISndInvalidOp");
- RlvUtil::notifyBlocked(RLV_STRING_BLOCKED_STARTIM, LLSD().with("RECIPIENT", group_id/*LLSLURL("group", group_id, "about").getSLURLString()*/));
+ RlvUtil::notifyBlocked(RLV_STRING_BLOCKED_STARTIM, LLSD().with("RECIPIENT", LLSLURL("group", group_id, "about").getSLURLString()));
return LLUUID::null;
}
// [/RLVa:KB]
diff --git a/indra/newview/llloginhandler.cpp b/indra/newview/llloginhandler.cpp
index 447087276..40f25011d 100644
--- a/indra/newview/llloginhandler.cpp
+++ b/indra/newview/llloginhandler.cpp
@@ -36,8 +36,8 @@
// viewer includes
#include "llpanellogin.h" // save_password_to_disk()
+#include "llslurl.h"
#include "llstartup.h" // getStartupState()
-#include "llurlsimstring.h"
#include "llviewercontrol.h" // gSavedSettings
#include "llviewernetwork.h" // EGridInfo
@@ -79,17 +79,15 @@ void LLLoginHandler::parse(const LLSD& queryMap)
if (startLocation == "specify")
{
- LLURLSimString::setString(queryMap["region"].asString());
+ LLStartUp::setStartSLURL(queryMap["region"].asString());
}
else if (startLocation == "home")
{
- gSavedSettings.setBOOL("LoginLastLocation", FALSE);
- LLURLSimString::setString(LLStringUtil::null);
+ LLStartUp::setStartSLURL(LLSLURL(LLSLURL::SIM_LOCATION_HOME));
}
else if (startLocation == "last")
{
- gSavedSettings.setBOOL("LoginLastLocation", TRUE);
- LLURLSimString::setString(LLStringUtil::null);
+ LLStartUp::setStartSLURL(LLSLURL(LLSLURL::SIM_LOCATION_LAST));
}
}
diff --git a/indra/newview/llloginhandler.h b/indra/newview/llloginhandler.h
index 0844b80c7..d36ceaf3c 100644
--- a/indra/newview/llloginhandler.h
+++ b/indra/newview/llloginhandler.h
@@ -39,7 +39,7 @@ class LLLoginHandler : public LLCommandHandler
{
public:
// allow from external browsers
- LLLoginHandler() : LLCommandHandler("login", false) { }
+ LLLoginHandler() : LLCommandHandler("login", UNTRUSTED_ALLOW) { }
/*virtual*/ bool handle(const LLSD& tokens, const LLSD& query_map, LLMediaCtrl* web);
// Fill in our internal fields from a SLURL like
diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp
index 17cf01b2f..af7c6d131 100644
--- a/indra/newview/llmediactrl.cpp
+++ b/indra/newview/llmediactrl.cpp
@@ -40,97 +40,123 @@
#include "llfloaterworldmap.h"
#include "lluictrlfactory.h"
#include "llurldispatcher.h"
-#include "llurlsimstring.h"
#include "llviewborder.h"
#include "llviewercontrol.h"
#include "llviewermedia.h"
+#include "llviewertexture.h"
#include "llviewerwindow.h"
-#include "llnotificationsutil.h"
#include "llweb.h"
#include "llrender.h"
#include "llpluginclassmedia.h"
+#include "llslurl.h"
+#include "lluictrlfactory.h" // LLRegisterWidget
+#include "llkeyboard.h"
+#include "llviewermenu.h"
// linden library includes
#include "llfocusmgr.h"
+#include "llsdutil.h"
+#include "lltextbox.h"
+#include "llbutton.h"
+#include "llcheckboxctrl.h"
+#include "llnotifications.h"
+#include "lllineeditor.h"
extern BOOL gRestoreGL;
-// Setting the mozilla buffer width to 2048 exactly doesn't work, since it pads its rowbytes a bit, pushing the texture width over 2048.
-// 2000 should give enough headroom for any amount of padding it cares to add.
-const S32 MAX_DIMENSION = 2000;
-const S32 MAX_TEXTURE_DIMENSION = 2048;
-
static LLRegisterWidget r("web_browser");
-LLMediaCtrl::LLMediaCtrl( const std::string& name, const LLRect& rect ) :
- LLUICtrl( name, rect, FALSE),
+LLMediaCtrl::Params::Params()
+: start_url("start_url"),
+ border_visible("border_visible", false),
+ decouple_texture_size("decouple_texture_size", false),
+ texture_width("texture_width", 1024),
+ texture_height("texture_height", 1024),
+ caret_color("caret_color"),
+ initial_mime_type("initial_mime_type"),
+ error_page_url("error_page_url"),
+ media_id("media_id"),
+ trusted_content("trusted_content", false),
+ focus_on_click("focus_on_click", true)
+{
+}
+
+LLMediaCtrl::LLMediaCtrl( const Params& p) :
+ LLPanel( p.name, p.rect, FALSE),
LLInstanceTracker(LLUUID::generateNewID()),
mTextureDepthBytes( 4 ),
- mWebBrowserImage( 0 ),
mBorder(NULL),
mFrequentUpdates( true ),
mForceUpdate( false ),
- mOpenLinksInExternalBrowser( false ),
- mOpenLinksInInternalBrowser( false ),
- mTrusted( false ),
mHomePageUrl( "" ),
- mIgnoreUIScale( true ),
mAlwaysRefresh( false ),
- mExternalUrl( "" ),
mMediaSource( 0 ),
- mTakeFocusOnClick( true ),
+ mTakeFocusOnClick( p.focus_on_click ),
mCurrentNavUrl( "about:blank" ),
- mLastSetCursor( UI_CURSOR_ARROW ),
mStretchToFill( true ),
mMaintainAspectRatio ( true ),
mDecoupleTextureSize ( false ),
mTextureWidth ( 1024 ),
mTextureHeight ( 1024 ),
- mHideLoading (false)
+ mClearCache(false),
+ mHomePageMimeType(p.initial_mime_type),
+ mErrorPageURL(p.error_page_url),
+ mTrusted(p.trusted_content),
+ mHoverTextChanged(false)
{
+ {
+ LLColor4 color = p.caret_color().get();
+ setCaretColor( (unsigned int)color.mV[0], (unsigned int)color.mV[1], (unsigned int)color.mV[2] );
+ }
+
+ setHomePageUrl(p.start_url, p.initial_mime_type);
+
+ setBorderVisible(p.border_visible);
+
+ setDecoupleTextureSize(p.decouple_texture_size);
+
+ setTextureSize(p.texture_width, p.texture_height);
+
if(!getDecoupleTextureSize())
{
- S32 screen_width = mIgnoreUIScale ?
- llround((F32)getRect().getWidth() * LLUI::getScaleFactor().mV[VX]) : getRect().getWidth();
- S32 screen_height = mIgnoreUIScale ?
- llround((F32)getRect().getHeight() * LLUI::getScaleFactor().mV[VY]) : getRect().getHeight();
-
+ S32 screen_width = llround((F32)getRect().getWidth() * LLUI::getScaleFactor().mV[VX]);
+ S32 screen_height = llround((F32)getRect().getHeight() * LLUI::getScaleFactor().mV[VY]);
+
setTextureSize(screen_width, screen_height);
}
+
+ mMediaTextureID = getKey();
+
// We don't need to create the media source up front anymore unless we have a non-empty home URL to navigate to.
- if(!mHomePageUrl.empty())
+ /*if(!mHomePageUrl.empty())
{
navigateHome();
- }
+ }*/
- LLRect border_rect( 0, getRect().getHeight() + 2, getRect().getWidth() + 2, 0 );
- mBorder = new LLViewBorder( std::string("web control border"), border_rect, LLViewBorder::BEVEL_IN );
- addChild( mBorder );
+ //LLRect border_rect( 0, getRect().getHeight() + 2, getRect().getWidth() + 2, 0 );
}
-////////////////////////////////////////////////////////////////////////////////
-// note: this is now a singleton and destruction happens via initClass() now
LLMediaCtrl::~LLMediaCtrl()
{
-
if (mMediaSource)
{
mMediaSource->remObserver( this );
mMediaSource = NULL;
}
-
- mWebBrowserImage = NULL;
}
////////////////////////////////////////////////////////////////////////////////
//
void LLMediaCtrl::setBorderVisible( BOOL border_visible )
{
- if ( mBorder )
+ if(border_visible && !mBorder)
{
- mBorder->setVisible( border_visible );
- };
+ mBorder = new LLViewBorder( std::string("web control border"), getLocalRect(), LLViewBorder::BEVEL_IN );
+ addChild( mBorder );
+ }
+ if(mBorder)
+ mBorder->setVisible(border_visible);
};
////////////////////////////////////////////////////////////////////////////////
@@ -140,39 +166,24 @@ void LLMediaCtrl::setTakeFocusOnClick( bool take_focus )
mTakeFocusOnClick = take_focus;
}
-
-////////////////////////////////////////////////////////////////////////////////
-// set flag that forces the embedded browser to open links in the external system browser
-void LLMediaCtrl::setOpenInExternalBrowser( bool valIn )
-{
- mOpenLinksInExternalBrowser = valIn;
-};
-
-////////////////////////////////////////////////////////////////////////////////
-// set flag that forces the embedded browser to open links in the internal browser floater
-void LLMediaCtrl::setOpenInInternalBrowser( bool valIn )
-{
- mOpenLinksInInternalBrowser = valIn;
-};
-
-////////////////////////////////////////////////////////////////////////////////
-void LLMediaCtrl::setTrusted( bool valIn )
-{
- mTrusted = valIn;
-}
-
////////////////////////////////////////////////////////////////////////////////
//
BOOL LLMediaCtrl::handleHover( S32 x, S32 y, MASK mask )
{
- if (LLUICtrl::handleHover(x, y, mask)) return TRUE;
+ if (LLPanel::handleHover(x, y, mask)) return TRUE;
convertInputCoords(x, y);
if (mMediaSource)
{
mMediaSource->mouseMove(x, y, mask);
-
- gViewerWindow->setCursor(mLastSetCursor);
+ gViewerWindow->setCursor(mMediaSource->getLastSetCursor());
+ }
+
+ // TODO: Is this the right way to handle hover text changes driven by the plugin?
+ if(mHoverTextChanged)
+ {
+ mHoverTextChanged = false;
+ //handleToolTip(x, y, mask);
}
return TRUE;
@@ -182,9 +193,36 @@ BOOL LLMediaCtrl::handleHover( S32 x, S32 y, MASK mask )
//
BOOL LLMediaCtrl::handleScrollWheel( S32 x, S32 y, S32 clicks )
{
- if (LLUICtrl::handleScrollWheel(x, y, clicks)) return TRUE;
+ if (LLPanel::handleScrollWheel(x, y, clicks)) return TRUE;
if (mMediaSource && mMediaSource->hasMedia())
- mMediaSource->getMediaPlugin()->scrollEvent(0, clicks, MASK_NONE);
+ mMediaSource->getMediaPlugin()->scrollEvent(0, clicks, gKeyboard->currentMask(TRUE));
+
+ return TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// virtual
+BOOL LLMediaCtrl::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen)
+{
+ std::string hover_text;
+
+ if (mMediaSource && mMediaSource->hasMedia())
+ hover_text = mMediaSource->getMediaPlugin()->getHoverText();
+
+ if(hover_text.empty())
+ {
+ return FALSE;
+ }
+ else
+ {
+ msg = hover_text;
+
+ S32 screen_x, screen_y;
+
+ localPointToScreen(x, y, &screen_x, &screen_y);
+ LLRect sticky_rect_screen;
+ sticky_rect_screen.setCenterAndSize(screen_x, screen_y, 20, 20);
+ }
return TRUE;
}
@@ -193,20 +231,12 @@ BOOL LLMediaCtrl::handleScrollWheel( S32 x, S32 y, S32 clicks )
//
BOOL LLMediaCtrl::handleMouseUp( S32 x, S32 y, MASK mask )
{
- if (LLUICtrl::handleMouseUp(x, y, mask)) return TRUE;
+ if (LLPanel::handleMouseUp(x, y, mask)) return TRUE;
convertInputCoords(x, y);
if (mMediaSource)
{
mMediaSource->mouseUp(x, y, mask);
-
- /*// *HACK: LLMediaImplLLMozLib automatically takes focus on mouseup,
- // in addition to the onFocusReceived() call below. Undo this. JC
- if (!mTakeFocusOnClick)
- {
- mMediaSource->focus(false);
- gViewerWindow->focusClient();
- }*/
}
gFocusMgr.setMouseCapture( NULL );
@@ -218,7 +248,7 @@ BOOL LLMediaCtrl::handleMouseUp( S32 x, S32 y, MASK mask )
//
BOOL LLMediaCtrl::handleMouseDown( S32 x, S32 y, MASK mask )
{
- if (LLUICtrl::handleMouseDown(x, y, mask)) return TRUE;
+ if (LLPanel::handleMouseDown(x, y, mask)) return TRUE;
convertInputCoords(x, y);
if (mMediaSource)
@@ -238,7 +268,7 @@ BOOL LLMediaCtrl::handleMouseDown( S32 x, S32 y, MASK mask )
//
BOOL LLMediaCtrl::handleRightMouseUp( S32 x, S32 y, MASK mask )
{
- /*if (LLPanel::handleRightMouseUp(x, y, mask)) return TRUE;
+ if (LLPanel::handleRightMouseUp(x, y, mask)) return TRUE;
convertInputCoords(x, y);
if (mMediaSource)
@@ -255,7 +285,7 @@ BOOL LLMediaCtrl::handleRightMouseUp( S32 x, S32 y, MASK mask )
}
gFocusMgr.setMouseCapture( NULL );
- */
+
return TRUE;
}
@@ -263,7 +293,7 @@ BOOL LLMediaCtrl::handleRightMouseUp( S32 x, S32 y, MASK mask )
//
BOOL LLMediaCtrl::handleRightMouseDown( S32 x, S32 y, MASK mask )
{
- if (LLUICtrl::handleRightMouseDown(x, y, mask)) return TRUE;
+ if (LLPanel::handleRightMouseDown(x, y, mask)) return TRUE;
S32 media_x = x, media_y = y;
convertInputCoords(media_x, media_y);
@@ -285,7 +315,7 @@ BOOL LLMediaCtrl::handleRightMouseDown( S32 x, S32 y, MASK mask )
//
BOOL LLMediaCtrl::handleDoubleClick( S32 x, S32 y, MASK mask )
{
- if (LLUICtrl::handleDoubleClick(x, y, mask)) return TRUE;
+ if (LLPanel::handleDoubleClick(x, y, mask)) return TRUE;
convertInputCoords(x, y);
if (mMediaSource)
@@ -313,7 +343,7 @@ void LLMediaCtrl::onFocusReceived()
LLEditMenuHandler::gEditMenuHandler = mMediaSource;
}
- LLUICtrl::onFocusReceived();
+ LLPanel::onFocusReceived();
}
////////////////////////////////////////////////////////////////////////////////
@@ -333,15 +363,14 @@ void LLMediaCtrl::onFocusLost()
gViewerWindow->focusClient();
- LLUICtrl::onFocusLost();
+ LLPanel::onFocusLost();
}
////////////////////////////////////////////////////////////////////////////////
//
-
BOOL LLMediaCtrl::postBuild ()
{
- //setVisibleCallback(boost::bind(&LLMediaCtrl::onVisibilityChange, this, _2));
+ setVisibleCallback(boost::bind(&LLMediaCtrl::onVisibilityChange, this, _2));
return true;
}
@@ -350,43 +379,20 @@ void LLMediaCtrl::onOpenWebInspector()
if (mMediaSource && mMediaSource->hasMedia())
mMediaSource->getMediaPlugin()->showWebInspector( true );
}
+
////////////////////////////////////////////////////////////////////////////////
//
BOOL LLMediaCtrl::handleKeyHere( KEY key, MASK mask )
{
BOOL result = FALSE;
- // FIXME: THIS IS SO WRONG.
- // Menu keys should be handled by the menu system and not passed to UI elements, but this is how LLTextEditor and LLLineEditor do it...
-
if (mMediaSource)
{
- if( MASK_CONTROL & mask )
- {
- if( 'C' == key )
- {
- mMediaSource->copy();
- result = TRUE;
- }
- else
- if( 'V' == key )
- {
- mMediaSource->paste();
- result = TRUE;
- }
- else
- if( 'X' == key )
- {
- mMediaSource->cut();
- result = TRUE;
- }
- }
-
- if(!result)
- {
- result = mMediaSource->handleKeyHere(key, mask);
- }
+ result = mMediaSource->handleKeyHere(key, mask);
}
+
+ if ( ! result )
+ result = LLPanel::handleKeyHere(key, mask);
return result;
}
@@ -400,14 +406,10 @@ void LLMediaCtrl::handleVisibilityChange ( BOOL new_visibility )
{
mMediaSource->setVisible( new_visibility );
}
- LLUICtrl::handleVisibilityChange( new_visibility );
- //Hack due to not being derived from LLPanel yet
- LLMediaCtrl::onVisibilityChange(LLSD(new_visibility));
}
////////////////////////////////////////////////////////////////////////////////
//
-
BOOL LLMediaCtrl::handleUnicodeCharHere(llwchar uni_char)
{
BOOL result = FALSE;
@@ -420,6 +422,9 @@ BOOL LLMediaCtrl::handleUnicodeCharHere(llwchar uni_char)
result = mMediaSource->handleUnicodeCharHere(uni_char);
}
+ if ( ! result )
+ result = LLPanel::handleUnicodeCharHere(uni_char);
+
return result;
}
@@ -444,8 +449,8 @@ void LLMediaCtrl::reshape( S32 width, S32 height, BOOL called_from_parent )
{
if(!getDecoupleTextureSize())
{
- S32 screen_width = mIgnoreUIScale ? llround((F32)width * LLUI::getScaleFactor().mV[VX]) : width;
- S32 screen_height = mIgnoreUIScale ? llround((F32)height * LLUI::getScaleFactor().mV[VY]) : height;
+ S32 screen_width = llround((F32)width * LLUI::getScaleFactor().mV[VX]);
+ S32 screen_height = llround((F32)height * LLUI::getScaleFactor().mV[VY]);
// when floater is minimized, these sizes are negative
if ( screen_height > 0 && screen_width > 0 )
@@ -497,6 +502,21 @@ bool LLMediaCtrl::canNavigateForward()
return false;
}
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaCtrl::clearCache()
+{
+ if(mMediaSource)
+ {
+ mMediaSource->clearCache();
+ }
+ else
+ {
+ mClearCache = true;
+ }
+
+}
+
////////////////////////////////////////////////////////////////////////////////
//
void LLMediaCtrl::set404RedirectUrl( std::string redirect_url )
@@ -541,31 +561,18 @@ void LLMediaCtrl::navigateTo( std::string url_in, std::string mime_type)
void LLMediaCtrl::navigateToLocalPage( const std::string& subdir, const std::string& filename_in )
{
std::string language = LLUI::getLanguage();
- std::string delim = gDirUtilp->getDirDelimiter();
- std::string filename;
-
- filename += subdir;
- filename += delim;
- filename += filename_in;
+ std::string filename(gDirUtilp->add(subdir, filename_in));
std::string expanded_filename = gDirUtilp->findSkinnedFilename("html", language, filename);
- if (! gDirUtilp->fileExists(expanded_filename))
+ if (expanded_filename.empty() && language != "en-us")
{
- if (language != "en-us")
- {
- expanded_filename = gDirUtilp->findSkinnedFilename("html", "en-us", filename);
- if (! gDirUtilp->fileExists(expanded_filename))
- {
- llwarns << "File " << subdir << delim << filename_in << "not found" << llendl;
- return;
- }
- }
- else
- {
- llwarns << "File " << subdir << delim << filename_in << "not found" << llendl;
- return;
- }
+ expanded_filename = gDirUtilp->findSkinnedFilename("html", "en-us", filename);
+ }
+ if(expanded_filename.empty())
+ {
+ llwarns << "File " << filename << "not found" << llendl;
+ return;
}
if (ensureMediaSourceExists())
{
@@ -589,15 +596,34 @@ void LLMediaCtrl::navigateHome()
////////////////////////////////////////////////////////////////////////////////
//
-void LLMediaCtrl::setHomePageUrl( const std::string urlIn )
+void LLMediaCtrl::setHomePageUrl( const std::string& urlIn, const std::string& mime_type )
{
mHomePageUrl = urlIn;
if (mMediaSource)
{
- mMediaSource->setHomeURL(mHomePageUrl);
+ mMediaSource->setHomeURL(mHomePageUrl, mime_type);
}
}
+void LLMediaCtrl::setTarget(const std::string& target)
+{
+ mTarget = target;
+ if (mMediaSource)
+ {
+ mMediaSource->setTarget(mTarget);
+ }
+}
+
+void LLMediaCtrl::setErrorPageURL(const std::string& url)
+{
+ mErrorPageURL = url;
+}
+
+const std::string& LLMediaCtrl::getErrorPageURL()
+{
+ return mErrorPageURL;
+}
+
////////////////////////////////////////////////////////////////////////////////
//
bool LLMediaCtrl::setCaretColor(unsigned int red, unsigned int green, unsigned int blue)
@@ -616,7 +642,6 @@ void LLMediaCtrl::setTextureSize(S32 width, S32 height)
if(mMediaSource)
{
mMediaSource->setSize(mTextureWidth, mTextureHeight);
- mWebBrowserImage->resize( mTextureWidth, mTextureHeight );
mForceUpdate = true;
}
}
@@ -634,14 +659,24 @@ bool LLMediaCtrl::ensureMediaSourceExists()
{
if(mMediaSource.isNull())
{
- mMediaSource = LLViewerMedia::newMediaImpl(mHomePageUrl, LLUUID::null, mTextureWidth, mTextureWidth, false, false, "text/html");
+ // If we don't already have a media source, try to create one.
+ mMediaSource = LLViewerMedia::newMediaImpl(mMediaTextureID, mTextureWidth, mTextureHeight);
if ( mMediaSource )
{
- // create a new texture (based on LLDynamic texture) that will be used to display the output
- mWebBrowserImage = new LLWebBrowserTexture( mTextureWidth, mTextureWidth, this, mMediaSource );
- mMediaSource->setHomeURL(mHomePageUrl);
+ mMediaSource->setUsedInUI(true);
+ mMediaSource->setHomeURL(mHomePageUrl, mHomePageMimeType);
+ mMediaSource->setTarget(mTarget);
mMediaSource->setVisible( getVisible() );
mMediaSource->addObserver( this );
+ mMediaSource->setBackgroundColor( getBackgroundColor() );
+ mMediaSource->setTrustedBrowser(mTrusted);
+ mMediaSource->setPageZoomFactor( LLUI::getScaleFactor().mV[ VX ] );
+
+ if(mClearCache)
+ {
+ mMediaSource->clearCache();
+ mClearCache = false;
+ }
}
else
{
@@ -658,7 +693,6 @@ bool LLMediaCtrl::ensureMediaSourceExists()
void LLMediaCtrl::unloadMediaSource()
{
mMediaSource = NULL;
- mWebBrowserImage = NULL; //release the dynamic texture too.
}
////////////////////////////////////////////////////////////////////////////////
@@ -672,15 +706,12 @@ LLPluginClassMedia* LLMediaCtrl::getMediaPlugin()
//
void LLMediaCtrl::draw()
{
- if ( ! mWebBrowserImage || mWebBrowserImage->getNeedsUpdate())
- return;
-
if ( gRestoreGL == 1 )
{
LLRect r = getRect();
reshape( r.getWidth(), r.getHeight(), FALSE );
return;
- };
+ }
// NOTE: optimization needed here - probably only need to do this once
// unless tearoffs change the parent which they probably do.
@@ -701,7 +732,7 @@ void LLMediaCtrl::draw()
bool draw_media = false;
LLPluginClassMedia* media_plugin = NULL;
- LLWebBrowserTexture* media_texture = mWebBrowserImage;
+ LLViewerMediaTexture* media_texture = NULL;
if(mMediaSource && mMediaSource->hasMedia())
{
@@ -709,29 +740,22 @@ void LLMediaCtrl::draw()
if(media_plugin && (media_plugin->textureValid()))
{
- media_texture = mWebBrowserImage;
+ media_texture = LLViewerTextureManager::findMediaTexture(mMediaTextureID);
if(media_texture)
{
draw_media = true;
}
}
}
+
+ bool background_visible = isBackgroundVisible();
+ bool background_opaque = isBackgroundOpaque();
+
if(draw_media)
{
gGL.pushUIMatrix();
{
- /*if (mIgnoreUIScale)
- {
- gGL.pushUIMatrix();
- gGL.loadUIIdentity();
- gGL.pushMatrix();
- gGL.loadIdentity();
- // font system stores true screen origin, need to scale this by UI scale factor
- // to get render origin for this view (with unit scale)
- gGL.translatef(floorf(LLFontGL::sCurOrigin.mX * LLUI::getScaleFactor().mV[VX]),
- floorf(LLFontGL::sCurOrigin.mY * LLUI::getScaleFactor().mV[VY]),
- LLFontGL::sCurDepth);
- }*/
+ mMediaSource->setPageZoomFactor( LLUI::getScaleFactor().mV[ VX ] );
// scale texture to fit the space using texture coords
gGL.getTexUnit(0)->bind(media_texture);
@@ -822,20 +846,26 @@ void LLMediaCtrl::draw()
}
gGL.end();
gGL.setSceneBlendType(LLRender::BT_ALPHA);
- /*if (mIgnoreUIScale)
- {
- gGL.popUIMatrix();
- gGL.popMatrix();
- }*/
}
gGL.popUIMatrix();
+
}
+ else
+ {
+ // Setting these will make LLPanel::draw draw the opaque background color.
+ setBackgroundVisible(true);
+ setBackgroundOpaque(true);
+ }
+
// highlight if keyboard focus here. (TODO: this needs some work)
if ( mBorder && mBorder->getVisible() )
mBorder->setKeyboardFocusHighlight( gFocusMgr.childHasKeyboardFocus( this ) );
-
- LLUICtrl::draw();
+ LLPanel::draw();
+
+ // Restore the previous values
+ setBackgroundVisible(background_visible);
+ setBackgroundOpaque(background_opaque);
}
////////////////////////////////////////////////////////////////////////////////
@@ -849,31 +879,17 @@ void LLMediaCtrl::convertInputCoords(S32& x, S32& y)
coords_opengl = mMediaSource->getMediaPlugin()->getTextureCoordsOpenGL();
}
- x = mIgnoreUIScale ? llround((F32)x * LLUI::getScaleFactor().mV[VX]) : x;
+ x = llround((F32)x * LLUI::getScaleFactor().mV[VX]);
if ( ! coords_opengl )
{
- y = mIgnoreUIScale ? llround((F32)(y) * LLUI::getScaleFactor().mV[VY]) : y;
+ y = llround((F32)(y) * LLUI::getScaleFactor().mV[VY]);
}
else
{
- y = mIgnoreUIScale ? llround((F32)(getRect().getHeight() - y) * LLUI::getScaleFactor().mV[VY]) : getRect().getHeight() - y;
+ y = llround((F32)(getRect().getHeight() - y) * LLUI::getScaleFactor().mV[VY]);
};
}
-////////////////////////////////////////////////////////////////////////////////
-// static
-bool LLMediaCtrl::onClickLinkExternalTarget(const LLSD& notification, const LLSD& response )
-{
- S32 option = LLNotification::getSelectedOption(notification, response);
- if ( 0 == option )
- {
- // open in external browser because we don't support
- // creation of our own secondary browser windows
- LLWeb::loadURLExternal( notification["payload"]["external_url"].asString() );
- }
- return false;
-}
-
////////////////////////////////////////////////////////////////////////////////
// inherited from LLViewerMediaObserver
//virtual
@@ -903,28 +919,14 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
case MEDIA_EVENT_CURSOR_CHANGED:
{
- LL_INFOS("Media") << "Media event: MEDIA_EVENT_CURSOR_CHANGED, new cursor is " << self->getCursorName() << LL_ENDL;
-
- std::string cursor = self->getCursorName();
-
- if(cursor == "arrow")
- mLastSetCursor = UI_CURSOR_ARROW;
- else if(cursor == "ibeam")
- mLastSetCursor = UI_CURSOR_IBEAM;
- else if(cursor == "splith")
- mLastSetCursor = UI_CURSOR_SIZEWE;
- else if(cursor == "splitv")
- mLastSetCursor = UI_CURSOR_SIZENS;
- else if(cursor == "hand")
- mLastSetCursor = UI_CURSOR_HAND;
- else // for anything else, default to the arrow
- mLastSetCursor = UI_CURSOR_ARROW;
- };
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CURSOR_CHANGED, new cursor is " << self->getCursorName() << LL_ENDL;
+ }
break;
case MEDIA_EVENT_NAVIGATE_BEGIN:
{
LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_NAVIGATE_BEGIN, url is " << self->getNavigateURI() << LL_ENDL;
+ hideNotification();
};
break;
@@ -959,20 +961,39 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
case MEDIA_EVENT_NAVIGATE_ERROR_PAGE:
{
LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_NAVIGATE_ERROR_PAGE" << LL_ENDL;
+ if ( mErrorPageURL.length() > 0 )
+ {
+ navigateTo(mErrorPageURL, "text/html");
+ };
};
break;
case MEDIA_EVENT_CLICK_LINK_HREF:
{
LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLICK_LINK_HREF, target is \"" << self->getClickTarget() << "\", uri is " << self->getClickURL() << LL_ENDL;
- onClickLinkHref(self);
+ // retrieve the event parameters
+ std::string url = self->getClickURL();
+ std::string target = self->getClickTarget();
+ std::string uuid = self->getClickUUID();
+
+ LLNotification::Params notify_params("PopupAttempt");
+ notify_params.payload = LLSD().with("target", target).with("url", url).with("uuid", uuid).with("media_id", mMediaTextureID);
+ notify_params.functor(boost::bind(&LLMediaCtrl::onPopup, this, _1, _2));
+
+ if (mTrusted)
+ {
+ LLNotifications::instance().forceResponse(notify_params, 0);
+ }
+ else
+ {
+ LLNotifications::instance().add(notify_params);
+ }
+ break;
};
- break;
case MEDIA_EVENT_CLICK_LINK_NOFOLLOW:
{
LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLICK_LINK_NOFOLLOW, uri is " << self->getClickURL() << LL_ENDL;
- onClickLinkNoFollow(self);
};
break;
@@ -997,30 +1018,42 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
case MEDIA_EVENT_CLOSE_REQUEST:
{
LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLOSE_REQUEST" << LL_ENDL;
- };
+ }
break;
case MEDIA_EVENT_PICK_FILE_REQUEST:
{
LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_PICK_FILE_REQUEST" << LL_ENDL;
- };
+ }
break;
case MEDIA_EVENT_GEOMETRY_CHANGE:
{
- LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_GEOMETRY_CHANGE" << LL_ENDL;
- };
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_GEOMETRY_CHANGE, uuid is " << self->getClickUUID() << LL_ENDL;
+ }
break;
case MEDIA_EVENT_AUTH_REQUEST:
{
- LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_AUTH_REQUEST" << LL_ENDL;
+ LLNotification::Params auth_request_params("AuthRequest");
+
+ // pass in host name and realm for site (may be zero length but will always exist)
+ LLSD args;
+ LLURL raw_url( self->getAuthURL().c_str() );
+ args["HOST_NAME"] = raw_url.getAuthority();
+ args["REALM"] = self->getAuthRealm();
+ auth_request_params.substitutions = args;
+
+ auth_request_params.payload = LLSD().with("media_id", mMediaTextureID);
+ auth_request_params.functor(boost::bind(&LLViewerMedia::onAuthSubmit, _1, _2));
+ LLNotifications::instance().add(auth_request_params);
};
break;
-
+
case MEDIA_EVENT_LINK_HOVERED:
{
- LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_LINK_HOVERED" << LL_ENDL;
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_LINK_HOVERED, hover text is: " << self->getHoverText() << LL_ENDL;
+ mHoverTextChanged = true;
};
break;
@@ -1042,65 +1075,28 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
////////////////////////////////////////////////////////////////////////////////
//
-void LLMediaCtrl::onClickLinkHref( LLPluginClassMedia* self )
+std::string LLMediaCtrl::getCurrentNavUrl()
{
- // retrieve the event parameters
- std::string target = self->getClickTarget();
- std::string url = self->getClickURL();
-
- // if there is a value for the target
- if ( !target.empty() )
- {
- if ( target == "_external" )
- {
- mExternalUrl = url;
- LLSD payload;
- payload["external_url"] = mExternalUrl;
- LLNotifications::instance().add( "WebLaunchExternalTarget", LLSD(), payload, onClickLinkExternalTarget);
- return;
- }
- }
-
- const std::string protocol1( "http://" );
- const std::string protocol2( "https://" );
- if( mOpenLinksInExternalBrowser )
- {
- if ( !url.empty() )
- {
- if ( LLStringUtil::compareInsensitive( url.substr( 0, protocol1.length() ), protocol1 ) == 0 ||
- LLStringUtil::compareInsensitive( url.substr( 0, protocol2.length() ), protocol2 ) == 0 )
- {
- LLWeb::loadURLExternal( url );
- }
- }
- }
- else
- if( mOpenLinksInInternalBrowser )
- {
- if ( !url.empty() )
- {
- if ( LLStringUtil::compareInsensitive( url.substr( 0, protocol1.length() ), protocol1 ) == 0 ||
- LLStringUtil::compareInsensitive( url.substr( 0, protocol2.length() ), protocol2 ) == 0 )
- {
- // If we spawn a new LLFloaterHTML, assume we want it to
- // follow this LLMediaCtrl's trust for whether or
- // not to open secondlife:///app/ links. JC.
-// const bool open_links_externally = false;
-// LLFloaterHtml::getInstance()->show(
-// event_in.mStringPayload,
-// "Second Life Browser",
-// open_links_externally,
-// mTrusted);
- }
- }
- }
+ return mCurrentNavUrl;
}
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLMediaCtrl::onClickLinkNoFollow( LLPluginClassMedia* self )
+bool LLMediaCtrl::onPopup(const LLSD& notification, const LLSD& response)
{
- std::string url = self->getClickURL();
+ if (response["open"])
+ {
+ LLWeb::loadURL(notification["payload"]["url"], notification["payload"]["target"], notification["payload"]["uuid"]);
+ }
+ else
+ {
+ // Make sure the opening instance knows its window open request was denied, so it can clean things up.
+ LLViewerMedia::proxyWindowClosed(notification["payload"]["uuid"]);
+ }
+ return FALSE;
+}
+
+void LLMediaCtrl::showNotification(LLNotificationPtr notify)
+{
+/* std::string url = self->getClickURL();
if (LLURLDispatcher::isSLURLCommand(url)
&& !mTrusted)
{
@@ -1109,241 +1105,24 @@ void LLMediaCtrl::onClickLinkNoFollow( LLPluginClassMedia* self )
return;
}
- LLURLDispatcher::dispatch(url, this, mTrusted);
+ LLURLDispatcher::dispatch(url, this, mTrusted);*/
+ LLNotifications::instance().add(notify);
}
-////////////////////////////////////////////////////////////////////////////////
-//
-LLWebBrowserTexture::LLWebBrowserTexture( S32 width, S32 height, LLMediaCtrl* browserCtrl, viewer_media_t media_source ) :
- LLViewerDynamicTexture( 512, 512, 4, ORDER_FIRST, TRUE ),
- mNeedsUpdate( true ),
- mNeedsResize( false ),
- mTextureCoordsOpenGL( true ),
- mWebBrowserCtrl( browserCtrl ),
- mMediaSource(media_source)
-{
- mElapsedTime.start();
- resize( width, height );
+void LLMediaCtrl::hideNotification()
+{
}
-////////////////////////////////////////////////////////////////////////////////
-//
-LLWebBrowserTexture::~LLWebBrowserTexture()
+void LLMediaCtrl::setTrustedContent(bool trusted)
{
- mElapsedTime.stop();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-BOOL LLWebBrowserTexture::needsRender()
-{
- bool texture_dirty = false;
-
- if ( mWebBrowserCtrl->getFrequentUpdates() ||
- mWebBrowserCtrl->getAlwaysRefresh() ||
- mWebBrowserCtrl->getForceUpdate() )
+ mTrusted = trusted;
+ if (mMediaSource)
{
- // All of these force an update
- return TRUE;
+ mMediaSource->setTrustedBrowser(trusted);
}
-
- // If the texture needs updating, render needs to be called.
- if (mMediaSource && mMediaSource->hasMedia())
- {
- LLPluginClassMedia* media = mMediaSource->getMediaPlugin();
-
- if(media->textureValid() && media->getDirty())
- {
- texture_dirty = true;
- }
- }
-
-
- return texture_dirty;
}
-////////////////////////////////////////////////////////////////////////////////
-//
-BOOL LLWebBrowserTexture::render()
-{
- if(updateBrowserTexture())
- {
- // updateBrowserTexture already verified that the media plugin is there and the texture is valid.
- LLPluginClassMedia* media_plugin = mMediaSource->getMediaPlugin();
- LLRect dirty_rect;
-
- if(mNeedsUpdate)
- {
- // If we need an update, use the whole rect instead of the dirty rect.
- dirty_rect.mLeft = 0;
- dirty_rect.mBottom = 0;
- dirty_rect.mRight = media_plugin->getWidth();
- dirty_rect.mTop = media_plugin->getHeight();
- }
- else
- {
- mNeedsUpdate = media_plugin->getDirty(&dirty_rect);
- }
-
- if ( mNeedsUpdate )
- {
- mNeedsUpdate = false;
- mWebBrowserCtrl->setForceUpdate(false);
-
- // Constrain the dirty rect to be inside the texture
- S32 x_pos = llmax(dirty_rect.mLeft, 0);
- S32 y_pos = llmax(dirty_rect.mBottom, 0);
- S32 width = llmin(dirty_rect.mRight, getWidth()) - x_pos;
- S32 height = llmin(dirty_rect.mTop, getHeight()) - y_pos;
-
- if(width > 0 && height > 0)
- {
- U8* data = media_plugin->getBitsData();
-
- // Offset the pixels pointer to match x_pos and y_pos
- data += ( x_pos * media_plugin->getTextureDepth() * media_plugin->getBitsWidth() );
- data += ( y_pos * media_plugin->getTextureDepth() );
-
- setSubImage(
- data,
- media_plugin->getBitsWidth(),
- media_plugin->getBitsHeight(),
- x_pos,
- y_pos,
- width,
- height,
- TRUE); // force a fast update (i.e. don't call analyzeAlpha, etc.)
- }
-
- media_plugin->resetDirty();
-
- return TRUE;
- };
- };
-
- return FALSE;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-S32 LLWebBrowserTexture::getMediaWidth()
-{
- return mMediaWidth;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-S32 LLWebBrowserTexture::getMediaHeight()
-{
- return mMediaHeight;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLWebBrowserTexture::setNeedsUpdate()
-{
- mNeedsUpdate = true;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-bool LLWebBrowserTexture::getNeedsUpdate()
-{
- return mNeedsUpdate;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-bool LLWebBrowserTexture::getTextureCoordsOpenGL()
-{
- return mTextureCoordsOpenGL;
-}
-
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLWebBrowserTexture::resize( S32 new_width, S32 new_height )
-{
- F32 scale_ratio = 1.f;
- if (new_width > MAX_DIMENSION)
- {
- scale_ratio = (F32)MAX_DIMENSION / (F32)new_width;
- }
- if (new_height > MAX_DIMENSION)
- {
- scale_ratio = llmin(scale_ratio, (F32)MAX_DIMENSION / (F32)new_height);
- }
-
- mMediaWidth = llround(scale_ratio * (F32)new_width);
- mMediaHeight = llround(scale_ratio * (F32)new_height);
-
- adjustSize();
-}
-
-bool LLWebBrowserTexture::adjustSize()
-{
- if (mMediaSource && mMediaSource->hasMedia())
- {
- int natural_width = mMediaSource->getMediaPlugin()->getNaturalWidth();
- int natural_height = mMediaSource->getMediaPlugin()->getNaturalHeight();
-
- if(natural_width != 0)
- {
- // If the media has a "natural size", use it.
- mMediaWidth = natural_width;
- mMediaHeight = natural_height;
- }
-
- mMediaSource->setSize(mMediaWidth, mMediaHeight);
- mNeedsResize = false;
-
- return true;
- }
- else
- {
- // The media isn't fully initialized yet, delay the resize until later.
- mNeedsResize = true;
- }
-
- return false;
-}
-
-bool LLWebBrowserTexture::updateBrowserTexture()
-{
- if (!adjustSize())
- return false;
-
- LLPluginClassMedia* media = mMediaSource->getMediaPlugin();
-
- if(!media->textureValid())
- return false;
-
- if(mMediaSource->mNeedsNewTexture
- || media->getTextureWidth() != getFullWidth()
- || media->getTextureHeight() != getFullHeight() )
- {
- //releaseGLTexture();
-
- mFullWidth = media->getTextureWidth();
- mFullHeight = media->getTextureHeight();
- mTextureCoordsOpenGL = media->getTextureCoordsOpenGL();
-
- const LLColor4U fill_color(0,0,0,255);
- // will create mWidth * mHeight sized texture, using the texture params specified by the media.
- generateGLTexture(
- media->getTextureFormatInternal(),
- media->getTextureFormatPrimary(),
- media->getTextureFormatType(),
- media->getTextureFormatSwapBytes(),
- &fill_color); //Initialize the texture to black.
-
-
- mMediaSource->mNeedsNewTexture = false;
- }
-
- return true;
-}
// virtual
LLXMLNodePtr LLMediaCtrl::getXML(bool save_children) const
{
@@ -1356,48 +1135,50 @@ LLXMLNodePtr LLMediaCtrl::getXML(bool save_children) const
LLView* LLMediaCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
{
- std::string name("web_browser");
- node->getAttributeString("name", name);
-
- std::string start_url("");
- node->getAttributeString("start_url", start_url );
-
- BOOL border_visible = true;
- node->getAttributeBOOL("border_visible", border_visible);
-
+ LLMediaCtrl::Params p;
+
+ BOOL bval;
+ LLColor4 color;
+ S32 ival;
LLRect rect;
+
+ std::string sval("web_browser");
+ node->getAttributeString("name", sval);
+ p.name = sval;
createRect(node, rect, parent, LLRect());
+ p.rect = rect;
- LLMediaCtrl* web_browser = new LLMediaCtrl( name, rect );
+ if(node->getAttributeString("start_url", sval ))
+ p.start_url = sval;
+ if(node->getAttributeString("error_page_url", sval ))
+ p.error_page_url = sval;
+ if(node->getAttributeString("media_id", sval ))
+ p.media_id = sval;
+ if(node->getAttributeString("initial_mime_type", sval ))
+ p.initial_mime_type = sval;
+ if(node->getAttributeBOOL("border_visible", bval))
+ p.border_visible = bval;
+ if(node->getAttributeBOOL("focus_on_click", bval))
+ p.focus_on_click = bval;
+ if(node->getAttributeBOOL("decouple_texture_size", bval))
+ p.focus_on_click = bval;
+ if(node->getAttributeBOOL("trusted_content", bval))
+ p.trusted_content = bval;
+ if(node->getAttributeS32("texture_width", ival))
+ p.texture_width = ival;
+ if(node->getAttributeBOOL("texture_height", ival))
+ p.texture_height = ival;
+ if(LLUICtrlFactory::getAttributeColor(node, "caret_color", color))
+ p.caret_color = color;
- if(node->hasAttribute("caret_color"))
- {
- LLColor4 color;
- LLUICtrlFactory::getAttributeColor(node, "caret_color", color);
- LLColor4U colorU = LLColor4U(color);
- web_browser->setCaretColor( colorU.mV[0], colorU.mV[1], colorU.mV[2] );
- }
-
- //BOOL ignore_ui_scale = web_browser->getIgnoreUIScale();
- //node->getAttributeBOOL("ignore_ui_scale", ignore_ui_scale);
- //web_browser->setIgnoreUIScale((bool)ignore_ui_scale);
+ LLMediaCtrl* web_browser = LLUICtrlFactory::create(p,parent);
web_browser->initFromXML(node, parent);
- web_browser->setHomePageUrl( start_url );
-
- web_browser->setBorderVisible( border_visible );
-
- if(! start_url.empty())
+ if(!p.start_url.getValue().empty())
{
web_browser->navigateHome();
}
return web_browser;
}
-
-std::string LLMediaCtrl::getCurrentNavUrl()
-{
- return mCurrentNavUrl;
-}
-
diff --git a/indra/newview/llmediactrl.h b/indra/newview/llmediactrl.h
index ef25ae0e3..f843fe075 100644
--- a/indra/newview/llmediactrl.h
+++ b/indra/newview/llmediactrl.h
@@ -34,25 +34,50 @@
#define LL_LLMediaCtrl_H
#include "llviewermedia.h"
-#include "llviewermediaobserver.h"
+
#include "lluictrl.h"
#include "llframetimer.h"
-#include "lldynamictexture.h"
class LLViewBorder;
-class LLWebBrowserTexture;
class LLUICtrlFactory;
////////////////////////////////////////////////////////////////////////////////
//
class LLMediaCtrl :
- public LLUICtrl,
+ public LLPanel,
public LLViewerMediaObserver,
public LLViewerMediaEventEmitter,
public LLInstanceTracker
{
- public:
- LLMediaCtrl( const std::string& name, const LLRect& rect );
+ LOG_CLASS(LLMediaCtrl);
+public:
+ struct Params : public LLInitParam::Block
+ {
+ Optional start_url;
+
+ Optional border_visible,
+ hide_loading,
+ decouple_texture_size,
+ trusted_content,
+ focus_on_click;
+
+ Optional texture_width,
+ texture_height;
+
+ Optional caret_color;
+
+ Optional initial_mime_type;
+ Optional media_id;
+ Optional error_page_url;
+
+ Params();
+ };
+
+protected:
+ LLMediaCtrl(const Params&);
+ friend class LLUICtrlFactory;
+
+public:
virtual ~LLMediaCtrl();
void setBorderVisible( BOOL border_visible );
@@ -74,6 +99,7 @@ class LLMediaCtrl :
virtual BOOL handleRightMouseUp(S32 x, S32 y, MASK mask);
virtual BOOL handleDoubleClick( S32 x, S32 y, MASK mask );
virtual BOOL handleScrollWheel( S32 x, S32 y, S32 clicks );
+ virtual BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen);
// navigation
void navigateTo( std::string url_in, std::string mime_type = "");
@@ -83,8 +109,6 @@ class LLMediaCtrl :
void navigateToLocalPage( const std::string& subdir, const std::string& filename_in );
bool canNavigateBack();
bool canNavigateForward();
- void setOpenInExternalBrowser( bool valIn );
- void setOpenInInternalBrowser( bool valIn );
std::string getCurrentNavUrl();
// By default, we do not handle "secondlife:///app/" SLURLs, because
@@ -93,12 +117,17 @@ class LLMediaCtrl :
// Javascript or some other mechanism. However, we need the search
// floater and login page to handle these URLs. Those are safe
// because we control the page content. See DEV-9530. JC.
- void setTrusted( bool valIn );
-
- void setHomePageUrl( const std::string urlIn );
+ void setHomePageUrl( const std::string& urlIn, const std::string& mime_type = LLStringUtil::null );
std::string getHomePageUrl();
- // set/clear URL to visit when a 404 page is reached
+ void setTarget(const std::string& target);
+
+ void setErrorPageURL(const std::string& url);
+ const std::string& getErrorPageURL();
+
+ // Clear the browser cache when the instance gets loaded
+ void clearCache();
+
void set404RedirectUrl( std::string redirect_url );
void clr404RedirectUrl();
@@ -106,9 +135,6 @@ class LLMediaCtrl :
bool getFrequentUpdates() { return mFrequentUpdates; };
void setFrequentUpdates( bool frequentUpdatesIn ) { mFrequentUpdates = frequentUpdatesIn; };
- void setIgnoreUIScale(bool ignore) { mIgnoreUIScale = ignore; }
- bool getIgnoreUIScale() { return mIgnoreUIScale; }
-
void setAlwaysRefresh(bool refresh) { mAlwaysRefresh = refresh; }
bool getAlwaysRefresh() { return mAlwaysRefresh; }
@@ -127,6 +153,11 @@ class LLMediaCtrl :
void setTextureSize(S32 width, S32 height);
+ void showNotification(boost::shared_ptr notify);
+ void hideNotification();
+
+ void setTrustedContent(bool trusted);
+
// over-rides
virtual BOOL handleKeyHere( KEY key, MASK mask);
virtual void handleVisibilityChange ( BOOL new_visibility );
@@ -142,80 +173,42 @@ class LLMediaCtrl :
// Incoming media event dispatcher
virtual void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event);
- // handlers for individual events (could be done inside the switch in handleMediaEvent, they're just individual functions for clarity)
- void onClickLinkHref( LLPluginClassMedia* self );
-
- void onClickLinkNoFollow( LLPluginClassMedia* self );
-
// right click debugging item
void onOpenWebInspector();
+ LLUUID getTextureID() {return mMediaTextureID;}
+
protected:
void convertInputCoords(S32& x, S32& y);
private:
void onVisibilityChange ( const LLSD& new_visibility );
- static bool onClickLinkExternalTarget( const LLSD&, const LLSD& );
+ bool onPopup(const LLSD& notification, const LLSD& response);
const S32 mTextureDepthBytes;
LLUUID mMediaTextureID;
- LLPointer mWebBrowserImage;
LLViewBorder* mBorder;
- bool mFrequentUpdates;
- bool mForceUpdate;
- bool mOpenLinksInExternalBrowser;
- bool mOpenLinksInInternalBrowser;
- bool mTrusted;
- std::string mHomePageUrl;
- std::string mExternalUrl;
- std::string mCurrentNavUrl;
- bool mIgnoreUIScale;
- bool mAlwaysRefresh;
- viewer_media_t mMediaSource;
- bool mTakeFocusOnClick;
- ECursorType mLastSetCursor;
- bool mStretchToFill;
- bool mMaintainAspectRatio;
- bool mHideLoading;
- bool mHidingInitialLoad;
- bool mDecoupleTextureSize;
- S32 mTextureWidth;
- S32 mTextureHeight;
-};
-
-////////////////////////////////////////////////////////////////////////////////
-//
-class LLWebBrowserTexture : public LLViewerDynamicTexture
-{
-LOG_CLASS(LLWebBrowserTexture);
- public:
- LLWebBrowserTexture( S32 width, S32 height, LLMediaCtrl* browserCtrl, viewer_media_t media_source );
- virtual ~LLWebBrowserTexture();
-
- virtual BOOL needsRender();
- virtual void preRender( BOOL clear_depth = TRUE ) {};
- virtual void postRender( BOOL success ) {};
- virtual BOOL render();
-
- bool adjustSize();
- S32 getMediaWidth();
- S32 getMediaHeight();
- bool getNeedsUpdate();
- void setNeedsUpdate();
- bool getTextureCoordsOpenGL();
-
- void resize( S32 new_width, S32 new_height );
- bool updateBrowserTexture();
-
- protected:
- S32 mMediaWidth;
- S32 mMediaHeight;
- bool mNeedsUpdate;
- bool mNeedsResize;
- bool mTextureCoordsOpenGL;
- LLFrameTimer mElapsedTime;
- LLMediaCtrl* mWebBrowserCtrl;
+ bool mFrequentUpdates,
+ mForceUpdate,
+ mTrusted,
+ mAlwaysRefresh,
+ mTakeFocusOnClick,
+ mStretchToFill,
+ mMaintainAspectRatio,
+ mHideLoading,
+ mHidingInitialLoad,
+ mClearCache,
+ mHoverTextChanged,
+ mDecoupleTextureSize;
+
+ std::string mHomePageUrl,
+ mHomePageMimeType,
+ mCurrentNavUrl,
+ mErrorPageURL,
+ mTarget;
viewer_media_t mMediaSource;
+ S32 mTextureWidth,
+ mTextureHeight;
};
#endif // LL_LLMediaCtrl_H
diff --git a/indra/newview/llmediadataclient.cpp b/indra/newview/llmediadataclient.cpp
new file mode 100644
index 000000000..31038b4aa
--- /dev/null
+++ b/indra/newview/llmediadataclient.cpp
@@ -0,0 +1,1070 @@
+/**
+ * @file llmediadataclient.cpp
+ * @brief class for queueing up requests for media data
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llmediadataclient.h"
+
+#if LL_MSVC
+// disable boost::lexical_cast warning
+#pragma warning (disable:4702)
+#endif
+
+#include
+
+#include "llhttpstatuscodes.h"
+#include "llsdutil.h"
+#include "llmediaentry.h"
+#include "lltextureentry.h"
+#include "llviewerregion.h"
+
+//
+// When making a request
+// - obtain the "overall interest score" of the object.
+// This would be the sum of the impls' interest scores.
+// - put the request onto a queue sorted by this score
+// (highest score at the front of the queue)
+// - On a timer, once a second, pull off the head of the queue and send
+// the request.
+// - Any request that gets a 503 still goes through the retry logic
+//
+
+/***************************************************************************************************************
+ What's up with this queueing code?
+
+ First, a bit of background:
+
+ Media on a prim was added into the system in the Viewer 2.0 timeframe. In order to avoid changing the
+ network format of objects, an unused field in the object (the "MediaURL" string) was repurposed to
+ indicate that the object had media data, and also hold a sequence number and the UUID of the agent
+ who last updated the data. The actual media data for objects is accessed via the "ObjectMedia" capability.
+ Due to concerns about sim performance, requests to this capability are rate-limited to 5 requests every
+ 5 seconds per agent.
+
+ The initial implementation of LLMediaDataClient used a single queue to manage requests to the "ObjectMedia" cap.
+ Requests to the cap were queued so that objects closer to the avatar were loaded in first, since they were most
+ likely to be the ones the media performance manager would load.
+
+ This worked in some cases, but we found that it was possible for a scripted object that constantly updated its
+ media data to starve other objects, since the same queue contained both requests to load previously unseen media
+ data and requests to fetch media data in response to object updates.
+
+ The solution for this we came up with was to have two queues. The sorted queue contains requests to fetch media
+ data for objects that don't have it yet, and the round-robin queue contains requests to update media data for
+ objects that have already completed their initial load. When both queues are non-empty, the code ping-pongs
+ between them so that updates can't completely block initial load-in.
+**************************************************************************************************************/
+
+//
+// Forward decls
+//
+const F32 LLMediaDataClient::QUEUE_TIMER_DELAY = 1.0; // seconds(s)
+const F32 LLMediaDataClient::UNAVAILABLE_RETRY_TIMER_DELAY = 5.0; // secs
+const U32 LLMediaDataClient::MAX_RETRIES = 4;
+const U32 LLMediaDataClient::MAX_SORTED_QUEUE_SIZE = 10000;
+const U32 LLMediaDataClient::MAX_ROUND_ROBIN_QUEUE_SIZE = 10000;
+
+// << operators
+std::ostream& operator<<(std::ostream &s, const LLMediaDataClient::request_queue_t &q);
+std::ostream& operator<<(std::ostream &s, const LLMediaDataClient::Request &q);
+
+template
+static typename T::iterator find_matching_request(T &c, const LLMediaDataClient::Request *request, LLMediaDataClient::Request::Type match_type)
+{
+ for(typename T::iterator iter = c.begin(); iter != c.end(); ++iter)
+ {
+ if(request->isMatch(*iter, match_type))
+ {
+ return iter;
+ }
+ }
+
+ return c.end();
+}
+
+template
+static typename T::iterator find_matching_request(T &c, const LLUUID &id, LLMediaDataClient::Request::Type match_type)
+{
+ for(typename T::iterator iter = c.begin(); iter != c.end(); ++iter)
+ {
+ if(((*iter)->getID() == id) && ((match_type == LLMediaDataClient::Request::ANY) || (match_type == (*iter)->getType())))
+ {
+ return iter;
+ }
+ }
+
+ return c.end();
+}
+
+// NOTE: remove_matching_requests will not work correctly for containers where deleting an element may invalidate iterators
+// to other elements in the container (such as std::vector).
+// If the implementation is changed to use a container with this property, this will need to be revisited.
+template
+static void remove_matching_requests(T &c, const LLUUID &id, LLMediaDataClient::Request::Type match_type)
+{
+ for(typename T::iterator iter = c.begin(); iter != c.end();)
+ {
+ typename T::value_type i = *iter;
+ typename T::iterator next = iter;
+ next++;
+ if((i->getID() == id) && ((match_type == LLMediaDataClient::Request::ANY) || (match_type == i->getType())))
+ {
+ i->markDead();
+ c.erase(iter);
+ }
+ iter = next;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////////////
+//
+// LLMediaDataClient
+//
+//////////////////////////////////////////////////////////////////////////////////////
+
+LLMediaDataClient::LLMediaDataClient(F32 queue_timer_delay,
+ F32 retry_timer_delay,
+ U32 max_retries,
+ U32 max_sorted_queue_size,
+ U32 max_round_robin_queue_size)
+ : mQueueTimerDelay(queue_timer_delay),
+ mRetryTimerDelay(retry_timer_delay),
+ mMaxNumRetries(max_retries),
+ mMaxSortedQueueSize(max_sorted_queue_size),
+ mMaxRoundRobinQueueSize(max_round_robin_queue_size),
+ mQueueTimerIsRunning(false)
+{
+}
+
+LLMediaDataClient::~LLMediaDataClient()
+{
+ stopQueueTimer();
+}
+
+bool LLMediaDataClient::isEmpty() const
+{
+ return mQueue.empty();
+}
+
+bool LLMediaDataClient::isInQueue(const LLMediaDataClientObject::ptr_t &object)
+{
+ if(find_matching_request(mQueue, object->getID()) != mQueue.end())
+ return true;
+
+ if(find_matching_request(mUnQueuedRequests, object->getID()) != mUnQueuedRequests.end())
+ return true;
+
+ return false;
+}
+
+void LLMediaDataClient::removeFromQueue(const LLMediaDataClientObject::ptr_t &object)
+{
+ LL_DEBUGS("LLMediaDataClient") << "removing requests matching ID " << object->getID() << LL_ENDL;
+ remove_matching_requests(mQueue, object->getID());
+ remove_matching_requests(mUnQueuedRequests, object->getID());
+}
+
+void LLMediaDataClient::startQueueTimer()
+{
+ if (! mQueueTimerIsRunning)
+ {
+ LL_DEBUGS("LLMediaDataClient") << "starting queue timer (delay=" << mQueueTimerDelay << " seconds)" << LL_ENDL;
+ // LLEventTimer automagically takes care of the lifetime of this object
+ new QueueTimer(mQueueTimerDelay, this);
+ }
+ else {
+ LL_DEBUGS("LLMediaDataClient") << "queue timer is already running" << LL_ENDL;
+ }
+}
+
+void LLMediaDataClient::stopQueueTimer()
+{
+ mQueueTimerIsRunning = false;
+}
+
+bool LLMediaDataClient::processQueueTimer()
+{
+ if(isEmpty())
+ return true;
+
+ LL_DEBUGS("LLMediaDataClient") << "QueueTimer::tick() started, queue size is: " << mQueue.size() << LL_ENDL;
+ LL_DEBUGS("LLMediaDataClientQueue") << "QueueTimer::tick() started, SORTED queue is: " << mQueue << LL_ENDL;
+
+ serviceQueue();
+
+ LL_DEBUGS("LLMediaDataClient") << "QueueTimer::tick() finished, queue size is: " << mQueue.size() << LL_ENDL;
+ LL_DEBUGS("LLMediaDataClientQueue") << "QueueTimer::tick() finished, SORTED queue is: " << mQueue << LL_ENDL;
+
+ return isEmpty();
+}
+
+LLMediaDataClient::request_ptr_t LLMediaDataClient::dequeue()
+{
+ request_ptr_t request;
+ request_queue_t *queue_p = getQueue();
+
+ if (queue_p->empty())
+ {
+ LL_DEBUGS("LLMediaDataClient") << "queue empty: " << (*queue_p) << LL_ENDL;
+ }
+ else
+ {
+ request = queue_p->front();
+
+ if(canServiceRequest(request))
+ {
+ // We will be returning this request, so remove it from the queue.
+ queue_p->pop_front();
+ }
+ else
+ {
+ // Don't return this request -- it's not ready to be serviced.
+ request = NULL;
+ }
+ }
+
+ return request;
+}
+
+void LLMediaDataClient::pushBack(request_ptr_t request)
+{
+ request_queue_t *queue_p = getQueue();
+ queue_p->push_front(request);
+}
+
+void LLMediaDataClient::trackRequest(request_ptr_t request)
+{
+ request_set_t::iterator iter = mUnQueuedRequests.find(request);
+
+ if(iter != mUnQueuedRequests.end())
+ {
+ LL_WARNS("LLMediaDataClient") << "Tracking already tracked request: " << *request << LL_ENDL;
+ }
+ else
+ {
+ mUnQueuedRequests.insert(request);
+ }
+}
+
+void LLMediaDataClient::stopTrackingRequest(request_ptr_t request)
+{
+ request_set_t::iterator iter = mUnQueuedRequests.find(request);
+
+ if (iter != mUnQueuedRequests.end())
+ {
+ mUnQueuedRequests.erase(iter);
+ }
+ else
+ {
+ LL_WARNS("LLMediaDataClient") << "Removing an untracked request: " << *request << LL_ENDL;
+ }
+}
+
+void LLMediaDataClient::serviceQueue()
+{
+ // Peel one off of the items from the queue and execute it
+ request_ptr_t request;
+
+ do
+ {
+ request = dequeue();
+
+ if(request.isNull())
+ {
+ // Queue is empty.
+ return;
+ }
+
+ if(request->isDead())
+ {
+ LL_INFOS("LLMediaDataClient") << "Skipping dead request " << *request << LL_ENDL;
+ continue;
+ }
+
+ } while(false);
+
+ // try to send the HTTP message to the cap url
+ std::string url = request->getCapability();
+ if (!url.empty())
+ {
+ const LLSD &sd_payload = request->getPayload();
+ LL_INFOS("LLMediaDataClient") << "Sending request for " << *request << LL_ENDL;
+
+ // Add this request to the non-queued tracking list
+ trackRequest(request);
+
+ // and make the post
+ LLHTTPClient::post(url, sd_payload, request->createResponder());
+ }
+ else
+ {
+ // Cap url doesn't exist.
+
+ if(request->getRetryCount() < mMaxNumRetries)
+ {
+ LL_WARNS("LLMediaDataClient") << "Could not send request " << *request << " (empty cap url), will retry." << LL_ENDL;
+ // Put this request back at the head of its queue, and retry next time the queue timer fires.
+ request->incRetryCount();
+ pushBack(request);
+ }
+ else
+ {
+ // This request has exceeded its maxumim retry count. It will be dropped.
+ LL_WARNS("LLMediaDataClient") << "Could not send request " << *request << " for " << mMaxNumRetries << " tries, dropping request." << LL_ENDL;
+ }
+
+ }
+}
+
+
+// dump the queue
+std::ostream& operator<<(std::ostream &s, const LLMediaDataClient::request_queue_t &q)
+{
+ int i = 0;
+ LLMediaDataClient::request_queue_t::const_iterator iter = q.begin();
+ LLMediaDataClient::request_queue_t::const_iterator end = q.end();
+ while (iter != end)
+ {
+ s << "\t" << i << "]: " << (*iter)->getID().asString() << "(" << (*iter)->getObject()->getMediaInterest() << ")";
+ iter++;
+ i++;
+ }
+ return s;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////
+//
+// LLMediaDataClient::QueueTimer
+// Queue of LLMediaDataClientObject smart pointers to request media for.
+//
+//////////////////////////////////////////////////////////////////////////////////////
+
+LLMediaDataClient::QueueTimer::QueueTimer(F32 time, LLMediaDataClient *mdc)
+: LLEventTimer(time), mMDC(mdc)
+{
+ mMDC->setIsRunning(true);
+}
+
+// virtual
+BOOL LLMediaDataClient::QueueTimer::tick()
+{
+ BOOL result = TRUE;
+
+ if (!mMDC.isNull())
+ {
+ result = mMDC->processQueueTimer();
+
+ if(result)
+ {
+ // This timer won't fire again.
+ mMDC->setIsRunning(false);
+ mMDC = NULL;
+ }
+ }
+
+ return result;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////////////
+//
+// LLMediaDataClient::Responder::RetryTimer
+//
+//////////////////////////////////////////////////////////////////////////////////////
+
+LLMediaDataClient::RetryTimer::RetryTimer(F32 time, request_ptr_t request)
+: LLEventTimer(time), mRequest(request)
+{
+ mRequest->startTracking();
+}
+
+// virtual
+BOOL LLMediaDataClient::RetryTimer::tick()
+{
+ mRequest->stopTracking();
+
+ if(mRequest->isDead())
+ {
+ LL_INFOS("LLMediaDataClient") << "RetryTimer fired for dead request: " << *mRequest << ", aborting." << LL_ENDL;
+ }
+ else
+ {
+ LL_INFOS("LLMediaDataClient") << "RetryTimer fired for: " << *mRequest << ", retrying." << LL_ENDL;
+ mRequest->reEnqueue();
+ }
+
+ // Release the ref to the request.
+ mRequest = NULL;
+
+ // Don't fire again
+ return TRUE;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////////////
+//
+// LLMediaDataClient::Request
+//
+//////////////////////////////////////////////////////////////////////////////////////
+/*static*/U32 LLMediaDataClient::Request::sNum = 0;
+
+LLMediaDataClient::Request::Request(Type in_type,
+ LLMediaDataClientObject *obj,
+ LLMediaDataClient *mdc,
+ S32 face)
+: mType(in_type),
+ mObject(obj),
+ mNum(++sNum),
+ mRetryCount(0),
+ mMDC(mdc),
+ mScore((F64)0.0),
+ mFace(face)
+{
+ mObjectID = mObject->getID();
+}
+
+const char *LLMediaDataClient::Request::getCapName() const
+{
+ if(mMDC)
+ return mMDC->getCapabilityName();
+
+ return "";
+}
+
+std::string LLMediaDataClient::Request::getCapability() const
+{
+ if(mMDC)
+ {
+ return getObject()->getCapabilityUrl(getCapName());
+ }
+
+ return "";
+}
+
+const char *LLMediaDataClient::Request::getTypeAsString() const
+{
+ Type t = getType();
+ switch (t)
+ {
+ case GET:
+ return "GET";
+ break;
+ case UPDATE:
+ return "UPDATE";
+ break;
+ case NAVIGATE:
+ return "NAVIGATE";
+ break;
+ case ANY:
+ return "ANY";
+ break;
+ }
+ return "";
+}
+
+
+void LLMediaDataClient::Request::reEnqueue()
+{
+ if(mMDC)
+ {
+ mMDC->enqueue(this);
+ }
+}
+
+F32 LLMediaDataClient::Request::getRetryTimerDelay() const
+{
+ if(mMDC)
+ return mMDC->mRetryTimerDelay;
+
+ return 0.0f;
+}
+
+U32 LLMediaDataClient::Request::getMaxNumRetries() const
+{
+ if(mMDC)
+ return mMDC->mMaxNumRetries;
+
+ return 0;
+}
+
+void LLMediaDataClient::Request::updateScore()
+{
+ F64 tmp = mObject->getMediaInterest();
+ if (tmp != mScore)
+ {
+ LL_DEBUGS("LLMediaDataClient") << "Score for " << mObject->getID() << " changed from " << mScore << " to " << tmp << LL_ENDL;
+ mScore = tmp;
+ }
+}
+
+void LLMediaDataClient::Request::markDead()
+{
+ mMDC = NULL;
+}
+
+bool LLMediaDataClient::Request::isDead()
+{
+ return ((mMDC == NULL) || mObject->isDead());
+}
+
+void LLMediaDataClient::Request::startTracking()
+{
+ if(mMDC)
+ mMDC->trackRequest(this);
+}
+
+void LLMediaDataClient::Request::stopTracking()
+{
+ if(mMDC)
+ mMDC->stopTrackingRequest(this);
+}
+
+std::ostream& operator<<(std::ostream &s, const LLMediaDataClient::Request &r)
+{
+ s << "request: num=" << r.getNum()
+ << " type=" << r.getTypeAsString()
+ << " ID=" << r.getID()
+ << " face=" << r.getFace()
+ << " #retries=" << r.getRetryCount();
+ return s;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////
+//
+// LLMediaDataClient::Responder
+//
+//////////////////////////////////////////////////////////////////////////////////////
+
+LLMediaDataClient::Responder::Responder(const request_ptr_t &request)
+: mRequest(request)
+{
+}
+
+/*virtual*/
+void LLMediaDataClient::Responder::error(U32 status, const std::string& reason)
+{
+ mRequest->stopTracking();
+
+ if(mRequest->isDead())
+ {
+ LL_WARNS("LLMediaDataClient") << "dead request " << *mRequest << LL_ENDL;
+ return;
+ }
+
+ if (status == HTTP_SERVICE_UNAVAILABLE)
+ {
+ F32 retry_timeout = mRequest->getRetryTimerDelay();
+
+ mRequest->incRetryCount();
+
+ if (mRequest->getRetryCount() < mRequest->getMaxNumRetries())
+ {
+ LL_INFOS("LLMediaDataClient") << *mRequest << " got SERVICE_UNAVAILABLE...retrying in " << retry_timeout << " seconds" << LL_ENDL;
+
+ // Start timer (instances are automagically tracked by
+ // InstanceTracker<> and LLEventTimer)
+ new RetryTimer(F32(retry_timeout/*secs*/), mRequest);
+ }
+ else
+ {
+ LL_INFOS("LLMediaDataClient") << *mRequest << " got SERVICE_UNAVAILABLE...retry count "
+ << mRequest->getRetryCount() << " exceeds " << mRequest->getMaxNumRetries() << ", not retrying" << LL_ENDL;
+ }
+ }
+ else
+ {
+ std::string msg = boost::lexical_cast(status) + ": " + reason;
+ LL_WARNS("LLMediaDataClient") << *mRequest << " http error(" << msg << ")" << LL_ENDL;
+ }
+}
+
+/*virtual*/
+void LLMediaDataClient::Responder::result(const LLSD& content)
+{
+ mRequest->stopTracking();
+
+ if(mRequest->isDead())
+ {
+ LL_WARNS("LLMediaDataClient") << "dead request " << *mRequest << LL_ENDL;
+ return;
+ }
+
+ LL_DEBUGS("LLMediaDataClientResponse") << *mRequest << " result : " << ll_print_sd(content) << LL_ENDL;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////
+//
+// LLObjectMediaDataClient
+// Subclass of LLMediaDataClient for the ObjectMedia cap
+//
+//////////////////////////////////////////////////////////////////////////////////////
+
+void LLObjectMediaDataClient::fetchMedia(LLMediaDataClientObject *object)
+{
+ // Create a get request and put it in the queue.
+ enqueue(new RequestGet(object, this));
+}
+
+const char *LLObjectMediaDataClient::getCapabilityName() const
+{
+ return "ObjectMedia";
+}
+
+LLObjectMediaDataClient::request_queue_t *LLObjectMediaDataClient::getQueue()
+{
+ return (mCurrentQueueIsTheSortedQueue) ? &mQueue : &mRoundRobinQueue;
+}
+
+void LLObjectMediaDataClient::sortQueue()
+{
+ if(!mQueue.empty())
+ {
+ // score all elements in the sorted queue.
+ for(request_queue_t::iterator iter = mQueue.begin(); iter != mQueue.end(); iter++)
+ {
+ (*iter)->updateScore();
+ }
+
+ // Re-sort the list...
+ mQueue.sort(compareRequestScores);
+
+ // ...then cull items over the max
+ U32 size = mQueue.size();
+ if (size > mMaxSortedQueueSize)
+ {
+ U32 num_to_cull = (size - mMaxSortedQueueSize);
+ LL_INFOS_ONCE("LLMediaDataClient") << "sorted queue MAXED OUT! Culling "
+ << num_to_cull << " items" << LL_ENDL;
+ while (num_to_cull-- > 0)
+ {
+ mQueue.back()->markDead();
+ mQueue.pop_back();
+ }
+ }
+ }
+
+}
+
+// static
+bool LLObjectMediaDataClient::compareRequestScores(const request_ptr_t &o1, const request_ptr_t &o2)
+{
+ if (o2.isNull()) return true;
+ if (o1.isNull()) return false;
+ return ( o1->getScore() > o2->getScore() );
+}
+
+void LLObjectMediaDataClient::enqueue(Request *request)
+{
+ if(request->isDead())
+ {
+ LL_DEBUGS("LLMediaDataClient") << "not queueing dead request " << *request << LL_ENDL;
+ return;
+ }
+
+ // Invariants:
+ // new requests always go into the sorted queue.
+ //
+
+ bool is_new = request->isNew();
+
+ if(!is_new && (request->getType() == Request::GET))
+ {
+ // For GET requests that are not new, if a matching request is already in the round robin queue,
+ // in flight, or being retried, leave it at its current position.
+ request_queue_t::iterator iter = find_matching_request(mRoundRobinQueue, request->getID(), Request::GET);
+ request_set_t::iterator iter2 = find_matching_request(mUnQueuedRequests, request->getID(), Request::GET);
+
+ if( (iter != mRoundRobinQueue.end()) || (iter2 != mUnQueuedRequests.end()) )
+ {
+ LL_DEBUGS("LLMediaDataClient") << "ALREADY THERE: NOT Queuing request for " << *request << LL_ENDL;
+
+ return;
+ }
+ }
+
+ // TODO: should an UPDATE cause pending GET requests for the same object to be removed from the queue?
+ // IF the update will cause an object update message to be sent out at some point in the future, it probably should.
+
+ // Remove any existing requests of this type for this object
+ remove_matching_requests(mQueue, request->getID(), request->getType());
+ remove_matching_requests(mRoundRobinQueue, request->getID(), request->getType());
+ remove_matching_requests(mUnQueuedRequests, request->getID(), request->getType());
+
+ if (is_new)
+ {
+ LL_DEBUGS("LLMediaDataClient") << "Queuing SORTED request for " << *request << LL_ENDL;
+
+ mQueue.push_back(request);
+
+ LL_DEBUGS("LLMediaDataClientQueue") << "SORTED queue:" << mQueue << LL_ENDL;
+ }
+ else
+ {
+ if (mRoundRobinQueue.size() > mMaxRoundRobinQueueSize)
+ {
+ LL_INFOS_ONCE("LLMediaDataClient") << "RR QUEUE MAXED OUT!!!" << LL_ENDL;
+ LL_DEBUGS("LLMediaDataClient") << "Not queuing " << *request << LL_ENDL;
+ return;
+ }
+
+ LL_DEBUGS("LLMediaDataClient") << "Queuing RR request for " << *request << LL_ENDL;
+ // Push the request on the pending queue
+ mRoundRobinQueue.push_back(request);
+
+ LL_DEBUGS("LLMediaDataClientQueue") << "RR queue:" << mRoundRobinQueue << LL_ENDL;
+ }
+ // Start the timer if not already running
+ startQueueTimer();
+}
+
+bool LLObjectMediaDataClient::canServiceRequest(request_ptr_t request)
+{
+ if(mCurrentQueueIsTheSortedQueue)
+ {
+ if(!request->getObject()->isInterestingEnough())
+ {
+ LL_DEBUGS("LLMediaDataClient") << "Not fetching " << *request << ": not interesting enough" << LL_ENDL;
+ return false;
+ }
+ }
+
+ return true;
+};
+
+void LLObjectMediaDataClient::swapCurrentQueue()
+{
+ // Swap
+ mCurrentQueueIsTheSortedQueue = !mCurrentQueueIsTheSortedQueue;
+ // If its empty, swap back
+ if (getQueue()->empty())
+ {
+ mCurrentQueueIsTheSortedQueue = !mCurrentQueueIsTheSortedQueue;
+ }
+}
+
+bool LLObjectMediaDataClient::isEmpty() const
+{
+ return mQueue.empty() && mRoundRobinQueue.empty();
+}
+
+bool LLObjectMediaDataClient::isInQueue(const LLMediaDataClientObject::ptr_t &object)
+{
+ // First, call parent impl.
+ if(LLMediaDataClient::isInQueue(object))
+ return true;
+
+ if(find_matching_request(mRoundRobinQueue, object->getID()) != mRoundRobinQueue.end())
+ return true;
+
+ return false;
+}
+
+void LLObjectMediaDataClient::removeFromQueue(const LLMediaDataClientObject::ptr_t &object)
+{
+ // First, call parent impl.
+ LLMediaDataClient::removeFromQueue(object);
+
+ remove_matching_requests(mRoundRobinQueue, object->getID());
+}
+
+bool LLObjectMediaDataClient::processQueueTimer()
+{
+ if(isEmpty())
+ return true;
+
+ LL_DEBUGS("LLMediaDataClient") << "started, SORTED queue size is: " << mQueue.size()
+ << ", RR queue size is: " << mRoundRobinQueue.size() << LL_ENDL;
+ LL_DEBUGS("LLMediaDataClientQueue") << " SORTED queue is: " << mQueue << LL_ENDL;
+ LL_DEBUGS("LLMediaDataClientQueue") << " RR queue is: " << mRoundRobinQueue << LL_ENDL;
+
+// purgeDeadRequests();
+
+ sortQueue();
+
+ LL_DEBUGS("LLMediaDataClientQueue") << "after sort, SORTED queue is: " << mQueue << LL_ENDL;
+
+ serviceQueue();
+
+ swapCurrentQueue();
+
+ LL_DEBUGS("LLMediaDataClient") << "finished, SORTED queue size is: " << mQueue.size()
+ << ", RR queue size is: " << mRoundRobinQueue.size() << LL_ENDL;
+ LL_DEBUGS("LLMediaDataClientQueue") << " SORTED queue is: " << mQueue << LL_ENDL;
+ LL_DEBUGS("LLMediaDataClientQueue") << " RR queue is: " << mRoundRobinQueue << LL_ENDL;
+
+ return isEmpty();
+}
+
+LLObjectMediaDataClient::RequestGet::RequestGet(LLMediaDataClientObject *obj, LLMediaDataClient *mdc):
+ LLMediaDataClient::Request(LLMediaDataClient::Request::GET, obj, mdc)
+{
+}
+
+LLSD LLObjectMediaDataClient::RequestGet::getPayload() const
+{
+ LLSD result;
+ result["verb"] = "GET";
+ result[LLTextureEntry::OBJECT_ID_KEY] = mObject->getID();
+
+ return result;
+}
+
+LLMediaDataClient::Responder *LLObjectMediaDataClient::RequestGet::createResponder()
+{
+ return new LLObjectMediaDataClient::Responder(this);
+}
+
+
+void LLObjectMediaDataClient::updateMedia(LLMediaDataClientObject *object)
+{
+ // Create an update request and put it in the queue.
+ enqueue(new RequestUpdate(object, this));
+}
+
+LLObjectMediaDataClient::RequestUpdate::RequestUpdate(LLMediaDataClientObject *obj, LLMediaDataClient *mdc):
+ LLMediaDataClient::Request(LLMediaDataClient::Request::UPDATE, obj, mdc)
+{
+}
+
+LLSD LLObjectMediaDataClient::RequestUpdate::getPayload() const
+{
+ LLSD result;
+ result["verb"] = "UPDATE";
+ result[LLTextureEntry::OBJECT_ID_KEY] = mObject->getID();
+
+ LLSD object_media_data;
+ int i = 0;
+ int end = mObject->getMediaDataCount();
+ for ( ; i < end ; ++i)
+ {
+ object_media_data.append(mObject->getMediaDataLLSD(i));
+ }
+
+ result[LLTextureEntry::OBJECT_MEDIA_DATA_KEY] = object_media_data;
+
+ return result;
+}
+
+LLMediaDataClient::Responder *LLObjectMediaDataClient::RequestUpdate::createResponder()
+{
+ // This just uses the base class's responder.
+ return new LLMediaDataClient::Responder(this);
+}
+
+
+/*virtual*/
+void LLObjectMediaDataClient::Responder::result(const LLSD& content)
+{
+ getRequest()->stopTracking();
+
+ if(getRequest()->isDead())
+ {
+ LL_WARNS("LLMediaDataClient") << "dead request " << *(getRequest()) << LL_ENDL;
+ return;
+ }
+
+ // This responder is only used for GET requests, not UPDATE.
+
+ LL_DEBUGS("LLMediaDataClientResponse") << *(getRequest()) << " GET returned: " << ll_print_sd(content) << LL_ENDL;
+
+ // Look for an error
+ if (content.has("error"))
+ {
+ const LLSD &error = content["error"];
+ LL_WARNS("LLMediaDataClient") << *(getRequest()) << " Error getting media data for object: code=" <<
+ error["code"].asString() << ": " << error["message"].asString() << LL_ENDL;
+
+ // XXX Warn user?
+ }
+ else
+ {
+ // Check the data
+ const LLUUID &object_id = content[LLTextureEntry::OBJECT_ID_KEY];
+ if (object_id != getRequest()->getObject()->getID())
+ {
+ // NOT good, wrong object id!!
+ LL_WARNS("LLMediaDataClient") << *(getRequest()) << " DROPPING response with wrong object id (" << object_id << ")" << LL_ENDL;
+ return;
+ }
+
+ // Otherwise, update with object media data
+ getRequest()->getObject()->updateObjectMediaData(content[LLTextureEntry::OBJECT_MEDIA_DATA_KEY],
+ content[LLTextureEntry::MEDIA_VERSION_KEY]);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////////////
+//
+// LLObjectMediaNavigateClient
+// Subclass of LLMediaDataClient for the ObjectMediaNavigate cap
+//
+//////////////////////////////////////////////////////////////////////////////////////
+
+const char *LLObjectMediaNavigateClient::getCapabilityName() const
+{
+ return "ObjectMediaNavigate";
+}
+
+void LLObjectMediaNavigateClient::enqueue(Request *request)
+{
+ if(request->isDead())
+ {
+ LL_DEBUGS("LLMediaDataClient") << "not queueing dead request " << *request << LL_ENDL;
+ return;
+ }
+
+ // If there's already a matching request in the queue, remove it.
+ request_queue_t::iterator iter = find_matching_request(mQueue, request);
+ if(iter != mQueue.end())
+ {
+ LL_DEBUGS("LLMediaDataClient") << "removing matching queued request " << (**iter) << LL_ENDL;
+ mQueue.erase(iter);
+ }
+ else
+ {
+ request_set_t::iterator set_iter = find_matching_request(mUnQueuedRequests, request);
+ if(set_iter != mUnQueuedRequests.end())
+ {
+ LL_DEBUGS("LLMediaDataClient") << "removing matching unqueued request " << (**set_iter) << LL_ENDL;
+ mUnQueuedRequests.erase(set_iter);
+ }
+ }
+
+#if 0
+ // Sadly, this doesn't work. It ends up creating a race condition when the user navigates and then hits the "back" button
+ // where the navigate-back appears to be spurious and doesn't get broadcast.
+ if(request->getObject()->isCurrentMediaUrl(request->getFace(), request->getURL()))
+ {
+ // This navigate request is trying to send the face to the current URL. Drop it.
+ LL_DEBUGS("LLMediaDataClient") << "dropping spurious request " << (*request) << LL_ENDL;
+ }
+ else
+#endif
+ {
+ LL_DEBUGS("LLMediaDataClient") << "queueing new request " << (*request) << LL_ENDL;
+ mQueue.push_back(request);
+
+ // Start the timer if not already running
+ startQueueTimer();
+ }
+}
+
+void LLObjectMediaNavigateClient::navigate(LLMediaDataClientObject *object, U8 texture_index, const std::string &url)
+{
+
+// LL_INFOS("LLMediaDataClient") << "navigate() initiated: " << ll_print_sd(sd_payload) << LL_ENDL;
+
+ // Create a get request and put it in the queue.
+ enqueue(new RequestNavigate(object, this, texture_index, url));
+}
+
+LLObjectMediaNavigateClient::RequestNavigate::RequestNavigate(LLMediaDataClientObject *obj, LLMediaDataClient *mdc, U8 texture_index, const std::string &url):
+ LLMediaDataClient::Request(LLMediaDataClient::Request::NAVIGATE, obj, mdc, (S32)texture_index),
+ mURL(url)
+{
+}
+
+LLSD LLObjectMediaNavigateClient::RequestNavigate::getPayload() const
+{
+ LLSD result;
+ result[LLTextureEntry::OBJECT_ID_KEY] = getID();
+ result[LLMediaEntry::CURRENT_URL_KEY] = mURL;
+ result[LLTextureEntry::TEXTURE_INDEX_KEY] = (LLSD::Integer)getFace();
+
+ return result;
+}
+
+LLMediaDataClient::Responder *LLObjectMediaNavigateClient::RequestNavigate::createResponder()
+{
+ return new LLObjectMediaNavigateClient::Responder(this);
+}
+
+/*virtual*/
+void LLObjectMediaNavigateClient::Responder::error(U32 status, const std::string& reason)
+{
+ getRequest()->stopTracking();
+
+ if(getRequest()->isDead())
+ {
+ LL_WARNS("LLMediaDataClient") << "dead request " << *(getRequest()) << LL_ENDL;
+ return;
+ }
+
+ // Bounce back (unless HTTP_SERVICE_UNAVAILABLE, in which case call base
+ // class
+ if (status == HTTP_SERVICE_UNAVAILABLE)
+ {
+ LLMediaDataClient::Responder::error(status, reason);
+ }
+ else
+ {
+ // bounce the face back
+ LL_WARNS("LLMediaDataClient") << *(getRequest()) << " Error navigating: http code=" << status << LL_ENDL;
+ const LLSD &payload = getRequest()->getPayload();
+ // bounce the face back
+ getRequest()->getObject()->mediaNavigateBounceBack((LLSD::Integer)payload[LLTextureEntry::TEXTURE_INDEX_KEY]);
+ }
+}
+
+/*virtual*/
+void LLObjectMediaNavigateClient::Responder::result(const LLSD& content)
+{
+ getRequest()->stopTracking();
+
+ if(getRequest()->isDead())
+ {
+ LL_WARNS("LLMediaDataClient") << "dead request " << *(getRequest()) << LL_ENDL;
+ return;
+ }
+
+ LL_INFOS("LLMediaDataClient") << *(getRequest()) << " NAVIGATE returned " << ll_print_sd(content) << LL_ENDL;
+
+ if (content.has("error"))
+ {
+ const LLSD &error = content["error"];
+ int error_code = error["code"];
+
+ if (ERROR_PERMISSION_DENIED_CODE == error_code)
+ {
+ LL_WARNS("LLMediaDataClient") << *(getRequest()) << " Navigation denied: bounce back" << LL_ENDL;
+ const LLSD &payload = getRequest()->getPayload();
+ // bounce the face back
+ getRequest()->getObject()->mediaNavigateBounceBack((LLSD::Integer)payload[LLTextureEntry::TEXTURE_INDEX_KEY]);
+ }
+ else
+ {
+ LL_WARNS("LLMediaDataClient") << *(getRequest()) << " Error navigating: code=" <<
+ error["code"].asString() << ": " << error["message"].asString() << LL_ENDL;
+ }
+
+ // XXX Warn user?
+ }
+ else
+ {
+ // No action required.
+ LL_DEBUGS("LLMediaDataClientResponse") << *(getRequest()) << " result : " << ll_print_sd(content) << LL_ENDL;
+ }
+}
diff --git a/indra/newview/llmediadataclient.h b/indra/newview/llmediadataclient.h
new file mode 100644
index 000000000..19ea5c6ce
--- /dev/null
+++ b/indra/newview/llmediadataclient.h
@@ -0,0 +1,416 @@
+/**
+ * @file llmediadataclient.h
+ * @brief class for queueing up requests to the media service
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLMEDIADATACLIENT_H
+#define LL_LLMEDIADATACLIENT_H
+
+#include "llhttpclient.h"
+#include
+#include "llrefcount.h"
+#include "llpointer.h"
+#include "lleventtimer.h"
+
+extern AIHTTPTimeoutPolicy mediaDataClientResponder_timeout;
+
+// Link seam for LLVOVolume
+class LLMediaDataClientObject : public LLRefCount
+{
+public:
+ // Get the number of media data items
+ virtual U8 getMediaDataCount() const = 0;
+ // Get the media data at index, as an LLSD
+ virtual LLSD getMediaDataLLSD(U8 index) const = 0;
+ // Return true if the current URL for the face in the media data matches the specified URL.
+ virtual bool isCurrentMediaUrl(U8 index, const std::string &url) const = 0;
+ // Get this object's UUID
+ virtual LLUUID getID() const = 0;
+ // Navigate back to previous URL
+ virtual void mediaNavigateBounceBack(U8 index) = 0;
+ // Does this object have media?
+ virtual bool hasMedia() const = 0;
+ // Update the object's media data to the given array
+ virtual void updateObjectMediaData(LLSD const &media_data_array, const std::string &version_string) = 0;
+ // Return the total "interest" of the media (on-screen area)
+ virtual F64 getMediaInterest() const = 0;
+ // Return the given cap url
+ virtual std::string getCapabilityUrl(const std::string &name) const = 0;
+ // Return whether the object has been marked dead
+ virtual bool isDead() const = 0;
+ // Returns a media version number for the object
+ virtual U32 getMediaVersion() const = 0;
+ // Returns whether the object is "interesting enough" to fetch
+ virtual bool isInterestingEnough() const = 0;
+ // Returns whether we've seen this object yet or not
+ virtual bool isNew() const = 0;
+
+ // smart pointer
+ typedef LLPointer ptr_t;
+};
+
+
+// This object creates a priority queue for requests.
+// Abstracts the Cap URL, the request, and the responder
+class LLMediaDataClient : public LLRefCount
+{
+public:
+ LOG_CLASS(LLMediaDataClient);
+
+ const static F32 QUEUE_TIMER_DELAY;// = 1.0; // seconds(s)
+ const static F32 UNAVAILABLE_RETRY_TIMER_DELAY;// = 5.0; // secs
+ const static U32 MAX_RETRIES;// = 4;
+ const static U32 MAX_SORTED_QUEUE_SIZE;// = 10000;
+ const static U32 MAX_ROUND_ROBIN_QUEUE_SIZE;// = 10000;
+
+ // Constructor
+ LLMediaDataClient(F32 queue_timer_delay = QUEUE_TIMER_DELAY,
+ F32 retry_timer_delay = UNAVAILABLE_RETRY_TIMER_DELAY,
+ U32 max_retries = MAX_RETRIES,
+ U32 max_sorted_queue_size = MAX_SORTED_QUEUE_SIZE,
+ U32 max_round_robin_queue_size = MAX_ROUND_ROBIN_QUEUE_SIZE);
+
+ F32 getRetryTimerDelay() const { return mRetryTimerDelay; }
+
+ // Returns true iff the queue is empty
+ virtual bool isEmpty() const;
+
+ // Returns true iff the given object is in the queue
+ virtual bool isInQueue(const LLMediaDataClientObject::ptr_t &object);
+
+ // Remove the given object from the queue. Returns true iff the given object is removed.
+ virtual void removeFromQueue(const LLMediaDataClientObject::ptr_t &object);
+
+ // Called only by the Queue timer and tests (potentially)
+ virtual bool processQueueTimer();
+
+protected:
+ // Destructor
+ virtual ~LLMediaDataClient(); // use unref
+
+ class Responder;
+
+ // Request (pure virtual base class for requests in the queue)
+ class Request : public LLRefCount
+ {
+ public:
+ // Subclasses must implement this to build a payload for their request type.
+ virtual LLSD getPayload() const = 0;
+ // and must create the correct type of responder.
+ virtual Responder *createResponder() = 0;
+
+ virtual std::string getURL() { return ""; }
+
+ enum Type {
+ GET,
+ UPDATE,
+ NAVIGATE,
+ ANY
+ };
+
+ protected:
+ // The only way to create one of these is through a subclass.
+ Request(Type in_type, LLMediaDataClientObject *obj, LLMediaDataClient *mdc, S32 face = -1);
+ public:
+ LLMediaDataClientObject *getObject() const { return mObject; }
+
+ U32 getNum() const { return mNum; }
+ U32 getRetryCount() const { return mRetryCount; }
+ void incRetryCount() { mRetryCount++; }
+ Type getType() const { return mType; }
+ F64 getScore() const { return mScore; }
+
+ // Note: may return empty string!
+ std::string getCapability() const;
+ const char *getCapName() const;
+ const char *getTypeAsString() const;
+
+ // Re-enqueue thyself
+ void reEnqueue();
+
+ F32 getRetryTimerDelay() const;
+ U32 getMaxNumRetries() const;
+
+ bool isObjectValid() const { return mObject.notNull() && (!mObject->isDead()); }
+ bool isNew() const { return isObjectValid() && mObject->isNew(); }
+ void updateScore();
+
+ void markDead();
+ bool isDead();
+ void startTracking();
+ void stopTracking();
+
+ friend std::ostream& operator<<(std::ostream &s, const Request &q);
+
+ const LLUUID &getID() const { return mObjectID; }
+ S32 getFace() const { return mFace; }
+
+ bool isMatch (const Request* other, Type match_type = ANY) const
+ {
+ return ((match_type == ANY) || (mType == other->mType)) &&
+ (mFace == other->mFace) &&
+ (mObjectID == other->mObjectID);
+ }
+ protected:
+ LLMediaDataClientObject::ptr_t mObject;
+ private:
+ Type mType;
+ // Simple tracking
+ U32 mNum;
+ static U32 sNum;
+ U32 mRetryCount;
+ F64 mScore;
+
+ LLUUID mObjectID;
+ S32 mFace;
+
+ // Back pointer to the MDC...not a ref!
+ LLMediaDataClient *mMDC;
+ };
+ typedef LLPointer request_ptr_t;
+
+ // Responder
+ class Responder : public LLHTTPClient::ResponderWithResult
+ {
+ public:
+
+ Responder(const request_ptr_t &request);
+ //If we get back an error (not found, etc...), handle it here
+ virtual void error(U32 status, const std::string& reason);
+ //If we get back a normal response, handle it here. Default just logs it.
+ virtual void result(const LLSD& content);
+ /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return mediaDataClientResponder_timeout; }
+ /*virtual*/ char const* getName(void) const { return "LLMediaDataClientResponder"; }
+
+ request_ptr_t &getRequest() { return mRequest; }
+
+ private:
+ request_ptr_t mRequest;
+ };
+
+ class RetryTimer : public LLEventTimer
+ {
+ public:
+ RetryTimer(F32 time, request_ptr_t);
+ virtual BOOL tick();
+ private:
+ // back-pointer
+ request_ptr_t mRequest;
+ };
+
+
+protected:
+ typedef std::list request_queue_t;
+ typedef std::set request_set_t;
+
+ // Subclasses must override to return a cap name
+ virtual const char *getCapabilityName() const = 0;
+
+ // Puts the request into a queue, appropriately handling duplicates, etc.
+ virtual void enqueue(Request*) = 0;
+
+ virtual void serviceQueue();
+
+ virtual request_queue_t *getQueue() { return &mQueue; };
+
+ // Gets the next request, removing it from the queue
+ virtual request_ptr_t dequeue();
+
+ virtual bool canServiceRequest(request_ptr_t request) { return true; };
+
+ // Returns a request to the head of the queue (should only be used for requests that came from dequeue
+ virtual void pushBack(request_ptr_t request);
+
+ void trackRequest(request_ptr_t request);
+ void stopTrackingRequest(request_ptr_t request);
+
+ request_queue_t mQueue;
+
+ const F32 mQueueTimerDelay;
+ const F32 mRetryTimerDelay;
+ const U32 mMaxNumRetries;
+ const U32 mMaxSortedQueueSize;
+ const U32 mMaxRoundRobinQueueSize;
+
+ // Set for keeping track of requests that aren't in either queue. This includes:
+ // Requests that have been sent and are awaiting a response (pointer held by the Responder)
+ // Requests that are waiting for their retry timers to fire (pointer held by the retry timer)
+ request_set_t mUnQueuedRequests;
+
+ void startQueueTimer();
+ void stopQueueTimer();
+
+private:
+
+ static F64 getObjectScore(const LLMediaDataClientObject::ptr_t &obj);
+
+ friend std::ostream& operator<<(std::ostream &s, const Request &q);
+ friend std::ostream& operator<<(std::ostream &s, const request_queue_t &q);
+
+ class QueueTimer : public LLEventTimer
+ {
+ public:
+ QueueTimer(F32 time, LLMediaDataClient *mdc);
+ virtual BOOL tick();
+ private:
+ // back-pointer
+ LLPointer mMDC;
+ };
+
+ void setIsRunning(bool val) { mQueueTimerIsRunning = val; }
+
+ bool mQueueTimerIsRunning;
+
+ template friend typename T::iterator find_matching_request(T &c, const LLMediaDataClient::Request *request, LLMediaDataClient::Request::Type match_type = LLMediaDataClient::Request::ANY);
+ template friend typename T::iterator find_matching_request(T &c, const LLUUID &id, LLMediaDataClient::Request::Type match_type = LLMediaDataClient::Request::ANY);
+ template friend void remove_matching_requests(T &c, const LLUUID &id, LLMediaDataClient::Request::Type match_type = LLMediaDataClient::Request::ANY);
+
+};
+
+// MediaDataClient specific for the ObjectMedia cap
+class LLObjectMediaDataClient : public LLMediaDataClient
+{
+public:
+ LOG_CLASS(LLObjectMediaDataClient);
+ LLObjectMediaDataClient(F32 queue_timer_delay = QUEUE_TIMER_DELAY,
+ F32 retry_timer_delay = UNAVAILABLE_RETRY_TIMER_DELAY,
+ U32 max_retries = MAX_RETRIES,
+ U32 max_sorted_queue_size = MAX_SORTED_QUEUE_SIZE,
+ U32 max_round_robin_queue_size = MAX_ROUND_ROBIN_QUEUE_SIZE)
+ : LLMediaDataClient(queue_timer_delay, retry_timer_delay, max_retries),
+ mCurrentQueueIsTheSortedQueue(true)
+ {}
+
+ void fetchMedia(LLMediaDataClientObject *object);
+ void updateMedia(LLMediaDataClientObject *object);
+
+ class RequestGet: public Request
+ {
+ public:
+ RequestGet(LLMediaDataClientObject *obj, LLMediaDataClient *mdc);
+ /*virtual*/ LLSD getPayload() const;
+ /*virtual*/ Responder *createResponder();
+ };
+
+ class RequestUpdate: public Request
+ {
+ public:
+ RequestUpdate(LLMediaDataClientObject *obj, LLMediaDataClient *mdc);
+ /*virtual*/ LLSD getPayload() const;
+ /*virtual*/ Responder *createResponder();
+ };
+
+ // Returns true iff the queue is empty
+ virtual bool isEmpty() const;
+
+ // Returns true iff the given object is in the queue
+ virtual bool isInQueue(const LLMediaDataClientObject::ptr_t &object);
+
+ // Remove the given object from the queue. Returns true iff the given object is removed.
+ virtual void removeFromQueue(const LLMediaDataClientObject::ptr_t &object);
+
+ virtual bool processQueueTimer();
+
+ virtual bool canServiceRequest(request_ptr_t request);
+
+protected:
+ // Subclasses must override to return a cap name
+ virtual const char *getCapabilityName() const;
+
+ virtual request_queue_t *getQueue();
+
+ // Puts the request into the appropriate queue
+ virtual void enqueue(Request*);
+
+ class Responder : public LLMediaDataClient::Responder
+ {
+ public:
+ Responder(const request_ptr_t &request)
+ : LLMediaDataClient::Responder(request) {}
+ virtual void result(const LLSD &content);
+ };
+private:
+ // The Get/Update data client needs a second queue to avoid object updates starving load-ins.
+ void swapCurrentQueue();
+
+ request_queue_t mRoundRobinQueue;
+ bool mCurrentQueueIsTheSortedQueue;
+
+ // Comparator for sorting
+ static bool compareRequestScores(const request_ptr_t &o1, const request_ptr_t &o2);
+ void sortQueue();
+};
+
+
+// MediaDataClient specific for the ObjectMediaNavigate cap
+class LLObjectMediaNavigateClient : public LLMediaDataClient
+{
+public:
+ LOG_CLASS(LLObjectMediaNavigateClient);
+ // NOTE: from llmediaservice.h
+ static const int ERROR_PERMISSION_DENIED_CODE = 8002;
+
+ LLObjectMediaNavigateClient(F32 queue_timer_delay = QUEUE_TIMER_DELAY,
+ F32 retry_timer_delay = UNAVAILABLE_RETRY_TIMER_DELAY,
+ U32 max_retries = MAX_RETRIES,
+ U32 max_sorted_queue_size = MAX_SORTED_QUEUE_SIZE,
+ U32 max_round_robin_queue_size = MAX_ROUND_ROBIN_QUEUE_SIZE)
+ : LLMediaDataClient(queue_timer_delay, retry_timer_delay, max_retries)
+ {}
+
+ void navigate(LLMediaDataClientObject *object, U8 texture_index, const std::string &url);
+
+ // Puts the request into the appropriate queue
+ virtual void enqueue(Request*);
+
+ class RequestNavigate: public Request
+ {
+ public:
+ RequestNavigate(LLMediaDataClientObject *obj, LLMediaDataClient *mdc, U8 texture_index, const std::string &url);
+ /*virtual*/ LLSD getPayload() const;
+ /*virtual*/ Responder *createResponder();
+ /*virtual*/ std::string getURL() { return mURL; }
+ private:
+ std::string mURL;
+ };
+
+protected:
+ // Subclasses must override to return a cap name
+ virtual const char *getCapabilityName() const;
+
+ class Responder : public LLMediaDataClient::Responder
+ {
+ public:
+ Responder(const request_ptr_t &request)
+ : LLMediaDataClient::Responder(request) {}
+ virtual void error(U32 status, const std::string& reason);
+ virtual void result(const LLSD &content);
+ private:
+ void mediaNavigateBounceBack();
+ };
+
+};
+
+
+#endif // LL_LLMEDIADATACLIENT_H
diff --git a/indra/newview/llmediaremotectrl.cpp b/indra/newview/llmediaremotectrl.cpp
index e5fa89e16..38ce628da 100644
--- a/indra/newview/llmediaremotectrl.cpp
+++ b/indra/newview/llmediaremotectrl.cpp
@@ -181,7 +181,7 @@ void LLMediaRemoteCtrl::enableMediaButtons()
std::string media_url = mControls->getString("default_tooltip_label");
LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
- if (gSavedSettings.getBOOL("AudioStreamingVideo"))
+ if (gSavedSettings.getBOOL("AudioStreamingMedia"))
{
if ( parcel && !parcel->getMediaURL().empty())
{
diff --git a/indra/newview/llpanelaudioprefs.cpp b/indra/newview/llpanelaudioprefs.cpp
index d58635c85..e61028fa8 100644
--- a/indra/newview/llpanelaudioprefs.cpp
+++ b/indra/newview/llpanelaudioprefs.cpp
@@ -111,7 +111,7 @@ void LLPanelAudioPrefs::refreshValues()
mPreviousHealthThreshold = gSavedSettings.getF32("UISndHealthReductionThreshold");
mPreviousStreamingMusic = gSavedSettings.getBOOL("AudioStreamingMusic");
- mPreviousStreamingVideo = gSavedSettings.getBOOL("AudioStreamingVideo");
+ mPreviousStreamingVideo = gSavedSettings.getBOOL("AudioStreamingMedia");
mPreviousMuteAudio = gSavedSettings.getBOOL("MuteAudio");
mPreviousMuteWhenMinimized = gSavedSettings.getBOOL("MuteWhenMinimized");
@@ -133,7 +133,7 @@ void LLPanelAudioPrefs::cancel()
gSavedSettings.setF32("UISndHealthReductionThreshold", mPreviousHealthThreshold );
gSavedSettings.setBOOL("AudioStreamingMusic", mPreviousStreamingMusic );
- gSavedSettings.setBOOL("AudioStreamingVideo", mPreviousStreamingVideo );
+ gSavedSettings.setBOOL("AudioStreamingMedia", mPreviousStreamingVideo );
gSavedSettings.setBOOL("MuteAudio", mPreviousMuteAudio );
diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp
index 524de0fb0..7374f8d05 100644
--- a/indra/newview/llpanelavatar.cpp
+++ b/indra/newview/llpanelavatar.cpp
@@ -567,7 +567,7 @@ BOOL LLPanelAvatarWeb::postBuild(void)
mWebBrowser->addObserver(this);
// links open in internally
- mWebBrowser->setOpenInExternalBrowser( false );
+ //mWebBrowser->setOpenInExternalBrowser( false );
return TRUE;
}
diff --git a/indra/newview/llpaneldirfind.cpp b/indra/newview/llpaneldirfind.cpp
index b380942f7..c181497cc 100644
--- a/indra/newview/llpaneldirfind.cpp
+++ b/indra/newview/llpaneldirfind.cpp
@@ -151,13 +151,9 @@ BOOL LLPanelDirFind::postBuild()
if (mWebBrowser)
{
mWebBrowser->addObserver(this);
-
- // new pages appear in same window as the results page now
- mWebBrowser->setOpenInInternalBrowser( false );
- mWebBrowser->setOpenInExternalBrowser( false );
// need to handle secondlife:///app/ URLs for direct teleports
- mWebBrowser->setTrusted( true );
+ mWebBrowser->setTrustedContent( true );
// redirect 404 pages from S3 somewhere else
mWebBrowser->set404RedirectUrl( getString("redirect_404_url") );
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 7f43b4ce3..2d7da3bc7 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -53,6 +53,8 @@
#include "llface.h"
#include "llinventorymodel.h" //Perms check for texture params
#include "lllineeditor.h"
+#include "llmediaentry.h"
+#include "llnotificationsutil.h"
#include "llresmgr.h"
#include "llselectmgr.h"
#include "llspinctrl.h"
@@ -66,8 +68,10 @@
#include "llviewerobject.h"
#include "llviewerregion.h"
#include "llviewerstats.h"
+#include "llvovolume.h"
#include "lluictrlfactory.h"
#include "llpluginclassmedia.h"
+#include "llviewertexturelist.h"
//
// Methods
@@ -549,20 +553,43 @@ void LLPanelFace::getState()
LLUUID id;
struct f1 : public LLSelectedTEGetFunctor
{
- LLUUID get(LLViewerObject* object, S32 te)
+ LLUUID get(LLViewerObject* object, S32 te_index)
{
+ LLUUID id;
//LLViewerTexture* image = object->getTEImage(te);
- LLTextureEntry* image = object->getTE(te); //Singu Note: Use this instead of the above.
- //The above actually returns LLViewerFetchedTexture::sDefaultImagep when
- //the texture id is null, which gives us IMG_DEFAULT, not LLUUID::null
- //Such behavior prevents the 'None' button from ever greying out in the face panel.
- return image ? image->getID() : LLUUID::null;
-
+ LLTextureEntry* image = object->getTE(te_index); //Singu Note: Use this instead of the above.
+ //The above actually returns LLViewerFetchedTexture::sDefaultImagep when
+ //the texture id is null, which gives us IMG_DEFAULT, not LLUUID::null
+ //Such behavior prevents the 'None' button from ever greying out in the face panel.
+ if (image) id = image->getID();
+ if (!id.isNull() && LLViewerMedia::textureHasMedia(id))
+ {
+ LLTextureEntry *te = object->getTE(te_index);
+ if (te)
+ {
+ LLViewerTexture* tex = te->getID().notNull() ? gTextureList.findImage(te->getID()) : NULL ;
+ if(!tex)
+ {
+ tex = LLViewerFetchedTexture::sDefaultImagep;
+ }
+ if (tex)
+ {
+ id = tex->getID();
+ }
+ }
+ }
+ return id;
}
} func;
identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, id );
+ if(LLViewerMedia::textureHasMedia(id))
+ {
+ getChildView("textbox autofix")->setEnabled(editable);
+ getChildView("button align")->setEnabled(editable);
+ }
+
if (identical)
{
// All selected have the same texture
@@ -593,13 +620,6 @@ void LLPanelFace::getState()
}
}
}
-
- if(LLViewerMedia::textureHasMedia(id))
- {
- childSetEnabled("textbox autofix",editable);
- childSetEnabled("button align",editable);
- }
-
}
@@ -1149,9 +1169,21 @@ struct LLPanelFaceSetMediaFunctor : public LLSelectedTEFunctor
{
virtual bool apply(LLViewerObject* object, S32 te)
{
- // TODO: the media impl pointer should actually be stored by the texture
- viewer_media_t pMediaImpl = LLViewerMedia::getMediaImplFromTextureID(object->getTE ( te )->getID());
- // only do this if it's a media texture
+ viewer_media_t pMediaImpl;
+
+ const LLTextureEntry* tep = object->getTE(te);
+ const LLMediaEntry* mep = tep->hasMedia() ? tep->getMediaData() : NULL;
+ if ( mep )
+ {
+ pMediaImpl = LLViewerMedia::getMediaImplFromTextureID(mep->getMediaID());
+ }
+
+ if ( pMediaImpl.isNull())
+ {
+ // If we didn't find face media for this face, check whether this face is showing parcel media.
+ pMediaImpl = LLViewerMedia::getMediaImplFromTextureID(tep->getID());
+ }
+
if ( pMediaImpl.notNull())
{
LLPluginClassMedia *media = pMediaImpl->getMediaPlugin();
@@ -1183,6 +1215,17 @@ void LLPanelFace::onClickAutoFix(void* userdata)
LLPanelFaceSendFunctor sendfunc;
LLSelectMgr::getInstance()->getSelection()->applyToObjects(&sendfunc);
}
+
+
+
+// TODO: I don't know who put these in or what these are for???
+void LLPanelFace::setMediaURL(const std::string& url)
+{
+}
+void LLPanelFace::setMediaType(const std::string& mime_type)
+{
+}
+
// static
void LLPanelFace::onCommitPlanarAlign(LLUICtrl* ctrl, void* userdata)
{
diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h
index 9363f076a..2f9a7887a 100644
--- a/indra/newview/llpanelface.h
+++ b/indra/newview/llpanelface.h
@@ -56,6 +56,8 @@ public:
virtual ~LLPanelFace();
void refresh();
+ void setMediaURL(const std::string& url);
+ void setMediaType(const std::string& mime_type);
protected:
void getState();
@@ -69,6 +71,7 @@ protected:
void sendShiny(); // applies and sends shininess
void sendFullbright(); // applies and sends full bright
void sendGlow();
+ void sendMedia();
// this function is to return TRUE if the dra should succeed.
static BOOL onDragTexture(LLUICtrl* ctrl, LLInventoryItem* item, void* ud);
diff --git a/indra/newview/llpanelgeneral.cpp b/indra/newview/llpanelgeneral.cpp
index bd67c5284..a044ac1a9 100644
--- a/indra/newview/llpanelgeneral.cpp
+++ b/indra/newview/llpanelgeneral.cpp
@@ -39,7 +39,6 @@
#include "llcolorswatch.h"
#include "llcombobox.h"
#include "lluictrlfactory.h"
-#include "llurlsimstring.h"
#include "llviewercontrol.h"
#include "llagent.h"
@@ -62,7 +61,11 @@ BOOL LLPanelGeneral::postBuild()
LLComboBox* namesystem_combobox = getChild("namesystem_combobox");
namesystem_combobox->setCurrentByIndex(gSavedSettings.getS32("PhoenixNameSystem"));
- childSetValue("default_start_location", gSavedSettings.getBOOL("LoginLastLocation") ? "MyLastLocation" : "MyHome");
+ std::string login_location = gSavedSettings.getString("LoginLocation");
+ if(login_location != "last" && login_location != "home")
+ login_location = "last";
+
+ childSetValue("default_start_location", login_location);
childSetValue("show_location_checkbox", gSavedSettings.getBOOL("ShowStartLocation"));
childSetValue("show_all_title_checkbox", gSavedSettings.getBOOL("RenderHideGroupTitleAll"));
childSetValue("language_is_public", gSavedSettings.getBOOL("LanguageIsPublic"));
@@ -148,7 +151,7 @@ void LLPanelGeneral::apply()
}
}
- gSavedSettings.setBOOL("LoginLastLocation", childGetValue("default_start_location").asString() == "MyLastLocation");
+ gSavedSettings.setString("LoginLocation", childGetValue("default_start_location").asString());
gSavedSettings.setBOOL("ShowStartLocation", childGetValue("show_location_checkbox"));
gSavedSettings.setBOOL("RenderHideGroupTitleAll", childGetValue("show_all_title_checkbox"));
gSavedSettings.setBOOL("LanguageIsPublic", childGetValue("language_is_public"));
@@ -165,8 +168,6 @@ void LLPanelGeneral::apply()
gSavedSettings.setBOOL("UIAutoScale", childGetValue("ui_auto_scale"));
gSavedSettings.setString("Language", childGetValue("language_combobox"));
- LLURLSimString::setString(childGetValue("location_combobox"));
-
LLComboBox* crash_behavior_combobox = getChild("crash_behavior_combobox");
gCrashSettings.setS32(CRASH_BEHAVIOR_SETTING, crash_behavior_combobox->getCurrentIndex());
}
diff --git a/indra/newview/llpanelgroup.h b/indra/newview/llpanelgroup.h
index cc063c8bb..f9ea38136 100644
--- a/indra/newview/llpanelgroup.h
+++ b/indra/newview/llpanelgroup.h
@@ -38,7 +38,7 @@
class LLOfferInfo;
-const F32 UPDATE_MEMBERS_SECONDS_PER_FRAME = 0.005; // 5ms
+const F32 UPDATE_MEMBERS_SECONDS_PER_FRAME = 0.005f; // 5ms
// Forward declares
class LLPanelGroupTab;
diff --git a/indra/newview/llpanellandmedia.cpp b/indra/newview/llpanellandmedia.cpp
index e49e849a0..07fc30553 100644
--- a/indra/newview/llpanellandmedia.cpp
+++ b/indra/newview/llpanellandmedia.cpp
@@ -92,6 +92,7 @@ BOOL LLPanelLandMedia::postBuild()
mMediaTextureCtrl->setCallbackUserData( this );
mMediaTextureCtrl->setAllowNoTexture ( TRUE );
mMediaTextureCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
+ mMediaTextureCtrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER);
mMediaTextureCtrl->setNonImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
mMediaAutoScaleCheck = getChild("media_auto_scale");
@@ -157,7 +158,7 @@ void LLPanelLandMedia::refresh()
std::string mime_type = parcel->getMediaType();
if (mime_type.empty())
{
- mime_type = "none/none";
+ mime_type = LLMIMETypes::getDefaultMimeType();
}
setMediaType(mime_type);
mMediaTypeCombo->setEnabled( can_change_media );
@@ -203,17 +204,17 @@ void LLPanelLandMedia::refresh()
mSetURLButton->setEnabled( can_change_media );
mResetURLButton->setEnabled( can_change_media );
- LLFloaterURLEntry* floater_url_entry = (LLFloaterURLEntry*)mURLEntryFloater.get();
+ /*LLFloaterURLEntry* floater_url_entry = (LLFloaterURLEntry*)mURLEntryFloater.get();
if (floater_url_entry)
{
floater_url_entry->updateFromLandMediaPanel();
- }
+ }*/
}
}
void LLPanelLandMedia::populateMIMECombo()
{
- std::string default_mime_type = "none/none";
+ std::string default_mime_type = LLMIMETypes::getDefaultMimeType();
std::string default_label;
LLMIMETypes::mime_widget_set_map_t::const_iterator it;
for (it = LLMIMETypes::sWidgetMap.begin(); it != LLMIMETypes::sWidgetMap.end(); ++it)
@@ -327,7 +328,7 @@ void LLPanelLandMedia::onCommitAny(LLUICtrl*, void *userdata)
void LLPanelLandMedia::onSetBtn(void *userdata)
{
LLPanelLandMedia *self = (LLPanelLandMedia *)userdata;
- self->mURLEntryFloater = LLFloaterURLEntry::show( self->getHandle() );
+ self->mURLEntryFloater = LLFloaterURLEntry::show( self->getHandle(), self->getMediaURL() );
LLFloater* parent_floater = gFloaterView->getParentFloater(self);
if (parent_floater)
{
diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index f2523b505..0dc6f669f 100644
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -45,6 +45,7 @@
#include "sgversion.h"
#include "v4color.h"
+#include "llappviewer.h"
#include "llbutton.h"
#include "llcheckboxctrl.h"
#include "llcommandhandler.h" // for secondlife:///app/login/
@@ -61,20 +62,17 @@
#include "llui.h"
#include "lluiconstants.h"
#include "llurlhistory.h" // OGPX : regionuri text box has a history of region uris (if FN/LN are loaded at startup)
-#include "llurlsimstring.h"
#include "llviewerbuild.h"
#include "llviewertexturelist.h"
#include "llviewermenu.h" // for handle_preferences()
#include "llviewernetwork.h"
#include "llviewerwindow.h" // to link into child list
#include "llnotify.h"
-#include "llurlsimstring.h"
#include "lluictrlfactory.h"
#include "llhttpclient.h"
#include "llweb.h"
#include "llmediactrl.h"
-#include "llfloatermediabrowser.h"
#include "llfloatertos.h"
#include "llglheaders.h"
@@ -84,7 +82,6 @@
// [/RLVa:KB]
//
-#include "llappviewer.h"
#include "llspinctrl.h"
#include "llviewermessage.h"
#include
@@ -93,8 +90,6 @@
#include "llstring.h"
#include
-#define USE_VIEWER_AUTH 0
-
class AIHTTPTimeoutPolicy;
extern AIHTTPTimeoutPolicy iamHereLogin_timeout;
@@ -113,7 +108,7 @@ static bool nameSplit(const std::string& full, std::string& first, std::string&
first = fragments[0];
if (fragments.size() == 1)
{
- if (gHippoGridManager->getConnectedGrid()->isAurora())
+ if (gHippoGridManager->getCurrentGrid()->isAurora())
last = "";
else
last = "Resident";
@@ -149,7 +144,7 @@ class LLLoginRefreshHandler : public LLCommandHandler
{
public:
// don't allow from external browsers
- LLLoginRefreshHandler() : LLCommandHandler("login_refresh", true) { }
+ LLLoginRefreshHandler() : LLCommandHandler("login_refresh", UNTRUSTED_BLOCK) { }
bool handle(const LLSD& tokens, const LLSD& query_map, LLMediaCtrl* web)
{
if (LLStartUp::getStartupState() < STATE_LOGIN_CLEANUP)
@@ -188,6 +183,8 @@ class LLIamHereLogin : public LLHTTPClient::ResponderHeadersOnly
{
if (mParent)
{
+ if(200 <= status && status < 300)
+ llinfos << "Found site" << llendl;
mParent->setSiteIsAlive(200 <= status && status < 300);
}
}
@@ -202,11 +199,6 @@ namespace {
boost::intrusive_ptr< LLIamHereLogin > gResponsePtr = 0;
};
-void set_start_location(LLUICtrl* ctrl, void* data)
-{
- LLURLSimString::setString(ctrl->getValue().asString());
-}
-
//---------------------------------------------------------------------------
// Public methods
//---------------------------------------------------------------------------
@@ -216,8 +208,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
: LLPanel(std::string("panel_login"), LLRect(0,600,800,0), FALSE), // not bordered
mLogoImage(),
mCallback(callback),
- mCallbackData(cb_data),
- mHtmlAvailable( TRUE )
+ mCallbackData(cb_data)
{
setFocusRoot(TRUE);
@@ -244,13 +235,8 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
LLUICtrlFactory::getInstance()->buildPanel(this, "panel_login.xml");
-#if USE_VIEWER_AUTH
- //leave room for the login menu bar
- setRect(LLRect(0, rect.getHeight()-18, rect.getWidth(), 0));
-#endif
reshape(rect.getWidth(), rect.getHeight());
-#if !USE_VIEWER_AUTH
LLComboBox* name_combo = sInstance->getChild("name_combo");
name_combo->setCommitCallback(onSelectLoginEntry);
name_combo->setFocusLostCallback(boost::bind(&LLPanelLogin::onLoginComboLostFocus, this, name_combo));
@@ -270,72 +256,48 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
sendChildToBack(getChildView("channel_text"));
sendChildToBack(getChildView("forgot_password_text"));
- //OGPX : This keeps the uris in a history file
- //OGPX TODO: should this be inside an OGP only check?
- LLComboBox* regioncombo = getChild("regionuri_edit");
- regioncombo->setAllowTextEntry(TRUE, 256, FALSE);
- std::string current_regionuri = gSavedSettings.getString("CmdLineRegionURI");
-
- // iterate on uri list adding to combobox (couldn't figure out how to add them all in one call)
- // ... and also append the command line value we might have gotten to the URLHistory
- LLSD regionuri_history = LLURLHistory::getURLHistory("regionuri");
- LLSD::array_iterator iter_history = regionuri_history.beginArray();
- LLSD::array_iterator iter_end = regionuri_history.endArray();
- for (; iter_history != iter_end; ++iter_history)
- {
- regioncombo->addSimpleElement((*iter_history).asString());
- }
-
- if ( LLURLHistory::appendToURLCollection("regionuri",current_regionuri))
- {
- // since we are in login, another read of urlhistory file is going to happen
- // so we need to persist the new value we just added (or maybe we should do it in startup.cpp?)
-
- // since URL history only populated on create of sInstance, add to combo list directly
- regioncombo->addSimpleElement(current_regionuri);
- }
-
- // select which is displayed if we have a current URL.
- regioncombo->setSelectedByValue(LLSD(current_regionuri),TRUE);
-
//llinfos << " url history: " << LLSDOStreamer(LLURLHistory::getURLHistory("regionuri")) << llendl;
- LLComboBox* combo = getChild("start_location_combo");
- combo->setAllowTextEntry(TRUE, 128, FALSE);
+ LLComboBox* location_combo = getChild("start_location_combo");
+ updateLocationSelectorsVisibility(); // separate so that it can be called from preferences
+ location_combo->setAllowTextEntry(TRUE, 128, FALSE);
+ location_combo->setFocusLostCallback( boost::bind(&LLPanelLogin::onLocationSLURL, this) );
+
+ LLComboBox *server_choice_combo = getChild("grids_combo");
+ server_choice_combo->setCommitCallback(boost::bind(&LLPanelLogin::onSelectGrid, _1));
+
+ // Load all of the grids, sorted, and then add a bar and the current grid at the top
+ updateGridCombo();
- // The XML file loads the combo with the following labels:
- // 0 - "My Home"
- // 1 - "My Last Location"
- // 2 - ""
-
- BOOL login_last = gSavedSettings.getBOOL("LoginLastLocation");
- std::string sim_string = LLURLSimString::sInstance.mSimString;
- if (!sim_string.empty())
+ LLSLURL start_slurl(LLStartUp::getStartSLURL());
+ if ( !start_slurl.isSpatial() ) // has a start been established by the command line or NextLoginLocation ?
{
- // Replace "" with this region name
- combo->remove(2);
- combo->add( sim_string );
- combo->setTextEntry(sim_string);
- combo->setCurrentByIndex( 2 );
- }
- else if (login_last)
- {
- combo->setCurrentByIndex( 1 );
+ // no, so get the preference setting
+ std::string defaultStartLocation = gSavedSettings.getString("LoginLocation");
+ LL_INFOS("AppInit")<<"default LoginLocation '"<setCurrentByIndex( 0 );
+ LLPanelLogin::onUpdateStartSLURL(start_slurl); // updates grid if needed
}
- combo->setCommitCallback( &set_start_location );
-
childSetAction("connect_btn", onClickConnect, this);
setDefaultBtn("connect_btn");
- // childSetAction("quit_btn", onClickQuit, this);
childSetAction("grids_btn", onClickGrids, this);
- childSetCommitCallback("grids_combo", onSelectGrid, this);
std::string channel = gVersionChannel;
@@ -355,38 +317,17 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
LLTextBox* create_new_account_text = getChild("create_new_account_text");
create_new_account_text->setClickedCallback(boost::bind(&onClickNewAccount));
-#endif
-
+
// get the web browser control
LLMediaCtrl* web_browser = getChild("login_html");
web_browser->addObserver(this);
-
- // Need to handle login secondlife:///app/ URLs
- web_browser->setTrusted( true );
-
- // don't make it a tab stop until SL-27594 is fixed
- web_browser->setTabStop(FALSE);
- // web_browser->navigateToLocalPage( "loading", "loading.html" );
-
- // make links open in external browser
- web_browser->setOpenInExternalBrowser( true );
+ web_browser->setBackgroundColor(LLColor4::black);
reshapeBrowser();
- updateGridCombo();
-
- childSetVisible("create_new_account_text",
- !gHippoGridManager->getConnectedGrid()->getRegisterUrl().empty());
- childSetVisible("forgot_password_text",
- !gHippoGridManager->getConnectedGrid()->getPasswordUrl().empty());
-
loadLoginPage();
-#if !USE_VIEWER_AUTH
- // Initialize visibility (and don't force visibility - use prefs)
- refreshLocation( false );
-#endif
-
+ refreshLoginPage();
}
void LLPanelLogin::setSiteIsAlive( bool alive )
@@ -400,33 +341,17 @@ void LLPanelLogin::setSiteIsAlive( bool alive )
loadLoginPage();
web_browser->setVisible(true);
-
- // mark as available
- mHtmlAvailable = TRUE;
}
}
else
// the site is not available (missing page, server down, other badness)
{
-#if !USE_VIEWER_AUTH
if ( web_browser )
{
// hide browser control (revealing default one)
web_browser->setVisible( FALSE );
-
- // mark as unavailable
- mHtmlAvailable = FALSE;
+ web_browser->navigateTo( "data:text/html,%3Chtml%3E%3Cbody%20bgcolor=%22#000000%22%3E%3C/body%3E%3C/html%3E", "text/html" );
}
-#else
-
- if ( web_browser )
- {
- web_browser->navigateToLocalPage( "loading-error" , "index.html" );
-
- // mark as available
- mHtmlAvailable = TRUE;
- }
-#endif
}
}
@@ -454,13 +379,8 @@ void LLPanelLogin::reshapeBrowser()
LLRect rect = gViewerWindow->getWindowRectScaled();
LLRect html_rect;
html_rect.setCenterAndSize(
-#if USE_VIEWER_AUTH
- rect.getCenterX() - 2, rect.getCenterY(),
- rect.getWidth() + 6, rect.getHeight());
-#else
- rect.getCenterX() - 2, rect.getCenterY() + 40,
- rect.getWidth() + 6, rect.getHeight() - 78 );
-#endif
+ rect.getCenterX() /*- 2*/, rect.getCenterY() + 40,
+ rect.getWidth() /*+ 6*/, rect.getHeight() - 78 );
web_browser->setRect( html_rect );
web_browser->reshape( html_rect.getWidth(), html_rect.getHeight(), TRUE );
reshape( rect.getWidth(), rect.getHeight(), 1 );
@@ -474,9 +394,6 @@ LLPanelLogin::~LLPanelLogin()
if ( gResponsePtr )
gResponsePtr->setParent( 0 );
- //// We know we're done with the image, so be rid of it.
- //gTextureList.deleteImage( mLogoImage );
-
if ( gFocusMgr.getDefaultKeyboardFocus() == this )
{
gFocusMgr.setDefaultKeyboardFocus(NULL);
@@ -518,14 +435,13 @@ void LLPanelLogin::draw()
S32 width = getRect().getWidth();
S32 height = getRect().getHeight();
- if ( mHtmlAvailable )
+ if ( getChild("login_html")->getVisible())
{
-#if !USE_VIEWER_AUTH
// draw a background box in black
- gl_rect_2d( 0, height - 264, width, 264, LLColor4( 0.0f, 0.0f, 0.0f, 1.f ) );
- // draw the bottom part of the background image - just the blue background to the native client UI
+ gl_rect_2d( 0, height - 264, width, 264, LLColor4::black );
+ // draw the bottom part of the background image
+ // just the blue background to the native client UI
mLogoImage->draw(0, -264, width + 8, mLogoImage->getHeight());
-#endif
}
else
{
@@ -560,12 +476,13 @@ BOOL LLPanelLogin::handleKeyHere(KEY key, MASK mask)
return TRUE;
}
- if ( KEY_F1 == key )
+ //Singu TODO: Re-implement f1 help.
+ /*if ( KEY_F1 == key )
{
llinfos << "Spawning HTML help window" << llendl;
gViewerHtmlHelp.show();
return TRUE;
- }
+ }*/
# if !LL_RELEASE_FOR_DOWNLOAD
if ( KEY_F2 == key )
@@ -605,12 +522,6 @@ void LLPanelLogin::setFocus(BOOL b)
// static
void LLPanelLogin::giveFocus()
{
-#if USE_VIEWER_AUTH
- if (sInstance)
- {
- sInstance->setFocus(TRUE);
- }
-#else
if( sInstance )
{
// Grab focus and move cursor to first blank input field
@@ -621,12 +532,9 @@ void LLPanelLogin::giveFocus()
BOOL have_pass = !pass.empty();
LLLineEditor* edit = NULL;
- LLUICtrl* combo = NULL;
- if (have_username)
+ LLComboBox* combo = NULL;
+ if (have_username && !have_pass)
{
- if(have_pass)
- combo = sInstance->getChild("connect_btn");
- else
// User saved his name but not his password. Move
// focus to password field.
edit = sInstance->getChild("password_edit");
@@ -647,7 +555,6 @@ void LLPanelLogin::giveFocus()
combo->setFocus(TRUE);
}
}
-#endif
}
@@ -770,7 +677,7 @@ void LLPanelLogin::getFields(std::string *firstname,
}
// static
-void LLPanelLogin::getLocation(std::string &location)
+/*void LLPanelLogin::getLocation(std::string &location)
{
if (!sInstance)
{
@@ -780,33 +687,14 @@ void LLPanelLogin::getLocation(std::string &location)
LLComboBox* combo = sInstance->getChild("start_location_combo");
location = combo->getValue().asString();
-}
+}*/
// static
-void LLPanelLogin::refreshLocation( bool force_visible )
+void LLPanelLogin::updateLocationSelectorsVisibility()
{
- if (!sInstance) return;
-
-#if USE_VIEWER_AUTH
- loadLoginPage();
-#else
- LLComboBox* combo = sInstance->getChild("start_location_combo");
-
- if (LLURLSimString::parse())
+ if (sInstance)
{
- combo->setCurrentByIndex( 3 ); // BUG? Maybe 2?
- combo->setTextEntry(LLURLSimString::sInstance.mSimString);
- }
- else
- {
- BOOL login_last = gSavedSettings.getBOOL("LoginLastLocation");
- combo->setCurrentByIndex( login_last ? 1 : 0 );
- }
-
- BOOL show_start = TRUE;
-
- if ( ! force_visible )
- show_start = gSavedSettings.getBOOL("ShowStartLocation");
+ BOOL show_start = gSavedSettings.getBOOL("ShowStartLocation");
// [RLVa:KB] - Alternate: Snowglobe-1.2.4 | Checked: 2009-07-08 (RLVa-1.0.0e)
// TODO-RLVa: figure out some way to make this work with RLV_EXTENSION_STARTLOCATION
@@ -818,11 +706,61 @@ void LLPanelLogin::refreshLocation( bool force_visible )
#endif // RLV_EXTENSION_STARTLOCATION
// [/RLVa:KB]
- sInstance->childSetVisible("start_location_combo", show_start); // maintain ShowStartLocation if legacy
- sInstance->childSetVisible("start_location_text", show_start);
- sInstance->childSetVisible("regionuri_edit",FALSE); // Do Not show regionuri box if legacy
+ sInstance->getChild("start_location_combo")->setVisible(show_start); // maintain ShowStartLocation if legacy
+ sInstance->getChild("start_location_text")->setVisible(show_start);
+
+ bool show_server = true;
+ sInstance->getChild("grids_combo")->setVisible(show_server);
+ sInstance->getChild("grids_text")->setVisible(show_server);
+ sInstance->getChild("grids_btn")->setVisible(show_server);
+ }
+
+}
-#endif
+// static
+void LLPanelLogin::onUpdateStartSLURL(const LLSLURL& new_start_slurl)
+{
+ if (!sInstance) return;
+
+ LL_DEBUGS("AppInit")<getChild("start_location_combo");
+ /*
+ * Determine whether or not the new_start_slurl modifies the grid.
+ *
+ * Note that some forms that could be in the slurl are grid-agnostic.,
+ * such as "home". Other forms, such as
+ * https://grid.example.com/region/Party%20Town/20/30/5
+ * specify a particular grid; in those cases we want to change the grid
+ * and the grid selector to match the new value.
+ */
+ enum LLSLURL::SLURL_TYPE new_slurl_type = new_start_slurl.getType();
+ switch ( new_slurl_type )
+ {
+ case LLSLURL::LOCATION:
+ {
+ location_combo->setCurrentByIndex( 2 );
+ location_combo->setTextEntry(new_start_slurl.getLocationString());
+ }
+ case LLSLURL::HOME_LOCATION:
+ location_combo->setCurrentByIndex( 0 ); // home location
+ break;
+ case LLSLURL::LAST_LOCATION:
+ location_combo->setCurrentByIndex( 1 ); // last location
+ break;
+ default:
+ LL_WARNS("AppInit")<<"invalid login slurl, using home"<setCurrentByIndex(1); // home location
+ break;
+ }
+
+ updateLocationSelectorsVisibility();
+}
+
+void LLPanelLogin::setLocation(const LLSLURL& slurl)
+{
+ LL_DEBUGS("AppInit")<<"setting Location "<getRootView()->removeChild( LLPanelLogin::sInstance );
-
- gFocusMgr.setDefaultKeyboardFocus(NULL);
+ LLPanelLogin::sInstance->getParent()->removeChild( LLPanelLogin::sInstance );
delete sInstance;
sInstance = NULL;
@@ -880,78 +816,47 @@ void LLPanelLogin::updateGridCombo()
}
}
-// static
-void LLPanelLogin::refreshLoginPage()
-{
- if (!sInstance || (LLStartUp::getStartupState() >= STATE_LOGIN_CLEANUP))
- return;
-
- sInstance->updateGridCombo();
-
- sInstance->childSetVisible("create_new_account_text",
- !gHippoGridManager->getConnectedGrid()->getRegisterUrl().empty());
- sInstance->childSetVisible("forgot_password_text",
- !gHippoGridManager->getConnectedGrid()->getPasswordUrl().empty());
-
- // kick off a request to grab the url manually
- gResponsePtr = LLIamHereLogin::build(sInstance);
-
- std::string login_page = gHippoGridManager->getConnectedGrid()->getLoginPage();
- if (!login_page.empty()) {
- LLHTTPClient::head(login_page, gResponsePtr.get());
- } else {
- sInstance->setSiteIsAlive(false);
- }
-}
-
void LLPanelLogin::loadLoginPage()
{
if (!sInstance) return;
- sInstance->updateGridCombo();
- std::ostringstream login_uri;
+ sInstance->updateGridCombo();
- std::string login_page = gHippoGridManager->getConnectedGrid()->getLoginPage();
- if (login_page.empty())
+ std::string login_page_str = gHippoGridManager->getCurrentGrid()->getLoginPage();
+ if (login_page_str.empty())
{
sInstance->setSiteIsAlive(false);
return;
}
-
- login_uri << login_page;
-
+
// Use the right delimeter depending on how LLURI parses the URL
- LLURI login_page_uri = LLURI(login_page);
- std::string first_query_delimiter = "&";
- if (login_page_uri.queryMap().size() == 0)
+ LLURI login_page = LLURI(login_page_str);
+ LLSD params(login_page.queryMap());
+
+ LL_DEBUGS("AppInit") << "login_page: " << login_page << LL_ENDL;
+
+ // Language
+ params["lang"] = LLUI::getLanguage();
+
+ // First Login?
+ if (gSavedSettings.getBOOL("FirstLoginThisInstall"))
{
- first_query_delimiter = "?";
- }
-
- // Language
- std::string language = LLUI::getLanguage();
- login_uri << first_query_delimiter<<"lang=" << language;
-
- // First Login?
- if (gSavedSettings.getBOOL("FirstLoginThisInstall"))
+ params["firstlogin"] = "TRUE"; // not bool: server expects string TRUE
+ }
+
+ if(login_page_str.find("secondlife.com") == -1)
{
- login_uri << "&firstlogin=TRUE";
- }
-
- std::string version = llformat("%d.%d.%d (%d)",
- gVersionMajor, gVersionMinor, gVersionPatch, gVersionBuild);
-
- if(login_page.find("secondlife.com") == -1) {
- login_uri << "&channel=" << LLWeb::curlEscape(gVersionChannel);
- login_uri << "&version=" << LLWeb::curlEscape(version);
+ params["version"]= llformat("%d.%d.%d (%d)",
+ gVersionMajor, gVersionMinor, gVersionPatch, gVersionBuild);
+ params["channel"] = gVersionChannel;
}
// Grid
- if (gHippoGridManager->getConnectedGrid()->isSecondLife()) {
+ if (gHippoGridManager->getCurrentGrid()->isSecondLife()) {
// find second life grid from login URI
// yes, this is heuristic, but hey, it is just to get the right login page...
- std::string tmp = gHippoGridManager->getConnectedGrid()->getLoginUri();
+ std::string tmp = gHippoGridManager->getCurrentGrid()->getLoginUri();
int i = tmp.find(".lindenlab.com");
if (i != std::string::npos) {
tmp = tmp.substr(0, i);
@@ -960,109 +865,35 @@ void LLPanelLogin::loadLoginPage()
i = tmp.rfind('/');
if (i != std::string::npos) {
tmp = tmp.substr(i+1);
- login_uri << "&grid=" << LLWeb::curlEscape(tmp);
+ params["grid"] = tmp;
}
}
}
- else if (gHippoGridManager->getConnectedGrid()->isOpenSimulator()){
- login_uri << "&grid=" << gHippoGridManager->getConnectedGrid()->getGridNick();
- }
- else if (gHippoGridManager->getConnectedGrid()->getPlatform() == HippoGridInfo::PLATFORM_AURORA)
+ else if (gHippoGridManager->getCurrentGrid()->isOpenSimulator())
{
- login_uri << "&grid=" << LLWeb::curlEscape(LLViewerLogin::getInstance()->getGridLabel());
+ params["grid"] = gHippoGridManager->getCurrentGrid()->getGridNick();
}
+ else if (gHippoGridManager->getCurrentGrid()->getPlatform() == HippoGridInfo::PLATFORM_AURORA)
+ {
+ params["grid"] = LLViewerLogin::getInstance()->getGridLabel();
+ }
+
+ // add OS info
+ params["os"] = LLAppViewer::instance()->getOSInfo().getOSStringSimple();
+ // Make an LLURI with this augmented info
+ LLURI login_uri(LLURI::buildHTTP(login_page.authority(),
+ login_page.path(),
+ params));
gViewerWindow->setMenuBackgroundColor(false, !LLViewerLogin::getInstance()->isInProductionGrid());
gLoginMenuBarView->setBackgroundColor(gMenuBarView->getBackgroundColor());
-
-#if USE_VIEWER_AUTH
- LLURLSimString::sInstance.parse();
-
- std::string location;
- std::string region;
- std::string password;
-
- if (LLURLSimString::parse())
- {
- std::ostringstream oRegionStr;
- location = "specify";
- oRegionStr << LLURLSimString::sInstance.mSimName << "/" << LLURLSimString::sInstance.mX << "/"
- << LLURLSimString::sInstance.mY << "/"
- << LLURLSimString::sInstance.mZ;
- region = oRegionStr.str();
- }
- else
- {
- if (gSavedSettings.getBOOL("LoginLastLocation"))
- {
- location = "last";
- }
- else
- {
- location = "home";
- }
- }
-
- std::string firstname, lastname;
-
- if(gSavedSettings.getLLSD("UserLoginInfo").size() == 3)
- {
- LLSD cmd_line_login = gSavedSettings.getLLSD("UserLoginInfo");
- firstname = cmd_line_login[0].asString();
- lastname = cmd_line_login[1].asString();
- password = cmd_line_login[2].asString();
- }
-
- if (firstname.empty())
- {
- firstname = gSavedSettings.getString("FirstName");
- }
-
- if (lastname.empty())
- {
- lastname = gSavedSettings.getString("LastName");
- }
-
- std::string curl_region = LLWeb::curlEscape(region);
-
- login_uri <<"firstname=" << firstname <<
- "&lastname=" << lastname << "&location=" << location << "®ion=" << curl_region;
-
- if (!password.empty())
- {
- login_uri << "&password=" << password;
- }
- else if (!(password = load_password_from_disk()).empty())
- {
- login_uri << "&password=$1$" << password;
- }
- if (gAutoLogin)
- {
- login_uri << "&auto_login=TRUE";
- }
- if (gSavedSettings.getBOOL("ShowStartLocation"))
- {
- login_uri << "&show_start_location=TRUE";
- }
- if (gSavedSettings.getBOOL("RememberPassword"))
- {
- login_uri << "&remember_password=TRUE";
- }
- BOOL show_server = sInstance ? sInstance->mShowServerCombo : FALSE;
- if (show_server || gSavedSettings.getBOOL("ForceShowGrid"))
- {
- login_uri << "&show_grid=TRUE";
- }
-#endif
-
LLMediaCtrl* web_browser = sInstance->getChild("login_html");
-
- if (web_browser->getCurrentNavUrl() != login_uri.str())
+ if (web_browser->getCurrentNavUrl() != login_uri.asString())
{
LL_DEBUGS("AppInit") << "loading: " << login_uri << LL_ENDL;
- web_browser->navigateTo( login_uri.str(), "text/html" );
+ web_browser->navigateTo( login_uri.asString(), "text/html" );
}
}
@@ -1116,7 +947,7 @@ void LLPanelLogin::onClickConnect(void *)
}
else
{
- if (gHippoGridManager->getConnectedGrid()->getRegisterUrl().empty()) {
+ if (gHippoGridManager->getCurrentGrid()->getRegisterUrl().empty()) {
LLNotificationsUtil::add("MustHaveAccountToLogInNoLinks");
} else {
LLNotificationsUtil::add("MustHaveAccountToLogIn", LLSD(), LLSD(),
@@ -1147,7 +978,7 @@ bool LLPanelLogin::newAccountAlertCallback(const LLSD& notification, const LLSD&
// static
void LLPanelLogin::onClickNewAccount()
{
- const std::string &url = gHippoGridManager->getConnectedGrid()->getRegisterUrl();
+ const std::string &url = gHippoGridManager->getCurrentGrid()->getRegisterUrl();
if (!url.empty()) {
llinfos << "Going to account creation URL." << llendl;
LLWeb::loadURLExternal(url);
@@ -1165,29 +996,6 @@ void LLPanelLogin::onClickGrids(void*)
LLFloaterPreference::switchTab(LLPreferenceCore::TAB_GRIDS);
}
-// static
-void LLPanelLogin::onSelectGrid(LLUICtrl *ctrl, void*)
-{
- gHippoGridManager->setCurrentGrid(ctrl->getValue());
- LLPanelLogin::refreshLoginPage();
-}
-
-// *NOTE: This function is dead as of 2008 August. I left it here in case
-// we suddenly decide to put the Quit button back. JC
-// static
-void LLPanelLogin::onClickQuit(void*)
-{
- if (sInstance && sInstance->mCallback)
- {
- // tell the responder we're not here anymore
- if ( gResponsePtr )
- gResponsePtr->setParent( 0 );
-
- sInstance->mCallback(1, sInstance->mCallbackData);
- }
-}
-
-
// static
void LLPanelLogin::onClickVersion(void*)
{
@@ -1199,7 +1007,7 @@ void LLPanelLogin::onClickForgotPassword()
{
if (sInstance )
{
- const std::string &url = gHippoGridManager->getConnectedGrid()->getPasswordUrl();
+ const std::string &url = gHippoGridManager->getCurrentGrid()->getPasswordUrl();
if (!url.empty()) {
LLWeb::loadURLExternal(url);
} else {
@@ -1218,6 +1026,63 @@ void LLPanelLogin::onPassKey(LLLineEditor* caller)
}
}
+// static
+//void LLPanelLogin::updateServer()
+void LLPanelLogin::refreshLoginPage()
+{
+ if (!sInstance || (LLStartUp::getStartupState() >= STATE_LOGIN_CLEANUP))
+ return;
+
+ sInstance->updateGridCombo();
+
+ sInstance->childSetVisible("create_new_account_text",
+ !gHippoGridManager->getCurrentGrid()->getRegisterUrl().empty());
+ sInstance->childSetVisible("forgot_password_text",
+ !gHippoGridManager->getCurrentGrid()->getPasswordUrl().empty());
+
+ std::string login_page = gHippoGridManager->getCurrentGrid()->getLoginPage();
+ if (!login_page.empty())
+ {
+ LLMediaCtrl* web_browser = sInstance->getChild("login_html");
+ if (web_browser->getCurrentNavUrl() != login_page)
+ {
+ if(gResponsePtr)
+ gResponsePtr->setParent(0); //Tell our previous responder that we no longer require its result.
+ gResponsePtr.reset(); //Deref previous responder
+
+ llinfos << "Firing off lookup for " << login_page << llendl;
+ // kick off a request to grab the url manually
+ gResponsePtr = LLIamHereLogin::build(sInstance);
+ LLHTTPClient::head(login_page, gResponsePtr.get());
+ }
+ }
+ else
+ {
+ if(gResponsePtr)
+ gResponsePtr->setParent(0); //Tell our previous responder that we no longer require its result.
+ gResponsePtr.reset(); //Deref previous responder
+ sInstance->setSiteIsAlive(false);
+ }
+}
+
+// static
+//void LLPanelLogin::onSelectServer()
+void LLPanelLogin::onSelectGrid(LLUICtrl *ctrl)
+{
+ gHippoGridManager->setCurrentGrid(ctrl->getValue());
+ LLPanelLogin::refreshLoginPage();
+}
+
+void LLPanelLogin::onLocationSLURL()
+{
+ LLComboBox* location_combo = getChild("start_location_combo");
+ std::string location = location_combo->getValue().asString();
+ LL_DEBUGS("AppInit")<
#include "llmediactrl.h" // LLMediaCtrlObserver
#include "llsavedlogins.h"
+#include "llslurl.h"
class LLUIImage;
class LLComboBox;
@@ -78,14 +79,12 @@ public:
*/
static void setFields(const LLSavedLoginEntry& entry, bool takeFocus = false);
- //static void addServer(const std::string& server, S32 domain_name);
- static void refreshLocation( bool force_visible );
+ static void getFields(std::string *firstname, std::string *lastname, std::string *password);
- static void getFields(std::string *firstname, std::string *lastname,
- std::string *password);
-
- //static BOOL isGridComboDirty();
- static void getLocation(std::string &location);
+ static void setLocation(const LLSLURL& slurl);
+
+ /// Call when preferences that control visibility may have changed
+ static void updateLocationSelectorsVisibility();
static void close();
@@ -102,19 +101,21 @@ public:
// inherited from LLViewerMediaObserver
/*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event);
+ /// to be called from LLStartUp::setStartSLURL
+ static void onUpdateStartSLURL(const LLSLURL& new_start_slurl);
+
private:
void reshapeBrowser();
+ void onLocationSLURL();
+
static void onClickConnect(void*);
static void onClickNewAccount();
static bool newAccountAlertCallback(const LLSD& notification, const LLSD& response);
static void onClickGrids(void*);
- static void onSelectGrid(LLUICtrl *ctrl, void*);
- static void onClickQuit(void*);
+ static void onSelectGrid(LLUICtrl *ctrl);
static void onClickVersion(void*);
static void onClickForgotPassword();
static void onPassKey(LLLineEditor* caller);
- //static void onSelectServer(LLUICtrl*, void*);
- //static void onServerComboLostFocus(LLFocusableElement*, void*);
static void onSelectLoginEntry(LLUICtrl*, void*);
void onLoginComboLostFocus(LLComboBox* combo_box);
static void onNameCheckChanged(LLUICtrl* ctrl, void* data);
@@ -154,7 +155,6 @@ private:
static LLPanelLogin* sInstance;
static BOOL sCapslockDidNotification;
- BOOL mHtmlAvailable;
LLSavedLogins mLoginHistoryData;
};
diff --git a/indra/newview/llpanelmediahud.cpp b/indra/newview/llpanelmediahud.cpp
deleted file mode 100644
index ad47eb732..000000000
--- a/indra/newview/llpanelmediahud.cpp
+++ /dev/null
@@ -1,664 +0,0 @@
-/**
- * @file llpanelmsgs.cpp
- * @brief Message popup preferences panel
- *
- * $LicenseInfo:firstyear=2003&license=viewergpl$
- *
- * Copyright (c) 2003-2009, Linden Research, Inc.
- *
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- *
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- *
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- *
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-//LLPanelMediaHUD
-#include "llagent.h"
-#include "llagentcamera.h"
-#include "llparcel.h"
-#include "llpanel.h"
-#include "llselectmgr.h"
-#include "llrender.h"
-#include "lldrawable.h"
-#include "llviewerwindow.h"
-#include "llwindow.h"
-#include "lluictrlfactory.h"
-#include "llbutton.h"
-#include "llface.h"
-#include "llhudview.h"
-#include "lliconctrl.h"
-#include "lltoolpie.h"
-#include "llviewercamera.h"
-#include "llpanelmediahud.h"
-#include "llpluginclassmedia.h"
-#include "llviewercontrol.h"
-#include "llviewerparcelmgr.h"
-#include "llviewermedia.h"
-#include "llviewermediafocus.h"
-#include "llvovolume.h"
-#include "llweb.h"
-
-glh::matrix4f glh_get_current_modelview();
-glh::matrix4f glh_get_current_projection();
-
-const F32 ZOOM_NEAR_PADDING = 1.0f;
-const F32 ZOOM_MEDIUM_PADDING = 1.2f;
-const F32 ZOOM_FAR_PADDING = 1.5f;
-
-//
-// LLPanelMediaHUD
-//
-
-LLPanelMediaHUD::LLPanelMediaHUD(viewer_media_t media_impl)
- : mMediaImpl(media_impl)
-{
- mMediaFocus = false;
- LLUICtrlFactory::getInstance()->buildPanel(this, "panel_media_hud.xml");
- mMouseMoveTimer.reset();
- mFadeTimer.stop();
- mCurrentZoom = ZOOM_NONE;
- mScrollState = SCROLL_NONE;
-}
-LLPanelMediaHUD::~LLPanelMediaHUD()
-{
- mMediaImpl = NULL;
-}
-
-BOOL LLPanelMediaHUD::postBuild()
-{
- LLButton* close_btn = getChild("close");
- close_btn->setClickedCallback(onClickClose, this);
-
- LLButton* back_btn = getChild("back");
- back_btn->setClickedCallback(onClickBack, this);
-
- LLButton* fwd_btn = getChild("fwd");
- fwd_btn->setClickedCallback(onClickForward, this);
-
- LLButton* home_btn = getChild("home");
- home_btn->setClickedCallback(onClickHome, this);
-
- LLButton* stop_btn = getChild("stop");
- stop_btn->setClickedCallback(onClickStop, this);
-
- LLButton* media_stop_btn = getChild("media_stop");
- media_stop_btn->setClickedCallback(onClickStop, this);
-
- LLButton* reload_btn = getChild("reload");
- reload_btn->setClickedCallback(onClickReload, this);
-
- LLButton* play_btn = getChild("play");
- play_btn->setClickedCallback(onClickPlay, this);
-
- LLButton* pause_btn = getChild("pause");
- pause_btn->setClickedCallback(onClickPause, this);
-
- LLButton* open_btn = getChild("new_window");
- open_btn->setClickedCallback(onClickOpen, this);
-
- LLButton* zoom_btn = getChild("zoom_frame");
- zoom_btn->setClickedCallback(onClickZoom, this);
-
- LLButton* open_btn_h = getChild("new_window_hover");
- open_btn_h->setClickedCallback(onClickOpen, this);
-
- LLButton* zoom_btn_h = getChild("zoom_frame_hover");
- zoom_btn_h->setClickedCallback(onClickZoom, this);
-
- LLButton* scroll_up_btn = getChild("scrollup");
- scroll_up_btn->setClickedCallback(onScrollUp, this);
- scroll_up_btn->setHeldDownCallback(onScrollUpHeld, this);
- scroll_up_btn->setMouseUpCallback(onScrollStop, this);
- LLButton* scroll_left_btn = getChild("scrollleft");
- scroll_left_btn->setClickedCallback(onScrollLeft, this);
- scroll_left_btn->setHeldDownCallback(onScrollLeftHeld, this);
- scroll_left_btn->setMouseUpCallback(onScrollStop, this);
- LLButton* scroll_right_btn = getChild("scrollright");
- scroll_right_btn->setClickedCallback(onScrollRight, this);
- scroll_right_btn->setHeldDownCallback(onScrollLeftHeld, this);
- scroll_right_btn->setMouseUpCallback(onScrollStop, this);
- LLButton* scroll_down_btn = getChild("scrolldown");
- scroll_down_btn->setClickedCallback(onScrollDown, this);
- scroll_down_btn->setHeldDownCallback(onScrollDownHeld, this);
- scroll_down_btn->setMouseUpCallback(onScrollStop, this);
-
- mMouseInactiveTime = gSavedSettings.getF32("MediaControlTimeout");
- mControlFadeTime = gSavedSettings.getF32("MediaControlFadeTime");
-
- mCurrentZoom = ZOOM_NONE;
- // clicks on HUD buttons do not remove keyboard focus from media
- setIsChrome(TRUE);
- return TRUE;
-}
-
-void LLPanelMediaHUD::updateShape()
-{
- const S32 MIN_HUD_WIDTH=200;
- const S32 MIN_HUD_HEIGHT=120;
-
- LLPluginClassMedia* media_plugin = NULL;
- if(mMediaImpl.notNull() && mMediaImpl->hasMedia())
- {
- media_plugin = mMediaImpl->getMediaPlugin();
- }
-
- // Early out for no media plugin
- if(media_plugin == NULL)
- {
- setVisible(FALSE);
- return;
- }
-
- LLParcel *parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
-
- bool can_navigate = parcel->getMediaAllowNavigate();
-
- // LLObjectSelectionHandle selection = LLViewerMediaFocus::getInstance()->getSelection();
-
- LLSelectNode* nodep = mMediaFocus ? LLSelectMgr::getInstance()->getSelection()->getFirstNode() : LLSelectMgr::getInstance()->getHoverNode();
- if(! nodep)
- {
- return;
- }
- setVisible(FALSE);
- LLViewerObject* objectp = nodep->getObject();
-
- if (objectp)
- {
-
- // Set the state of the buttons
- LLButton* back_btn = getChild("back");
- LLButton* fwd_btn = getChild("fwd");
- LLButton* reload_btn = getChild("reload");
- LLButton* play_btn = getChild("play");
- LLButton* pause_btn = getChild("pause");
- LLButton* stop_btn = getChild("stop");
- LLButton* media_stop_btn = getChild("media_stop");
- LLButton* home_btn = getChild("home");
- LLButton* close_btn = getChild("close");
- LLButton* open_btn = getChild("new_window");
- LLPanel* media_focused_panel = getChild("media_focused_controls");
- LLPanel* media_hover_panel = getChild("media_hover_controls");
- back_btn->setVisible(true);
- fwd_btn->setVisible(true);
- reload_btn->setVisible(true);
- stop_btn->setVisible(false);
- home_btn->setVisible(true);
- close_btn->setVisible(true);
- open_btn->setVisible(true);
-
-
- if(mMediaFocus)
- {
- back_btn->setEnabled(mMediaImpl->canNavigateBack() && can_navigate);
- fwd_btn->setEnabled(mMediaImpl->canNavigateForward() && can_navigate);
- stop_btn->setEnabled(can_navigate);
- home_btn->setEnabled(can_navigate);
- LLPluginClassMediaOwner::EMediaStatus result = media_plugin->getStatus();
-
- if(media_plugin->pluginSupportsMediaTime())
- {
- reload_btn->setEnabled(FALSE);
- reload_btn->setVisible(FALSE);
- media_stop_btn->setVisible(TRUE);
- home_btn->setVisible(FALSE);
- back_btn->setEnabled(TRUE);
- fwd_btn->setEnabled(TRUE);
- switch(result)
- {
- case LLPluginClassMediaOwner::MEDIA_PLAYING:
- play_btn->setEnabled(FALSE);
- play_btn->setVisible(FALSE);
- pause_btn->setEnabled(TRUE);
- pause_btn->setVisible(TRUE);
- media_stop_btn->setEnabled(TRUE);
- break;
- case LLPluginClassMediaOwner::MEDIA_PAUSED:
- default:
- pause_btn->setEnabled(FALSE);
- pause_btn->setVisible(FALSE);
- play_btn->setEnabled(TRUE);
- play_btn->setVisible(TRUE);
- media_stop_btn->setEnabled(FALSE);
- break;
- }
- }
- else
- {
- play_btn->setVisible(FALSE);
- pause_btn->setVisible(FALSE);
- media_stop_btn->setVisible(FALSE);
- if(result == LLPluginClassMediaOwner::MEDIA_LOADING)
- {
- reload_btn->setEnabled(FALSE);
- reload_btn->setVisible(FALSE);
- stop_btn->setEnabled(TRUE);
- stop_btn->setVisible(TRUE);
- }
- else
- {
- reload_btn->setEnabled(TRUE);
- reload_btn->setVisible(TRUE);
- stop_btn->setEnabled(FALSE);
- stop_btn->setVisible(FALSE);
- }
- }
- }
- media_focused_panel->setVisible(mMediaFocus);
- media_hover_panel->setVisible(!mMediaFocus);
-
- if(media_plugin == NULL)
- // Handle Scrolling
- switch (mScrollState)
- {
- case SCROLL_UP:
- media_plugin->scrollEvent(0, -1, MASK_NONE);
- break;
- case SCROLL_DOWN:
- media_plugin->scrollEvent(0, 1, MASK_NONE);
- break;
- case SCROLL_LEFT:
- mMediaImpl->handleKeyHere(KEY_LEFT, MASK_NONE);
- break;
- case SCROLL_RIGHT:
- mMediaImpl->handleKeyHere(KEY_RIGHT, MASK_NONE);
- break;
- case SCROLL_NONE:
- default:
- break;
- }
- LLBBox screen_bbox;
- setVisible(TRUE);
- glh::matrix4f mat = glh_get_current_projection()*glh_get_current_modelview();
- std::vector::iterator vert_it;
- std::vector::iterator vert_end;
- std::vector vect_face;
-
- LLVolume* volume = objectp->getVolume();
-
- if (volume)
- {
- const LLVolumeFace& vf = volume->getVolumeFace(nodep->getLastSelectedTE());
-
- const LLVector3* ext = (LLVector3*)vf.mExtents->getF32ptr();
-
- LLVector3 center = (ext[0]+ext[1])*0.5f;
- LLVector3 size = (ext[1]-ext[0])*0.5f;
- LLVector3 vert[] =
- {
- center + size.scaledVec(LLVector3(1,1,1)),
- center + size.scaledVec(LLVector3(-1,1,1)),
- center + size.scaledVec(LLVector3(1,-1,1)),
- center + size.scaledVec(LLVector3(-1,-1,1)),
- center + size.scaledVec(LLVector3(1,1,-1)),
- center + size.scaledVec(LLVector3(-1,1,-1)),
- center + size.scaledVec(LLVector3(1,-1,-1)),
- center + size.scaledVec(LLVector3(-1,-1,-1)),
- };
-
- LLVOVolume* vo = (LLVOVolume*) objectp;
-
- for (U32 i = 0; i < 8; i++)
- {
- vect_face.push_back(vo->volumePositionToAgent(vert[i]));
- }
- }
- vert_it = vect_face.begin();
- vert_end = vect_face.end();
-
- LLVector3 min = LLVector3(1,1,1);
- LLVector3 max = LLVector3(-1,-1,-1);
- for(; vert_it != vert_end; ++vert_it)
- {
- // project silhouette vertices into screen space
- glh::vec3f screen_vert = glh::vec3f(vert_it->mV);
- mat.mult_matrix_vec(screen_vert);
-
- // add to screenspace bounding box
- update_min_max(min, max, LLVector3(screen_vert.v));
- }
-
- LLCoordGL screen_min;
- screen_min.mX = llround((F32)gViewerWindow->getWindowWidth() * (min.mV[VX] + 1.f) * 0.5f);
- screen_min.mY = llround((F32)gViewerWindow->getWindowHeight() * (min.mV[VY] + 1.f) * 0.5f);
-
- LLCoordGL screen_max;
- screen_max.mX = llround((F32)gViewerWindow->getWindowWidth() * (max.mV[VX] + 1.f) * 0.5f);
- screen_max.mY = llround((F32)gViewerWindow->getWindowHeight() * (max.mV[VY] + 1.f) * 0.5f);
-
- // grow panel so that screenspace bounding box fits inside "media_region" element of HUD
- LLRect media_hud_rect;
- getParent()->screenRectToLocal(LLRect(screen_min.mX, screen_max.mY, screen_max.mX, screen_min.mY), &media_hud_rect);
- LLView* media_region = getChild("media_region");
- media_hud_rect.mLeft -= media_region->getRect().mLeft;
- media_hud_rect.mBottom -= media_region->getRect().mBottom;
- media_hud_rect.mTop += getRect().getHeight() - media_region->getRect().mTop;
- media_hud_rect.mRight += getRect().getWidth() - media_region->getRect().mRight;
-
- // keep all parts of HUD on-screen
- media_hud_rect.intersectWith(getParent()->getLocalRect());
-
- // If we had to clip the rect, don't display the border
- childSetVisible("bg_image", false);
-
- // clamp to minimum size, keeping centered
- media_hud_rect.setCenterAndSize(media_hud_rect.getCenterX(), media_hud_rect.getCenterY(),
- llmax(MIN_HUD_WIDTH, media_hud_rect.getWidth()), llmax(MIN_HUD_HEIGHT, media_hud_rect.getHeight()));
-
- setShape(media_hud_rect);
-
- // Test mouse position to see if the cursor is stationary
- LLCoordWindow cursor_pos_window;
- getWindow()->getCursorPosition(&cursor_pos_window);
-
- // If last pos is not equal to current pos, the mouse has moved
- // We need to reset the timer, and make sure the panel is visible
- if(cursor_pos_window.mX != mLastCursorPos.mX ||
- cursor_pos_window.mY != mLastCursorPos.mY ||
- mScrollState != SCROLL_NONE)
- {
- mMouseMoveTimer.start();
- mLastCursorPos = cursor_pos_window;
- }
-
- // Mouse has been stationary, but not for long enough to fade the UI
- if(mMouseMoveTimer.getElapsedTimeF32() < mMouseInactiveTime)
- {
- // If we have started fading, reset the alpha values
- if(mFadeTimer.getStarted())
- {
- F32 alpha = 1.0f;
- setAlpha(alpha);
- mFadeTimer.stop();
- }
- }
- // If we need to start fading the UI (and we have not already started)
- else if (!mFadeTimer.getStarted())
- {
- mFadeTimer.start();
- }
- }
-}
-/*virtual*/
-void LLPanelMediaHUD::draw()
-{
- if(mFadeTimer.getStarted())
- {
- if(mFadeTimer.getElapsedTimeF32() >= mControlFadeTime)
- {
- setVisible(FALSE);
- }
- else
- {
- F32 time = mFadeTimer.getElapsedTimeF32();
- F32 alpha = llmax(lerp(1.0, 0.0, time / mControlFadeTime), 0.0f);
- setAlpha(alpha);
- }
- }
- LLPanel::draw();
-}
-void LLPanelMediaHUD::setAlpha(F32 alpha)
-{
- LLViewQuery query;
-
- LLView* query_view = mMediaFocus ? getChildView("media_focused_controls") : getChildView("media_hover_controls");
- viewList_t children = query(query_view);
- for (viewList_t::iterator child_iter = children.begin();
- child_iter != children.end(); ++child_iter)
- {
- LLUICtrl* ctrl = dynamic_cast(*child_iter);
- if (ctrl)
- ctrl->setAlpha(alpha);
- }
-
- LLPanel::setAlpha(alpha);
-}
-BOOL LLPanelMediaHUD::handleScrollWheel(S32 x, S32 y, S32 clicks)
-{
- return LLViewerMediaFocus::getInstance()->handleScrollWheel(x, y, clicks);
-}
-bool LLPanelMediaHUD::isMouseOver()
-{
- if( ! getVisible() )
- {
- return false;
- }
- LLRect screen_rect;
- LLCoordWindow cursor_pos_window;
- getWindow()->getCursorPosition(&cursor_pos_window);
-
- localRectToScreen(getLocalRect(), &screen_rect);
- // screenPointToLocal(cursor_pos_gl.mX, cursor_pos_gl.mY, &local_mouse_x, &local_mouse_y);
-
- if(screen_rect.pointInRect(cursor_pos_window.mX, cursor_pos_window.mY))
- {
- return true;
- }
- return false;
-}
-
-//static
-void LLPanelMediaHUD::onClickClose(void* user_data)
-{
- LLViewerMediaFocus::getInstance()->setFocusFace(FALSE, NULL, 0, NULL);
- LLPanelMediaHUD* this_panel = static_cast (user_data);
- if(this_panel->mCurrentZoom != ZOOM_NONE)
- {
- // gAgentCamera.setFocusOnAvatar(TRUE, ANIMATE);
- this_panel->mCurrentZoom = ZOOM_NONE;
- }
- this_panel->setVisible(FALSE);
-
-}
-
-//static
-void LLPanelMediaHUD::onClickBack(void* user_data)
-{
- LLPanelMediaHUD* this_panel = static_cast (user_data);
- if (this_panel->mMediaImpl.notNull() && this_panel->mMediaImpl->hasMedia())
- {
- if(this_panel->mMediaImpl->getMediaPlugin()->pluginSupportsMediaTime())
- {
- this_panel->mMediaImpl->getMediaPlugin()->start(-2.0);
- }
- else
- {
- this_panel->mMediaImpl->getMediaPlugin()->browse_back();
- }
-
- }
-}
-//static
-void LLPanelMediaHUD::onClickForward(void* user_data)
-{
- LLPanelMediaHUD* this_panel = static_cast (user_data);
- if (this_panel->mMediaImpl.notNull() && this_panel->mMediaImpl->hasMedia())
- {
- if(this_panel->mMediaImpl->getMediaPlugin()->pluginSupportsMediaTime())
- {
- this_panel->mMediaImpl->getMediaPlugin()->start(2.0);
- }
- else
- {
- this_panel->mMediaImpl->getMediaPlugin()->browse_forward();
- }
- }
-}
-//static
-void LLPanelMediaHUD::onClickHome(void* user_data)
-{
- //LLViewerMedia::navigateHome();
- LLPanelMediaHUD* this_panel = static_cast (user_data);
- if(this_panel->mMediaImpl.notNull())
- {
- this_panel->mMediaImpl->navigateHome();
- }
-}
-//static
-void LLPanelMediaHUD::onClickOpen(void* user_data)
-{
- LLPanelMediaHUD* this_panel = static_cast (user_data);
- if(this_panel->mMediaImpl.notNull())
- {
- LLWeb::loadURL(this_panel->mMediaImpl->getMediaURL());
- }
-}
-//static
-void LLPanelMediaHUD::onClickReload(void* user_data)
-{
- //LLViewerMedia::navigateHome();
- LLPanelMediaHUD* this_panel = static_cast (user_data);
- LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
- if(objectp && this_panel->mMediaImpl.notNull())
- {
- this_panel->mMediaImpl->navigateTo(objectp->getMediaURL());
- }
-}
-//static
-void LLPanelMediaHUD::onClickPlay(void* user_data)
-{
- LLPanelMediaHUD* this_panel = static_cast (user_data);
- if (this_panel->mMediaImpl.notNull() && this_panel->mMediaImpl->hasMedia())
- {
- this_panel->mMediaImpl->getMediaPlugin()->start();
- }
-}
-//static
-void LLPanelMediaHUD::onClickPause(void* user_data)
-{
- LLPanelMediaHUD* this_panel = static_cast (user_data);
- if (this_panel->mMediaImpl.notNull() && this_panel->mMediaImpl->hasMedia())
- {
- this_panel->mMediaImpl->getMediaPlugin()->pause();
- }
-}
-//static
-void LLPanelMediaHUD::onClickStop(void* user_data)
-{
- LLPanelMediaHUD* this_panel = static_cast (user_data);
- if (this_panel->mMediaImpl.notNull() && this_panel->mMediaImpl->hasMedia())
- {
- if(this_panel->mMediaImpl->getMediaPlugin()->pluginSupportsMediaTime())
- {
- this_panel->mMediaImpl->getMediaPlugin()->stop();
- }
- else
- {
- this_panel->mMediaImpl->getMediaPlugin()->browse_stop();
- }
- }
-}
-//static
-void LLPanelMediaHUD::onClickZoom(void* user_data)
-{
- LLPanelMediaHUD* this_panel = static_cast (user_data);
- this_panel->nextZoomLevel();
-}
-void LLPanelMediaHUD::nextZoomLevel()
-{
- F32 zoom_padding = 0.0f;
- S32 last_zoom_level = (S32)mCurrentZoom;
- mCurrentZoom = (EZoomLevel)((last_zoom_level + 1) % (S32)ZOOM_END);
-
- switch (mCurrentZoom)
- {
- case ZOOM_NONE:
- {
- gAgentCamera.setFocusOnAvatar(TRUE, ANIMATE);
- break;
- }
- case ZOOM_MEDIUM:
- {
- zoom_padding = ZOOM_MEDIUM_PADDING;
- break;
- }
- default:
- {
- gAgentCamera.setFocusOnAvatar(TRUE, ANIMATE);
- break;
- }
- }
-
- if (zoom_padding > 0.0f)
- LLViewerMediaFocus::getInstance()->setCameraZoom(zoom_padding);
-}
-void LLPanelMediaHUD::onScrollUp(void* user_data)
-{
- LLPanelMediaHUD* this_panel = static_cast (user_data);
- if(this_panel->mMediaImpl.notNull() && this_panel->mMediaImpl->hasMedia())
- {
- this_panel->mMediaImpl->getMediaPlugin()->scrollEvent(0, -1, MASK_NONE);
- }
-}
-void LLPanelMediaHUD::onScrollUpHeld(void* user_data)
-{
- LLPanelMediaHUD* this_panel = static_cast (user_data);
- this_panel->mScrollState = SCROLL_UP;
-}
-void LLPanelMediaHUD::onScrollRight(void* user_data)
-{
- LLPanelMediaHUD* this_panel = static_cast (user_data);
- if(this_panel->mMediaImpl.notNull())
- {
- this_panel->mMediaImpl->handleKeyHere(KEY_RIGHT, MASK_NONE);
- }
-}
-void LLPanelMediaHUD::onScrollRightHeld(void* user_data)
-{
- LLPanelMediaHUD* this_panel = static_cast (user_data);
- this_panel->mScrollState = SCROLL_RIGHT;
-}
-
-void LLPanelMediaHUD::onScrollLeft(void* user_data)
-{
- LLPanelMediaHUD* this_panel = static_cast (user_data);
- if(this_panel->mMediaImpl.notNull())
- {
- this_panel->mMediaImpl->handleKeyHere(KEY_LEFT, MASK_NONE);
- }
-}
-void LLPanelMediaHUD::onScrollLeftHeld(void* user_data)
-{
- LLPanelMediaHUD* this_panel = static_cast (user_data);
- this_panel->mScrollState = SCROLL_LEFT;
-}
-
-void LLPanelMediaHUD::onScrollDown(void* user_data)
-{
- LLPanelMediaHUD* this_panel = static_cast (user_data);
- if(this_panel->mMediaImpl.notNull() && this_panel->mMediaImpl->hasMedia())
- {
- this_panel->mMediaImpl->getMediaPlugin()->scrollEvent(0, 1, MASK_NONE);
- }
-}
-void LLPanelMediaHUD::onScrollDownHeld(void* user_data)
-{
- LLPanelMediaHUD* this_panel = static_cast (user_data);
- this_panel->mScrollState = SCROLL_DOWN;
-}
-
-void LLPanelMediaHUD::onScrollStop(void* user_data)
-{
- LLPanelMediaHUD* this_panel = static_cast (user_data);
- this_panel->mScrollState = SCROLL_NONE;
-}
diff --git a/indra/newview/llpanelmediahud.h b/indra/newview/llpanelmediahud.h
deleted file mode 100644
index 1d1f5e1be..000000000
--- a/indra/newview/llpanelmediahud.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/**
- * @file llpanelmediahud.h
- * @brief Media hud panel
- *
- * $LicenseInfo:firstyear=2003&license=viewergpl$
- *
- * Copyright (c) 2003-2009, Linden Research, Inc.
- *
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- *
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- *
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- *
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
-
-#ifndef LL_PANELMEDIAHUD_H
-#define LL_PANELMEDIAHUD_H
-
-#include "llpanel.h"
-#include "llviewermedia.h"
-
-#include "llcoord.h"
-
-class LLViewerMediaImpl;
-
-class LLPanelMediaHUD : public LLPanel
-{
-public:
- LLPanelMediaHUD(viewer_media_t media_impl);
- virtual ~LLPanelMediaHUD();
- /*virtual*/ BOOL postBuild();
- virtual void draw();
- virtual void setAlpha(F32 alpha);
- virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
- void updateShape();
- bool isMouseOver();
- void setMediaFocus(bool b) { mMediaFocus = b; }
- void nextZoomLevel();
- void resetZoomLevel() { mCurrentZoom = ZOOM_NONE; }
-
- LLHandle getHandle() const { return getDerivedHandle(); }
-
- void setMediaImpl(viewer_media_t media_impl) { mMediaImpl = media_impl; }
-
-
- enum EZoomLevel
- {
- ZOOM_NONE = 0,
- ZOOM_MEDIUM = 1,
- ZOOM_END
- };
- enum EScrollDir
- {
- SCROLL_UP = 0,
- SCROLL_DOWN,
- SCROLL_LEFT,
- SCROLL_RIGHT,
- SCROLL_NONE
- };
-
-private:
- static void onClickClose(void* user_data);
- static void onClickBack(void* user_data);
- static void onClickForward(void* user_data);
- static void onClickHome(void* user_data);
- static void onClickOpen(void* user_data);
- static void onClickReload(void* user_data);
- static void onClickPlay(void* user_data);
- static void onClickPause(void* user_data);
- static void onClickStop(void* user_data);
- static void onClickZoom(void* user_data);
- static void onScrollUp(void* user_data);
- static void onScrollUpHeld(void* user_data);
- static void onScrollLeft(void* user_data);
- static void onScrollLeftHeld(void* user_data);
- static void onScrollRight(void* user_data);
- static void onScrollRightHeld(void* user_data);
- static void onScrollDown(void* user_data);
- static void onScrollDownHeld(void* user_data);
- static void onScrollStop(void* user_data);
-
- bool mMediaFocus;
- LLMatrix4 mLastCameraMat;
- EZoomLevel mCurrentZoom;
- EScrollDir mScrollState;
- LLCoordWindow mLastCursorPos;
- LLFrameTimer mMouseMoveTimer;
- LLFrameTimer mFadeTimer;
- F32 mMouseInactiveTime;
- F32 mControlFadeTime;
- viewer_media_t mMediaImpl;
-};
-
-#endif // LL_PANELMEDIAHUD_H
diff --git a/indra/newview/llpanelprimmediacontrols.cpp b/indra/newview/llpanelprimmediacontrols.cpp
new file mode 100644
index 000000000..b57c3fdcb
--- /dev/null
+++ b/indra/newview/llpanelprimmediacontrols.cpp
@@ -0,0 +1,1358 @@
+/**
+ * @file llpanelmsgs.cpp
+ * @brief Message popup preferences panel
+ *
+ * $LicenseInfo:firstyear=2003&license=viewergpl$
+ *
+ * Copyright (c) 2003-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llagent.h"
+#include "llagentcamera.h"
+#include "llparcel.h"
+#include "llpanel.h"
+#include "llselectmgr.h"
+#include "llmediaentry.h"
+#include "llrender.h"
+#include "lldrawable.h"
+#include "llviewerwindow.h"
+#include "lluictrlfactory.h"
+#include "llbutton.h"
+#include "llface.h"
+#include "llcombobox.h"
+#include "lllayoutstack.h"
+#include "llslider.h"
+#include "llhudview.h"
+#include "lliconctrl.h"
+#include "lltoolpie.h"
+#include "llviewercamera.h"
+#include "llviewerobjectlist.h"
+#include "llpanelprimmediacontrols.h"
+#include "llpluginclassmedia.h"
+#include "llprogressbar.h"
+#include "llsliderctrl.h"
+#include "llstring.h"
+#include "llviewercontrol.h"
+#include "llviewerdisplay.h"
+#include "llviewerparcelmgr.h"
+#include "llviewermedia.h"
+#include "llviewermediafocus.h"
+#include "llvovolume.h"
+#include "llweb.h"
+#include "llwindow.h"
+#include "llfloatertools.h" // to enable hide if build tools are up
+#include "llvector4a.h"
+#include "lllayoutstack.h"
+
+// Functions pulled from pipeline.cpp
+glh::matrix4f glh_get_current_modelview();
+glh::matrix4f glh_get_current_projection();
+// Functions pulled from llviewerdisplay.cpp
+bool get_hud_matrices(glh::matrix4f &proj, glh::matrix4f &model);
+
+// Warning: make sure these two match!
+const LLPanelPrimMediaControls::EZoomLevel LLPanelPrimMediaControls::kZoomLevels[] = { ZOOM_NONE, ZOOM_MEDIUM };
+const int LLPanelPrimMediaControls::kNumZoomLevels = 2;
+
+//
+// LLPanelPrimMediaControls
+//
+
+LLPanelPrimMediaControls::LLPanelPrimMediaControls() :
+ mAlpha(1.f),
+ mCurrentURL(""),
+ mPreviousURL(""),
+ mPauseFadeout(false),
+ mUpdateSlider(true),
+ mClearFaceOnFade(false),
+ mCurrentRate(0.0),
+ mMovieDuration(0.0),
+ mTargetObjectID(LLUUID::null),
+ mTargetObjectFace(0),
+ mTargetImplID(LLUUID::null),
+ mTargetObjectNormal(LLVector3::zero),
+ mZoomObjectID(LLUUID::null),
+ mZoomObjectFace(0),
+ mVolumeSliderVisible(0),
+ mHideImmediately(false)
+{
+ mCommitCallbackRegistrar.add("MediaCtrl.Close", boost::bind(&LLPanelPrimMediaControls::onClickClose, this));
+ mCommitCallbackRegistrar.add("MediaCtrl.Back", boost::bind(&LLPanelPrimMediaControls::onClickBack, this));
+ mCommitCallbackRegistrar.add("MediaCtrl.Forward", boost::bind(&LLPanelPrimMediaControls::onClickForward, this));
+ mCommitCallbackRegistrar.add("MediaCtrl.Home", boost::bind(&LLPanelPrimMediaControls::onClickHome, this));
+ mCommitCallbackRegistrar.add("MediaCtrl.Stop", boost::bind(&LLPanelPrimMediaControls::onClickStop, this));
+ mCommitCallbackRegistrar.add("MediaCtrl.MediaStop", boost::bind(&LLPanelPrimMediaControls::onClickMediaStop, this));
+ mCommitCallbackRegistrar.add("MediaCtrl.Reload", boost::bind(&LLPanelPrimMediaControls::onClickReload, this));
+ mCommitCallbackRegistrar.add("MediaCtrl.Play", boost::bind(&LLPanelPrimMediaControls::onClickPlay, this));
+ mCommitCallbackRegistrar.add("MediaCtrl.Pause", boost::bind(&LLPanelPrimMediaControls::onClickPause, this));
+ mCommitCallbackRegistrar.add("MediaCtrl.Open", boost::bind(&LLPanelPrimMediaControls::onClickOpen, this));
+ mCommitCallbackRegistrar.add("MediaCtrl.Zoom", boost::bind(&LLPanelPrimMediaControls::onClickZoom, this));
+ mCommitCallbackRegistrar.add("MediaCtrl.CommitURL", boost::bind(&LLPanelPrimMediaControls::onCommitURL, this));
+ mCommitCallbackRegistrar.add("MediaCtrl.JumpProgress", boost::bind(&LLPanelPrimMediaControls::onCommitSlider, this));
+ mCommitCallbackRegistrar.add("MediaCtrl.CommitVolumeUp", boost::bind(&LLPanelPrimMediaControls::onCommitVolumeUp, this));
+ mCommitCallbackRegistrar.add("MediaCtrl.CommitVolumeDown", boost::bind(&LLPanelPrimMediaControls::onCommitVolumeDown, this));
+ mCommitCallbackRegistrar.add("MediaCtrl.Volume", boost::bind(&LLPanelPrimMediaControls::onCommitVolumeSlider, this));
+ mCommitCallbackRegistrar.add("MediaCtrl.ToggleMute", boost::bind(&LLPanelPrimMediaControls::onToggleMute, this));
+ mCommitCallbackRegistrar.add("MediaCtrl.ShowVolumeSlider", boost::bind(&LLPanelPrimMediaControls::showVolumeSlider, this));
+ mCommitCallbackRegistrar.add("MediaCtrl.HideVolumeSlider", boost::bind(&LLPanelPrimMediaControls::hideVolumeSlider, this));
+ mCommitCallbackRegistrar.add("MediaCtrl.SkipBack", boost::bind(&LLPanelPrimMediaControls::onClickSkipBack, this));
+ mCommitCallbackRegistrar.add("MediaCtrl.SkipForward", boost::bind(&LLPanelPrimMediaControls::onClickSkipForward, this));
+
+ //LLUICtrlFactory::getInstance()->buildPanel(this, "panel_media_hud.xml");
+ LLUICtrlFactory::getInstance()->buildPanel(this, "panel_prim_media_controls.xml");
+ mInactivityTimer.reset();
+ mFadeTimer.stop();
+ mCurrentZoom = ZOOM_NONE;
+ mScrollState = SCROLL_NONE;
+
+ mPanelHandle.bind(this);
+
+ mInactiveTimeout = gSavedSettings.getF32("MediaControlTimeout");
+ mControlFadeTime = gSavedSettings.getF32("MediaControlFadeTime");
+}
+
+LLPanelPrimMediaControls::~LLPanelPrimMediaControls()
+{
+}
+
+BOOL LLPanelPrimMediaControls::postBuild()
+{
+ mMediaRegion = getChild("media_region");
+ mBackCtrl = getChild("back");
+ mFwdCtrl = getChild("fwd");
+ mReloadCtrl = getChild("reload");
+ mPlayCtrl = getChild("play");
+ mPauseCtrl = getChild("pause");
+ mStopCtrl = getChild("stop");
+ mMediaStopCtrl = getChild("media_stop");
+ mHomeCtrl = getChild("home");
+ mUnzoomCtrl = getChild("close"); // This is actually "unzoom"
+ mOpenCtrl = getChild("new_window");
+ mZoomCtrl = getChild("zoom_frame");
+ mMediaProgressPanel = getChild("media_progress_indicator");
+ mMediaProgressBar = getChild("media_progress_bar");
+ mMediaAddressCtrl = getChild("media_address");
+ mMediaAddress = getChild("media_address_url");
+ mMediaPlaySliderPanel = getChild("media_play_position");
+ mMediaPlaySliderCtrl = getChild("media_play_slider");
+ mSkipFwdCtrl = getChild("skip_forward");
+ mSkipBackCtrl = getChild("skip_back");
+ mVolumeCtrl = getChild("media_volume");
+ mMuteBtn = getChild("media_mute_button");
+ mVolumeSliderCtrl = getChild("volume_slider");
+ mWhitelistIcon = getChild("media_whitelist_flag");
+ mSecureLockIcon = getChild("media_secure_lock_flag");
+ mMediaControlsStack = getChild("media_controls");
+ mLeftBookend = getChild("left_bookend");
+ mRightBookend = getChild("right_bookend");
+ mBackgroundImage = LLUI::getUIImage(getString("control_background_image_name"));
+ mVolumeSliderBackgroundImage = LLUI::getUIImage(getString("control_background_image_name"));
+ LLStringUtil::convertToF32(getString("skip_step"), mSkipStep);
+ LLStringUtil::convertToS32(getString("min_width"), mMinWidth);
+ LLStringUtil::convertToS32(getString("min_height"), mMinHeight);
+ LLStringUtil::convertToF32(getString("zoom_near_padding"), mZoomNearPadding);
+ LLStringUtil::convertToF32(getString("zoom_medium_padding"), mZoomMediumPadding);
+ LLStringUtil::convertToF32(getString("zoom_far_padding"), mZoomFarPadding);
+ LLStringUtil::convertToS32(getString("top_world_view_avoid_zone"), mTopWorldViewAvoidZone);
+
+ // These are currently removed...but getChild creates a "dummy" widget.
+ // This class handles them missing.
+ mMediaPanelScroll = findChild("media_panel_scroll");
+ mScrollUpCtrl = findChild("scrollup");
+ mScrollLeftCtrl = findChild("scrollleft");
+ mScrollRightCtrl = findChild("scrollright");
+ mScrollDownCtrl = findChild("scrolldown");
+
+ if (mScrollUpCtrl)
+ {
+ mScrollUpCtrl->setClickedCallback(onScrollUp, this);
+ mScrollUpCtrl->setHeldDownCallback(onScrollUpHeld, this);
+ mScrollUpCtrl->setMouseUpCallback(onScrollStop, this);
+ }
+ if (mScrollLeftCtrl)
+ {
+ mScrollLeftCtrl->setClickedCallback(onScrollLeft, this);
+ mScrollLeftCtrl->setHeldDownCallback(onScrollLeftHeld, this);
+ mScrollLeftCtrl->setMouseUpCallback(onScrollStop, this);
+ }
+ if (mScrollRightCtrl)
+ {
+ mScrollRightCtrl->setClickedCallback(onScrollRight, this);
+ mScrollRightCtrl->setHeldDownCallback(onScrollRightHeld, this);
+ mScrollRightCtrl->setMouseUpCallback(onScrollStop, this);
+ }
+ if (mScrollDownCtrl)
+ {
+ mScrollDownCtrl->setClickedCallback(onScrollDown, this);
+ mScrollDownCtrl->setHeldDownCallback(onScrollDownHeld, this);
+ mScrollDownCtrl->setMouseUpCallback(onScrollStop, this);
+ }
+
+ mMediaAddress->setFocusReceivedCallback(boost::bind(&LLPanelPrimMediaControls::onInputURL, _1, this ));
+
+ gAgent.setMouselookModeInCallback(boost::bind(&LLPanelPrimMediaControls::onMouselookModeIn, this));
+
+ mCurrentZoom = ZOOM_NONE;
+ // clicks on buttons do not remove keyboard focus from media
+ setIsChrome(TRUE);
+ return TRUE;
+}
+
+void LLPanelPrimMediaControls::setMediaFace(LLPointer objectp, S32 face, viewer_media_t media_impl, LLVector3 pick_normal)
+{
+ if (media_impl.notNull() && objectp.notNull())
+ {
+ LLUUID prev_id = mTargetImplID;
+ mTargetImplID = media_impl->getMediaTextureID();
+ mTargetObjectID = objectp->getID();
+ mTargetObjectFace = face;
+ mTargetObjectNormal = pick_normal;
+ mClearFaceOnFade = false;
+
+ if (prev_id != mTargetImplID)
+ mVolumeSliderCtrl->setValue(media_impl->getVolume());
+ }
+ else
+ {
+ // This happens on a timer now.
+// mTargetImplID = LLUUID::null;
+// mTargetObjectID = LLUUID::null;
+// mTargetObjectFace = 0;
+ mClearFaceOnFade = true;
+ }
+
+ updateShape();
+}
+
+void LLPanelPrimMediaControls::focusOnTarget()
+{
+ // Sets the media focus to the current target of the LLPanelPrimMediaControls.
+ // This is how we transition from hover to focus when the user clicks on a control.
+ LLViewerMediaImpl* media_impl = getTargetMediaImpl();
+ if(media_impl)
+ {
+ if(!media_impl->hasFocus())
+ {
+ // The current target doesn't have media focus -- focus on it.
+ LLViewerObject* objectp = getTargetObject();
+ LLViewerMediaFocus::getInstance()->setFocusFace(objectp, mTargetObjectFace, media_impl, mTargetObjectNormal);
+ }
+ }
+}
+
+LLViewerMediaImpl* LLPanelPrimMediaControls::getTargetMediaImpl()
+{
+ return LLViewerMedia::getMediaImplFromTextureID(mTargetImplID);
+}
+
+LLViewerObject* LLPanelPrimMediaControls::getTargetObject()
+{
+ return gObjectList.findObject(mTargetObjectID);
+}
+
+LLPluginClassMedia* LLPanelPrimMediaControls::getTargetMediaPlugin()
+{
+ LLViewerMediaImpl* impl = getTargetMediaImpl();
+ if(impl && impl->hasMedia())
+ {
+ return impl->getMediaPlugin();
+ }
+
+ return NULL;
+}
+
+void LLPanelPrimMediaControls::updateShape()
+{
+ LLViewerMediaImpl* media_impl = getTargetMediaImpl();
+ LLViewerObject* objectp = getTargetObject();
+
+ if(!media_impl || gFloaterTools->getVisible())
+ {
+ setVisible(FALSE);
+ return;
+ }
+
+ LLPluginClassMedia* media_plugin = NULL;
+ if(media_impl->hasMedia())
+ {
+ media_plugin = media_impl->getMediaPlugin();
+ }
+
+ LLParcel *parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+
+ bool can_navigate = parcel->getMediaAllowNavigate();
+ bool enabled = false;
+ bool is_zoomed = (mCurrentZoom != ZOOM_NONE) && (mTargetObjectID == mZoomObjectID) && (mTargetObjectFace == mZoomObjectFace);
+ // There is no such thing as "has_focus" being different from normal controls set
+ // anymore (as of user feedback from bri 10/09). So we cheat here and force 'has_focus'
+ // to 'true' (or, actually, we use a setting)
+ bool has_focus = (gSavedSettings.getBOOL("PrimMediaControlsUseHoverControlSet")) ? media_impl->hasFocus() : true;
+ setVisible(enabled);
+
+ if (objectp)
+ {
+ bool mini_controls = false;
+ LLMediaEntry *media_data = objectp->getTE(mTargetObjectFace)->getMediaData();
+ if (media_data && NULL != dynamic_cast(objectp))
+ {
+ // Don't show the media controls if we do not have permissions
+ enabled = dynamic_cast(objectp)->hasMediaPermission(media_data, LLVOVolume::MEDIA_PERM_CONTROL);
+ mini_controls = (LLMediaEntry::MINI == media_data->getControls());
+ }
+ const bool is_hud = objectp->isHUDAttachment();
+
+ //
+ // Set the state of the buttons
+ //
+
+ // XXX RSP: TODO: FIXME: clean this up so that it is clearer what mode we are in,
+ // and that only the proper controls get made visible/enabled according to that mode.
+ mBackCtrl->setVisible(has_focus);
+ mFwdCtrl->setVisible(has_focus);
+ mReloadCtrl->setVisible(has_focus);
+ mStopCtrl->setVisible(false);
+ mHomeCtrl->setVisible(has_focus);
+ mZoomCtrl->setVisible(!is_zoomed);
+ mUnzoomCtrl->setVisible(is_zoomed);
+ mOpenCtrl->setVisible(true);
+ mMediaAddressCtrl->setVisible(has_focus && !mini_controls);
+ mMediaPlaySliderPanel->setVisible(has_focus && !mini_controls);
+ mVolumeCtrl->setVisible(false);
+
+ mWhitelistIcon->setVisible(!mini_controls && (media_data)?media_data->getWhiteListEnable():false);
+ // Disable zoom if HUD
+ mZoomCtrl->setEnabled(!is_hud);
+ mUnzoomCtrl->setEnabled(!is_hud);
+ mSecureLockIcon->setVisible(false);
+ mCurrentURL = media_impl->getCurrentMediaURL();
+
+ mBackCtrl->setEnabled((media_impl != NULL) && media_impl->canNavigateBack() && can_navigate);
+ mFwdCtrl->setEnabled((media_impl != NULL) && media_impl->canNavigateForward() && can_navigate);
+ mStopCtrl->setEnabled(has_focus && can_navigate);
+ mHomeCtrl->setEnabled(has_focus && can_navigate);
+ LLPluginClassMediaOwner::EMediaStatus result = ((media_impl != NULL) && media_impl->hasMedia()) ? media_plugin->getStatus() : LLPluginClassMediaOwner::MEDIA_NONE;
+
+ mVolumeCtrl->setVisible(has_focus);
+ mVolumeCtrl->setEnabled(has_focus);
+ mVolumeSliderCtrl->setEnabled(has_focus && shouldVolumeSliderBeVisible());
+ mVolumeSliderCtrl->setVisible(has_focus && shouldVolumeSliderBeVisible());
+
+ if(media_plugin && media_plugin->pluginSupportsMediaTime())
+ {
+ mReloadCtrl->setEnabled(false);
+ mReloadCtrl->setVisible(false);
+ mMediaStopCtrl->setVisible(has_focus);
+ mHomeCtrl->setVisible(has_focus);
+ mBackCtrl->setVisible(false);
+ mFwdCtrl->setVisible(false);
+ mMediaAddressCtrl->setVisible(false);
+ mMediaAddressCtrl->setEnabled(false);
+ mMediaPlaySliderPanel->setVisible(has_focus && !mini_controls);
+ mMediaPlaySliderPanel->setEnabled(has_focus && !mini_controls);
+ mSkipFwdCtrl->setVisible(has_focus && !mini_controls);
+ mSkipFwdCtrl->setEnabled(has_focus && !mini_controls);
+ mSkipBackCtrl->setVisible(has_focus && !mini_controls);
+ mSkipBackCtrl->setEnabled(has_focus && !mini_controls);
+
+ mVolumeCtrl->setVisible(has_focus);
+ mVolumeCtrl->setEnabled(has_focus);
+ mVolumeSliderCtrl->setEnabled(has_focus && shouldVolumeSliderBeVisible());
+ mVolumeSliderCtrl->setVisible(has_focus && shouldVolumeSliderBeVisible());
+
+ mWhitelistIcon->setVisible(false);
+ mSecureLockIcon->setVisible(false);
+ if (mMediaPanelScroll)
+ {
+ mMediaPanelScroll->setVisible(false);
+ mScrollUpCtrl->setVisible(false);
+ mScrollDownCtrl->setVisible(false);
+ mScrollRightCtrl->setVisible(false);
+ mScrollDownCtrl->setVisible(false);
+ }
+
+ F32 volume = media_impl->getVolume();
+ // movie's url changed
+ if(mCurrentURL!=mPreviousURL)
+ {
+ mMovieDuration = media_plugin->getDuration();
+ mPreviousURL = mCurrentURL;
+ }
+
+ if(mMovieDuration == 0)
+ {
+ mMovieDuration = media_plugin->getDuration();
+ mMediaPlaySliderCtrl->setValue(0);
+ mMediaPlaySliderCtrl->setEnabled(false);
+ }
+ // TODO: What if it's not fully loaded
+
+ if(mUpdateSlider && mMovieDuration!= 0)
+ {
+ F64 current_time = media_plugin->getCurrentTime();
+ F32 percent = current_time / mMovieDuration;
+ mMediaPlaySliderCtrl->setValue(percent);
+ mMediaPlaySliderCtrl->setEnabled(true);
+ }
+
+ // video vloume
+ if(volume <= 0.0)
+ {
+ mMuteBtn->setToggleState(true);
+ }
+ else if (volume >= 1.0)
+ {
+ mMuteBtn->setToggleState(false);
+ }
+ else
+ {
+ mMuteBtn->setToggleState(false);
+ }
+
+ switch(result)
+ {
+ case LLPluginClassMediaOwner::MEDIA_PLAYING:
+ mPlayCtrl->setEnabled(FALSE);
+ mPlayCtrl->setVisible(FALSE);
+ mPauseCtrl->setEnabled(TRUE);
+ mPauseCtrl->setVisible(has_focus);
+
+ break;
+ case LLPluginClassMediaOwner::MEDIA_PAUSED:
+ default:
+ mPauseCtrl->setEnabled(FALSE);
+ mPauseCtrl->setVisible(FALSE);
+ mPlayCtrl->setEnabled(TRUE);
+ mPlayCtrl->setVisible(has_focus);
+ break;
+ }
+ }
+ else // web based
+ {
+ if(media_plugin)
+ {
+ mCurrentURL = media_plugin->getLocation();
+ }
+ else
+ {
+ mCurrentURL.clear();
+ }
+
+ mPlayCtrl->setVisible(FALSE);
+ mPauseCtrl->setVisible(FALSE);
+ mMediaStopCtrl->setVisible(FALSE);
+ mMediaAddressCtrl->setVisible(has_focus && !mini_controls);
+ mMediaAddressCtrl->setEnabled(has_focus && !mini_controls);
+ mMediaPlaySliderPanel->setVisible(FALSE);
+ mMediaPlaySliderPanel->setEnabled(FALSE);
+ mSkipFwdCtrl->setVisible(FALSE);
+ mSkipFwdCtrl->setEnabled(FALSE);
+ mSkipBackCtrl->setVisible(FALSE);
+ mSkipBackCtrl->setEnabled(FALSE);
+
+ if(media_impl->getVolume() <= 0.0)
+ {
+ mMuteBtn->setToggleState(true);
+ }
+ else
+ {
+ mMuteBtn->setToggleState(false);
+ }
+
+ if (mMediaPanelScroll)
+ {
+ mMediaPanelScroll->setVisible(has_focus);
+ mScrollUpCtrl->setVisible(has_focus);
+ mScrollDownCtrl->setVisible(has_focus);
+ mScrollRightCtrl->setVisible(has_focus);
+ mScrollDownCtrl->setVisible(has_focus);
+ }
+ // TODO: get the secure lock bool from media plug in
+ std::string prefix = std::string("https://");
+ std::string test_prefix = mCurrentURL.substr(0, prefix.length());
+ LLStringUtil::toLower(test_prefix);
+ if(test_prefix == prefix)
+ {
+ mSecureLockIcon->setVisible(has_focus);
+ }
+
+ if(mCurrentURL!=mPreviousURL)
+ {
+ setCurrentURL();
+ mPreviousURL = mCurrentURL;
+ }
+
+ if(result == LLPluginClassMediaOwner::MEDIA_LOADING)
+ {
+ mReloadCtrl->setEnabled(FALSE);
+ mReloadCtrl->setVisible(FALSE);
+ mStopCtrl->setEnabled(TRUE);
+ mStopCtrl->setVisible(has_focus);
+ }
+ else
+ {
+ mReloadCtrl->setEnabled(TRUE);
+ mReloadCtrl->setVisible(has_focus);
+ mStopCtrl->setEnabled(FALSE);
+ mStopCtrl->setVisible(FALSE);
+ }
+ }
+
+
+ if(media_plugin)
+ {
+ //
+ // Handle progress bar
+ //
+ if(LLPluginClassMediaOwner::MEDIA_LOADING == media_plugin->getStatus())
+ {
+ mMediaProgressPanel->setVisible(true);
+ mMediaProgressBar->setValue(media_plugin->getProgressPercent());
+ }
+ else
+ {
+ mMediaProgressPanel->setVisible(false);
+ }
+ }
+
+ if(media_impl)
+ {
+ //
+ // Handle Scrolling
+ //
+ switch (mScrollState)
+ {
+ case SCROLL_UP:
+ media_impl->scrollWheel(0, -1, MASK_NONE);
+ break;
+ case SCROLL_DOWN:
+ media_impl->scrollWheel(0, 1, MASK_NONE);
+ break;
+ case SCROLL_LEFT:
+ media_impl->scrollWheel(1, 0, MASK_NONE);
+ // media_impl->handleKeyHere(KEY_LEFT, MASK_NONE);
+ break;
+ case SCROLL_RIGHT:
+ media_impl->scrollWheel(-1, 0, MASK_NONE);
+ // media_impl->handleKeyHere(KEY_RIGHT, MASK_NONE);
+ break;
+ case SCROLL_NONE:
+ default:
+ break;
+ }
+ }
+
+ setVisible(enabled);
+
+ //
+ // Calculate position and shape of the controls
+ //
+ std::vector::iterator vert_it;
+ std::vector::iterator vert_end;
+ std::vector vect_face;
+
+ LLVolume* volume = objectp->getVolume();
+
+ if (volume)
+ {
+ const LLVolumeFace& vf = volume->getVolumeFace(mTargetObjectFace);
+
+ LLVector3 ext[2];
+ ext[0].set(vf.mExtents[0].getF32ptr());
+ ext[1].set(vf.mExtents[1].getF32ptr());
+
+ LLVector3 center = (ext[0]+ext[1])*0.5f;
+ LLVector3 size = (ext[1]-ext[0])*0.5f;
+ LLVector3 vert[] =
+ {
+ center + size.scaledVec(LLVector3(1,1,1)),
+ center + size.scaledVec(LLVector3(-1,1,1)),
+ center + size.scaledVec(LLVector3(1,-1,1)),
+ center + size.scaledVec(LLVector3(-1,-1,1)),
+ center + size.scaledVec(LLVector3(1,1,-1)),
+ center + size.scaledVec(LLVector3(-1,1,-1)),
+ center + size.scaledVec(LLVector3(1,-1,-1)),
+ center + size.scaledVec(LLVector3(-1,-1,-1)),
+ };
+
+ LLVOVolume* vo = (LLVOVolume*) objectp;
+
+ for (U32 i = 0; i < 8; i++)
+ {
+ vect_face.push_back(vo->volumePositionToAgent(vert[i]));
+ }
+ }
+ vert_it = vect_face.begin();
+ vert_end = vect_face.end();
+
+ glh::matrix4f mat;
+ if (!is_hud)
+ {
+ mat = glh_get_current_projection() * glh_get_current_modelview();
+ }
+ else {
+ glh::matrix4f proj, modelview;
+ if (get_hud_matrices(proj, modelview))
+ mat = proj * modelview;
+ }
+ LLVector3 min = LLVector3(1,1,1);
+ LLVector3 max = LLVector3(-1,-1,-1);
+ for(; vert_it != vert_end; ++vert_it)
+ {
+ // project silhouette vertices into screen space
+ glh::vec3f screen_vert = glh::vec3f(vert_it->mV);
+ mat.mult_matrix_vec(screen_vert);
+
+ // add to screenspace bounding box
+ update_min_max(min, max, LLVector3(screen_vert.v));
+ }
+
+ // convert screenspace bbox to pixels (in screen coords)
+ LLRect window_rect = gViewerWindow->getWorldViewRectScaled();
+ LLCoordGL screen_min;
+ screen_min.mX = llround((F32)window_rect.mLeft + (F32)window_rect.getWidth() * (min.mV[VX] + 1.f) * 0.5f);
+ screen_min.mY = llround((F32)window_rect.mBottom + (F32)window_rect.getHeight() * (min.mV[VY] + 1.f) * 0.5f);
+
+ LLCoordGL screen_max;
+ screen_max.mX = llround((F32)window_rect.mLeft + (F32)window_rect.getWidth() * (max.mV[VX] + 1.f) * 0.5f);
+ screen_max.mY = llround((F32)window_rect.mBottom + (F32)window_rect.getHeight() * (max.mV[VY] + 1.f) * 0.5f);
+
+ // grow panel so that screenspace bounding box fits inside "media_region" element of panel
+ LLRect media_panel_rect;
+ // Get the height of the controls (less the volume slider)
+ S32 controls_height = mMediaControlsStack->getRect().getHeight() - mVolumeSliderCtrl->getRect().getHeight();
+ getParent()->screenRectToLocal(LLRect(screen_min.mX, screen_max.mY, screen_max.mX, screen_min.mY), &media_panel_rect);
+ media_panel_rect.mTop += controls_height;
+
+ // keep all parts of panel on-screen
+ // Area of the top of the world view to avoid putting the controls
+ window_rect.mTop -= mTopWorldViewAvoidZone;
+ // Don't include "spacing" bookends on left & right of the media controls
+ window_rect.mLeft -= mLeftBookend->getRect().getWidth();
+ window_rect.mRight += mRightBookend->getRect().getWidth();
+ // Don't include the volume slider
+ window_rect.mBottom -= mVolumeSliderCtrl->getRect().getHeight();
+ media_panel_rect.intersectWith(window_rect);
+
+ // clamp to minimum size, keeping rect inside window
+ S32 centerX = media_panel_rect.getCenterX();
+ S32 centerY = media_panel_rect.getCenterY();
+ // Shrink screen rect by min width and height, to ensure containment
+ window_rect.stretch(-mMinWidth/2, -mMinHeight/2);
+ window_rect.clampPointToRect(centerX, centerY);
+ media_panel_rect.setCenterAndSize(centerX, centerY,
+ llmax(mMinWidth, media_panel_rect.getWidth()),
+ llmax(mMinHeight, media_panel_rect.getHeight()));
+
+ // Finally set the size of the panel
+ setShape(media_panel_rect, true);
+
+ // Test mouse position to see if the cursor is stationary
+ LLCoordWindow cursor_pos_window;
+ getWindow()->getCursorPosition(&cursor_pos_window);
+
+ // If last pos is not equal to current pos, the mouse has moved
+ // We need to reset the timer, and make sure the panel is visible
+ if(cursor_pos_window.mX != mLastCursorPos.mX ||
+ cursor_pos_window.mY != mLastCursorPos.mY ||
+ mScrollState != SCROLL_NONE)
+ {
+ mInactivityTimer.start();
+ mLastCursorPos = cursor_pos_window;
+ }
+
+ if(isMouseOver() || hasFocus())
+ {
+ // Never fade the controls if the mouse is over them or they have keyboard focus.
+ mFadeTimer.stop();
+ }
+ else if(!mClearFaceOnFade && (mInactivityTimer.getElapsedTimeF32() < mInactiveTimeout))
+ {
+ // Mouse is over the object, but has not been stationary for long enough to fade the UI
+ mFadeTimer.stop();
+ }
+ else if(! mFadeTimer.getStarted() )
+ {
+ // we need to start fading the UI (and we have not already started)
+ mFadeTimer.reset();
+ mFadeTimer.start();
+ }
+ else
+ {
+ // I don't think this is correct anymore. This is done in draw() after the fade has completed.
+ // setVisible(FALSE);
+ }
+ }
+}
+
+/*virtual*/
+void LLPanelPrimMediaControls::draw()
+{
+ LLViewerMediaImpl* impl = getTargetMediaImpl();
+ if (impl)
+ {
+ LLNotificationPtr notification = impl->getCurrentNotification();
+ if (notification != mActiveNotification)
+ {
+ mActiveNotification = notification;
+ if (notification)
+ {
+ showNotification(notification);
+ }
+ else
+ {
+ hideNotification();
+ }
+ }
+ }
+
+ F32 alpha = 1.f;
+ if(mHideImmediately)
+ {
+ //hide this panel
+ clearFaceOnFade();
+
+ mHideImmediately = false;
+ }
+ else if(mFadeTimer.getStarted())
+ {
+ F32 time = mFadeTimer.getElapsedTimeF32();
+ alpha *= llmax(lerp(1.0, 0.0, time / mControlFadeTime), 0.0f);
+
+ if(time >= mControlFadeTime)
+ {
+ //hide this panel
+ clearFaceOnFade();
+ }
+ }
+
+ // Build rect for icon area in coord system of this panel
+ // Assumes layout_stack is a direct child of this panel
+ mMediaControlsStack->updateLayout();
+
+ // adjust for layout stack spacing
+ S32 space = mMediaControlsStack->getPanelSpacing() + 2;
+ LLRect controls_bg_area = mMediaControlsStack->getRect();
+
+ controls_bg_area.mTop += space + 2;
+
+ // adjust to ignore space from volume slider
+ controls_bg_area.mBottom += mVolumeSliderCtrl->getRect().getHeight();
+
+ // adjust to ignore space from left bookend padding
+ controls_bg_area.mLeft += mLeftBookend->getRect().getWidth() - space;
+
+ // ignore space from right bookend padding
+ controls_bg_area.mRight -= mRightBookend->getRect().getWidth() - space - 2;
+
+ // draw control background UI image
+ mBackgroundImage->draw( controls_bg_area, UI_VERTEX_COLOR % alpha);
+
+ // draw volume slider background UI image
+ if (mVolumeSliderCtrl->getVisible())
+ {
+ LLRect volume_slider_rect;
+ screenRectToLocal(mVolumeSliderCtrl->calcScreenRect(), &volume_slider_rect);
+ mVolumeSliderBackgroundImage->draw(volume_slider_rect, UI_VERTEX_COLOR % alpha);
+ }
+
+ {
+ //LLViewDrawContext context(alpha);
+ LLPanel::draw();
+ }
+}
+
+BOOL LLPanelPrimMediaControls::handleScrollWheel(S32 x, S32 y, S32 clicks)
+{
+ mInactivityTimer.start();
+ return LLViewerMediaFocus::getInstance()->handleScrollWheel(x, y, clicks);
+}
+
+BOOL LLPanelPrimMediaControls::handleMouseDown(S32 x, S32 y, MASK mask)
+{
+ mInactivityTimer.start();
+ return LLPanel::handleMouseDown(x, y, mask);
+}
+
+BOOL LLPanelPrimMediaControls::handleMouseUp(S32 x, S32 y, MASK mask)
+{
+ mInactivityTimer.start();
+ return LLPanel::handleMouseUp(x, y, mask);
+}
+
+BOOL LLPanelPrimMediaControls::handleKeyHere( KEY key, MASK mask )
+{
+ mInactivityTimer.start();
+ return LLPanel::handleKeyHere(key, mask);
+}
+
+bool LLPanelPrimMediaControls::isMouseOver()
+{
+ bool result = false;
+
+ if( getVisible() )
+ {
+ LLCoordWindow cursor_pos_window;
+ LLCoordScreen cursor_pos_screen;
+ LLCoordGL cursor_pos_gl;
+ S32 x, y;
+ getWindow()->getCursorPosition(&cursor_pos_window);
+ cursor_pos_gl = cursor_pos_window.convert();
+
+ if(mMediaControlsStack->getVisible())
+ {
+ mMediaControlsStack->screenPointToLocal(cursor_pos_gl.mX, cursor_pos_gl.mY, &x, &y);
+
+ LLView *hit_child = mMediaControlsStack->childFromPoint(x, y);
+ if(hit_child && hit_child->getVisible())
+ {
+ // This was useful for debugging both coordinate translation and view hieararchy problems...
+ // llinfos << "mouse coords: " << x << ", " << y << " hit child " << hit_child->getName() << llendl;
+
+ // This will be a direct child of the LLLayoutStack, which should be a layout_panel.
+ // These may not shown/hidden by the logic in updateShape(), so we need to do another hit test on the children of the layout panel,
+ // which are the actual controls.
+ hit_child->screenPointToLocal(cursor_pos_gl.mX, cursor_pos_gl.mY, &x, &y);
+
+ LLView *hit_child_2 = hit_child->childFromPoint(x, y);
+ if(hit_child_2 && hit_child_2->getVisible())
+ {
+ // This was useful for debugging both coordinate translation and view hieararchy problems...
+ // llinfos << " mouse coords: " << x << ", " << y << " hit child 2 " << hit_child_2->getName() << llendl;
+ result = true;
+ }
+ }
+ }
+ }
+
+ return result;
+}
+
+
+void LLPanelPrimMediaControls::onClickClose()
+{
+ close();
+}
+
+void LLPanelPrimMediaControls::close()
+{
+ resetZoomLevel(true);
+ LLViewerMediaFocus::getInstance()->clearFocus();
+ setVisible(FALSE);
+}
+
+
+void LLPanelPrimMediaControls::onClickBack()
+{
+ focusOnTarget();
+
+ LLViewerMediaImpl* impl =getTargetMediaImpl();
+
+ if (impl)
+ {
+ impl->navigateBack();
+ }
+}
+
+void LLPanelPrimMediaControls::onClickForward()
+{
+ focusOnTarget();
+
+ LLViewerMediaImpl* impl = getTargetMediaImpl();
+
+ if (impl)
+ {
+ impl->navigateForward();
+ }
+}
+
+void LLPanelPrimMediaControls::onClickHome()
+{
+ focusOnTarget();
+
+ LLViewerMediaImpl* impl = getTargetMediaImpl();
+
+ if(impl)
+ {
+ impl->navigateHome();
+ }
+}
+
+void LLPanelPrimMediaControls::onClickOpen()
+{
+ LLViewerMediaImpl* impl = getTargetMediaImpl();
+ if(impl)
+ {
+ LLWeb::loadURL(impl->getCurrentMediaURL());
+ }
+}
+
+void LLPanelPrimMediaControls::onClickReload()
+{
+ focusOnTarget();
+
+ //LLViewerMedia::navigateHome();
+ LLViewerMediaImpl* impl = getTargetMediaImpl();
+
+ if(impl)
+ {
+ impl->navigateReload();
+ }
+}
+
+void LLPanelPrimMediaControls::onClickPlay()
+{
+ focusOnTarget();
+
+ LLViewerMediaImpl* impl = getTargetMediaImpl();
+
+ if(impl)
+ {
+ impl->play();
+ }
+}
+
+void LLPanelPrimMediaControls::onClickPause()
+{
+ focusOnTarget();
+
+ LLViewerMediaImpl* impl = getTargetMediaImpl();
+
+ if(impl)
+ {
+ impl->pause();
+ }
+}
+
+void LLPanelPrimMediaControls::onClickStop()
+{
+ focusOnTarget();
+
+ LLViewerMediaImpl* impl = getTargetMediaImpl();
+
+ if(impl)
+ {
+ impl->navigateStop();
+ }
+}
+
+void LLPanelPrimMediaControls::onClickMediaStop()
+{
+ focusOnTarget();
+
+ LLViewerMediaImpl* impl = getTargetMediaImpl();
+
+ if(impl)
+ {
+ impl->stop();
+ }
+}
+
+void LLPanelPrimMediaControls::onClickSkipBack()
+{
+ focusOnTarget();
+
+ LLViewerMediaImpl* impl =getTargetMediaImpl();
+
+ if (impl)
+ {
+ impl->skipBack(mSkipStep);
+ }
+}
+
+void LLPanelPrimMediaControls::onClickSkipForward()
+{
+ focusOnTarget();
+
+ LLViewerMediaImpl* impl = getTargetMediaImpl();
+
+ if (impl)
+ {
+ impl->skipForward(mSkipStep);
+ }
+}
+
+void LLPanelPrimMediaControls::onClickZoom()
+{
+ focusOnTarget();
+
+ if(mCurrentZoom == ZOOM_NONE)
+ {
+ nextZoomLevel();
+ }
+}
+
+void LLPanelPrimMediaControls::nextZoomLevel()
+{
+ LLViewerObject* objectp = getTargetObject();
+ if(objectp && objectp->isHUDAttachment())
+ {
+ // Never allow zooming on HUD attachments.
+ return;
+ }
+
+ int index = 0;
+ while (index < kNumZoomLevels)
+ {
+ if (kZoomLevels[index] == mCurrentZoom)
+ {
+ index++;
+ break;
+ }
+ index++;
+ }
+ mCurrentZoom = kZoomLevels[index % kNumZoomLevels];
+ updateZoom();
+}
+
+void LLPanelPrimMediaControls::resetZoomLevel(bool reset_camera)
+{
+ if(mCurrentZoom != ZOOM_NONE)
+ {
+ mCurrentZoom = ZOOM_NONE;
+ if(reset_camera)
+ {
+ updateZoom();
+ }
+ }
+}
+
+void LLPanelPrimMediaControls::updateZoom()
+{
+ F32 zoom_padding = 0.0f;
+ switch (mCurrentZoom)
+ {
+ case ZOOM_NONE:
+ {
+ gAgentCamera.setFocusOnAvatar(TRUE, ANIMATE);
+ break;
+ }
+ case ZOOM_FAR:
+ {
+ zoom_padding = mZoomFarPadding;
+ break;
+ }
+ case ZOOM_MEDIUM:
+ {
+ zoom_padding = mZoomMediumPadding;
+ break;
+ }
+ case ZOOM_NEAR:
+ {
+ zoom_padding = mZoomNearPadding;
+ break;
+ }
+ default:
+ {
+ gAgentCamera.setFocusOnAvatar(TRUE, ANIMATE);
+ break;
+ }
+ }
+
+ if (zoom_padding > 0.0f)
+ {
+ // since we only zoom into medium for now, always set zoom_in constraint to true
+ LLViewerMediaFocus::setCameraZoom(getTargetObject(), mTargetObjectNormal, zoom_padding, true);
+ }
+
+ // Remember the object ID/face we zoomed into, so we can update the zoom icon appropriately
+ mZoomObjectID = mTargetObjectID;
+ mZoomObjectFace = mTargetObjectFace;
+}
+
+void LLPanelPrimMediaControls::onScrollUp(void* user_data)
+{
+ LLPanelPrimMediaControls* this_panel = static_cast (user_data);
+ this_panel->focusOnTarget();
+
+ LLViewerMediaImpl* impl = this_panel->getTargetMediaImpl();
+
+ if(impl)
+ {
+ impl->scrollWheel(0, -1, MASK_NONE);
+ }
+}
+void LLPanelPrimMediaControls::onScrollUpHeld(void* user_data)
+{
+ LLPanelPrimMediaControls* this_panel = static_cast (user_data);
+ this_panel->mScrollState = SCROLL_UP;
+}
+void LLPanelPrimMediaControls::onScrollRight(void* user_data)
+{
+ LLPanelPrimMediaControls* this_panel = static_cast (user_data);
+ this_panel->focusOnTarget();
+
+ LLViewerMediaImpl* impl = this_panel->getTargetMediaImpl();
+
+ if(impl)
+ {
+ impl->scrollWheel(-1, 0, MASK_NONE);
+// impl->handleKeyHere(KEY_RIGHT, MASK_NONE);
+ }
+}
+void LLPanelPrimMediaControls::onScrollRightHeld(void* user_data)
+{
+ LLPanelPrimMediaControls* this_panel = static_cast (user_data);
+ this_panel->mScrollState = SCROLL_RIGHT;
+}
+
+void LLPanelPrimMediaControls::onScrollLeft(void* user_data)
+{
+ LLPanelPrimMediaControls* this_panel = static_cast (user_data);
+ this_panel->focusOnTarget();
+
+ LLViewerMediaImpl* impl = this_panel->getTargetMediaImpl();
+
+ if(impl)
+ {
+ impl->scrollWheel(1, 0, MASK_NONE);
+// impl->handleKeyHere(KEY_LEFT, MASK_NONE);
+ }
+}
+void LLPanelPrimMediaControls::onScrollLeftHeld(void* user_data)
+{
+ LLPanelPrimMediaControls* this_panel = static_cast (user_data);
+ this_panel->mScrollState = SCROLL_LEFT;
+}
+
+void LLPanelPrimMediaControls::onScrollDown(void* user_data)
+{
+ LLPanelPrimMediaControls* this_panel = static_cast (user_data);
+ this_panel->focusOnTarget();
+
+ LLViewerMediaImpl* impl = this_panel->getTargetMediaImpl();
+
+ if(impl)
+ {
+ impl->scrollWheel(0, 1, MASK_NONE);
+ }
+}
+void LLPanelPrimMediaControls::onScrollDownHeld(void* user_data)
+{
+ LLPanelPrimMediaControls* this_panel = static_cast (user_data);
+ this_panel->mScrollState = SCROLL_DOWN;
+}
+
+void LLPanelPrimMediaControls::onScrollStop(void* user_data)
+{
+ LLPanelPrimMediaControls* this_panel = static_cast (user_data);
+ this_panel->mScrollState = SCROLL_NONE;
+}
+
+void LLPanelPrimMediaControls::onCommitURL()
+{
+ focusOnTarget();
+
+ std::string url = mMediaAddress->getValue().asString();
+ if(getTargetMediaImpl() && !url.empty())
+ {
+ getTargetMediaImpl()->navigateTo( url, "", true);
+
+ // Make sure keyboard focus is set to the media focus object.
+ gFocusMgr.setKeyboardFocus(LLViewerMediaFocus::getInstance());
+
+ }
+ mPauseFadeout = false;
+ mFadeTimer.start();
+}
+
+
+void LLPanelPrimMediaControls::onInputURL(LLFocusableElement* caller, void *userdata)
+{
+
+ LLPanelPrimMediaControls* this_panel = static_cast (userdata);
+ this_panel->focusOnTarget();
+
+ this_panel->mPauseFadeout = true;
+ this_panel->mFadeTimer.stop();
+ this_panel->mFadeTimer.reset();
+
+}
+
+void LLPanelPrimMediaControls::setCurrentURL()
+{
+#ifdef USE_COMBO_BOX_FOR_MEDIA_URL
+// LLComboBox* media_address_combo = getChild("media_address_combo");
+// // redirects will navigate momentarily to about:blank, don't add to history
+// if (media_address_combo && mCurrentURL != "about:blank")
+// {
+// media_address_combo->remove(mCurrentURL);
+// media_address_combo->add(mCurrentURL);
+// media_address_combo->selectByValue(mCurrentURL);
+// }
+#else // USE_COMBO_BOX_FOR_MEDIA_URL
+ if (mMediaAddress && mCurrentURL != "about:blank")
+ {
+ mMediaAddress->setValue(mCurrentURL);
+ }
+#endif // USE_COMBO_BOX_FOR_MEDIA_URL
+}
+
+void LLPanelPrimMediaControls::onCommitSlider()
+{
+ focusOnTarget();
+
+ LLViewerMediaImpl* media_impl = getTargetMediaImpl();
+ if (media_impl)
+ {
+ // get slider value
+ F64 slider_value = mMediaPlaySliderCtrl->getValue().asReal();
+ if(slider_value <= 0.0)
+ {
+ media_impl->stop();
+ }
+ else
+ {
+ media_impl->seek(slider_value*mMovieDuration);
+ //mUpdateSlider= false;
+ }
+ }
+}
+
+void LLPanelPrimMediaControls::onCommitVolumeUp()
+{
+ focusOnTarget();
+
+ LLViewerMediaImpl* media_impl = getTargetMediaImpl();
+ if (media_impl)
+ {
+ F32 volume = media_impl->getVolume();
+
+ volume += 0.1f;
+ if(volume >= 1.0f)
+ {
+ volume = 1.0f;
+ }
+
+ media_impl->setVolume(volume);
+ mMuteBtn->setToggleState(false);
+ }
+}
+
+void LLPanelPrimMediaControls::onCommitVolumeDown()
+{
+ focusOnTarget();
+
+ LLViewerMediaImpl* media_impl = getTargetMediaImpl();
+ if (media_impl)
+ {
+ F32 volume = media_impl->getVolume();
+
+ volume -= 0.1f;
+ if(volume <= 0.0f)
+ {
+ volume = 0.0f;
+ }
+
+ media_impl->setVolume(volume);
+ mMuteBtn->setToggleState(false);
+ }
+}
+
+void LLPanelPrimMediaControls::onCommitVolumeSlider()
+{
+ focusOnTarget();
+
+ LLViewerMediaImpl* media_impl = getTargetMediaImpl();
+ if (media_impl)
+ {
+ media_impl->setVolume(mVolumeSliderCtrl->getValueF32());
+ }
+}
+
+void LLPanelPrimMediaControls::onToggleMute()
+{
+ focusOnTarget();
+
+ LLViewerMediaImpl* media_impl = getTargetMediaImpl();
+ if (media_impl)
+ {
+ F32 volume = media_impl->getVolume();
+
+ if(volume > 0.0)
+ {
+ media_impl->setVolume(0.0);
+ }
+ else if (mVolumeSliderCtrl->getValueF32() == 0.0)
+ {
+ media_impl->setVolume(1.0);
+ mVolumeSliderCtrl->setValue(1.0);
+ }
+ else
+ {
+ media_impl->setVolume(mVolumeSliderCtrl->getValueF32());
+ }
+ }
+}
+
+void LLPanelPrimMediaControls::showVolumeSlider()
+{
+ mVolumeSliderVisible++;
+}
+
+void LLPanelPrimMediaControls::hideVolumeSlider()
+{
+ mVolumeSliderVisible--;
+}
+
+bool LLPanelPrimMediaControls::shouldVolumeSliderBeVisible()
+{
+ return mVolumeSliderVisible > 0;
+}
+
+
+void LLPanelPrimMediaControls::clearFaceOnFade()
+{
+ if(mClearFaceOnFade)
+ {
+ // Hiding this object makes scroll events go missing after it fades out
+ // (see DEV-41755 for a full description of the train wreck).
+ // Only hide the controls when we're untargeting.
+ setVisible(FALSE);
+
+ mClearFaceOnFade = false;
+ mVolumeSliderVisible = 0;
+ mTargetImplID = LLUUID::null;
+ mTargetObjectID = LLUUID::null;
+ mTargetObjectFace = 0;
+ }
+}
+
+void LLPanelPrimMediaControls::onMouselookModeIn()
+{
+ LLViewerMediaFocus::getInstance()->clearHover();
+ mHideImmediately = true;
+}
+
+void LLPanelPrimMediaControls::showNotification(LLNotificationPtr notify)
+{
+ LLNotifications::instance().add(notify);
+}
+
+void LLPanelPrimMediaControls::hideNotification()
+{
+}
diff --git a/indra/newview/llpanelprimmediacontrols.h b/indra/newview/llpanelprimmediacontrols.h
new file mode 100644
index 000000000..7db687d23
--- /dev/null
+++ b/indra/newview/llpanelprimmediacontrols.h
@@ -0,0 +1,227 @@
+/**
+ * @file llpanelmediahud.h
+ * @brief Media hud panel
+ *
+ * $LicenseInfo:firstyear=2003&license=viewergpl$
+ *
+ * Copyright (c) 2003-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_PANELPRIMMEDIACONTROLS_H
+#define LL_PANELPRIMMEDIACONTROLS_H
+
+#include "llpanel.h"
+#include "llviewermedia.h"
+#include "llnotificationptr.h"
+#include "llcoord.h"
+
+class LLButton;
+class LLIconCtrl;
+class LLLayoutStack;
+class LLProgressBar;
+class LLSliderCtrl;
+class LLViewerMediaImpl;
+
+class LLPanelPrimMediaControls : public LLPanel
+{
+public:
+ LLPanelPrimMediaControls();
+ virtual ~LLPanelPrimMediaControls();
+ /*virtual*/ BOOL postBuild();
+ virtual void draw();
+ virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
+
+ virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
+ virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
+ virtual BOOL handleKeyHere(KEY key, MASK mask);
+
+ void updateShape();
+ bool isMouseOver();
+
+ void showNotification(LLNotificationPtr notify);
+ void hideNotification();
+
+
+ enum EZoomLevel
+ {
+ ZOOM_NONE = 0,
+ ZOOM_FAR,
+ ZOOM_MEDIUM,
+ ZOOM_NEAR
+ };
+
+ EZoomLevel getZoomLevel() const { return mCurrentZoom; }
+ void nextZoomLevel();
+ void resetZoomLevel(bool reset_camera = true);
+ void close();
+
+ LLHandle getHandle() const { return mPanelHandle; }
+ void setMediaFace(LLPointer objectp, S32 face, viewer_media_t media_impl, LLVector3 pick_normal = LLVector3::zero);
+
+
+ static const EZoomLevel kZoomLevels[];
+ static const int kNumZoomLevels;
+
+ enum EScrollDir
+ {
+ SCROLL_UP = 0,
+ SCROLL_DOWN,
+ SCROLL_LEFT,
+ SCROLL_RIGHT,
+ SCROLL_NONE
+ };
+
+private:
+ void onClickClose();
+ void onClickBack();
+ void onClickForward();
+ void onClickHome();
+ void onClickOpen();
+ void onClickReload();
+ void onClickPlay();
+ void onClickPause();
+ void onClickStop();
+ void onClickZoom();
+ void onClickSkipBack();
+ void onClickSkipForward();
+ void onClickMediaStop();
+ void onCommitURL();
+
+ void updateZoom();
+ void setCurrentURL();
+ void onCommitSlider();
+
+ void onCommitVolumeUp();
+ void onCommitVolumeDown();
+ void onCommitVolumeSlider();
+ void onToggleMute();
+ void showVolumeSlider();
+ void hideVolumeSlider();
+ bool shouldVolumeSliderBeVisible();
+
+ static void onScrollUp(void* user_data);
+ static void onScrollUpHeld(void* user_data);
+ static void onScrollLeft(void* user_data);
+ static void onScrollLeftHeld(void* user_data);
+ static void onScrollRight(void* user_data);
+ static void onScrollRightHeld(void* user_data);
+ static void onScrollDown(void* user_data);
+ static void onScrollDownHeld(void* user_data);
+ static void onScrollStop(void* user_data);
+
+ static void onInputURL(LLFocusableElement* caller, void *userdata);
+ static bool hasControlsPermission(LLViewerObject *obj, const LLMediaEntry *media_entry);
+
+ void focusOnTarget();
+
+ LLViewerMediaImpl* getTargetMediaImpl();
+ LLViewerObject* getTargetObject();
+ LLPluginClassMedia* getTargetMediaPlugin();
+
+private:
+
+ void clearFaceOnFade();
+
+ void onMouselookModeIn();
+
+ LLView *mMediaRegion;
+ LLUICtrl *mBackCtrl;
+ LLUICtrl *mFwdCtrl;
+ LLUICtrl *mReloadCtrl;
+ LLUICtrl *mPlayCtrl;
+ LLUICtrl *mPauseCtrl;
+ LLUICtrl *mStopCtrl;
+ LLUICtrl *mMediaStopCtrl;
+ LLUICtrl *mHomeCtrl;
+ LLUICtrl *mUnzoomCtrl;
+ LLUICtrl *mOpenCtrl;
+ LLUICtrl *mSkipBackCtrl;
+ LLUICtrl *mSkipFwdCtrl;
+ LLUICtrl *mZoomCtrl;
+ LLPanel *mMediaProgressPanel;
+ LLProgressBar *mMediaProgressBar;
+ LLUICtrl *mMediaAddressCtrl;
+ LLUICtrl *mMediaAddress;
+ LLUICtrl *mMediaPlaySliderPanel;
+ LLUICtrl *mMediaPlaySliderCtrl;
+ LLUICtrl *mVolumeCtrl;
+ LLButton *mMuteBtn;
+ LLSliderCtrl *mVolumeSliderCtrl;
+ LLIconCtrl *mWhitelistIcon;
+ LLIconCtrl *mSecureLockIcon;
+ LLLayoutStack *mMediaControlsStack;
+ LLUICtrl *mLeftBookend;
+ LLUICtrl *mRightBookend;
+ LLUIImage* mBackgroundImage;
+ LLUIImage* mVolumeSliderBackgroundImage;
+ F32 mSkipStep;
+ S32 mMinWidth;
+ S32 mMinHeight;
+ F32 mZoomNearPadding;
+ F32 mZoomMediumPadding;
+ F32 mZoomFarPadding;
+ S32 mTopWorldViewAvoidZone;
+
+ LLUICtrl *mMediaPanelScroll;
+ LLButton *mScrollUpCtrl;
+ LLButton *mScrollLeftCtrl;
+ LLButton *mScrollRightCtrl;
+ LLButton *mScrollDownCtrl;
+
+ bool mPauseFadeout;
+ bool mUpdateSlider;
+ bool mClearFaceOnFade;
+ bool mHideImmediately;
+
+ LLMatrix4 mLastCameraMat;
+ EZoomLevel mCurrentZoom;
+ EScrollDir mScrollState;
+ LLCoordWindow mLastCursorPos;
+ LLFrameTimer mInactivityTimer;
+ LLFrameTimer mFadeTimer;
+ F32 mInactiveTimeout;
+ F32 mControlFadeTime;
+ LLRootHandle mPanelHandle;
+ F32 mAlpha;
+ std::string mCurrentURL;
+ std::string mPreviousURL;
+ F64 mCurrentRate;
+ F64 mMovieDuration;
+
+ LLUUID mTargetObjectID;
+ S32 mTargetObjectFace;
+ LLUUID mTargetImplID;
+ LLVector3 mTargetObjectNormal;
+
+ LLUUID mZoomObjectID;
+ S32 mZoomObjectFace;
+
+ S32 mVolumeSliderVisible;
+
+ LLNotificationPtr mActiveNotification;
+};
+
+#endif // LL_PANELMEDIAHUD_H
diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp
index 009965c40..ad3747811 100644
--- a/indra/newview/llpanelprofile.cpp
+++ b/indra/newview/llpanelprofile.cpp
@@ -59,7 +59,6 @@ std::string getProfileURL(const std::string& agent_name)
return url;
}
-#ifdef AI_UNUSED
class LLProfileHandler : public LLCommandHandler
{
public:
@@ -79,13 +78,12 @@ public:
}
};
LLProfileHandler gProfileHandler;
-#endif // AI_UNUSED
class LLAgentHandler : public LLCommandHandler
{
public:
// requires trusted browser to trigger
- LLAgentHandler() : LLCommandHandler("agent", true/*UNTRUSTED_THROTTLE*/) { }
+ LLAgentHandler() : LLCommandHandler("agent", UNTRUSTED_THROTTLE) { }
bool handle(const LLSD& params, const LLSD& query_map,
LLMediaCtrl* web)
diff --git a/indra/newview/llpanelweb.cpp b/indra/newview/llpanelweb.cpp
index 9f60ecda4..986b5580a 100644
--- a/indra/newview/llpanelweb.cpp
+++ b/indra/newview/llpanelweb.cpp
@@ -44,17 +44,6 @@
#include "llviewerwindow.h"
#include "llpluginclassmedia.h"
-// helper functions for getting/freeing the web browser media
-// if creating/destroying these is too slow, we'll need to create
-// a static member and update all our static callbacks
-viewer_media_t get_web_media()
-{
-
- viewer_media_t media_source = LLViewerMedia::newMediaImpl("", LLUUID::null, 0, 0, 0, 0, "text/html");
-
- return media_source;
-}
-
LLPanelWeb::LLPanelWeb()
{
LLUICtrlFactory::getInstance()->buildPanel(this, "panel_preferences_web.xml");
@@ -98,15 +87,14 @@ void LLPanelWeb::apply()
bool value = childGetValue("use_external_browser").asString() == "external" ? true : false;
gSavedSettings.setBOOL("UseExternalBrowser", value);
- viewer_media_t media_source = get_web_media();
- if (media_source && media_source->hasMedia())
- {
- media_source->getMediaPlugin()->enable_cookies(childGetValue("cookies_enabled"));
+ LLViewerMedia::setCookiesEnabled(getChild("cookies_enabled")->getValue());
- bool proxy_enable = childGetValue("web_proxy_enabled");
- std::string proxy_address = childGetValue("web_proxy_editor");
- int proxy_port = childGetValue("web_proxy_port");
- media_source->getMediaPlugin()->proxy_setup(proxy_enable, proxy_address, proxy_port);
+ if (hasChild("web_proxy_enabled") && hasChild("web_proxy_editor") && hasChild("web_proxy_port"))
+ {
+ bool proxy_enable = getChild("web_proxy_enabled")->getValue();
+ std::string proxy_address = getChild("web_proxy_editor")->getValue();
+ int proxy_port = getChild("web_proxy_port")->getValue();
+ LLViewerMedia::setProxyConfig(proxy_enable, proxy_address, proxy_port);
}
}
@@ -126,9 +114,7 @@ bool LLPanelWeb::callback_clear_browser_cache(const LLSD& notification, const LL
S32 option = LLNotification::getSelectedOption(notification, response);
if ( option == 0 ) // YES
{
- viewer_media_t media_source = get_web_media();
- if (media_source && media_source->hasMedia())
- media_source->getMediaPlugin()->clear_cache();
+ LLViewerMedia::clearAllCaches();
}
return false;
}
@@ -145,25 +131,11 @@ bool LLPanelWeb::callback_clear_cookies(const LLSD& notification, const LLSD& re
S32 option = LLNotification::getSelectedOption(notification, response);
if ( option == 0 ) // YES
{
- viewer_media_t media_source = get_web_media();
- if (media_source && media_source->hasMedia())
- media_source->getMediaPlugin()->clear_cookies();
+ LLViewerMedia::clearAllCookies();
}
return false;
}
-// static
-void LLPanelWeb::onCommitCookies(LLUICtrl* ctrl, void* data)
-{
- LLPanelWeb* self = (LLPanelWeb*)data;
- LLCheckBoxCtrl* check = (LLCheckBoxCtrl*)ctrl;
-
- if (!self || !check) return;
-
- viewer_media_t media_source = get_web_media();
- if (media_source && media_source->hasMedia())
- media_source->getMediaPlugin()->enable_cookies(check->get());
-}
// static
void LLPanelWeb::onCommitWebProxyEnabled(LLUICtrl* ctrl, void* data)
{
@@ -174,6 +146,4 @@ void LLPanelWeb::onCommitWebProxyEnabled(LLUICtrl* ctrl, void* data)
self->childSetEnabled("web_proxy_editor", check->get());
self->childSetEnabled("web_proxy_port", check->get());
self->childSetEnabled("proxy_text_label", check->get());
-
-
}
diff --git a/indra/newview/llpanelweb.h b/indra/newview/llpanelweb.h
index 449b9cb29..8e64a0ec6 100644
--- a/indra/newview/llpanelweb.h
+++ b/indra/newview/llpanelweb.h
@@ -51,7 +51,6 @@ private:
static void onClickClearCookies(void*);
static bool callback_clear_browser_cache(const LLSD& notification, const LLSD& response);
static bool callback_clear_cookies(const LLSD& notification, const LLSD& response);
- static void onCommitCookies(LLUICtrl* ctrl, void* data);
static void onCommitWebProxyEnabled(LLUICtrl* ctrl, void* data);
};
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 300330cb6..646f83f2e 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -35,6 +35,7 @@
#include "lldbstrings.h"
#include "lleconomy.h"
#include "llgl.h"
+#include "llmediaentry.h"
#include "llrender.h"
#include "llnotifications.h"
#include "llpermissions.h"
@@ -1895,47 +1896,79 @@ void LLSelectMgr::selectionSetFullbright(U8 fullbright)
getSelection()->applyToObjects(&sendfunc);
}
-void LLSelectMgr::selectionSetMediaTypeAndURL(U8 media_type, const std::string& media_url)
-{
- U8 media_flags = LLTextureEntry::MF_NONE;
- if (media_type == LLViewerObject::MEDIA_SET)
- {
- media_flags = LLTextureEntry::MF_HAS_MEDIA;
- }
-
+// This function expects media_data to be a map containing relevant
+// media data name/value pairs (e.g. home_url, etc.)
+void LLSelectMgr::selectionSetMedia(U8 media_type, const LLSD &media_data)
+{
struct f : public LLSelectedTEFunctor
{
U8 mMediaFlags;
- f(const U8& t) : mMediaFlags(t) {}
+ const LLSD &mMediaData;
+ f(const U8& t, const LLSD& d) : mMediaFlags(t), mMediaData(d) {}
bool apply(LLViewerObject* object, S32 te)
{
if (object->permModify())
{
- // update viewer side color in anticipation of update from simulator
- object->setTEMediaFlags(te, mMediaFlags);
+ // If we are adding media, then check the current state of the
+ // media data on this face.
+ // - If it does not have media, AND we are NOT setting the HOME URL, then do NOT add media to this
+ // face.
+ // - If it does not have media, and we ARE setting the HOME URL, add media to this face.
+ // - If it does already have media, add/update media to/on this face
+ // If we are removing media, just do it (ignore the passed-in LLSD).
+ if (mMediaFlags & LLTextureEntry::MF_HAS_MEDIA)
+ {
+ llassert(mMediaData.isMap());
+ const LLTextureEntry *texture_entry = object->getTE(te);
+ if (!mMediaData.isMap() ||
+ (NULL != texture_entry) && !texture_entry->hasMedia() && !mMediaData.has(LLMediaEntry::HOME_URL_KEY))
+ {
+ // skip adding/updating media
+ }
+ else {
+ // Add/update media
+ object->setTEMediaFlags(te, mMediaFlags);
+ LLVOVolume *vo = dynamic_cast(object);
+ llassert(NULL != vo);
+ if (NULL != vo)
+ {
+ vo->syncMediaData(te, mMediaData, true/*merge*/, true/*ignore_agent*/);
+ }
+ }
+ }
+ else
+ {
+ // delete media (or just set the flags)
+ object->setTEMediaFlags(te, mMediaFlags);
+ }
}
return true;
}
- } setfunc(media_flags);
+ } setfunc(media_type, media_data);
getSelection()->applyToTEs(&setfunc);
-
- struct g : public LLSelectedObjectFunctor
+
+ struct f2 : public LLSelectedObjectFunctor
{
- U8 media_type;
- const std::string& media_url ;
- g(U8 a, const std::string& b) : media_type(a), media_url(b) {}
virtual bool apply(LLViewerObject* object)
{
if (object->permModify())
{
object->sendTEUpdate();
- object->setMediaType(media_type);
- object->setMediaURL(media_url);
+ LLVOVolume *vo = dynamic_cast(object);
+ llassert(NULL != vo);
+ // It's okay to skip this object if hasMedia() is false...
+ // the sendTEUpdate() above would remove all media data if it were
+ // there.
+ if (NULL != vo && vo->hasMedia())
+ {
+ // Send updated media data FOR THE ENTIRE OBJECT
+ vo->sendMediaDataUpdate();
+ }
}
return true;
}
- } sendfunc(media_type, media_url);
- getSelection()->applyToObjects(&sendfunc);
+ } func2;
+ mSelectedObjects->applyToObjects( &func2 );
}
void LLSelectMgr::selectionSetGlow(F32 glow)
@@ -4097,6 +4130,7 @@ void LLSelectMgr::deselectAllIfTooFar()
if ( (gSavedSettings.getBOOL("LimitSelectDistance") || (fRlvFartouch) )
// [/RLVa:KB]
&& (!mSelectedObjects->getPrimaryObject() || !mSelectedObjects->getPrimaryObject()->isAvatar())
+ && (mSelectedObjects->getPrimaryObject() != LLViewerMediaFocus::getInstance()->getFocusedObject())
&& !mSelectedObjects->isAttachment()
&& !selectionCenter.isExactlyZero())
{
@@ -5538,7 +5572,7 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud)
{
LLUUID inspect_item_id = LLFloaterInspect::getSelectedUUID();
- LLUUID focus_item_id = LLViewerMediaFocus::getInstance()->getSelectedUUID();
+ LLUUID focus_item_id = LLViewerMediaFocus::getInstance()->getFocusedObjectID();
//
//for (S32 pass = 0; pass < 2; pass++)
//{
diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h
index 7aa6eea13..3526d93d6 100644
--- a/indra/newview/llselectmgr.h
+++ b/indra/newview/llselectmgr.h
@@ -528,7 +528,7 @@ public:
void selectionSetTexGen( U8 texgen );
void selectionSetShiny( U8 shiny );
void selectionSetFullbright( U8 fullbright );
- void selectionSetMediaTypeAndURL(U8 media_type, const std::string& media_url);
+ void selectionSetMedia( U8 media_type, const LLSD &media_data );
void selectionSetClickAction(U8 action);
void selectionSetIncludeInSearch(bool include_in_search);
void selectionSetGlow(const F32 glow);
@@ -663,6 +663,8 @@ public:
void sendAttach(U8 attachment_point, bool replace=true);
void sendDetach();
void sendDropAttachment();
+ void sendLink();
+ void sendDelink();
//void sendHinge(U8 type);
//void sendDehinge();
void sendSelect();
@@ -703,8 +705,7 @@ private:
void (*pack_body)(LLSelectNode* node, void *user_data),
void *user_data,
ESendType send_type);
- void sendLink();
- void sendDelink();
+
static void packAgentID( void *);
static void packAgentAndSessionID(void* user_data);
diff --git a/indra/newview/llslurl.cpp b/indra/newview/llslurl.cpp
new file mode 100644
index 000000000..69f731467
--- /dev/null
+++ b/indra/newview/llslurl.cpp
@@ -0,0 +1,526 @@
+/**
+ * @file llurlsimstring.cpp (was llsimurlstring.cpp)
+ * @brief Handles "SLURL fragments" like Ahern/123/45 for
+ * startup processing, login screen, prefs, etc.
+ *
+ * $LicenseInfo:firstyear=2010&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llslurl.h"
+
+#include "llpanellogin.h"
+#include "llviewercontrol.h"
+#include "llviewernetwork.h"
+#include "llfiltersd2xmlrpc.h"
+#include "curl/curl.h"
+#include "hippogridmanager.h"
+
+const char* LLSLURL::SLURL_HTTP_SCHEME = "http";
+const char* LLSLURL::SLURL_HTTPS_SCHEME = "https";
+const char* LLSLURL::SLURL_SECONDLIFE_SCHEME = "secondlife";
+const char* LLSLURL::SLURL_SECONDLIFE_PATH = "secondlife";
+const char* LLSLURL::SLURL_COM = "slurl.com";
+// For DnD - even though www.slurl.com redirects to slurl.com in a browser, you can copy and drag
+// text with www.slurl.com or a link explicitly pointing at www.slurl.com so testing for this
+// version is required also.
+
+const char* LLSLURL::WWW_SLURL_COM = "www.slurl.com";
+const char* LLSLURL::MAPS_SECONDLIFE_COM = "maps.secondlife.com";
+const char* LLSLURL::SLURL_X_GRID_LOCATION_INFO_SCHEME = "x-grid-location-info";
+const char* LLSLURL::SLURL_APP_PATH = "app";
+const char* LLSLURL::SLURL_REGION_PATH = "region";
+const char* LLSLURL::SIM_LOCATION_HOME = "home";
+const char* LLSLURL::SIM_LOCATION_LAST = "last";
+
+
+const std::string MAIN_GRID_SLURL_BASE = "http://maps.secondlife.com/secondlife/";
+const std::string SYSTEM_GRID_APP_SLURL_BASE = "secondlife:///app";
+#define MAINGRID "util.agni.lindenlab.com"
+
+// resolve a simstring from a slurl
+LLSLURL::LLSLURL(const std::string& slurl)
+{
+ // by default we go to agni.
+ mType = INVALID;
+
+ if(slurl == SIM_LOCATION_HOME)
+ {
+ mType = HOME_LOCATION;
+ }
+ else if(slurl.empty() || (slurl == SIM_LOCATION_LAST))
+ {
+ mType = LAST_LOCATION;
+ }
+ else
+ {
+ LLURI slurl_uri;
+ // parse the slurl as a uri
+ if(slurl.find(':') == std::string::npos)
+ {
+ // There may be no scheme ('secondlife:' etc.) passed in. In that case
+ // we want to normalize the slurl by putting the appropriate scheme
+ // in front of the slurl. So, we grab the appropriate slurl base
+ // from the grid manager which may be http://slurl.com/secondlife/ for maingrid, or
+ // https:///region/ for Standalone grid (the word region, not the region name)
+ // these slurls are typically passed in from the 'starting location' box on the login panel,
+ // where the user can type in ///
+ //std::string fixed_slurl = LLGridManager::getInstance()->getSLURLBase();
+ //Singu TODO: Implement LLHippoGridMgr::getSLURLBase some day. For now it's hardcoded.
+ std::string fixed_slurl = MAIN_GRID_SLURL_BASE;
+
+ // the slurl that was passed in might have a prepended /, or not. So,
+ // we strip off the prepended '/' so we don't end up with http://slurl.com/secondlife////
+ // or some such.
+
+ if(slurl[0] == '/')
+ {
+ fixed_slurl += slurl.substr(1);
+ }
+ else
+ {
+ fixed_slurl += slurl;
+ }
+ // We then load the slurl into a LLURI form
+ slurl_uri = LLURI(fixed_slurl);
+ }
+ else
+ {
+ // as we did have a scheme, implying a URI style slurl, we
+ // simply parse it as a URI
+ slurl_uri = LLURI(slurl);
+ }
+
+ LLSD path_array = slurl_uri.pathArray();
+
+ // determine whether it's a maingrid URI or an Standalone/open style URI
+ // by looking at the scheme. If it's a 'secondlife:' slurl scheme or
+ // 'sl:' scheme, we know it's maingrid
+
+ // At the end of this if/else block, we'll have determined the grid,
+ // and the slurl type (APP or LOCATION)
+ if(slurl_uri.scheme() == LLSLURL::SLURL_SECONDLIFE_SCHEME)
+ {
+ // parse a maingrid style slurl. We know the grid is maingrid
+ // so grab it.
+ // A location slurl for maingrid (with the special schemes) can be in the form
+ // secondlife://///
+ // or
+ // secondlife:///secondlife////
+ // where if grid is empty, it specifies Agni
+
+ // An app style slurl for maingrid can be
+ // secondlife:///app/
+ // where an empty grid implies Agni
+
+ // we'll start by checking the top of the 'path' which will be
+ // either 'app', 'secondlife', or .
+
+ // default to maingrid
+
+ mGrid = MAINGRID;
+
+ if ((path_array[0].asString() == LLSLURL::SLURL_SECONDLIFE_PATH) ||
+ (path_array[0].asString() == LLSLURL::SLURL_APP_PATH))
+ {
+ // it's in the form secondlife:///(app|secondlife)
+ // so parse the grid name to derive the grid ID
+ if (!slurl_uri.hostName().empty())
+ {
+ mGrid = gHippoGridManager->getGrid(slurl_uri.hostName())->getGridNick();
+ }
+ else if(path_array[0].asString() == LLSLURL::SLURL_SECONDLIFE_PATH)
+ {
+ // If the slurl is in the form secondlife:///secondlife/ form,
+ // then we are in fact on maingrid.
+ mGrid = MAINGRID;
+ }
+ else if(path_array[0].asString() == LLSLURL::SLURL_APP_PATH)
+ {
+ // for app style slurls, where no grid name is specified, assume the currently
+ // selected or logged in grid.
+ mGrid = gHippoGridManager->getCurrentGridNick();
+ }
+
+ if(mGrid.empty())
+ {
+ // we couldn't find the grid in the grid manager, so bail
+ LL_WARNS("AppInit")<<"unable to find grid"< or /app/, so it must be secondlife://
+ // therefore the hostname will be the region name, and it's a location type
+ mType = LOCATION;
+ // 'normalize' it so the region name is in fact the head of the path_array
+ path_array.insert(0, slurl_uri.hostName());
+ }
+ }
+ else if((slurl_uri.scheme() == LLSLURL::SLURL_HTTP_SCHEME) ||
+ (slurl_uri.scheme() == LLSLURL::SLURL_HTTPS_SCHEME) ||
+ (slurl_uri.scheme() == LLSLURL::SLURL_X_GRID_LOCATION_INFO_SCHEME))
+ {
+ // We're dealing with either a Standalone style slurl or slurl.com slurl
+ if ((slurl_uri.hostName() == LLSLURL::SLURL_COM) ||
+ (slurl_uri.hostName() == LLSLURL::WWW_SLURL_COM) ||
+ (slurl_uri.hostName() == LLSLURL::MAPS_SECONDLIFE_COM))
+ {
+ // slurl.com implies maingrid
+ mGrid = MAINGRID;
+ }
+ else
+ {
+ // Don't try to match any old http:/// URL as a SLurl.
+ // SLE SLurls will have the grid hostname in the URL, so only
+ // match http URLs if the hostname matches the grid hostname
+ // (or its a slurl.com or maps.secondlife.com URL).
+ if ((slurl_uri.scheme() == LLSLURL::SLURL_HTTP_SCHEME ||
+ slurl_uri.scheme() == LLSLURL::SLURL_HTTPS_SCHEME) &&
+ slurl_uri.hostName() != gHippoGridManager->getCurrentGridNick())
+ {
+ return;
+ }
+
+ // As it's a Standalone grid/open, we will always have a hostname, as Standalone/open style
+ // urls are properly formed, unlike the stinky maingrid style
+ mGrid = slurl_uri.hostName();
+ }
+ if (path_array.size() == 0)
+ {
+ // um, we need a path...
+ return;
+ }
+
+ // we need to normalize the urls so
+ // the path portion starts with the 'command' that we want to do
+ // it can either be region or app.
+ if ((path_array[0].asString() == LLSLURL::SLURL_REGION_PATH) ||
+ (path_array[0].asString() == LLSLURL::SLURL_SECONDLIFE_PATH))
+ {
+ // strip off 'region' or 'secondlife'
+ path_array.erase(0);
+ // it's a location
+ mType = LOCATION;
+ }
+ else if (path_array[0].asString() == LLSLURL::SLURL_APP_PATH)
+ {
+ mType = APP;
+ path_array.erase(0);
+ // leave app appended.
+ }
+ else
+ {
+ // not a valid https/http/x-grid-location-info slurl, so it'll likely just be a URL
+ return;
+ }
+ }
+ else
+ {
+ // invalid scheme, so bail
+ return;
+ }
+
+
+ if(path_array.size() == 0)
+ {
+ // we gotta have some stuff after the specifier as to whether it's a region or command
+ return;
+ }
+
+ // now that we know whether it's an app slurl or a location slurl,
+ // parse the slurl into the proper data structures.
+ if(mType == APP)
+ {
+ // grab the app command type and strip it (could be a command to jump somewhere,
+ // or whatever )
+ mAppCmd = path_array[0].asString();
+ path_array.erase(0);
+
+ // Grab the parameters
+ mAppPath = path_array;
+ // and the query
+ mAppQuery = slurl_uri.query();
+ mAppQueryMap = slurl_uri.queryMap();
+ return;
+ }
+ else if(mType == LOCATION)
+ {
+ // at this point, head of the path array should be [ , ,