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
+ AudioStreamingMedia
+
+ Comment
+ Enable streaming
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 1
AudioStreamingMusic
@@ -2269,17 +2292,6 @@ This should be as low as possible, but too low may break functionality
Value
1
- AudioStreamingVideo
-
- Comment
- Enable streaming video
- Persist
- 1
- Type
- Boolean
- Value
- 0
-
AuditTexture
Comment
@@ -2724,23 +2736,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
@@ -3802,17 +3814,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
@@ -5452,6 +5453,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
@@ -5463,6 +5475,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
@@ -6036,17 +6059,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
@@ -6091,6 +6103,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
@@ -7438,6 +7461,22 @@ This should be as low as possible, but too low may break functionality
Value
-1
+ FloaterVoiceEffectRect
+
+ Comment
+ Rectangle for voice morpher floater
+ Persist
+ 1
+ Type
+ Rect
+ Value
+
+ 0
+ 300
+ 360
+ 0
+
+
FloaterWorldMapRect2
Comment
@@ -8812,6 +8851,17 @@ This should be as low as possible, but too low may break functionality
Value
0
+ LastMediaSettingsTab
+
+ Comment
+ Last selected tab in media settings window
+ Persist
+ 1
+ Type
+ S32
+ Value
+ 0
+
LastRunVersion
Comment
@@ -9131,16 +9181,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
@@ -9457,13 +9507,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
@@ -10448,6 +10553,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
@@ -10651,6 +10836,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
@@ -10959,6 +11232,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
@@ -16475,6 +16792,17 @@ This should be as low as possible, but too low may break functionality
Value
0.40000000596
+ moapbeacon
+
+ Comment
+ Beacon / Highlight media on a prim sources
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 0
+
particlesbeacon
Comment
@@ -16573,6 +16901,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
@@ -16585,17 +16935,6 @@ This should be as low as possible, but too low may break functionality
Value
0
- keepbeacons
-
- Comment
- Keep beacons when closing floater
- Persist
- 1
- Type
- Boolean
- Value
- 0
-
ClearBeaconAfterTeleport
Comment
@@ -16651,6 +16990,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
@@ -16770,6 +17122,22 @@ This should be as low as possible, but too low may break functionality
473
+ FloaterNearbyMediaRect
+
+ Comment
+ Rectangle for nearby media floater.
+ Persist
+ 1
+ Type
+ Rect
+ Value
+
+ 0
+ 0
+ 0
+ 0
+
+
WindEnabled
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/hippogridmanager.cpp b/indra/newview/hippogridmanager.cpp
index 93168da88..d7c02be7f 100644
--- a/indra/newview/hippogridmanager.cpp
+++ b/indra/newview/hippogridmanager.cpp
@@ -506,7 +506,7 @@ void HippoGridInfo::formatFee(std::string &fee, int cost, bool showFree) const
}
//static
-std::string HippoGridInfo::sanitizeGridNick(std::string &gridnick)
+std::string HippoGridInfo::sanitizeGridNick(const std::string &gridnick)
{
std::string tmp;
int size = gridnick.size();
@@ -529,7 +529,7 @@ std::string HippoGridInfo::sanitizeGridNick(std::string &gridnick)
}
-std::string HippoGridInfo::getGridNick()
+std::string HippoGridInfo::getGridNick() const
{
if(!mGridNick.empty())
{
@@ -684,42 +684,57 @@ void HippoGridManager::discardAndReload()
HippoGridInfo* HippoGridManager::getGrid(const std::string& grid) const
{
+ if(grid.empty())
+ return NULL;
+
std::map::const_iterator it;
it = mGridInfo.find(grid);
+
+ //The grids are keyed by 'name' which equates to something like "Second Life"
+ //Try to match such first.
if (it != mGridInfo.end())
{
return it->second;
}
- else
+ else //Fall back to nick short names. (so something like "secondlife" will work)
{
- return 0;
+ for(it = mGridInfo.begin(); it != mGridInfo.end(); ++it)
+ {
+ if(it->second && LLStringUtil::compareInsensitive(it->second->getGridNick(), grid)==0)
+ return it->second;
+ }
}
+ return NULL;
}
HippoGridInfo* HippoGridManager::getCurrentGrid() const
{
HippoGridInfo* grid = getGrid(mCurrentGrid);
- if (grid)
+ if(!grid)
{
- return grid;
- }
- else
- {
- return &HippoGridInfo::FALLBACK_GRIDINFO;
+ grid = getGrid(mDefaultGrid);
}
+ return grid ? grid : &HippoGridInfo::FALLBACK_GRIDINFO;
}
-const std::string& HippoGridManager::getDefaultGridNick() const
+std::string HippoGridManager::getDefaultGridNick() const
+{
+ HippoGridInfo* grid = getGrid(mDefaultGrid);
+ return grid ? grid->getGridNick() : HippoGridInfo::FALLBACK_GRIDINFO.getGridNick();
+}
+
+std::string HippoGridManager::getCurrentGridNick() const
+{
+ return getCurrentGrid()->getGridNick();
+}
+
+const std::string& HippoGridManager::getDefaultGridName() const
{
return mDefaultGrid;
}
-const std::string& HippoGridManager::getCurrentGridNick() const
+const std::string& HippoGridManager::getCurrentGridName() const
{
- if (mCurrentGrid.empty())
- {
- return mDefaultGrid;
- }
return mCurrentGrid;
}
diff --git a/indra/newview/hippogridmanager.h b/indra/newview/hippogridmanager.h
index 9562d563f..e5600dfa9 100644
--- a/indra/newview/hippogridmanager.h
+++ b/indra/newview/hippogridmanager.h
@@ -57,7 +57,7 @@ public:
const std::string& getVoiceConnector() const { return mVoiceConnector; }
std::string getSearchUrl(SearchType ty, bool is_web) const;
bool isRenderCompat() const { return mRenderCompat; }
- std::string getGridNick();
+ std::string getGridNick() const;
int getMaxAgentGroups() const { return mMaxAgentGroups; }
const std::string& getCurrencySymbol() const { return mCurrencySymbol; }
@@ -99,7 +99,7 @@ public:
bool retrieveGridInfo();
static const char* getPlatformString(Platform platform);
- static std::string sanitizeGridNick(std::string &gridnick);
+ static std::string sanitizeGridNick(const std::string &gridnick);
static HippoGridInfo FALLBACK_GRIDINFO;
static void initFallback();
@@ -163,8 +163,10 @@ public:
HippoGridInfo* getConnectedGrid() const { return mConnectedGrid ? mConnectedGrid : getCurrentGrid(); }
HippoGridInfo* getCurrentGrid() const;
- const std::string& getDefaultGridNick() const;
- const std::string& getCurrentGridNick() const;
+ std::string getDefaultGridNick() const;
+ std::string getCurrentGridNick() const;
+ const std::string& getDefaultGridName() const;
+ const std::string& getCurrentGridName() const;
void setDefaultGrid(const std::string& grid);
void setCurrentGrid(const std::string& grid);
diff --git a/indra/newview/hippopanelgrids.cpp b/indra/newview/hippopanelgrids.cpp
index 6af943c5b..c5fe98de2 100644
--- a/indra/newview/hippopanelgrids.cpp
+++ b/indra/newview/hippopanelgrids.cpp
@@ -164,7 +164,7 @@ BOOL HippoPanelGridsImpl::postBuild()
// called internally too
void HippoPanelGridsImpl::refresh()
{
- const std::string &defaultGrid = gHippoGridManager->getDefaultGridNick();
+ const std::string &defaultGrid = gHippoGridManager->getDefaultGridName();
LLComboBox *grids = getChild("grid_selector");
S32 selectIndex = -1, i = 0;
@@ -365,7 +365,7 @@ bool HippoPanelGridsImpl::saveCurGrid()
void HippoPanelGridsImpl::reset()
{
mState = NORMAL;
- mCurGrid = gHippoGridManager->getCurrentGridNick();
+ mCurGrid = gHippoGridManager->getCurrentGridName();
loadCurGrid();
}
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 06f84e9cf..5cb16e6d9 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
@@ -749,9 +752,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
@@ -969,6 +974,8 @@ bool LLAppViewer::init()
LLEnvManagerNew::instance().usePrefs();
gGLActive = FALSE;
+ LLViewerMedia::initClass();
+ LL_INFOS("InitInfo") << "Viewer media initialized." << LL_ENDL ;
return true;
}
@@ -1695,8 +1702,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
@@ -1773,7 +1779,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
@@ -2323,30 +2328,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");
@@ -2425,18 +2417,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;
@@ -2492,9 +2477,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 7f278fae9..a242a029b 100644
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -30,6 +30,7 @@
#include "llavataractions.h"
#include "llavatarnamecache.h" // IDEVO
+#include "llnotifications.h"
#include "llnotificationsutil.h" // for LLNotificationsUtil
#include "roles_constants.h" // for GP_MEMBER_INVITE
@@ -46,6 +47,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 +179,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;
}
}
@@ -203,11 +205,10 @@ void LLAvatarActions::endIM(const LLUUID& id)
}
}
-/* Singu TODO: Voice refactor
static void on_avatar_name_cache_start_call(const LLUUID& agent_id,
const LLAvatarName& av_name)
{
- LLUUID session_id = gIMMgr->addSession(LLCacheName::cleanFullName(av_name.getLegacyName()), IM_NOTHING_SPECIAL, agent_id, true);
+ LLUUID session_id = gIMMgr->addSession(LLCacheName::cleanFullName(av_name.getLegacyName()), IM_NOTHING_SPECIAL, agent_id);
if (session_id.notNull())
{
gIMMgr->startCall(session_id);
@@ -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);
@@ -269,7 +270,7 @@ void LLAvatarActions::startAdhocCall(const uuid_vec_t& ids)
// create the new ad hoc voice session
const std::string title = LLTrans::getString("conference-title");
LLUUID session_id = gIMMgr->addSession(title, IM_SESSION_CONFERENCE_START,
- ids[0], id_array, true);
+ ids[0], id_array);
if (session_id.isNull())
{
return;
@@ -279,7 +280,6 @@ void LLAvatarActions::startAdhocCall(const uuid_vec_t& ids)
make_ui_sound("UISndStartIM");
}
-*/
/* AD *TODO: Is this function needed any more?
I fixed it a bit(added check for canCall), but it appears that it is not used
@@ -312,7 +312,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..95e39ee89 100644
--- a/indra/newview/llchatbar.cpp
+++ b/indra/newview/llchatbar.cpp
@@ -111,7 +111,7 @@ private:
//
LLChatBar::LLChatBar()
-: LLPanel(LLStringUtil::null, LLRect(), BORDER_NO),
+: LLPanel(),
mInputEditor(NULL),
mGestureLabelTimer(),
mLastSpecialChatChannel(0),
@@ -509,7 +509,7 @@ void LLChatBar::sendChat( EChatType type )
// static
void LLChatBar::startChat(const char* line)
{
- gChatBar->setVisible(TRUE);
+ gChatBar->getParent()->setVisible(TRUE);
gChatBar->setKeyboardFocus(TRUE);
gSavedSettings.setBOOL("ChatVisible", TRUE);
@@ -540,7 +540,7 @@ void LLChatBar::stopChat()
gAgent.stopTyping();
// hide chat bar so it doesn't grab focus back
- gChatBar->setVisible(FALSE);
+ gChatBar->getParent()->setVisible(FALSE);
gSavedSettings.setBOOL("ChatVisible", FALSE);
}
@@ -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/llchatbar.h b/indra/newview/llchatbar.h
index 4ab866f8c..b031e312a 100644
--- a/indra/newview/llchatbar.h
+++ b/indra/newview/llchatbar.h
@@ -36,6 +36,7 @@
#include "llpanel.h"
#include "llframetimer.h"
#include "llchat.h"
+#include "lllayoutstack.h"
class LLLineEditor;
class LLMessageSystem;
@@ -45,8 +46,7 @@ class LLFrameTimer;
class LLChatBarGestureObserver;
class LLComboBox;
-class LLChatBar
-: public LLPanel
+class LLChatBar : public LLPanel
{
public:
// constructor for inline chat-bars (e.g. hosted in chat history window)
diff --git a/indra/newview/llcolorswatch.cpp b/indra/newview/llcolorswatch.cpp
index d42ea03e6..61fcd5d7b 100644
--- a/indra/newview/llcolorswatch.cpp
+++ b/indra/newview/llcolorswatch.cpp
@@ -351,9 +351,6 @@ LLXMLNodePtr LLColorSwatchCtrl::getXML(bool save_children) const
LLView* LLColorSwatchCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
{
- std::string name("colorswatch");
- node->getAttributeString("name", name);
-
std::string label;
node->getAttributeString("label", label);
@@ -372,7 +369,7 @@ LLView* LLColorSwatchCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFa
}
LLColorSwatchCtrl* color_swatch = new LLColorSwatchCtrl(
- name,
+ "colorswatch",
rect,
label,
color );
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/llfloateractivespeakers.cpp b/indra/newview/llfloateractivespeakers.cpp
index 7d9706ad4..077951e3e 100644
--- a/indra/newview/llfloateractivespeakers.cpp
+++ b/indra/newview/llfloateractivespeakers.cpp
@@ -34,12 +34,22 @@
#include "llfloateractivespeakers.h"
#include "llparticipantlist.h"
+#include "llpanelvoiceeffect.h"
#include "llspeakers.h"
#include "lluictrlfactory.h"
+namespace
+{
+ void* createEffectPanel(void*)
+ {
+ return new LLPanelVoiceEffect;
+ }
+}
+
LLFloaterActiveSpeakers::LLFloaterActiveSpeakers(const LLSD& seed) : mPanel(NULL)
{
mFactoryMap["active_speakers_panel"] = LLCallbackMap(createSpeakersPanel, NULL);
+ mFactoryMap["panel_voice_effect"] = LLCallbackMap(createEffectPanel, NULL);
// do not automatically open singleton floaters (as result of getInstance())
BOOL no_open = FALSE;
LLUICtrlFactory::getInstance()->buildFloater(this, "floater_active_speakers.xml", &getFactoryMap(), no_open);
diff --git a/indra/newview/llfloaterbeacons.cpp b/indra/newview/llfloaterbeacons.cpp
index b8d457fa9..696708a50 100644
--- a/indra/newview/llfloaterbeacons.cpp
+++ b/indra/newview/llfloaterbeacons.cpp
@@ -36,7 +36,6 @@
#include "llviewercontrol.h"
#include "lluictrlfactory.h"
#include "llcheckboxctrl.h"
-#include "llsliderctrl.h"
#include "pipeline.h"
// [RLVa:KB]
@@ -45,8 +44,6 @@
LLFloaterBeacons::LLFloaterBeacons(const LLSD& seed)
{
- LLUICtrlFactory::getInstance()->buildFloater(this, "floater_beacons.xml");
-
// Initialize pipeline states from saved settings.
// OK to do at floater constructor time because beacons do not display unless the floater is open
// therefore it is OK to not initialize the pipeline state before needed.
@@ -59,20 +56,14 @@ LLFloaterBeacons::LLFloaterBeacons(const LLSD& seed)
LLPipeline::setRenderParticleBeacons( gSavedSettings.getBOOL("particlesbeacon"));
LLPipeline::setRenderHighlights( gSavedSettings.getBOOL("renderhighlights"));
LLPipeline::setRenderBeacons( gSavedSettings.getBOOL("renderbeacons"));
- getChild("beacon_width_label")->setEnabled(gSavedSettings.getBOOL("renderbeacons"));
- getChild("beacon_width")->setEnabled(gSavedSettings.getBOOL("renderbeacons"));
+ LLPipeline::setRenderMOAPBeacons( gSavedSettings.getBOOL("moapbeacon"));
+ mCommitCallbackRegistrar.add("Beacons.UICheck", boost::bind(&LLFloaterBeacons::onClickUICheck, this,_1));
+
+ LLUICtrlFactory::getInstance()->buildFloater(this, "floater_beacons.xml");
}
BOOL LLFloaterBeacons::postBuild()
{
- childSetCommitCallback("always_on", onClickUICheck, this);
- childSetCommitCallback("touch_only", onClickUICheck, this);
- childSetCommitCallback("scripted", onClickUICheck, this);
- childSetCommitCallback("physical", onClickUICheck, this);
- childSetCommitCallback("sounds", onClickUICheck, this);
- childSetCommitCallback("particles", onClickUICheck, this);
- childSetCommitCallback("highlights", onClickUICheck, this);
- childSetCommitCallback("beacons", onClickUICheck, this);
return TRUE;
}
@@ -105,64 +96,59 @@ void LLFloaterBeacons::close(bool app_quitting)
// Callback attached to each check box control to both affect their main purpose
// and to implement the couple screwy interdependency rules that some have.
-//static
-void LLFloaterBeacons::onClickUICheck(LLUICtrl *ctrl, void* data)
+
+void LLFloaterBeacons::onClickUICheck(LLUICtrl *ctrl)
{
LLCheckBoxCtrl *check = (LLCheckBoxCtrl *)ctrl;
std::string name = check->getName();
- LLFloaterBeacons* view = (LLFloaterBeacons*)data;
- if (name == "always_on") gSavedSettings.setBOOL("BeaconsKeepVisible", check->get());
- else if (name == "touch_only") LLPipeline::setRenderScriptedTouchBeacons(check->get());
- else if (name == "scripted") LLPipeline::setRenderScriptedBeacons(check->get());
- else if (name == "physical") LLPipeline::setRenderPhysicalBeacons(check->get());
- else if (name == "sounds") LLPipeline::setRenderSoundBeacons(check->get());
- else if (name == "particles") LLPipeline::setRenderParticleBeacons(check->get());
- else if (name == "highlights") LLPipeline::setRenderHighlights(check->get());
- else if (name == "beacons")
- {
- bool enabled = check->get();
- LLPipeline::setRenderBeacons(enabled);
- view->getChild("beacon_width_label")->setEnabled(enabled);
- view->getChild("beacon_width")->setEnabled(enabled);
- }
-
- if (check->get())
+ if (name == "touch_only")
{
+ LLPipeline::toggleRenderScriptedTouchBeacons(NULL);
// Don't allow both to be ON at the same time. Toggle the other one off if both now on.
if (LLPipeline::getRenderScriptedTouchBeacons(NULL) &&
LLPipeline::getRenderScriptedBeacons(NULL) )
{
- if (name == "touch_only")
- {
- LLPipeline::setRenderScriptedBeacons(FALSE);
- view->getChild("scripted")->setControlValue(LLSD(FALSE));
- }
- else
- {
- LLPipeline::setRenderScriptedTouchBeacons(FALSE);
- view->getChild("touch_only")->setControlValue(LLSD(FALSE));
- }
+ LLPipeline::setRenderScriptedBeacons(FALSE);
+ getChild("scripted")->setControlValue(LLSD(FALSE));
}
}
- else
+
+ else if (name == "scripted")
+ {
+ LLPipeline::toggleRenderScriptedBeacons(NULL);
+ // Don't allow both to be ON at the same time. Toggle the other one off if both now on.
+ if (LLPipeline::getRenderScriptedTouchBeacons(NULL) &&
+ LLPipeline::getRenderScriptedBeacons(NULL) )
+ {
+ LLPipeline::setRenderScriptedTouchBeacons(FALSE);
+ getChild("touch_only")->setControlValue(LLSD(FALSE));
+ }
+ }
+ else if (name == "physical") LLPipeline::setRenderPhysicalBeacons(check->get());
+ else if (name == "sounds") LLPipeline::setRenderSoundBeacons(check->get());
+ else if (name == "particles") LLPipeline::setRenderParticleBeacons(check->get());
+ else if (name == "moapbeacon") LLPipeline::setRenderMOAPBeacons(check->get());
+ else if (name == "highlights")
{
+ LLPipeline::toggleRenderHighlights(NULL);
// Don't allow both to be OFF at the same time. Toggle the other one on if both now off.
if (!LLPipeline::getRenderBeacons(NULL) &&
!LLPipeline::getRenderHighlights(NULL))
{
- if (name == "highlights")
- {
- LLPipeline::setRenderBeacons(TRUE);
- view->getChild("beacons")->setControlValue(LLSD(TRUE));
- view->getChild("beacon_width_label")->setEnabled(TRUE);
- view->getChild("beacon_width")->setEnabled(TRUE);
- }
- else
- {
- LLPipeline::setRenderHighlights(TRUE);
- view->getChild("highlights")->setControlValue(LLSD(TRUE));
- }
+ LLPipeline::setRenderBeacons(TRUE);
+ getChild("beacons")->setControlValue(LLSD(TRUE));
+ }
+ }
+ else if (name == "beacons")
+ {
+ LLPipeline::toggleRenderBeacons(NULL);
+ // Don't allow both to be OFF at the same time. Toggle the other one on if both now off.
+ if (!LLPipeline::getRenderBeacons(NULL) &&
+ !LLPipeline::getRenderHighlights(NULL))
+ {
+ LLPipeline::setRenderHighlights(TRUE);
+ getChild("highlights")->setControlValue(LLSD(TRUE));
}
}
}
diff --git a/indra/newview/llfloaterbeacons.h b/indra/newview/llfloaterbeacons.h
index c7a7b8803..03ec20d41 100644
--- a/indra/newview/llfloaterbeacons.h
+++ b/indra/newview/llfloaterbeacons.h
@@ -46,11 +46,10 @@ public:
// Needed to make the floater visibility toggle the beacons.
/*virtual*/ void open();
/*virtual*/ void close(bool app_quitting);
+ void onClickUICheck(LLUICtrl *ctrl);
private:
LLFloaterBeacons(const LLSD& seed);
-
- static void onClickUICheck(LLUICtrl *ctrl, void* data);
};
#endif
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/llfloaterdaycycle.cpp b/indra/newview/llfloaterdaycycle.cpp
index 0873c0351..3cf67821f 100644
--- a/indra/newview/llfloaterdaycycle.cpp
+++ b/indra/newview/llfloaterdaycycle.cpp
@@ -123,7 +123,7 @@ void LLFloaterDayCycle::onClickHelp(void* data)
LLFloaterDayCycle* self = LLFloaterDayCycle::instance();
std::string xml_alert = *(std::string *) data;
- LLNotifications::instance().add(self->contextualNotification(xml_alert));
+ self->addContextualNotification(xml_alert);
}
void LLFloaterDayCycle::initHelpBtn(const std::string& name, const std::string& xml_alert)
diff --git a/indra/newview/llfloaterdirectory.cpp b/indra/newview/llfloaterdirectory.cpp
index cd3c85b5f..a696e61ff 100644
--- a/indra/newview/llfloaterdirectory.cpp
+++ b/indra/newview/llfloaterdirectory.cpp
@@ -71,6 +71,8 @@
#include "llviewerregion.h"
#include "llwindow.h"
+#include "llnotifications.h"
+
const char* market_panel = "market_panel";
class LLPanelDirMarket : public LLPanelDirFind
diff --git a/indra/newview/llfloaterenvsettings.cpp b/indra/newview/llfloaterenvsettings.cpp
index 9e59cf046..57a952244 100644
--- a/indra/newview/llfloaterenvsettings.cpp
+++ b/indra/newview/llfloaterenvsettings.cpp
@@ -70,7 +70,7 @@ LLFloaterEnvSettings::~LLFloaterEnvSettings()
void LLFloaterEnvSettings::onClickHelp(void* data)
{
LLFloaterEnvSettings* self = (LLFloaterEnvSettings*)data;
- LLNotifications::instance().add(self->contextualNotification("EnvSettingsHelpButton"));
+ self->addContextualNotification("EnvSettingsHelpButton");
}
void LLFloaterEnvSettings::initCallbacks(void)
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 62fa849dd..000000000
--- a/indra/newview/llfloatermediabrowser.cpp
+++ /dev/null
@@ -1,433 +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, 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/llfloatermediasettings.cpp b/indra/newview/llfloatermediasettings.cpp
new file mode 100644
index 000000000..151ed53b6
--- /dev/null
+++ b/indra/newview/llfloatermediasettings.cpp
@@ -0,0 +1,319 @@
+/**
+ * @file llfloatermediasettings.cpp
+ * @brief Tabbed dialog for media settings - class implementation
+ *
+ * $LicenseInfo:firstyear=2002&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 "llfloatermediasettings.h"
+#include "llfloaterwhitelistentry.h"
+#include "llpanelmediasettingsgeneral.h"
+#include "llpanelmediasettingssecurity.h"
+#include "llpanelmediasettingspermissions.h"
+#include "llviewercontrol.h"
+#include "lluictrlfactory.h"
+#include "llbutton.h"
+#include "llselectmgr.h"
+#include "llsdutil.h"
+
+LLFloaterMediaSettings* LLFloaterMediaSettings::sInstance = NULL;
+
+////////////////////////////////////////////////////////////////////////////////
+//
+LLFloaterMediaSettings::LLFloaterMediaSettings(const LLSD& key)
+ : LLFloater(key),
+ mTabContainer(NULL),
+ mPanelMediaSettingsGeneral(NULL),
+ mPanelMediaSettingsSecurity(NULL),
+ mPanelMediaSettingsPermissions(NULL),
+ mWaitingToClose( false ),
+ mIdenticalHasMediaInfo( true ),
+ mMultipleMedia(false),
+ mMultipleValidMedia(false)
+{
+ LLUICtrlFactory::getInstance()->buildFloater(this,"floater_media_settings.xml");
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+LLFloaterMediaSettings::~LLFloaterMediaSettings()
+{
+ if ( mPanelMediaSettingsGeneral )
+ {
+ delete mPanelMediaSettingsGeneral;
+ mPanelMediaSettingsGeneral = NULL;
+ }
+
+ if ( mPanelMediaSettingsSecurity )
+ {
+ delete mPanelMediaSettingsSecurity;
+ mPanelMediaSettingsSecurity = NULL;
+ }
+
+ if ( mPanelMediaSettingsPermissions )
+ {
+ delete mPanelMediaSettingsPermissions;
+ mPanelMediaSettingsPermissions = NULL;
+ }
+
+ sInstance = NULL;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+BOOL LLFloaterMediaSettings::postBuild()
+{
+ mApplyBtn = getChild("Apply");
+ mApplyBtn->setClickedCallback(onBtnApply, this);
+
+ mCancelBtn = getChild("Cancel");
+ mCancelBtn->setClickedCallback(onBtnCancel, this);
+
+ mOKBtn = getChild("OK");
+ mOKBtn->setClickedCallback(onBtnOK, this);
+
+ mTabContainer = getChild( "tab_container" );
+
+ mPanelMediaSettingsGeneral = new LLPanelMediaSettingsGeneral();
+ mTabContainer->addTabPanel( mPanelMediaSettingsGeneral, mPanelMediaSettingsGeneral->getLabel() );
+ mPanelMediaSettingsGeneral->setParent( this );
+
+ // note that "permissions" tab is really "Controls" tab - refs to 'perms' and
+ // 'permissions' not changed to 'controls' since we don't want to change
+ // shared files in server code and keeping everything the same seemed best.
+ mPanelMediaSettingsPermissions = new LLPanelMediaSettingsPermissions();
+ mTabContainer->addTabPanel( mPanelMediaSettingsPermissions, mPanelMediaSettingsPermissions->getLabel() );
+
+ mPanelMediaSettingsSecurity = new LLPanelMediaSettingsSecurity();
+ mTabContainer->addTabPanel( mPanelMediaSettingsSecurity, mPanelMediaSettingsSecurity->getLabel() );
+ mPanelMediaSettingsSecurity->setParent( this );
+
+ // restore the last tab viewed from persistance variable storage
+ if (!mTabContainer->selectTab(gSavedSettings.getS32("LastMediaSettingsTab")))
+ {
+ mTabContainer->selectFirstTab();
+ };
+
+ sInstance = this;
+
+ return TRUE;
+}
+
+//static
+LLFloaterMediaSettings* LLFloaterMediaSettings::getInstance()
+{
+ if ( !sInstance )
+ {
+ sInstance = new LLFloaterMediaSettings(LLSD());
+ sInstance->setVisible(FALSE);
+ }
+
+ return sInstance;
+}
+
+//static
+void LLFloaterMediaSettings::apply()
+{
+ if (sInstance->haveValuesChanged())
+ {
+ LLSD settings;
+ sInstance->mPanelMediaSettingsGeneral->preApply();
+ sInstance->mPanelMediaSettingsGeneral->getValues( settings, false );
+ sInstance->mPanelMediaSettingsSecurity->preApply();
+ sInstance->mPanelMediaSettingsSecurity->getValues( settings, false );
+ sInstance->mPanelMediaSettingsPermissions->preApply();
+ sInstance->mPanelMediaSettingsPermissions->getValues( settings, false );
+
+ LLSelectMgr::getInstance()->selectionSetMedia( LLTextureEntry::MF_HAS_MEDIA, settings );
+
+ sInstance->mPanelMediaSettingsGeneral->postApply();
+ sInstance->mPanelMediaSettingsSecurity->postApply();
+ sInstance->mPanelMediaSettingsPermissions->postApply();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void LLFloaterMediaSettings::onClose(bool app_quitting)
+{
+ if(mPanelMediaSettingsGeneral)
+ {
+ mPanelMediaSettingsGeneral->onClose(app_quitting);
+ }
+ if(LLFloaterWhiteListEntry::instanceExists())
+ LLFloaterWhiteListEntry::getInstance()->close(app_quitting);
+
+ LLFloater::onClose(app_quitting);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//static
+void LLFloaterMediaSettings::initValues( const LLSD& media_settings, bool editable )
+{
+ if (sInstance->hasFocus()) return;
+
+ sInstance->clearValues(editable);
+ // update all panels with values from simulator
+ sInstance->mPanelMediaSettingsGeneral->
+ initValues( sInstance->mPanelMediaSettingsGeneral, media_settings, editable );
+
+ sInstance->mPanelMediaSettingsSecurity->
+ initValues( sInstance->mPanelMediaSettingsSecurity, media_settings, editable );
+
+ sInstance->mPanelMediaSettingsPermissions->
+ initValues( sInstance->mPanelMediaSettingsPermissions, media_settings, editable );
+
+ // Squirrel away initial values
+ sInstance->mInitialValues.clear();
+ sInstance->mPanelMediaSettingsGeneral->getValues( sInstance->mInitialValues );
+ sInstance->mPanelMediaSettingsSecurity->getValues( sInstance->mInitialValues );
+ sInstance->mPanelMediaSettingsPermissions->getValues( sInstance->mInitialValues );
+
+ sInstance->mApplyBtn->setEnabled(editable);
+ sInstance->mOKBtn->setEnabled(editable);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLFloaterMediaSettings::commitFields()
+{
+ if (hasFocus())
+ {
+ LLUICtrl* cur_focus = dynamic_cast(gFocusMgr.getKeyboardFocus());
+ if (cur_focus && cur_focus->acceptsTextInput())
+ {
+ cur_focus->onCommit();
+ };
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//static
+void LLFloaterMediaSettings::clearValues( bool editable)
+{
+ if (sInstance)
+ {
+ // clean up all panels before updating
+ sInstance->mPanelMediaSettingsGeneral ->clearValues(sInstance->mPanelMediaSettingsGeneral, editable);
+ sInstance->mPanelMediaSettingsSecurity ->clearValues(sInstance->mPanelMediaSettingsSecurity, editable);
+ sInstance->mPanelMediaSettingsPermissions->clearValues(sInstance->mPanelMediaSettingsPermissions, editable);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// static
+void LLFloaterMediaSettings::onBtnOK( void* userdata )
+{
+ sInstance->commitFields();
+
+ sInstance->apply();
+
+ sInstance->close();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// static
+void LLFloaterMediaSettings::onBtnApply( void* userdata )
+{
+ sInstance->commitFields();
+
+ sInstance->apply();
+
+ sInstance->mInitialValues.clear();
+ sInstance->mPanelMediaSettingsGeneral->getValues( sInstance->mInitialValues );
+ sInstance->mPanelMediaSettingsSecurity->getValues( sInstance->mInitialValues );
+ sInstance->mPanelMediaSettingsPermissions->getValues( sInstance->mInitialValues );
+
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// static
+void LLFloaterMediaSettings::onBtnCancel( void* userdata )
+{
+ sInstance->close();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// static
+void LLFloaterMediaSettings::onTabChanged(void* user_data, bool from_click)
+{
+ LLTabContainer* self = (LLTabContainer*)user_data;
+ gSavedSettings.setS32("LastMediaSettingsTab", self->getCurrentPanelIndex());
+}
+////////////////////////////////////////////////////////////////////////////////
+//
+const std::string LLFloaterMediaSettings::getHomeUrl()
+{
+ if ( mPanelMediaSettingsGeneral )
+ return mPanelMediaSettingsGeneral->getHomeUrl();
+ else
+ return std::string( "" );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// virtual
+void LLFloaterMediaSettings::draw()
+{
+ if (NULL != mApplyBtn)
+ {
+ // Set the enabled state of the "Apply" button if values changed
+ mApplyBtn->setEnabled( haveValuesChanged() );
+ }
+
+ LLFloater::draw();
+}
+
+
+//private
+bool LLFloaterMediaSettings::haveValuesChanged() const
+{
+ bool values_changed = false;
+ // *NOTE: The code below is very inefficient. Better to do this
+ // only when data change.
+ // Every frame, check to see what the values are. If they are not
+ // the same as the initial media data, enable the OK/Apply buttons
+ LLSD settings;
+ sInstance->mPanelMediaSettingsGeneral->getValues( settings );
+ sInstance->mPanelMediaSettingsSecurity->getValues( settings );
+ sInstance->mPanelMediaSettingsPermissions->getValues( settings );
+ LLSD::map_const_iterator iter = settings.beginMap();
+ LLSD::map_const_iterator end = settings.endMap();
+ for ( ; iter != end; ++iter )
+ {
+ const std::string ¤t_key = iter->first;
+ const LLSD ¤t_value = iter->second;
+ if ( ! llsd_equals(current_value, mInitialValues[current_key]))
+ {
+ values_changed = true;
+ break;
+ }
+ }
+ return values_changed;
+}
+
+bool LLFloaterMediaSettings::instanceExists()
+{
+ return sInstance;
+}
+
+
diff --git a/indra/newview/llfloatermediasettings.h b/indra/newview/llfloatermediasettings.h
new file mode 100644
index 000000000..1d2553098
--- /dev/null
+++ b/indra/newview/llfloatermediasettings.h
@@ -0,0 +1,89 @@
+/**
+ * @file llfloatermediasettings.cpp
+ * @brief Tabbed dialog for media settings - class definition
+ *
+ * $LicenseInfo:firstyear=2002&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_LLFLOATERMEDIASETTINGS_H
+#define LL_LLFLOATERMEDIASETTINGS_H
+
+#include "llfloater.h"
+#include "lltabcontainer.h"
+
+class LLPanelMediaSettingsGeneral;
+class LLPanelMediaSettingsSecurity;
+class LLPanelMediaSettingsPermissions;
+
+class LLFloaterMediaSettings :
+ public LLFloater
+{
+public:
+ LLFloaterMediaSettings(const LLSD& key);
+ ~LLFloaterMediaSettings();
+
+ /*virtual*/ BOOL postBuild();
+ /*virtual*/ void onClose(bool app_quitting);
+
+ static LLFloaterMediaSettings* getInstance();
+ static bool instanceExists();
+ static void apply();
+ static void initValues( const LLSD& media_settings , bool editable);
+ static void clearValues( bool editable);
+
+ LLPanelMediaSettingsSecurity* getPanelSecurity(){return mPanelMediaSettingsSecurity;};
+ const std::string getHomeUrl();
+ //bool passesWhiteList( const std::string& test_url );
+
+ virtual void draw();
+
+ bool mIdenticalHasMediaInfo;
+ bool mMultipleMedia;
+ bool mMultipleValidMedia;
+
+protected:
+ LLButton *mOKBtn;
+ LLButton *mCancelBtn;
+ LLButton *mApplyBtn;
+
+ LLTabContainer *mTabContainer;
+ LLPanelMediaSettingsGeneral* mPanelMediaSettingsGeneral;
+ LLPanelMediaSettingsSecurity* mPanelMediaSettingsSecurity;
+ LLPanelMediaSettingsPermissions* mPanelMediaSettingsPermissions;
+
+ static void onBtnOK(void*);
+ static void onBtnCancel(void*);
+ static void onBtnApply(void*);
+ static void onTabChanged(void* user_data, bool from_click);
+ void commitFields();
+
+ static LLFloaterMediaSettings* sInstance;
+
+private:
+
+ bool haveValuesChanged() const;
+
+ LLSD mInitialValues;
+ bool mWaitingToClose;
+};
+
+#endif // LL_LLFLOATERMEDIASETTINGS_H
diff --git a/indra/newview/llfloaternotificationsconsole.cpp b/indra/newview/llfloaternotificationsconsole.cpp
index fc358d79a..d4133befe 100644
--- a/indra/newview/llfloaternotificationsconsole.cpp
+++ b/indra/newview/llfloaternotificationsconsole.cpp
@@ -43,7 +43,7 @@
const S32 NOTIFICATION_PANEL_HEADER_HEIGHT = 20;
const S32 HEADER_PADDING = 38;
-class LLNotificationChannelPanel : public LLPanel
+class LLNotificationChannelPanel : public LLLayoutPanel
{
public:
LLNotificationChannelPanel(const std::string& channel_name);
@@ -59,8 +59,9 @@ private:
};
LLNotificationChannelPanel::LLNotificationChannelPanel(const std::string& channel_name)
- : LLPanel(channel_name)
+ : LLLayoutPanel(NOTIFICATION_PANEL_HEADER_HEIGHT,true,true)
{
+ setName(channel_name);
mChannelPtr = LLNotifications::instance().getChannel(channel_name);
mChannelRejectsPtr = LLNotificationChannelPtr(
LLNotificationChannel::buildChannel(channel_name + "rejects", mChannelPtr->getParentChannelName(), !boost::bind(mChannelPtr->getFilter(), _1)));
@@ -203,7 +204,7 @@ void LLFloaterNotificationConsole::addChannel(const std::string& name, bool open
{
LLLayoutStack& stack = getChildRef("notification_channels");
LLNotificationChannelPanel* panelp = new LLNotificationChannelPanel(name);
- stack.addPanel(panelp, 0, NOTIFICATION_PANEL_HEADER_HEIGHT, TRUE, TRUE, LLLayoutStack::ANIMATE);
+ stack.addPanel(panelp, LLLayoutStack::ANIMATE);
LLButton& header_button = panelp->getChildRef("header");
header_button.setToggleState(!open);
@@ -217,7 +218,7 @@ void LLFloaterNotificationConsole::removeChannel(const std::string& name)
LLPanel* panelp = getChild(name, TRUE, FALSE);
if (panelp)
{
- getChildRef("notification_channels").removePanel(panelp);
+ getChildRef("notification_channels").removeChild(panelp);
delete panelp;
}
diff --git a/indra/newview/llfloaternotificationsconsole.h b/indra/newview/llfloaternotificationsconsole.h
index 302428a3f..c4a361538 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/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index 387c20ccc..ea6a0e0fd 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -124,6 +124,7 @@ public:
static void closeWithoutSaving();
protected:
+ friend class LLPanelNearByMedia;
LLPreferenceCore *mPreferenceCore;
/*virtual*/ void onClose(bool app_quitting);
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/llfloatertools.cpp b/indra/newview/llfloatertools.cpp
index 1cbaac1a7..d63fde073 100644
--- a/indra/newview/llfloatertools.cpp
+++ b/indra/newview/llfloatertools.cpp
@@ -45,9 +45,13 @@
#include "llcombobox.h"
#include "lldraghandle.h"
#include "llfloaterbuildoptions.h"
+#include "llfloatermediasettings.h"
#include "llfloateropenobject.h"
#include "llfocusmgr.h"
+#include "llmediaentry.h"
+#include "llmediactrl.h"
#include "llmenugl.h"
+#include "llnotificationsutil.h"
#include "llpanelcontents.h"
#include "llpanelface.h"
#include "llpanelland.h"
@@ -55,6 +59,7 @@
#include "llpanelobject.h"
#include "llpanelvolume.h"
#include "llpanelpermissions.h"
+#include "llparcel.h"
#include "llresmgr.h"
#include "llselectmgr.h"
#include "llslider.h"
@@ -74,12 +79,15 @@
#include "lltoolpipette.h"
#include "lltoolplacer.h"
#include "lltoolselectland.h"
+#include "lltrans.h"
#include "llui.h"
#include "llviewercontrol.h"
#include "llviewerjoystick.h"
+#include "llviewerregion.h"
#include "llviewermenu.h"
#include "llviewerparcelmgr.h"
#include "llviewerwindow.h"
+#include "llvovolume.h"
#include "lluictrlfactory.h"
#include "llmeshrepository.h"
@@ -103,23 +111,21 @@ const std::string PANEL_NAMES[LLFloaterTools::PANEL_COUNT] =
// Local prototypes
-void commit_grid_mode(LLUICtrl *ctrl, void*);
-void commit_select_component(LLUICtrl *ctrl, void *data);
+void commit_grid_mode(LLUICtrl *ctrl);
+void commit_select_component(void *data);
void click_show_more(void*);
void click_popup_info(void*);
void click_popup_done(void*);
void click_popup_minimize(void*);
-void click_popup_grab_drag(LLUICtrl *, void*);
-void click_popup_grab_lift(LLUICtrl *, void*);
-void click_popup_grab_spin(LLUICtrl *, void*);
-void click_popup_dozer_mode(LLUICtrl *, void *user);
-void commit_slider_dozer_size(LLUICtrl *, void*);
-void commit_slider_dozer_force(LLUICtrl *, void*);
+void commit_slider_dozer_size(LLUICtrl *);
+void commit_slider_dozer_force(LLUICtrl *);
void click_apply_to_selection(void*);
-void commit_radio_zoom(LLUICtrl *, void*);
-void commit_radio_orbit(LLUICtrl *, void*);
-void commit_radio_pan(LLUICtrl *, void*);
-void commit_slider_zoom(LLUICtrl *ctrl, void*);
+void commit_radio_group_focus(LLUICtrl* ctrl);
+void commit_radio_group_move(LLUICtrl* ctrl);
+void commit_radio_group_edit(LLUICtrl* ctrl);
+void commit_radio_group_land(LLUICtrl* ctrl);
+
+void commit_slider_zoom(LLUICtrl *ctrl);
void commit_select_tool(LLUICtrl *ctrl, void *data);
@@ -224,58 +230,40 @@ BOOL LLFloaterTools::postBuild()
LLRect rect;
mBtnFocus = getChild("button focus");//btn;
- childSetAction("button focus",LLFloaterTools::setEditTool, (void*)LLToolCamera::getInstance());
mBtnMove = getChild("button move");
- childSetAction("button move",LLFloaterTools::setEditTool, (void*)LLToolGrab::getInstance());
mBtnEdit = getChild("button edit");
- childSetAction("button edit",LLFloaterTools::setEditTool, (void*)LLToolCompTranslate::getInstance());
mBtnCreate = getChild("button create");
- childSetAction("button create",LLFloaterTools::setEditTool, (void*)LLToolCompCreate::getInstance());
mBtnLand = getChild("button land" );
- childSetAction("button land",LLFloaterTools::setEditTool, (void*)LLToolSelectLand::getInstance());
mTextStatus = getChild("text status");
- childSetCommitCallback("slider zoom",commit_slider_zoom,this);
mRadioZoom = getChild("radio zoom");
- childSetCommitCallback("radio zoom",commit_radio_zoom,this);
mRadioOrbit = getChild("radio orbit");
- childSetCommitCallback("radio orbit",commit_radio_orbit,this);
mRadioPan = getChild("radio pan");
- childSetCommitCallback("radio pan",commit_radio_pan,this);
mRadioMove = getChild("radio move");
- childSetCommitCallback("radio move",click_popup_grab_drag,this);
mRadioLift = getChild("radio lift");
- childSetCommitCallback("radio lift",click_popup_grab_lift,this);
mRadioSpin = getChild("radio spin");
- childSetCommitCallback("radio spin",click_popup_grab_spin,NULL);
mRadioPosition = getChild("radio position");
- childSetCommitCallback("radio position",commit_select_tool,NULL);
mRadioRotate = getChild("radio rotate");
- childSetCommitCallback("radio rotate",commit_select_tool,NULL);
mRadioStretch = getChild("radio stretch");
- childSetCommitCallback("radio stretch",commit_select_tool,NULL);
mRadioSelectFace = getChild("radio select face");
- childSetCommitCallback("radio select face",commit_select_tool,NULL);
mRadioAlign = getChild("radio align");
- childSetCommitCallback("radio align",commit_select_tool,NULL);
+ mTitleMedia = getChild("title_media");
+
mCheckSelectIndividual = getChild("checkbox edit linked parts");
- childSetValue("checkbox edit linked parts",(BOOL)gSavedSettings.getBOOL("EditLinkedParts"));
- childSetCommitCallback("checkbox edit linked parts",commit_select_component,this);
+ getChild("checkbox edit linked parts")->setValue((BOOL)gSavedSettings.getBOOL("EditLinkedParts"));
mCheckSnapToGrid = getChild("checkbox snap to grid");
- childSetValue("checkbox snap to grid",(BOOL)gSavedSettings.getBOOL("SnapEnabled"));
+ getChild("checkbox snap to grid")->setValue((BOOL)gSavedSettings.getBOOL("SnapEnabled"));
mBtnGridOptions = getChild("Options...");
- childSetAction("Options...",onClickGridOptions, this);
mCheckStretchUniform = getChild("checkbox uniform");
- childSetValue("checkbox uniform",(BOOL)gSavedSettings.getBOOL("ScaleUniform"));
+ getChild("checkbox uniform")->setValue((BOOL)gSavedSettings.getBOOL("ScaleUniform"));
mCheckStretchTexture = getChild("checkbox stretch textures");
- childSetValue("checkbox stretch textures",(BOOL)gSavedSettings.getBOOL("ScaleStretchTextures"));
+ getChild("checkbox stretch textures")->setValue((BOOL)gSavedSettings.getBOOL("ScaleStretchTextures"));
mCheckLimitDrag = getChild("checkbox limit drag distance");
childSetValue("checkbox limit drag distance",(BOOL)gSavedSettings.getBOOL("LimitDragDistance"));
mTextGridMode = getChild("text ruler mode");
mComboGridMode = getChild("combobox grid mode");
- childSetCommitCallback("combobox grid mode",commit_grid_mode, this);
mCheckShowHighlight = getChild("checkbox show highlight");
mCheckActualRoot = getChild("checkbox actual root");
@@ -297,38 +285,28 @@ BOOL LLFloaterTools::postBuild()
if ((mComboTreesGrass = findChild("trees_grass")))
childSetCommitCallback("trees_grass", onSelectTreesGrass, (void*)0);
mCheckCopySelection = getChild("checkbox copy selection");
- childSetValue("checkbox copy selection",(BOOL)gSavedSettings.getBOOL("CreateToolCopySelection"));
+ getChild("checkbox copy selection")->setValue((BOOL)gSavedSettings.getBOOL("CreateToolCopySelection"));
mCheckSticky = getChild("checkbox sticky");
- childSetValue("checkbox sticky",(BOOL)gSavedSettings.getBOOL("CreateToolKeepSelected"));
+ getChild("checkbox sticky")->setValue((BOOL)gSavedSettings.getBOOL("CreateToolKeepSelected"));
mCheckCopyCenters = getChild("checkbox copy centers");
- childSetValue("checkbox copy centers",(BOOL)gSavedSettings.getBOOL("CreateToolCopyCenters"));
+ getChild("checkbox copy centers")->setValue((BOOL)gSavedSettings.getBOOL("CreateToolCopyCenters"));
mCheckCopyRotates = getChild("checkbox copy rotates");
- childSetValue("checkbox copy rotates",(BOOL)gSavedSettings.getBOOL("CreateToolCopyRotates"));
+ getChild("checkbox copy rotates")->setValue((BOOL)gSavedSettings.getBOOL("CreateToolCopyRotates"));
mRadioSelectLand = getChild("radio select land");
- childSetCommitCallback("radio select land",commit_select_tool, NULL);
mRadioDozerFlatten = getChild("radio flatten");
- childSetCommitCallback("radio flatten",click_popup_dozer_mode, (void*)0);
mRadioDozerRaise = getChild("radio raise");
- childSetCommitCallback("radio raise",click_popup_dozer_mode, (void*)1);
mRadioDozerLower = getChild("radio lower");
- childSetCommitCallback("radio lower",click_popup_dozer_mode, (void*)2);
mRadioDozerSmooth = getChild("radio smooth");
- childSetCommitCallback("radio smooth",click_popup_dozer_mode, (void*)3);
mRadioDozerNoise = getChild("radio noise");
- childSetCommitCallback("radio noise",click_popup_dozer_mode, (void*)4);
mRadioDozerRevert = getChild("radio revert");
- childSetCommitCallback("radio revert",click_popup_dozer_mode, (void*)5);
mBtnApplyToSelection = getChild("button apply to selection");
- childSetAction("button apply to selection",click_apply_to_selection, (void*)0);
mSliderDozerSize = getChild("slider brush size");
- childSetCommitCallback("slider brush size", commit_slider_dozer_size, (void*)0);
- childSetValue( "slider brush size", gSavedSettings.getF32("LandBrushSize"));
+ getChild("slider brush size")->setValue(gSavedSettings.getF32("LandBrushSize"));
mSliderDozerForce = getChild("slider force");
- childSetCommitCallback("slider force",commit_slider_dozer_force, (void*)0);
// the setting stores the actual force multiplier, but the slider is logarithmic, so we convert here
- childSetValue("slider force", log10(gSavedSettings.getF32("LandBrushForce")));
+ getChild("slider force")->setValue(log10(gSavedSettings.getF32("LandBrushForce")));
mTab = getChild("Object Info Tabs");
if(mTab)
@@ -362,14 +340,17 @@ LLFloaterTools::LLFloaterTools()
mBtnLand(NULL),
mTextStatus(NULL),
+ //Camera Focus
mRadioOrbit(NULL),
mRadioZoom(NULL),
mRadioPan(NULL),
+ //Move via physics
mRadioMove(NULL),
mRadioLift(NULL),
mRadioSpin(NULL),
+ //Edit prim
mRadioPosition(NULL),
mRadioRotate(NULL),
mRadioStretch(NULL),
@@ -380,6 +361,7 @@ LLFloaterTools::LLFloaterTools()
mCheckSnapToGrid(NULL),
mBtnGridOptions(NULL),
mTextGridMode(NULL),
+ mTitleMedia(NULL),
mComboGridMode(NULL),
mCheckStretchUniform(NULL),
mCheckStretchTexture(NULL),
@@ -400,6 +382,8 @@ LLFloaterTools::LLFloaterTools()
mCheckCopySelection(NULL),
mCheckCopyCenters(NULL),
mCheckCopyRotates(NULL),
+
+ //Edit land
mRadioSelectLand(NULL),
mRadioDozerFlatten(NULL),
mRadioDozerRaise(NULL),
@@ -407,6 +391,7 @@ LLFloaterTools::LLFloaterTools()
mRadioDozerSmooth(NULL),
mRadioDozerNoise(NULL),
mRadioDozerRevert(NULL),
+
mSliderDozerSize(NULL),
mSliderDozerForce(NULL),
mBtnApplyToSelection(NULL),
@@ -419,7 +404,8 @@ LLFloaterTools::LLFloaterTools()
mPanelFace(NULL),
mPanelLandInfo(NULL),
- mDirty(TRUE)
+ mDirty(TRUE),
+ mNeedMediaTitle(TRUE)
{
setAutoFocus(FALSE);
LLCallbackMap::map_t factory_map;
@@ -431,6 +417,23 @@ LLFloaterTools::LLFloaterTools()
factory_map["ContentsInventory"] = LLCallbackMap(createPanelContentsInventory, this);//LLPanelContents
factory_map["land info panel"] = LLCallbackMap(createPanelLandInfo, this);//LLPanelLandInfo
+ mCommitCallbackRegistrar.add("BuildTool.setTool", boost::bind(&LLFloaterTools::setTool,this, _2));
+ mCommitCallbackRegistrar.add("BuildTool.commitDozerSize", boost::bind(&commit_slider_dozer_size, _1));
+ mCommitCallbackRegistrar.add("BuildTool.commitZoom", boost::bind(&commit_slider_zoom, _1));
+ mCommitCallbackRegistrar.add("BuildTool.commitRadioFocus", boost::bind(&commit_radio_group_focus, _1));
+ mCommitCallbackRegistrar.add("BuildTool.commitRadioMove", boost::bind(&commit_radio_group_move,_1));
+ mCommitCallbackRegistrar.add("BuildTool.commitRadioEdit", boost::bind(&commit_radio_group_edit,_1));
+
+ mCommitCallbackRegistrar.add("BuildTool.gridMode", boost::bind(&commit_grid_mode,_1));
+ mCommitCallbackRegistrar.add("BuildTool.selectComponent", boost::bind(&commit_select_component, this));
+ mCommitCallbackRegistrar.add("BuildTool.gridOptions", boost::bind(&LLFloaterTools::onClickGridOptions,this));
+ mCommitCallbackRegistrar.add("BuildTool.applyToSelection", boost::bind(&click_apply_to_selection, this));
+ mCommitCallbackRegistrar.add("BuildTool.commitRadioLand", boost::bind(&commit_radio_group_land,_1));
+ mCommitCallbackRegistrar.add("BuildTool.LandBrushForce", boost::bind(&commit_slider_dozer_force,_1));
+ mCommitCallbackRegistrar.add("BuildTool.AddMedia", boost::bind(&LLFloaterTools::onClickBtnAddMedia,this));
+ mCommitCallbackRegistrar.add("BuildTool.DeleteMedia", boost::bind(&LLFloaterTools::onClickBtnDeleteMedia,this));
+ mCommitCallbackRegistrar.add("BuildTool.EditMedia", boost::bind(&LLFloaterTools::onClickBtnEditMedia,this));
+
LLUICtrlFactory::getInstance()->buildFloater(this,"floater_tools.xml",&factory_map,FALSE);
}
@@ -539,6 +542,8 @@ void LLFloaterTools::refresh()
mPanelObject->refresh();
mPanelVolume->refresh();
mPanelFace->refresh();
+ if(mTitleMedia)
+ refreshMedia();
mPanelContents->refresh();
mPanelLandInfo->refresh();
}
@@ -551,6 +556,10 @@ void LLFloaterTools::draw()
mDirty = FALSE;
}
+ // grab media name/title and update the UI widget
+ if(mTitleMedia)
+ updateMediaTitle();
+
// mCheckSelectIndividual->set(gSavedSettings.getBOOL("EditLinkedParts"));
LLFloater::draw();
}
@@ -755,8 +764,8 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask)
if (mCheckCopyCenters) mCheckCopyCenters ->setVisible( create_visible );
if (mCheckCopyRotates) mCheckCopyRotates ->setVisible( create_visible );
- if (mCheckCopyCenters) mCheckCopyCenters->setEnabled( mCheckCopySelection->get() );
- if (mCheckCopyRotates) mCheckCopyRotates->setEnabled( mCheckCopySelection->get() );
+ if (mCheckCopyCenters && mCheckCopySelection) mCheckCopyCenters->setEnabled( mCheckCopySelection->get() );
+ if (mCheckCopyRotates && mCheckCopySelection) mCheckCopyRotates->setEnabled( mCheckCopySelection->get() );
// Land buttons
BOOL land_visible = (tool == LLToolBrushLand::getInstance() || tool == LLToolSelectLand::getInstance() );
@@ -809,13 +818,13 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask)
if (mSliderDozerSize)
{
mSliderDozerSize ->setVisible( land_visible );
- childSetVisible("Bulldozer:", land_visible);
- childSetVisible("Dozer Size:", land_visible);
+ getChildView("Bulldozer:")->setVisible( land_visible);
+ getChildView("Dozer Size:")->setVisible( land_visible);
}
if (mSliderDozerForce)
{
mSliderDozerForce ->setVisible( land_visible );
- childSetVisible("Strength:", land_visible);
+ getChildView("Strength:")->setVisible( land_visible);
}
childSetVisible("link_num_obj_count", !land_visible);
@@ -851,6 +860,10 @@ void LLFloaterTools::onClose(bool app_quitting)
LLViewerJoystick::getInstance()->moveAvatar(false);
+ // destroy media source used to grab media title
+ if( mTitleMedia )
+ mTitleMedia->unloadMediaSource();
+
// Different from handle_reset_view in that it doesn't actually
// move the camera if EditCameraMovement is not set.
gAgentCamera.resetView(gSavedSettings.getBOOL("EditCameraMovement"));
@@ -885,6 +898,9 @@ void LLFloaterTools::onClose(bool app_quitting)
// gMenuBarView->setItemVisible(std::string("Tools"), FALSE);
// gMenuBarView->arrange();
+
+ if(LLFloaterMediaSettings::instanceExists())
+ LLFloaterMediaSettings::getInstance()->close();
}
void LLFloaterTools::showPanel(EInfoPanel panel)
@@ -903,66 +919,63 @@ void click_popup_done(void*)
handle_reset_view();
}
-void click_popup_grab_drag(LLUICtrl*, void*)
+void commit_radio_group_move(LLUICtrl* ctrl)
{
- gGrabBtnVertical = FALSE;
- gGrabBtnSpin = FALSE;
+ std::string selected = ctrl->getName();
+ if (selected == "radio move")
+ {
+ gGrabBtnVertical = FALSE;
+ gGrabBtnSpin = FALSE;
+ }
+ else if (selected == "radio lift")
+ {
+ gGrabBtnVertical = TRUE;
+ gGrabBtnSpin = FALSE;
+ }
+ else if (selected == "radio spin")
+ {
+ gGrabBtnVertical = FALSE;
+ gGrabBtnSpin = TRUE;
+ }
}
-void click_popup_grab_lift(LLUICtrl*, void*)
+void commit_radio_group_focus(LLUICtrl* ctrl)
{
- gGrabBtnVertical = TRUE;
- gGrabBtnSpin = FALSE;
+ std::string selected = ctrl->getName();
+ if (selected == "radio zoom")
+ {
+ gCameraBtnZoom = TRUE;
+ gCameraBtnOrbit = FALSE;
+ gCameraBtnPan = FALSE;
+ }
+ else if (selected == "radio orbit")
+ {
+ gCameraBtnZoom = FALSE;
+ gCameraBtnOrbit = TRUE;
+ gCameraBtnPan = FALSE;
+ }
+ else if (selected == "radio pan")
+ {
+ gCameraBtnZoom = FALSE;
+ gCameraBtnOrbit = FALSE;
+ gCameraBtnPan = TRUE;
+ }
}
-void click_popup_grab_spin(LLUICtrl*, void*)
-{
- gGrabBtnVertical = FALSE;
- gGrabBtnSpin = TRUE;
-}
-
-void commit_radio_zoom(LLUICtrl *, void*)
-{
- gCameraBtnZoom = TRUE;
- gCameraBtnOrbit = FALSE;
- gCameraBtnPan = FALSE;
-}
-
-void commit_radio_orbit(LLUICtrl *, void*)
-{
- gCameraBtnZoom = FALSE;
- gCameraBtnOrbit = TRUE;
- gCameraBtnPan = FALSE;
-}
-
-void commit_radio_pan(LLUICtrl *, void*)
-{
- gCameraBtnZoom = FALSE;
- gCameraBtnOrbit = FALSE;
- gCameraBtnPan = TRUE;
-}
-
-void commit_slider_zoom(LLUICtrl *ctrl, void*)
+void commit_slider_zoom(LLUICtrl *ctrl)
{
// renormalize value, since max "volume" level is 0.5 for some reason
F32 zoom_level = (F32)ctrl->getValue().asReal() * 2.f; // / 0.5f;
gAgentCamera.setCameraZoomFraction(zoom_level);
}
-void click_popup_dozer_mode(LLUICtrl *, void *user)
-{
- S32 mode = (S32)(intptr_t) user;
- gFloaterTools->setEditTool( LLToolBrushLand::getInstance() );
- gSavedSettings.setS32("RadioLandBrushAction", mode);
-}
-
-void commit_slider_dozer_size(LLUICtrl *ctrl, void*)
+void commit_slider_dozer_size(LLUICtrl *ctrl)
{
F32 size = (F32)ctrl->getValue().asReal();
gSavedSettings.setF32("LandBrushSize", size);
}
-void commit_slider_dozer_force(LLUICtrl *ctrl, void*)
+void commit_slider_dozer_force(LLUICtrl *ctrl)
{
// the slider is logarithmic, so we exponentiate to get the actual force multiplier
F32 dozer_force = pow(10.f, (F32)ctrl->getValue().asReal());
@@ -974,12 +987,11 @@ void click_apply_to_selection(void*)
LLToolBrushLand::getInstance()->modifyLandInSelectionGlobal();
}
-void commit_select_tool(LLUICtrl *ctrl, void *data)
+void commit_radio_group_edit(LLUICtrl *ctrl)
{
S32 show_owners = gSavedSettings.getBOOL("ShowParcelOwners");
- LLCheckBoxCtrl* group = (LLCheckBoxCtrl*)ctrl;
- std::string selected = group->getName();
+ std::string selected = ctrl->getName();
if (selected == "radio position")
{
LLFloaterTools::setEditTool( LLToolCompTranslate::getInstance() );
@@ -1000,14 +1012,37 @@ void commit_select_tool(LLUICtrl *ctrl, void *data)
{
LLFloaterTools::setEditTool( QToolAlign::getInstance() );
}
- else if (selected == "radio select land")
- {
- LLFloaterTools::setEditTool( LLToolSelectLand::getInstance());
- }
gSavedSettings.setBOOL("ShowParcelOwners", show_owners);
}
-void commit_select_component(LLUICtrl *ctrl, void *data)
+void commit_radio_group_land(LLUICtrl* ctrl)
+{
+ std::string selected = ctrl->getName();
+ if (selected == "radio select land")
+ {
+ LLFloaterTools::setEditTool( LLToolSelectLand::getInstance() );
+ }
+ else
+ {
+ LLFloaterTools::setEditTool( LLToolBrushLand::getInstance() );
+ S32 dozer_mode = gSavedSettings.getS32("RadioLandBrushAction");
+ if (selected == "radio flatten")
+ dozer_mode = 0;
+ else if (selected == "radio raise")
+ dozer_mode = 1;
+ else if (selected == "radio lower")
+ dozer_mode = 2;
+ else if (selected == "radio smooth")
+ dozer_mode = 3;
+ else if (selected == "radio noise")
+ dozer_mode = 4;
+ else if (selected == "radio revert")
+ dozer_mode = 5;
+ gSavedSettings.setS32("RadioLandBrushAction", dozer_mode);
+ }
+}
+
+void commit_select_component(void *data)
{
LLFloaterTools* floaterp = (LLFloaterTools*)data;
@@ -1039,15 +1074,14 @@ void LLFloaterTools::setObjectType( LLPCode pcode )
gFocusMgr.setMouseCapture(NULL);
}
-void commit_grid_mode(LLUICtrl *ctrl, void *data)
+void commit_grid_mode(LLUICtrl *ctrl)
{
LLComboBox* combo = (LLComboBox*)ctrl;
LLSelectMgr::getInstance()->setGridMode((EGridMode)combo->getCurrentIndex());
}
-// static
-void LLFloaterTools::onClickGridOptions(void* data)
+void LLFloaterTools::onClickGridOptions()
{
//LLFloaterTools* floaterp = (LLFloaterTools*)data;
LLFloaterBuildOptions::show(NULL);
@@ -1055,18 +1089,866 @@ void LLFloaterTools::onClickGridOptions(void* data)
//floaterp->addDependentFloater(LLFloaterBuildOptions::getInstance(), FALSE);
}
+// static
void LLFloaterTools::setEditTool(void* tool_pointer)
{
LLTool *tool = (LLTool *)tool_pointer;
LLToolMgr::getInstance()->getCurrentToolset()->selectTool( tool );
}
+void LLFloaterTools::setTool(const LLSD& user_data)
+{
+ std::string control_name = user_data.asString();
+ if(control_name == "Focus")
+ LLToolMgr::getInstance()->getCurrentToolset()->selectTool((LLTool *) LLToolCamera::getInstance() );
+ else if (control_name == "Move" )
+ LLToolMgr::getInstance()->getCurrentToolset()->selectTool( (LLTool *)LLToolGrab::getInstance() );
+ else if (control_name == "Edit" )
+ LLToolMgr::getInstance()->getCurrentToolset()->selectTool( (LLTool *) LLToolCompTranslate::getInstance());
+ else if (control_name == "Create" )
+ LLToolMgr::getInstance()->getCurrentToolset()->selectTool( (LLTool *) LLToolCompCreate::getInstance());
+ else if (control_name == "Land" )
+ LLToolMgr::getInstance()->getCurrentToolset()->selectTool( (LLTool *) LLToolSelectLand::getInstance());
+ else
+ llwarns<<" no parameter name "<setCurrentToolset(gBasicToolset);
LLFloater::onFocusReceived();
}
+// Media stuff
+void LLFloaterTools::refreshMedia()
+{
+ if(!mTitleMedia)
+ return;
+ getMediaState();
+}
+
+bool LLFloaterTools::selectedMediaEditable()
+{
+ U32 owner_mask_on;
+ U32 owner_mask_off;
+ U32 valid_owner_perms = LLSelectMgr::getInstance()->selectGetPerm( PERM_OWNER,
+ &owner_mask_on, &owner_mask_off );
+ U32 group_mask_on;
+ U32 group_mask_off;
+ U32 valid_group_perms = LLSelectMgr::getInstance()->selectGetPerm( PERM_GROUP,
+ &group_mask_on, &group_mask_off );
+ U32 everyone_mask_on;
+ U32 everyone_mask_off;
+ S32 valid_everyone_perms = LLSelectMgr::getInstance()->selectGetPerm( PERM_EVERYONE,
+ &everyone_mask_on, &everyone_mask_off );
+
+ bool selected_Media_editable = false;
+
+ // if perms we got back are valid
+ if ( valid_owner_perms &&
+ valid_group_perms &&
+ valid_everyone_perms )
+ {
+
+ if ( ( owner_mask_on & PERM_MODIFY ) ||
+ ( group_mask_on & PERM_MODIFY ) ||
+ ( group_mask_on & PERM_MODIFY ) )
+ {
+ selected_Media_editable = true;
+ }
+ else
+ // user is NOT allowed to press the RESET button
+ {
+ selected_Media_editable = false;
+ };
+ };
+
+ return selected_Media_editable;
+}
+void LLFloaterTools::getMediaState()
+{
+ LLObjectSelectionHandle selected_objects =LLSelectMgr::getInstance()->getSelection();
+ LLViewerObject* first_object = selected_objects->getFirstObject();
+ LLTextBox* media_info = getChild("media_info");
+
+ if( !(first_object
+ && first_object->getPCode() == LL_PCODE_VOLUME
+ &&first_object->permModify()
+ ))
+ {
+ getChildView("Add_Media")->setEnabled(FALSE);
+ media_info->setValue("");
+ clearMediaSettings();
+ return;
+ }
+
+ std::string url = first_object->getRegion()->getCapability("ObjectMedia");
+ bool has_media_capability = (!url.empty());
+
+ if(!has_media_capability)
+ {
+ getChildView("Add_Media")->setEnabled(FALSE);
+ LL_WARNS("LLFloaterTools: media") << "Media not enabled (no capability) in this region!" << LL_ENDL;
+ clearMediaSettings();
+ return;
+ }
+
+ BOOL is_nonpermanent_enforced = (LLSelectMgr::getInstance()->getSelection()->getFirstRootNode()
+ && LLSelectMgr::getInstance()->selectGetRootsNonPermanentEnforced())
+ || LLSelectMgr::getInstance()->selectGetNonPermanentEnforced();
+ bool editable = is_nonpermanent_enforced && (first_object->permModify() || selectedMediaEditable());
+
+ // Check modify permissions and whether any selected objects are in
+ // the process of being fetched. If they are, then we're not editable
+ if (editable)
+ {
+ LLObjectSelection::iterator iter = selected_objects->begin();
+ LLObjectSelection::iterator end = selected_objects->end();
+ for ( ; iter != end; ++iter)
+ {
+ LLSelectNode* node = *iter;
+ LLVOVolume* object = dynamic_cast(node->getObject());
+ if (NULL != object)
+ {
+ if (!object->permModify())
+ {
+ LL_INFOS("LLFloaterTools: media")
+ << "Selection not editable due to lack of modify permissions on object id "
+ << object->getID() << LL_ENDL;
+
+ editable = false;
+ break;
+ }
+ // XXX DISABLE this for now, because when the fetch finally
+ // does come in, the state of this floater doesn't properly
+ // update. Re-selecting fixes the problem, but there is
+ // contention as to whether this is a sufficient solution.
+// if (object->isMediaDataBeingFetched())
+// {
+// LL_INFOS("LLFloaterTools: media")
+// << "Selection not editable due to media data being fetched for object id "
+// << object->getID() << LL_ENDL;
+//
+// editable = false;
+// break;
+// }
+ }
+ }
+ }
+
+ // Media settings
+ bool bool_has_media = false;
+ struct media_functor : public LLSelectedTEGetFunctor
+ {
+ bool get(LLViewerObject* object, S32 face)
+ {
+ LLTextureEntry *te = object->getTE(face);
+ if (te)
+ {
+ return te->hasMedia();
+ }
+ return false;
+ }
+ } func;
+
+
+ // check if all faces have media(or, all dont have media)
+ LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo = selected_objects->getSelectedTEValue( &func, bool_has_media );
+
+ const LLMediaEntry default_media_data;
+
+ struct functor_getter_media_data : public LLSelectedTEGetFunctor< LLMediaEntry>
+ {
+ functor_getter_media_data(const LLMediaEntry& entry): mMediaEntry(entry) {}
+
+ LLMediaEntry get( LLViewerObject* object, S32 face )
+ {
+ if ( object )
+ if ( object->getTE(face) )
+ if ( object->getTE(face)->getMediaData() )
+ return *(object->getTE(face)->getMediaData());
+ return mMediaEntry;
+ };
+
+ const LLMediaEntry& mMediaEntry;
+
+ } func_media_data(default_media_data);
+
+ LLMediaEntry media_data_get;
+ LLFloaterMediaSettings::getInstance()->mMultipleMedia = !(selected_objects->getSelectedTEValue( &func_media_data, media_data_get ));
+
+ std::string multi_media_info_str = LLTrans::getString("Multiple Media");
+ std::string media_title = "";
+ mNeedMediaTitle = false;
+ // update UI depending on whether "object" (prim or face) has media
+ // and whether or not you are allowed to edit it.
+
+ getChildView("Add_Media")->setEnabled(editable);
+ // IF all the faces have media (or all dont have media)
+ if ( LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo )
+ {
+ // TODO: get media title and set it.
+ media_info->setValue("");
+ // if identical is set, all faces are same (whether all empty or has the same media)
+ if(!(LLFloaterMediaSettings::getInstance()->mMultipleMedia) )
+ {
+ // Media data is valid
+ if(media_data_get!=default_media_data)
+ {
+ // initial media title is the media URL (until we get the name)
+ media_title = media_data_get.getHomeURL();
+
+ // kick off a navigate and flag that we need to update the title
+ navigateToTitleMedia( media_data_get.getHomeURL() );
+ mNeedMediaTitle = true;
+ }
+ // else all faces might be empty.
+ }
+ else // there' re Different Medias' been set on on the faces.
+ {
+ media_title = multi_media_info_str;
+ mNeedMediaTitle = false;
+ }
+
+ getChildView("media_tex")->setEnabled(bool_has_media && editable);
+ getChildView("edit_media")->setEnabled(bool_has_media && LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo && editable );
+ getChildView("delete_media")->setEnabled(bool_has_media && editable );
+ getChildView("add_media")->setEnabled(( ! bool_has_media ) && editable );
+ // TODO: display a list of all media on the face - use 'identical' flag
+ }
+ else // not all face has media but at least one does.
+ {
+ // seleted faces have not identical value
+ LLFloaterMediaSettings::getInstance()->mMultipleValidMedia = selected_objects->isMultipleTEValue(&func_media_data, default_media_data );
+
+ if(LLFloaterMediaSettings::getInstance()->mMultipleValidMedia)
+ {
+ media_title = multi_media_info_str;
+ mNeedMediaTitle = false;
+ }
+ else
+ {
+ // Media data is valid
+ if(media_data_get!=default_media_data)
+ {
+ // initial media title is the media URL (until we get the name)
+ media_title = media_data_get.getHomeURL();
+
+ // kick off a navigate and flag that we need to update the title
+ navigateToTitleMedia( media_data_get.getHomeURL() );
+ mNeedMediaTitle = true;
+ }
+ }
+
+ getChildView("media_tex")->setEnabled(TRUE);
+ getChildView("edit_media")->setEnabled(LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo);
+ getChildView("delete_media")->setEnabled(TRUE);
+ getChildView("add_media")->setEnabled(FALSE );
+ }
+ media_info->setText(media_title);
+
+ // load values for media settings
+ updateMediaSettings();
+
+ if(mTitleMedia)
+ LLFloaterMediaSettings::initValues(mMediaSettings, editable );
+}
+//////////////////////////////////////////////////////////////////////////////
+// called when a user wants to add media to a prim or prim face
+void LLFloaterTools::onClickBtnAddMedia()
+{
+ // check if multiple faces are selected
+ if(LLSelectMgr::getInstance()->getSelection()->isMultipleTESelected())
+ {
+ LLNotificationsUtil::add("MultipleFacesSelected", LLSD(), LLSD(), multipleFacesSelectedConfirm);
+ }
+ else
+ {
+ onClickBtnEditMedia();
+ }
+}
+
+// static
+bool LLFloaterTools::multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ switch( option )
+ {
+ case 0: // "Yes"
+ gFloaterTools->onClickBtnEditMedia();
+ break;
+ case 1: // "No"
+ default:
+ break;
+ }
+ return false;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// called when a user wants to edit existing media settings on a prim or prim face
+// TODO: test if there is media on the item and only allow editing if present
+void LLFloaterTools::onClickBtnEditMedia()
+{
+ refreshMedia();
+ LLFloaterMediaSettings::getInstance()->open();
+ LLFloaterMediaSettings::getInstance()->setVisible(TRUE);
+ const LLRect& rect = getRect();
+ U32 height_offset = rect.getHeight() - LLFloaterMediaSettings::getInstance()->getRect().getHeight();
+ LLFloaterMediaSettings::getInstance()->setOrigin(rect.mRight, rect.mBottom + height_offset);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// called when a user wants to delete media from a prim or prim face
+void LLFloaterTools::onClickBtnDeleteMedia()
+{
+ LLNotificationsUtil::add("DeleteMedia", LLSD(), LLSD(), deleteMediaConfirm);
+}
+
+
+// static
+bool LLFloaterTools::deleteMediaConfirm(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ switch( option )
+ {
+ case 0: // "Yes"
+ LLSelectMgr::getInstance()->selectionSetMedia( 0, LLSD() );
+ if(LLFloaterMediaSettings::instanceExists())
+ {
+ LLFloaterMediaSettings::getInstance()->close();
+ }
+ break;
+
+ case 1: // "No"
+ default:
+ break;
+ }
+ return false;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+void LLFloaterTools::clearMediaSettings()
+{
+ LLFloaterMediaSettings::clearValues(false);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+void LLFloaterTools::navigateToTitleMedia( const std::string url )
+{
+ if ( mTitleMedia )
+ {
+ LLPluginClassMedia* media_plugin = mTitleMedia->getMediaPlugin();
+ if ( media_plugin )
+ {
+ // if it's a movie, we don't want to hear it
+ media_plugin->setVolume( 0 );
+ };
+ mTitleMedia->navigateTo( url );
+ };
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+void LLFloaterTools::updateMediaTitle()
+{
+ // only get the media name if we need it
+ if ( ! mNeedMediaTitle || !mTitleMedia )
+ return;
+
+ // get plugin impl
+ LLPluginClassMedia* media_plugin = mTitleMedia->getMediaPlugin();
+ if ( media_plugin )
+ {
+ // get the media name (asynchronous - must call repeatedly)
+ std::string media_title = media_plugin->getMediaName();
+
+ // only replace the title if what we get contains something
+ if ( ! media_title.empty() )
+ {
+ // update the UI widget
+ LLTextBox* media_title_field = getChild("media_info");
+ if ( media_title_field )
+ {
+ media_title_field->setText( media_title );
+
+ // stop looking for a title when we get one
+ // FIXME: check this is the right approach
+ mNeedMediaTitle = false;
+ };
+ };
+ };
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+void LLFloaterTools::updateMediaSettings()
+{
+ bool identical( false );
+ std::string base_key( "" );
+ std::string value_str( "" );
+ int value_int = 0;
+ bool value_bool = false;
+ LLObjectSelectionHandle selected_objects =LLSelectMgr::getInstance()->getSelection();
+ // TODO: (CP) refactor this using something clever or boost or both !!
+
+ const LLMediaEntry default_media_data;
+
+ // controls
+ U8 value_u8 = default_media_data.getControls();
+ struct functor_getter_controls : public LLSelectedTEGetFunctor< U8 >
+ {
+ functor_getter_controls(const LLMediaEntry &entry) : mMediaEntry(entry) {}
+
+ U8 get( LLViewerObject* object, S32 face )
+ {
+ if ( object )
+ if ( object->getTE(face) )
+ if ( object->getTE(face)->getMediaData() )
+ return object->getTE(face)->getMediaData()->getControls();
+ return mMediaEntry.getControls();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_controls(default_media_data);
+ identical = selected_objects->getSelectedTEValue( &func_controls, value_u8 );
+ base_key = std::string( LLMediaEntry::CONTROLS_KEY );
+ mMediaSettings[ base_key ] = value_u8;
+ mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+
+ // First click (formerly left click)
+ value_bool = default_media_data.getFirstClickInteract();
+ struct functor_getter_first_click : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_first_click(const LLMediaEntry& entry): mMediaEntry(entry) {}
+
+ bool get( LLViewerObject* object, S32 face )
+ {
+ if ( object )
+ if ( object->getTE(face) )
+ if ( object->getTE(face)->getMediaData() )
+ return object->getTE(face)->getMediaData()->getFirstClickInteract();
+ return mMediaEntry.getFirstClickInteract();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_first_click(default_media_data);
+ identical = selected_objects->getSelectedTEValue( &func_first_click, value_bool );
+ base_key = std::string( LLMediaEntry::FIRST_CLICK_INTERACT_KEY );
+ mMediaSettings[ base_key ] = value_bool;
+ mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+
+ // Home URL
+ value_str = default_media_data.getHomeURL();
+ struct functor_getter_home_url : public LLSelectedTEGetFunctor< std::string >
+ {
+ functor_getter_home_url(const LLMediaEntry& entry): mMediaEntry(entry) {}
+
+ std::string get( LLViewerObject* object, S32 face )
+ {
+ if ( object )
+ if ( object->getTE(face) )
+ if ( object->getTE(face)->getMediaData() )
+ return object->getTE(face)->getMediaData()->getHomeURL();
+ return mMediaEntry.getHomeURL();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_home_url(default_media_data);
+ identical = selected_objects->getSelectedTEValue( &func_home_url, value_str );
+ base_key = std::string( LLMediaEntry::HOME_URL_KEY );
+ mMediaSettings[ base_key ] = value_str;
+ mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+
+ // Current URL
+ value_str = default_media_data.getCurrentURL();
+ struct functor_getter_current_url : public LLSelectedTEGetFunctor< std::string >
+ {
+ functor_getter_current_url(const LLMediaEntry& entry): mMediaEntry(entry) {}
+
+ std::string get( LLViewerObject* object, S32 face )
+ {
+ if ( object )
+ if ( object->getTE(face) )
+ if ( object->getTE(face)->getMediaData() )
+ return object->getTE(face)->getMediaData()->getCurrentURL();
+ return mMediaEntry.getCurrentURL();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_current_url(default_media_data);
+ identical = selected_objects->getSelectedTEValue( &func_current_url, value_str );
+ base_key = std::string( LLMediaEntry::CURRENT_URL_KEY );
+ mMediaSettings[ base_key ] = value_str;
+ mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+
+ // Auto zoom
+ value_bool = default_media_data.getAutoZoom();
+ struct functor_getter_auto_zoom : public LLSelectedTEGetFunctor< bool >
+ {
+
+ functor_getter_auto_zoom(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get( LLViewerObject* object, S32 face )
+ {
+ if ( object )
+ if ( object->getTE(face) )
+ if ( object->getTE(face)->getMediaData() )
+ return object->getTE(face)->getMediaData()->getAutoZoom();
+ return mMediaEntry.getAutoZoom();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_auto_zoom(default_media_data);
+ identical = selected_objects->getSelectedTEValue( &func_auto_zoom, value_bool );
+ base_key = std::string( LLMediaEntry::AUTO_ZOOM_KEY );
+ mMediaSettings[ base_key ] = value_bool;
+ mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+
+ // Auto play
+ //value_bool = default_media_data.getAutoPlay();
+ // set default to auto play TRUE -- angela EXT-5172
+ value_bool = true;
+ struct functor_getter_auto_play : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_auto_play(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get( LLViewerObject* object, S32 face )
+ {
+ if ( object )
+ if ( object->getTE(face) )
+ if ( object->getTE(face)->getMediaData() )
+ return object->getTE(face)->getMediaData()->getAutoPlay();
+ //return mMediaEntry.getAutoPlay(); set default to auto play TRUE -- angela EXT-5172
+ return true;
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_auto_play(default_media_data);
+ identical = selected_objects->getSelectedTEValue( &func_auto_play, value_bool );
+ base_key = std::string( LLMediaEntry::AUTO_PLAY_KEY );
+ mMediaSettings[ base_key ] = value_bool;
+ mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+
+
+ // Auto scale
+ // set default to auto scale TRUE -- angela EXT-5172
+ //value_bool = default_media_data.getAutoScale();
+ value_bool = true;
+ struct functor_getter_auto_scale : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_auto_scale(const LLMediaEntry& entry): mMediaEntry(entry) {}
+
+ bool get( LLViewerObject* object, S32 face )
+ {
+ if ( object )
+ if ( object->getTE(face) )
+ if ( object->getTE(face)->getMediaData() )
+ return object->getTE(face)->getMediaData()->getAutoScale();
+ // return mMediaEntry.getAutoScale(); set default to auto scale TRUE -- angela EXT-5172
+ return true;
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_auto_scale(default_media_data);
+ identical = selected_objects->getSelectedTEValue( &func_auto_scale, value_bool );
+ base_key = std::string( LLMediaEntry::AUTO_SCALE_KEY );
+ mMediaSettings[ base_key ] = value_bool;
+ mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+
+ // Auto loop
+ value_bool = default_media_data.getAutoLoop();
+ struct functor_getter_auto_loop : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_auto_loop(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get( LLViewerObject* object, S32 face )
+ {
+ if ( object )
+ if ( object->getTE(face) )
+ if ( object->getTE(face)->getMediaData() )
+ return object->getTE(face)->getMediaData()->getAutoLoop();
+ return mMediaEntry.getAutoLoop();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_auto_loop(default_media_data);
+ identical = selected_objects->getSelectedTEValue( &func_auto_loop, value_bool );
+ base_key = std::string( LLMediaEntry::AUTO_LOOP_KEY );
+ mMediaSettings[ base_key ] = value_bool;
+ mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+
+ // width pixels (if not auto scaled)
+ value_int = default_media_data.getWidthPixels();
+ struct functor_getter_width_pixels : public LLSelectedTEGetFunctor< int >
+ {
+ functor_getter_width_pixels(const LLMediaEntry& entry): mMediaEntry(entry) {}
+
+ int get( LLViewerObject* object, S32 face )
+ {
+ if ( object )
+ if ( object->getTE(face) )
+ if ( object->getTE(face)->getMediaData() )
+ return object->getTE(face)->getMediaData()->getWidthPixels();
+ return mMediaEntry.getWidthPixels();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_width_pixels(default_media_data);
+ identical = selected_objects->getSelectedTEValue( &func_width_pixels, value_int );
+ base_key = std::string( LLMediaEntry::WIDTH_PIXELS_KEY );
+ mMediaSettings[ base_key ] = value_int;
+ mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+
+ // height pixels (if not auto scaled)
+ value_int = default_media_data.getHeightPixels();
+ struct functor_getter_height_pixels : public LLSelectedTEGetFunctor< int >
+ {
+ functor_getter_height_pixels(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ int get( LLViewerObject* object, S32 face )
+ {
+ if ( object )
+ if ( object->getTE(face) )
+ if ( object->getTE(face)->getMediaData() )
+ return object->getTE(face)->getMediaData()->getHeightPixels();
+ return mMediaEntry.getHeightPixels();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_height_pixels(default_media_data);
+ identical = selected_objects->getSelectedTEValue( &func_height_pixels, value_int );
+ base_key = std::string( LLMediaEntry::HEIGHT_PIXELS_KEY );
+ mMediaSettings[ base_key ] = value_int;
+ mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+
+ // Enable Alt image
+ value_bool = default_media_data.getAltImageEnable();
+ struct functor_getter_enable_alt_image : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_enable_alt_image(const LLMediaEntry& entry): mMediaEntry(entry) {}
+
+ bool get( LLViewerObject* object, S32 face )
+ {
+ if ( object )
+ if ( object->getTE(face) )
+ if ( object->getTE(face)->getMediaData() )
+ return object->getTE(face)->getMediaData()->getAltImageEnable();
+ return mMediaEntry.getAltImageEnable();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_enable_alt_image(default_media_data);
+ identical = selected_objects->getSelectedTEValue( &func_enable_alt_image, value_bool );
+ base_key = std::string( LLMediaEntry::ALT_IMAGE_ENABLE_KEY );
+ mMediaSettings[ base_key ] = value_bool;
+ mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+
+ // Perms - owner interact
+ value_bool = 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_OWNER );
+ struct functor_getter_perms_owner_interact : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_perms_owner_interact(const LLMediaEntry& entry): mMediaEntry(entry) {}
+
+ bool get( LLViewerObject* object, S32 face )
+ {
+ if ( object )
+ if ( object->getTE(face) )
+ if ( object->getTE(face)->getMediaData() )
+ return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_OWNER));
+ return 0 != ( mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_OWNER );
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_perms_owner_interact(default_media_data);
+ identical = selected_objects->getSelectedTEValue( &func_perms_owner_interact, value_bool );
+ base_key = std::string( LLPanelContents::PERMS_OWNER_INTERACT_KEY );
+ mMediaSettings[ base_key ] = value_bool;
+ mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+
+ // Perms - owner control
+ value_bool = 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_OWNER );
+ struct functor_getter_perms_owner_control : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_perms_owner_control(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get( LLViewerObject* object, S32 face )
+ {
+ if ( object )
+ if ( object->getTE(face) )
+ if ( object->getTE(face)->getMediaData() )
+ return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_OWNER));
+ return 0 != ( mMediaEntry.getPermsControl() & LLMediaEntry::PERM_OWNER );
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_perms_owner_control(default_media_data);
+ identical = selected_objects ->getSelectedTEValue( &func_perms_owner_control, value_bool );
+ base_key = std::string( LLPanelContents::PERMS_OWNER_CONTROL_KEY );
+ mMediaSettings[ base_key ] = value_bool;
+ mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+
+ // Perms - group interact
+ value_bool = 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_GROUP );
+ struct functor_getter_perms_group_interact : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_perms_group_interact(const LLMediaEntry& entry): mMediaEntry(entry) {}
+
+ bool get( LLViewerObject* object, S32 face )
+ {
+ if ( object )
+ if ( object->getTE(face) )
+ if ( object->getTE(face)->getMediaData() )
+ return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_GROUP));
+ return 0 != ( mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_GROUP );
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_perms_group_interact(default_media_data);
+ identical = selected_objects->getSelectedTEValue( &func_perms_group_interact, value_bool );
+ base_key = std::string( LLPanelContents::PERMS_GROUP_INTERACT_KEY );
+ mMediaSettings[ base_key ] = value_bool;
+ mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+
+ // Perms - group control
+ value_bool = 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_GROUP );
+ struct functor_getter_perms_group_control : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_perms_group_control(const LLMediaEntry& entry): mMediaEntry(entry) {}
+
+ bool get( LLViewerObject* object, S32 face )
+ {
+ if ( object )
+ if ( object->getTE(face) )
+ if ( object->getTE(face)->getMediaData() )
+ return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_GROUP));
+ return 0 != ( mMediaEntry.getPermsControl() & LLMediaEntry::PERM_GROUP );
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_perms_group_control(default_media_data);
+ identical = selected_objects->getSelectedTEValue( &func_perms_group_control, value_bool );
+ base_key = std::string( LLPanelContents::PERMS_GROUP_CONTROL_KEY );
+ mMediaSettings[ base_key ] = value_bool;
+ mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+
+ // Perms - anyone interact
+ value_bool = 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_ANYONE );
+ struct functor_getter_perms_anyone_interact : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_perms_anyone_interact(const LLMediaEntry& entry): mMediaEntry(entry) {}
+
+ bool get( LLViewerObject* object, S32 face )
+ {
+ if ( object )
+ if ( object->getTE(face) )
+ if ( object->getTE(face)->getMediaData() )
+ return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_ANYONE));
+ return 0 != ( mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_ANYONE );
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_perms_anyone_interact(default_media_data);
+ identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func_perms_anyone_interact, value_bool );
+ base_key = std::string( LLPanelContents::PERMS_ANYONE_INTERACT_KEY );
+ mMediaSettings[ base_key ] = value_bool;
+ mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+
+ // Perms - anyone control
+ value_bool = 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_ANYONE );
+ struct functor_getter_perms_anyone_control : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_perms_anyone_control(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get( LLViewerObject* object, S32 face )
+ {
+ if ( object )
+ if ( object->getTE(face) )
+ if ( object->getTE(face)->getMediaData() )
+ return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_ANYONE));
+ return 0 != ( mMediaEntry.getPermsControl() & LLMediaEntry::PERM_ANYONE );
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_perms_anyone_control(default_media_data);
+ identical = selected_objects->getSelectedTEValue( &func_perms_anyone_control, value_bool );
+ base_key = std::string( LLPanelContents::PERMS_ANYONE_CONTROL_KEY );
+ mMediaSettings[ base_key ] = value_bool;
+ mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+
+ // security - whitelist enable
+ value_bool = default_media_data.getWhiteListEnable();
+ struct functor_getter_whitelist_enable : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_whitelist_enable(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get( LLViewerObject* object, S32 face )
+ {
+ if ( object )
+ if ( object->getTE(face) )
+ if ( object->getTE(face)->getMediaData() )
+ return object->getTE(face)->getMediaData()->getWhiteListEnable();
+ return mMediaEntry.getWhiteListEnable();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_whitelist_enable(default_media_data);
+ identical = selected_objects->getSelectedTEValue( &func_whitelist_enable, value_bool );
+ base_key = std::string( LLMediaEntry::WHITELIST_ENABLE_KEY );
+ mMediaSettings[ base_key ] = value_bool;
+ mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+
+ // security - whitelist URLs
+ std::vector value_vector_str = default_media_data.getWhiteList();
+ struct functor_getter_whitelist_urls : public LLSelectedTEGetFunctor< std::vector >
+ {
+ functor_getter_whitelist_urls(const LLMediaEntry& entry): mMediaEntry(entry) {}
+
+ std::vector get( LLViewerObject* object, S32 face )
+ {
+ if ( object )
+ if ( object->getTE(face) )
+ if ( object->getTE(face)->getMediaData() )
+ return object->getTE(face)->getMediaData()->getWhiteList();
+ return mMediaEntry.getWhiteList();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_whitelist_urls(default_media_data);
+ identical = selected_objects->getSelectedTEValue( &func_whitelist_urls, value_vector_str );
+ base_key = std::string( LLMediaEntry::WHITELIST_KEY );
+ mMediaSettings[ base_key ].clear();
+ std::vector< std::string >::iterator iter = value_vector_str.begin();
+ while( iter != value_vector_str.end() )
+ {
+ std::string white_list_url = *iter;
+ mMediaSettings[ base_key ].append( white_list_url );
+ ++iter;
+ };
+
+ mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
+}
+
// static
void LLFloaterTools::onSelectTreesGrass(LLUICtrl*, void*)
{
@@ -1140,3 +2022,4 @@ void LLFloaterTools::updateTreeGrassCombo(bool visible)
mComboTreesGrass->setVisible(visible);
tree_grass_label->setVisible(visible);
}
+
diff --git a/indra/newview/llfloatertools.h b/indra/newview/llfloatertools.h
index 90cdf83eb..fec736819 100644
--- a/indra/newview/llfloatertools.h
+++ b/indra/newview/llfloatertools.h
@@ -49,6 +49,7 @@ class LLPanelLandInfo;
class LLSlider;
class LLTabContainer;
class LLTextBox;
+class LLMediaCtrl;
class LLTool;
class LLParcelSelection;
class LLObjectSelection;
@@ -71,11 +72,11 @@ public:
LLFloaterTools();
virtual ~LLFloaterTools();
- virtual void onOpen();
- virtual BOOL canClose();
- virtual void onClose(bool app_quitting);
+ /*virtual*/ void onOpen();
+ /*virtual*/ BOOL canClose();
+ /*virtual*/ void onClose(bool app_quitting);
/*virtual*/ void draw();
- virtual void onFocusReceived();
+ /*virtual*/ void onFocusReceived();
// call this once per frame to handle visibility, rect location,
// button highlights, etc.
@@ -100,13 +101,25 @@ public:
void setStatusText(const std::string& text);
static void setEditTool(void* data);
+ void setTool(const LLSD& user_data);
void saveLastTool();
+ void onClickBtnDeleteMedia();
+ void onClickBtnAddMedia();
+ void onClickBtnEditMedia();
+ void clearMediaSettings();
+ void updateMediaTitle();
+ void navigateToTitleMedia( const std::string url );
+ bool selectedMediaEditable();
private:
void refresh();
-
+ void refreshMedia();
+ void getMediaState();
+ void updateMediaSettings();
+ static bool deleteMediaConfirm(const LLSD& notification, const LLSD& response);
+ static bool multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response);
static void setObjectType( LLPCode pcode );
- static void onClickGridOptions(void* data);
+ void onClickGridOptions();
public:
LLButton *mBtnFocus;
@@ -190,6 +203,8 @@ public:
LLParcelSelectionHandle mParcelSelection;
LLObjectSelectionHandle mObjectSelection;
+ LLMediaCtrl *mTitleMedia;
+ bool mNeedMediaTitle;
private:
BOOL mDirty;
@@ -197,6 +212,8 @@ private:
void updateTreeGrassCombo(bool visible);
static void onSelectTreesGrass(LLUICtrl*, void*);
+protected:
+ LLSD mMediaSettings;
};
extern LLFloaterTools *gFloaterTools;
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/llfloatervoiceeffect.cpp b/indra/newview/llfloatervoiceeffect.cpp
new file mode 100644
index 000000000..415798086
--- /dev/null
+++ b/indra/newview/llfloatervoiceeffect.cpp
@@ -0,0 +1,318 @@
+/**
+ * @file llfloatervoiceeffect.cpp
+ * @author Aimee
+ * @brief Selection and preview of voice effect.
+ *
+ * $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 "llfloatervoiceeffect.h"
+
+#include "llscrolllistctrl.h"
+#include "lltexteditor.h" // For linked text hack
+#include "lltrans.h"
+#include "lluictrlfactory.h"
+#include "llweb.h"
+
+LLFloaterVoiceEffect::LLFloaterVoiceEffect(const LLSD& key)
+ : LLFloater(/*key*/)
+{
+ mCommitCallbackRegistrar.add("VoiceEffect.Record", boost::bind(&LLFloaterVoiceEffect::onClickRecord, this));
+ mCommitCallbackRegistrar.add("VoiceEffect.Play", boost::bind(&LLFloaterVoiceEffect::onClickPlay, this));
+ mCommitCallbackRegistrar.add("VoiceEffect.Stop", boost::bind(&LLFloaterVoiceEffect::onClickStop, this));
+ mCommitCallbackRegistrar.add("VoiceEffect.Activate", boost::bind(&LLFloaterVoiceEffect::onClickActivate, this));
+ LLUICtrlFactory::getInstance()->buildFloater(this, "floater_voice_effect.xml");
+}
+
+// virtual
+LLFloaterVoiceEffect::~LLFloaterVoiceEffect()
+{
+ if(LLVoiceClient::instanceExists())
+ {
+ LLVoiceEffectInterface* effect_interface = LLVoiceClient::instance().getVoiceEffectInterface();
+ if (effect_interface)
+ {
+ effect_interface->removeObserver(this);
+ }
+ }
+}
+
+// virtual
+BOOL LLFloaterVoiceEffect::postBuild()
+{
+ setDefaultBtn("record_btn");
+ getChild("record_btn")->setFocus(true);
+
+ // Singu Note: Here we must hack together a linked piece of text
+ if (LLTextEditor* editor = getChild("voice_morphing_link"))
+ {
+ editor->setParseHTML(true); // For some reason, adding style doesn't work unless this is true.
+ const std::string text = editor->getValue();
+ editor->clear();
+ LLStyleSP link(new LLStyle);
+ link->setLinkHREF(LLTrans::getString("voice_morphing_url"));
+ link->setColor(gSavedSettings.getColor4("HTMLLinkColor"));
+ editor->appendStyledText(text, false, false, link);
+ }
+
+ mVoiceEffectList = getChild("voice_effect_list");
+ if (mVoiceEffectList)
+ {
+ mVoiceEffectList->setCommitCallback(boost::bind(&LLFloaterVoiceEffect::onClickPlay, this));
+// mVoiceEffectList->setDoubleClickCallback(boost::bind(&LLFloaterVoiceEffect::onClickActivate, this));
+ }
+
+ return TRUE;
+}
+
+// virtual
+void LLFloaterVoiceEffect::onOpen()
+{
+ LLVoiceEffectInterface* effect_interface = LLVoiceClient::instance().getVoiceEffectInterface();
+ if (effect_interface)
+ {
+ effect_interface->addObserver(this);
+
+ // Disconnect from the current voice channel ready to record a voice sample for previewing
+ effect_interface->enablePreviewBuffer(true);
+ }
+
+ refreshEffectList();
+ updateControls();
+}
+
+// virtual
+void LLFloaterVoiceEffect::onClose(bool app_quitting)
+{
+ LLVoiceEffectInterface* effect_interface = LLVoiceClient::instance().getVoiceEffectInterface();
+ if (effect_interface)
+ {
+ effect_interface->enablePreviewBuffer(false);
+ }
+ setVisible(false);
+}
+
+void LLFloaterVoiceEffect::refreshEffectList()
+{
+ if (!mVoiceEffectList)
+ {
+ return;
+ }
+
+ LLVoiceEffectInterface* effect_interface = LLVoiceClient::instance().getVoiceEffectInterface();
+ if (!effect_interface)
+ {
+ mVoiceEffectList->setEnabled(false);
+ return;
+ }
+
+ LL_DEBUGS("Voice")<< "Rebuilding Voice Morph list."<< LL_ENDL;
+
+ // Preserve selected items and scroll position
+ S32 scroll_pos = mVoiceEffectList->getScrollPos();
+ uuid_vec_t selected_items;
+ std::vector items = mVoiceEffectList->getAllSelected();
+ for(std::vector::const_iterator it = items.begin(); it != items.end(); it++)
+ {
+ selected_items.push_back((*it)->getUUID());
+ }
+
+ mVoiceEffectList->deleteAllItems();
+
+ {
+ // Add the "No Voice Morph" entry
+ LLSD element;
+
+ element["id"] = LLUUID::null;
+ element["columns"][NAME_COLUMN]["column"] = "name";
+ element["columns"][NAME_COLUMN]["value"] = getString("no_voice_effect");
+ element["columns"][NAME_COLUMN]["font"] = "SANSSERIF";
+ element["columns"][NAME_COLUMN]["font-style"] = "BOLD";
+
+ /*LLScrollListItem* sl_item =*/ mVoiceEffectList->addElement(element, ADD_BOTTOM);
+ /* Singu Note: Ours works
+ // *HACK: Copied from llfloatergesture.cpp : ["font"]["style"] does not affect font style :(
+ if(sl_item)
+ {
+ ((LLScrollListText*)sl_item->getColumn(0))->setFontStyle(LLFontGL::BOLD);
+ }
+ */
+ }
+
+ // Add each Voice Morph template, if there are any (template list includes all usable effects)
+ const voice_effect_list_t& template_list = effect_interface->getVoiceEffectTemplateList();
+ if (!template_list.empty())
+ {
+ for (voice_effect_list_t::const_iterator it = template_list.begin(); it != template_list.end(); ++it)
+ {
+ const LLUUID& effect_id = it->second;
+
+ std::string localized_effect = "effect_" + it->first;
+ std::string effect_name = hasString(localized_effect) ? getString(localized_effect) : it->first; // XML contains localized effects names
+
+ LLSD effect_properties = effect_interface->getVoiceEffectProperties(effect_id);
+
+ // Tag the active effect.
+ if (effect_id == LLVoiceClient::instance().getVoiceEffectDefault())
+ {
+ effect_name += " " + getString("active_voice_effect");
+ }
+
+ // Tag available effects that are new this session
+ if (effect_properties["is_new"].asBoolean())
+ {
+ effect_name += " " + getString("new_voice_effect");
+ }
+
+ LLDate expiry_date = effect_properties["expiry_date"].asDate();
+ bool is_template_only = effect_properties["template_only"].asBoolean();
+
+ std::string font_style = "NORMAL";
+ if (!is_template_only)
+ {
+ font_style = "BOLD";
+ }
+
+ LLSD element;
+ element["id"] = effect_id;
+
+ element["columns"][NAME_COLUMN]["column"] = "name";
+ element["columns"][NAME_COLUMN]["value"] = effect_name;
+ element["columns"][NAME_COLUMN]["font"] = "SANSSERIF";
+ element["columns"][NAME_COLUMN]["font-style"] = font_style;
+
+ element["columns"][1]["column"] = "expires";
+ if (!is_template_only)
+ {
+ element["columns"][DATE_COLUMN]["value"] = expiry_date;
+ element["columns"][DATE_COLUMN]["type"] = "date";
+ }
+ else {
+ element["columns"][DATE_COLUMN]["value"] = getString("unsubscribed_voice_effect");
+ }
+ element["columns"][DATE_COLUMN]["font"] = "SANSSERIF";
+ element["columns"][DATE_COLUMN]["font-style"] = "NORMAL";
+
+ /*LLScrollListItem* sl_item =*/ mVoiceEffectList->addElement(element, ADD_BOTTOM);
+ /* Singu Note: Ours works
+ // *HACK: Copied from llfloatergesture.cpp : ["font"]["style"] does not affect font style :(
+ if(sl_item)
+ {
+ LLFontGL::StyleFlags style = is_template_only ? LLFontGL::NORMAL : LLFontGL::BOLD;
+ LLScrollListText* slt = dynamic_cast(sl_item->getColumn(0));
+ llassert(slt);
+ if (slt)
+ {
+ slt->setFontStyle(style);
+ }
+ }
+ */
+ }
+ }
+
+ // Re-select items that were selected before, and restore the scroll position
+ for(uuid_vec_t::iterator it = selected_items.begin(); it != selected_items.end(); it++)
+ {
+ mVoiceEffectList->selectByID(*it);
+ }
+ mVoiceEffectList->setScrollPos(scroll_pos);
+ mVoiceEffectList->setEnabled(true);
+}
+
+void LLFloaterVoiceEffect::updateControls()
+{
+ bool recording = false;
+
+ LLVoiceEffectInterface* effect_interface = LLVoiceClient::instance().getVoiceEffectInterface();
+ if (effect_interface)
+ {
+ recording = effect_interface->isPreviewRecording();
+ }
+
+ getChild("record_btn")->setVisible(!recording);
+ getChild("record_stop_btn")->setVisible(recording);
+}
+
+// virtual
+void LLFloaterVoiceEffect::onVoiceEffectChanged(bool effect_list_updated)
+{
+ if (effect_list_updated)
+ {
+ refreshEffectList();
+ }
+ updateControls();
+}
+
+void LLFloaterVoiceEffect::onClickRecord()
+{
+ LL_DEBUGS("Voice") << "Record clicked" << LL_ENDL;
+ LLVoiceEffectInterface* effect_interface = LLVoiceClient::instance().getVoiceEffectInterface();
+ if (effect_interface)
+ {
+ effect_interface->recordPreviewBuffer();
+ }
+ updateControls();
+}
+
+void LLFloaterVoiceEffect::onClickPlay()
+{
+ LL_DEBUGS("Voice") << "Play clicked" << LL_ENDL;
+ if (!mVoiceEffectList)
+ {
+ return;
+ }
+
+ const LLUUID& effect_id = mVoiceEffectList->getCurrentID();
+
+ LLVoiceEffectInterface* effect_interface = LLVoiceClient::instance().getVoiceEffectInterface();
+ if (effect_interface)
+ {
+ effect_interface->playPreviewBuffer(effect_id);
+ }
+ updateControls();
+}
+
+void LLFloaterVoiceEffect::onClickStop()
+{
+ LL_DEBUGS("Voice") << "Stop clicked" << LL_ENDL;
+ LLVoiceEffectInterface* effect_interface = LLVoiceClient::instance().getVoiceEffectInterface();
+ if (effect_interface)
+ {
+ effect_interface->stopPreviewBuffer();
+ }
+ updateControls();
+}
+
+void LLFloaterVoiceEffect::onClickActivate()
+{
+ LL_DEBUGS("Voice") << "Activate clicked" << LL_ENDL;
+ LLVoiceEffectInterface* effect_interface = LLVoiceClient::instance().getVoiceEffectInterface();
+ if (effect_interface && mVoiceEffectList)
+ {
+ //effect_interface->setVoiceEffect(mVoiceEffectList->getCurrentID()); // Singu Note: This would return early, since we're disconnected from voice, just set the string and refresh list
+ gSavedPerAccountSettings.setString("VoiceEffectDefault", mVoiceEffectList->getCurrentID().asString());
+ refreshEffectList();
+ }
+}
+
diff --git a/indra/newview/llfloatervoiceeffect.h b/indra/newview/llfloatervoiceeffect.h
new file mode 100644
index 000000000..9bee8937c
--- /dev/null
+++ b/indra/newview/llfloatervoiceeffect.h
@@ -0,0 +1,74 @@
+/**
+ * @file llfloatervoiceeffect.h
+ * @author Aimee
+ * @brief Selection and preview of voice effects.
+ *
+ * $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$
+ */
+
+#ifndef LL_LLFLOATERVOICEEFFECT_H
+#define LL_LLFLOATERVOICEEFFECT_H
+
+#include "llfloater.h"
+#include "llvoiceclient.h"
+
+class LLButton;
+class LLScrollListCtrl;
+
+class LLFloaterVoiceEffect
+ : public LLFloater
+ , public LLVoiceEffectObserver
+ , public LLFloaterSingleton
+{
+public:
+ LOG_CLASS(LLFloaterVoiceEffect);
+
+ LLFloaterVoiceEffect(const LLSD& key);
+ virtual ~LLFloaterVoiceEffect();
+
+ virtual BOOL postBuild();
+ virtual void onOpen();
+ virtual void onClose(bool app_quitting);
+
+private:
+ enum ColumnIndex
+ {
+ NAME_COLUMN = 0,
+ DATE_COLUMN = 1,
+ };
+
+ void refreshEffectList();
+ void updateControls();
+
+ /// Called by voice effect provider when voice effect list is changed.
+ virtual void onVoiceEffectChanged(bool effect_list_updated);
+
+ void onClickRecord();
+ void onClickPlay();
+ void onClickStop();
+ void onClickActivate();
+
+ LLUUID mSelectedID;
+ LLScrollListCtrl* mVoiceEffectList;
+};
+
+#endif
diff --git a/indra/newview/llfloaterwater.cpp b/indra/newview/llfloaterwater.cpp
index 7f4173056..f444a7cbc 100644
--- a/indra/newview/llfloaterwater.cpp
+++ b/indra/newview/llfloaterwater.cpp
@@ -159,7 +159,7 @@ void LLFloaterWater::onClickHelp(void* data)
LLFloaterWater* self = LLFloaterWater::instance();
const std::string* xml_alert = (std::string*)data;
- LLNotifications::instance().add(self->contextualNotification(*xml_alert));
+ self->addContextualNotification(*xml_alert);
}
void LLFloaterWater::initHelpBtn(const std::string& name, const std::string& xml_alert)
@@ -175,7 +175,7 @@ bool LLFloaterWater::newPromptCallback(const LLSD& notification, const LLSD& res
return false;
}
- S32 option = LLNotification::getSelectedOption(notification, response);
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
if(option == 0)
{
LLWaterParamManager * param_mgr = LLWaterParamManager::getInstance();
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/llfloaterwhitelistentry.cpp b/indra/newview/llfloaterwhitelistentry.cpp
new file mode 100644
index 000000000..f930e0940
--- /dev/null
+++ b/indra/newview/llfloaterwhitelistentry.cpp
@@ -0,0 +1,91 @@
+/**
+ * @file llfloaterwhitelistentry.cpp
+ * @brief LLFloaterWhistListEntry class implementation
+ *
+ * $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$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloatermediasettings.h"
+#include "llfloaterwhitelistentry.h"
+#include "llpanelmediasettingssecurity.h"
+#include "lluictrlfactory.h"
+#include "llwindow.h"
+#include "llviewerwindow.h"
+#include "lllineeditor.h"
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+LLFloaterWhiteListEntry::LLFloaterWhiteListEntry() :
+ LLFloater()
+{
+ LLUICtrlFactory::getInstance()->buildFloater(this, "floater_whitelist_entry.xml");
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+LLFloaterWhiteListEntry::~LLFloaterWhiteListEntry()
+{
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+BOOL LLFloaterWhiteListEntry::postBuild()
+{
+ mWhiteListEdit = getChild("whitelist_entry");
+
+ childSetAction("cancel_btn", onBtnCancel, this);
+ childSetAction("ok_btn", onBtnOK, this);
+
+ setDefaultBtn("ok_btn");
+
+ return TRUE;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// static
+void LLFloaterWhiteListEntry::onBtnOK( void* userdata )
+{
+ LLFloaterWhiteListEntry *self =(LLFloaterWhiteListEntry *)userdata;
+
+ LLPanelMediaSettingsSecurity* panel = LLFloaterMediaSettings::instanceExists() ? LLFloaterMediaSettings::getInstance()->getPanelSecurity() : NULL;
+ if ( panel )
+ {
+ std::string white_list_item = self->mWhiteListEdit->getText();
+
+ panel->addWhiteListEntry( white_list_item );
+ panel->updateWhitelistEnableStatus();
+ };
+
+ self->close();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// static
+void LLFloaterWhiteListEntry::onBtnCancel( void* userdata )
+{
+ LLFloaterWhiteListEntry *self =(LLFloaterWhiteListEntry *)userdata;
+
+ self->close();
+}
diff --git a/indra/newview/llfloaterwhitelistentry.h b/indra/newview/llfloaterwhitelistentry.h
new file mode 100644
index 000000000..da23b1ebf
--- /dev/null
+++ b/indra/newview/llfloaterwhitelistentry.h
@@ -0,0 +1,50 @@
+/**
+ * @file llfloaterwhitelistentry.h
+ * @brief LLFloaterWhiteListEntry class definition
+ *
+ * $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_LLFLOATERWHITELISTENTRY_H
+#define LL_LLFLOATERWHITELISTENTRY_H
+
+#include "llfloater.h"
+
+class LLLineEditor;
+
+class LLFloaterWhiteListEntry :
+ public LLFloater, public LLSingleton
+{
+ public:
+ LLFloaterWhiteListEntry();
+ ~LLFloaterWhiteListEntry();
+
+ BOOL postBuild();
+
+ private:
+ LLLineEditor* mWhiteListEdit;
+
+ static void onBtnOK(void*);
+ static void onBtnCancel(void*);
+};
+
+#endif // LL_LLFLOATERWHITELISTENTRY_H
diff --git a/indra/newview/llfloaterwindlight.cpp b/indra/newview/llfloaterwindlight.cpp
index b5a23367c..7e9eb6a1f 100644
--- a/indra/newview/llfloaterwindlight.cpp
+++ b/indra/newview/llfloaterwindlight.cpp
@@ -213,7 +213,7 @@ void LLFloaterWindLight::onClickHelp(void* data)
LLFloaterWindLight* self = LLFloaterWindLight::instance();
const std::string xml_alert = *(std::string*)data;
- LLNotifications::instance().add(self->contextualNotification(xml_alert));
+ self->addContextualNotification(xml_alert);
}
void LLFloaterWindLight::initHelpBtn(const std::string& name, const std::string& xml_alert)
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..ade7e1d1f 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)
{
@@ -128,7 +128,6 @@ void LLGroupActions::search()
LLFloaterDirectory::showGroups();
}
-/* Singu TODO: Voice refactor
// static
void LLGroupActions::startCall(const LLUUID& group_id)
{
@@ -162,7 +161,6 @@ void LLGroupActions::startCall(const LLUUID& group_id)
make_ui_sound("UISndStartIM");
}
-*/
// static
void LLGroupActions::join(const LLUUID& group_id)
@@ -402,7 +400,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/llhoverview.cpp b/indra/newview/llhoverview.cpp
index 2427a89cb..dd53f11d6 100644
--- a/indra/newview/llhoverview.cpp
+++ b/indra/newview/llhoverview.cpp
@@ -70,6 +70,9 @@
#include "llviewertexturelist.h"
//#include "lltoolobjpicker.h"
#include "llhudmanager.h" // HACK for creating flex obj's
+#include "llviewermenu.h"
+#include "llviewermedia.h"
+#include "llmediaentry.h"
#include "llhudmanager.h" // For testing effects
#include "llhudeffect.h"
@@ -294,201 +297,257 @@ void LLHoverView::updateText()
//
BOOL suppressObjectHoverDisplay = !gSavedSettings.getBOOL("ShowAllObjectHoverTip");
- LLSelectNode *nodep = LLSelectMgr::getInstance()->getHoverNode();;
+ LLSelectNode *nodep = LLSelectMgr::getInstance()->getHoverNode();
if (nodep)
{
line.clear();
- if (nodep->mName.empty())
- {
- line.append(LLTrans::getString("TooltipNoName"));
- }
- else
- {
- line.append( nodep->mName );
- }
- mText.push_back(line);
- if (!nodep->mDescription.empty()
- && nodep->mDescription != DEFAULT_DESC)
+ bool for_copy = nodep->mValid && nodep->mPermissions->getMaskEveryone() & PERM_COPY && hit_object && hit_object->permCopy();
+ bool for_sale = nodep->mValid && for_sale_selection(nodep);
+
+ bool has_media = false;
+ bool is_time_based_media = false;
+ bool is_web_based_media = false;
+ bool is_media_playing = false;
+ bool is_media_displaying = false;
+
+ // Does this face have media?
+ const LLTextureEntry* tep = hit_object ? hit_object->getTE(mLastPickInfo.mObjectFace) : NULL;
+
+ if(tep)
{
- mText.push_back( nodep->mDescription );
- }
-
- // Line: "Owner: James Linden"
- line.clear();
- line.append(LLTrans::getString("TooltipOwner") + " ");
-
- if (nodep->mValid)
- {
- LLUUID owner;
- std::string name;
- if (!nodep->mPermissions->isGroupOwned())
+ has_media = tep->hasMedia();
+ const LLMediaEntry* mep = has_media ? tep->getMediaData() : NULL;
+ if (mep)
{
- owner = nodep->mPermissions->getOwner();
- if (LLUUID::null == owner)
+ viewer_media_t media_impl = LLViewerMedia::getMediaImplFromTextureID(mep->getMediaID());
+ LLPluginClassMedia* media_plugin = NULL;
+
+ if (media_impl.notNull() && (media_impl->hasMedia()))
{
- line.append(LLTrans::getString("TooltipPublic"));
- }
- else if(LLAvatarNameCache::getPNSName(owner, name))
- {
-// [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e)
- if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES))
- {
- name = RlvStrings::getAnonym(name);
+ is_media_displaying = true;
+ //LLStringUtil::format_map_t args;
+
+ media_plugin = media_impl->getMediaPlugin();
+ if(media_plugin)
+ {
+ if(media_plugin->pluginSupportsMediaTime())
+ {
+ is_time_based_media = true;
+ is_web_based_media = false;
+ //args["[CurrentURL]"] = media_impl->getMediaURL();
+ is_media_playing = media_impl->isMediaPlaying();
+ }
+ else
+ {
+ is_time_based_media = false;
+ is_web_based_media = true;
+ //args["[CurrentURL]"] = media_plugin->getLocation();
+ }
+ //tooltip_msg.append(LLTrans::getString("CurrentURL", args));
}
-// [/RLVa:KB]
+ }
+ }
+ }
- line.append(name);
+
+ // Avoid showing tip over media that's displaying unless it's for sale
+ // also check the primary node since sometimes it can have an action even though
+ // the root node doesn't
+
+ if(!suppressObjectHoverDisplay || !is_media_displaying || for_sale)
+ {
+ if (nodep->mName.empty())
+ {
+ line.append(LLTrans::getString("TooltipNoName"));
+ }
+ else
+ {
+ line.append( nodep->mName );
+ }
+
+ mText.push_back(line);
+
+ if (!nodep->mDescription.empty()
+ && nodep->mDescription != DEFAULT_DESC)
+ {
+ mText.push_back( nodep->mDescription );
+ }
+
+ // Line: "Owner: James Linden"
+ line.clear();
+ line.append(LLTrans::getString("TooltipOwner") + " ");
+
+ if (nodep->mValid)
+ {
+ LLUUID owner;
+ std::string name;
+ if (!nodep->mPermissions->isGroupOwned())
+ {
+ owner = nodep->mPermissions->getOwner();
+ if (LLUUID::null == owner)
+ {
+ line.append(LLTrans::getString("TooltipPublic"));
+ }
+ else if(LLAvatarNameCache::getPNSName(owner, name))
+ {
+ // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e)
+ if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES))
+ {
+ name = RlvStrings::getAnonym(name);
+ }
+ // [/RLVa:KB]
+
+ line.append(name);
+ }
+ else
+ {
+ line.append(LLTrans::getString("RetrievingData"));
+ }
}
else
{
- line.append(LLTrans::getString("RetrievingData"));
+ std::string name;
+ owner = nodep->mPermissions->getGroup();
+ if (gCacheName->getGroupName(owner, name))
+ {
+ line.append(name);
+ line.append(LLTrans::getString("TooltipIsGroup"));
+ }
+ else
+ {
+ line.append(LLTrans::getString("RetrievingData"));
+ }
}
}
else
{
- std::string name;
- owner = nodep->mPermissions->getGroup();
- if (gCacheName->getGroupName(owner, name))
- {
- line.append(name);
- line.append(LLTrans::getString("TooltipIsGroup"));
- }
- else
- {
- line.append(LLTrans::getString("RetrievingData"));
- }
- }
- }
- else
- {
- line.append(LLTrans::getString("RetrievingData"));
- }
- mText.push_back(line);
-
- // Build a line describing any special properties of this object.
- LLViewerObject *object = hit_object;
- LLViewerObject *parent = (LLViewerObject *)object->getParent();
-
- if (object &&
- (object->flagUsePhysics() ||
- object->flagScripted() ||
- object->flagHandleTouch() || (parent && parent->flagHandleTouch()) ||
- object->flagTakesMoney() || (parent && parent->flagTakesMoney()) ||
- object->flagAllowInventoryAdd() ||
- object->flagTemporary() ||
- object->flagPhantom()) )
- {
- line.clear();
- if (object->flagScripted())
- {
-
- line.append(LLTrans::getString("TooltipFlagScript") + " ");
- }
-
- if (object->flagUsePhysics())
- {
- line.append(LLTrans::getString("TooltipFlagPhysics") + " ");
- }
-
- if (object->flagHandleTouch() || (parent && parent->flagHandleTouch()) )
- {
- line.append(LLTrans::getString("TooltipFlagTouch") + " ");
- suppressObjectHoverDisplay = FALSE; // Show tip
- }
-
- if (object->flagTakesMoney() || (parent && parent->flagTakesMoney()) )
- {
- line.append(gHippoGridManager->getConnectedGrid()->getCurrencySymbol() + " ");
- suppressObjectHoverDisplay = FALSE; // Show tip
- }
-
- if (object->flagAllowInventoryAdd())
- {
- line.append(LLTrans::getString("TooltipFlagDropInventory") + " ");
- suppressObjectHoverDisplay = FALSE; // Show tip
- }
-
- if (object->flagPhantom())
- {
- line.append(LLTrans::getString("TooltipFlagPhantom") + " ");
- }
-
- if (object->flagTemporary())
- {
- line.append(LLTrans::getString("TooltipFlagTemporary") + " ");
- }
-
- if (object->flagUsePhysics() ||
- object->flagHandleTouch() ||
- (parent && parent->flagHandleTouch()) )
- {
- line.append(LLTrans::getString("TooltipFlagRightClickMenu") + " ");
+ line.append(LLTrans::getString("RetrievingData"));
}
mText.push_back(line);
- }
- // Free to copy / For Sale: L$
- line.clear();
- if (nodep->mValid)
- {
- BOOL for_copy = nodep->mPermissions->getMaskEveryone() & PERM_COPY && object->permCopy();
- BOOL for_sale = nodep->mSaleInfo.isForSale() &&
- nodep->mPermissions->getMaskOwner() & PERM_TRANSFER &&
- (nodep->mPermissions->getMaskOwner() & PERM_COPY ||
- nodep->mSaleInfo.getSaleType() != LLSaleInfo::FS_COPY);
- if (for_copy)
+ // Build a line describing any special properties of this object.
+ LLViewerObject *object = hit_object;
+ LLViewerObject *parent = (LLViewerObject *)object->getParent();
+
+ if (object &&
+ (object->flagUsePhysics() ||
+ object->flagScripted() ||
+ object->flagHandleTouch() || (parent && parent->flagHandleTouch()) ||
+ object->flagTakesMoney() || (parent && parent->flagTakesMoney()) ||
+ object->flagAllowInventoryAdd() ||
+ object->flagTemporary() ||
+ object->flagPhantom()) )
{
- line.append(LLTrans::getString("TooltipFreeToCopy"));
- suppressObjectHoverDisplay = FALSE; // Show tip
+ line.clear();
+ if (object->flagScripted())
+ {
+
+ line.append(LLTrans::getString("TooltipFlagScript") + " ");
+ }
+
+ if (object->flagUsePhysics())
+ {
+ line.append(LLTrans::getString("TooltipFlagPhysics") + " ");
+ }
+
+ if (object->flagHandleTouch() || (parent && parent->flagHandleTouch()) )
+ {
+ line.append(LLTrans::getString("TooltipFlagTouch") + " ");
+ suppressObjectHoverDisplay = FALSE; // Show tip
+ }
+
+ if (object->flagTakesMoney() || (parent && parent->flagTakesMoney()) )
+ {
+ line.append(gHippoGridManager->getConnectedGrid()->getCurrencySymbol() + " ");
+ suppressObjectHoverDisplay = FALSE; // Show tip
+ }
+
+ if (object->flagAllowInventoryAdd())
+ {
+ line.append(LLTrans::getString("TooltipFlagDropInventory") + " ");
+ suppressObjectHoverDisplay = FALSE; // Show tip
+ }
+
+ if (object->flagPhantom())
+ {
+ line.append(LLTrans::getString("TooltipFlagPhantom") + " ");
+ }
+
+ if (object->flagTemporary())
+ {
+ line.append(LLTrans::getString("TooltipFlagTemporary") + " ");
+ }
+
+ if (object->flagUsePhysics() ||
+ object->flagHandleTouch() ||
+ (parent && parent->flagHandleTouch()) )
+ {
+ line.append(LLTrans::getString("TooltipFlagRightClickMenu") + " ");
+ }
+ mText.push_back(line);
}
- else if (for_sale)
+
+ // Free to copy / For Sale: L$
+ line.clear();
+ if (nodep->mValid)
{
- LLStringUtil::format_map_t args;
- args["[AMOUNT]"] = llformat("%d", nodep->mSaleInfo.getSalePrice());
- line.append(LLTrans::getString("TooltipForSaleL$", args));
- suppressObjectHoverDisplay = FALSE; // Show tip
+ if (for_copy)
+ {
+ line.append(LLTrans::getString("TooltipFreeToCopy"));
+ suppressObjectHoverDisplay = FALSE; // Show tip
+ }
+ else if (for_sale)
+ {
+ LLStringUtil::format_map_t args;
+ args["[AMOUNT]"] = llformat("%d", nodep->mSaleInfo.getSalePrice());
+ line.append(LLTrans::getString("TooltipForSaleL$", args));
+ suppressObjectHoverDisplay = FALSE; // Show tip
+ }
+ else
+ {
+ // Nothing if not for sale
+ // line.append("Not for sale");
+ }
}
else
{
- // Nothing if not for sale
- // line.append("Not for sale");
+ LLStringUtil::format_map_t args;
+ args["[MESSAGE]"] = LLTrans::getString("RetrievingData");
+ line.append(LLTrans::getString("TooltipForSaleMsg", args));
}
+ mText.push_back(line);
+ line.clear();
+ S32 prim_count = LLSelectMgr::getInstance()->getHoverObjects()->getObjectCount();
+ line.append(llformat("Prims: %d", prim_count));
+ mText.push_back(line);
+
+ line.clear();
+ line.append("Position: ");
+
+ LLViewerRegion *region = gAgent.getRegion();
+ LLVector3 position = region->getPosRegionFromGlobal(hit_object->getPositionGlobal());//regionp->getOriginAgent();
+ LLVector3 mypos = region->getPosRegionFromGlobal(gAgent.getPositionGlobal());
+
+
+ LLVector3 delta = position - mypos;
+ F32 distance = (F32)delta.magVec();
+
+ line.append(llformat("<%.02f,%.02f,%.02f>",position.mV[0],position.mV[1],position.mV[2]));
+ mText.push_back(line);
+ line.clear();
+ line.append(llformat("Distance: %.02fm",distance));
+ mText.push_back(line);
}
else
{
- LLStringUtil::format_map_t args;
- args["[MESSAGE]"] = LLTrans::getString("RetrievingData");
- line.append(LLTrans::getString("TooltipForSaleMsg", args));
+ suppressObjectHoverDisplay = TRUE;
+ }
+ // If the hover tip shouldn't be shown, delete all the object text
+ if (suppressObjectHoverDisplay)
+ {
+ mText.clear();
}
- mText.push_back(line);
- }
- line.clear();
- S32 prim_count = LLSelectMgr::getInstance()->getHoverObjects()->getObjectCount();
- line.append(llformat("Prims: %d", prim_count));
- mText.push_back(line);
-
- line.clear();
- line.append("Position: ");
-
- LLViewerRegion *region = gAgent.getRegion();
- LLVector3 position = region->getPosRegionFromGlobal(hit_object->getPositionGlobal());//regionp->getOriginAgent();
- LLVector3 mypos = region->getPosRegionFromGlobal(gAgent.getPositionGlobal());
-
-
- LLVector3 delta = position - mypos;
- F32 distance = (F32)delta.magVec();
-
- line.append(llformat("<%.02f,%.02f,%.02f>",position.mV[0],position.mV[1],position.mV[2]));
- mText.push_back(line);
- line.clear();
- line.append(llformat("Distance: %.02fm",distance));
- mText.push_back(line);
-
- // If the hover tip shouldn't be shown, delete all the object text
- if (suppressObjectHoverDisplay)
- {
- mText.clear();
}
}
}
diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp
index edd499610..88d8467df 100644
--- a/indra/newview/llimpanel.cpp
+++ b/indra/newview/llimpanel.cpp
@@ -315,7 +315,7 @@ LLFloaterIMPanel::LLFloaterIMPanel(
mSentTypingState(TRUE),
mNumUnreadMessages(0),
mShowSpeakersOnConnect(TRUE),
- mAutoConnect(FALSE),
+ mStartCallOnInitialize(false),
mTextIMPossible(TRUE),
mProfileButtonEnabled(TRUE),
mCallBackEnabled(TRUE),
@@ -352,7 +352,7 @@ LLFloaterIMPanel::LLFloaterIMPanel(
mTypingLineStartIndex(0),
mSentTypingState(TRUE),
mShowSpeakersOnConnect(TRUE),
- mAutoConnect(FALSE),
+ mStartCallOnInitialize(false),
mTextIMPossible(TRUE),
mProfileButtonEnabled(TRUE),
mCallBackEnabled(TRUE),
@@ -574,8 +574,8 @@ BOOL LLFloaterIMPanel::postBuild()
if (LLUICtrl* ctrl = findChild("rp_mode"))
ctrl->setCommitCallback(boost::bind(&LLFloaterIMPanel::onRPMode, this, _2));
- childSetAction("start_call_btn", onClickStartCall, this);
- childSetAction("end_call_btn", onClickEndCall, this);
+ getChild("start_call_btn")->setCommitCallback(boost::bind(&LLIMMgr::startCall, gIMMgr, mSessionUUID, LLVoiceChannel::OUTGOING_CALL));
+ getChild("end_call_btn")->setCommitCallback(boost::bind(&LLIMMgr::endCall, gIMMgr, mSessionUUID));
getChild("send_btn")->setCommitCallback(boost::bind(&LLFloaterIMPanel::onSendMsg,this));
if (LLButton* btn = findChild("toggle_active_speakers_btn"))
btn->setCommitCallback(boost::bind(&LLFloaterIMPanel::onClickToggleActiveSpeakers, this, _2));
@@ -600,8 +600,8 @@ BOOL LLFloaterIMPanel::postBuild()
if (mDialog == IM_NOTHING_SPECIAL)
{
- childSetAction("mute_btn", onClickMuteVoice, this);
- childSetCommitCallback("speaker_volume", onVolumeChange, this);
+ getChild("mute_btn")->setCommitCallback(boost::bind(&LLFloaterIMPanel::onClickMuteVoice, this));
+ getChild("speaker_volume")->setCommitCallback(boost::bind(&LLVoiceClient::setUserVolume, LLVoiceClient::getInstance(), mOtherParticipantUUID, _2));
}
setDefaultBtn("send_btn");
@@ -625,33 +625,16 @@ void* LLFloaterIMPanel::createSpeakersPanel(void* data)
return floaterp->mSpeakerPanel;
}
-//static
-void LLFloaterIMPanel::onClickMuteVoice(void* user_data)
+void LLFloaterIMPanel::onClickMuteVoice()
{
- LLFloaterIMPanel* floaterp = (LLFloaterIMPanel*)user_data;
- if (floaterp)
+ LLMute mute(mOtherParticipantUUID, getTitle(), LLMute::AGENT);
+ if (!LLMuteList::getInstance()->isMuted(mOtherParticipantUUID, LLMute::flagVoiceChat))
{
- BOOL is_muted = LLMuteList::getInstance()->isMuted(floaterp->mOtherParticipantUUID, LLMute::flagVoiceChat);
-
- LLMute mute(floaterp->mOtherParticipantUUID, floaterp->getTitle(), LLMute::AGENT);
- if (!is_muted)
- {
- LLMuteList::getInstance()->add(mute, LLMute::flagVoiceChat);
- }
- else
- {
- LLMuteList::getInstance()->remove(mute, LLMute::flagVoiceChat);
- }
+ LLMuteList::getInstance()->add(mute, LLMute::flagVoiceChat);
}
-}
-
-//static
-void LLFloaterIMPanel::onVolumeChange(LLUICtrl* source, void* user_data)
-{
- LLFloaterIMPanel* floaterp = (LLFloaterIMPanel*)user_data;
- if (floaterp)
+ else
{
- LLVoiceClient::getInstance()->setUserVolume(floaterp->mOtherParticipantUUID, (F32)source->getValue().asReal());
+ LLMuteList::getInstance()->remove(mute, LLMute::flagVoiceChat);
}
}
@@ -670,7 +653,7 @@ void LLFloaterIMPanel::draw()
mEndCallBtn->setVisible(LLVoiceClient::getInstance()->voiceEnabled() && mVoiceChannel->getState() >= LLVoiceChannel::STATE_CALL_STARTED);
mStartCallBtn->setVisible(LLVoiceClient::getInstance()->voiceEnabled() && mVoiceChannel->getState() < LLVoiceChannel::STATE_CALL_STARTED);
mStartCallBtn->setEnabled(enable_connect);
- mSendBtn->setEnabled(!childGetValue("chat_editor").asString().empty());
+ mSendBtn->setEnabled(!mInputEditor->getValue().asString().empty());
LLPointer self_speaker = mSpeakers->findSpeaker(gAgent.getID());
if(!mTextIMPossible)
@@ -689,12 +672,6 @@ void LLFloaterIMPanel::draw()
mInputEditor->setLabel(getString("default_text_label"));
}
- if (mAutoConnect && enable_connect)
- {
- onClickStartCall(this);
- mAutoConnect = FALSE;
- }
-
// show speakers window when voice first connects
if (mShowSpeakersOnConnect && mVoiceChannel->isActive())
{
@@ -1111,14 +1088,6 @@ void LLFloaterIMPanel::onClickStartCall(void* userdata)
self->mVoiceChannel->activate();
}
-// static
-void LLFloaterIMPanel::onClickEndCall(void* userdata)
-{
- LLFloaterIMPanel* self = (LLFloaterIMPanel*) userdata;
-
- self->getVoiceChannel()->deactivate();
-}
-
void LLFloaterIMPanel::onClickToggleActiveSpeakers(const LLSD& value)
{
childSetVisible("active_speakers_panel", !value);
@@ -1454,11 +1423,6 @@ LL_WARNS("Splitting") << "Pos: " << pos << " next_split: " << next_split << LL_E
mSentTypingState = TRUE;
}
-void LLFloaterIMPanel::updateSpeakersList(const LLSD& speaker_updates)
-{
- mSpeakers->updateSpeakers(speaker_updates);
-}
-
void LLFloaterIMPanel::processSessionUpdate(const LLSD& session_update)
{
if (
@@ -1482,11 +1446,6 @@ void LLFloaterIMPanel::processSessionUpdate(const LLSD& session_update)
}
}
-void LLFloaterIMPanel::setSpeakers(const LLSD& speaker_list)
-{
- mSpeakers->setSpeakers(speaker_list);
-}
-
void LLFloaterIMPanel::sessionInitReplyReceived(const LLUUID& session_id)
{
mSessionUUID = session_id;
@@ -1512,11 +1471,12 @@ void LLFloaterIMPanel::sessionInitReplyReceived(const LLUUID& session_id)
mOtherParticipantUUID,
mDialog);
}
-}
-void LLFloaterIMPanel::requestAutoConnect()
-{
- mAutoConnect = TRUE;
+ // auto-start the call on session initialization?
+ if (mStartCallOnInitialize)
+ {
+ gIMMgr->startCall(mSessionUUID);
+ }
}
void LLFloaterIMPanel::setTyping(BOOL typing)
diff --git a/indra/newview/llimpanel.h b/indra/newview/llimpanel.h
index 7d4d1fe71..0f659a820 100644
--- a/indra/newview/llimpanel.h
+++ b/indra/newview/llimpanel.h
@@ -121,20 +121,15 @@ public:
static void* createSpeakersPanel(void* data);
//callbacks for P2P muting and volume control
- static void onClickMuteVoice(void* user_data);
- static void onVolumeChange(LLUICtrl* source, void* user_data);
+ void onClickMuteVoice();
const LLUUID& getSessionID() const { return mSessionUUID; }
const LLUUID& getOtherParticipantID() const { return mOtherParticipantUUID; }
- void updateSpeakersList(const LLSD& speaker_updates);
void processSessionUpdate(const LLSD& update);
- void setSpeakers(const LLSD& speaker_list);
LLVoiceChannel* getVoiceChannel() { return mVoiceChannel; }
LLIMSpeakerMgr* getSpeakerManager() const { return mSpeakers; } // Singu TODO: LLIMModel::getSpeakerManager
EInstantMessage getDialogType() const { return mDialog; }
- void requestAutoConnect();
-
void sessionInitReplyReceived(const LLUUID& im_session_id);
// Handle other participant in the session typing.
@@ -161,6 +156,10 @@ public:
bool isGroupSessionType() const { return mSessionType == GROUP_SESSION;}
SType mSessionType;
+ // LLIMModel Functionality
+ bool getSessionInitialized() const { return mSessionInitialized; }
+ bool mStartCallOnInitialize;
+
private:
// called by constructors
void init(const std::string& session_label);
@@ -236,8 +235,6 @@ private:
BOOL mShowSpeakersOnConnect;
- BOOL mAutoConnect;
-
BOOL mTextIMPossible;
BOOL mProfileButtonEnabled;
BOOL mCallBackEnabled;
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 06ac47b5b..837b76ff8 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -53,6 +53,7 @@
#include "llfloaterchatterbox.h"
#include "llhttpnode.h"
#include "llimpanel.h"
+#include "llnotificationsutil.h"
#include "llsdserialize.h"
#include "llspeakers.h"
#include "lltabcontainer.h"
@@ -60,7 +61,6 @@
#include "llviewermenu.h"
#include "llviewermessage.h"
#include "llviewerwindow.h"
-#include "llvoicechannel.h"
#include "llnotify.h"
#include "llviewerregion.h"
@@ -115,6 +115,7 @@ LLColor4 agent_chat_color(const LLUUID& id, const std::string& name, bool local_
//{
// return (LLStringUtil::compareDict( a->mName, b->mName ) < 0);
//}
+
class LLViewerChatterBoxInvitationAcceptResponder : public LLHTTPClient::ResponderWithResult
{
public:
@@ -130,10 +131,9 @@ public:
{
if ( gIMMgr)
{
- LLFloaterIMPanel* floaterp =
- gIMMgr->findFloaterBySession(mSessionID);
-
- if (floaterp)
+ LLFloaterIMPanel* floater = gIMMgr->findFloaterBySession(mSessionID);
+ LLIMSpeakerMgr* speaker_mgr = floater ? floater->getSpeakerManager() : NULL;
+ if (speaker_mgr)
{
//we've accepted our invitation
//and received a list of agents that were
@@ -147,26 +147,26 @@ public:
//but unfortunately, our base that we are receiving here
//may not be the most up to date. It was accurate at
//some point in time though.
- floaterp->setSpeakers(content);
+ speaker_mgr->setSpeakers(content);
//we now have our base of users in the session
//that was accurate at some point, but maybe not now
//so now we apply all of the udpates we've received
//in case of race conditions
- floaterp->updateSpeakersList(
- gIMMgr->getPendingAgentListUpdates(mSessionID));
+ speaker_mgr->updateSpeakers(gIMMgr->getPendingAgentListUpdates(mSessionID));
+ }
- if ( mInvitiationType == LLIMMgr::INVITATION_TYPE_VOICE )
- {
- floaterp->requestAutoConnect();
- LLFloaterIMPanel::onClickStartCall(floaterp);
- // always open IM window when connecting to voice
- LLFloaterChatterBox::showInstance(TRUE);
- }
- else if ( mInvitiationType == LLIMMgr::INVITATION_TYPE_IMMEDIATE )
- {
- LLFloaterChatterBox::showInstance(TRUE);
- }
+ if (LLIMMgr::INVITATION_TYPE_VOICE == mInvitiationType)
+ {
+ gIMMgr->startCall(mSessionID, LLVoiceChannel::INCOMING_CALL);
+ }
+
+ if ((mInvitiationType == LLIMMgr::INVITATION_TYPE_VOICE
+ || mInvitiationType == LLIMMgr::INVITATION_TYPE_IMMEDIATE)
+ && gIMMgr->hasSession(mSessionID))
+ {
+ // always open IM window when connecting to voice
+ LLFloaterChatterBox::showInstance(TRUE);
}
gIMMgr->clearPendingAgentListUpdates(mSessionID);
@@ -176,6 +176,8 @@ public:
/*virtual*/ void error(U32 statusNum, const std::string& reason)
{
+ llwarns << "LLViewerChatterBoxInvitationAcceptResponder error [status:"
+ << statusNum << "]: " << reason << llendl;
//throw something back to the viewer here?
if ( gIMMgr )
{
@@ -286,11 +288,14 @@ protected:
bool inviteUserResponse(const LLSD& notification, const LLSD& response)
{
+ if (!gIMMgr)
+ return false;
+
const LLSD& payload = notification["payload"];
LLUUID session_id = payload["session_id"].asUUID();
EInstantMessage type = (EInstantMessage)payload["type"].asInteger();
LLIMMgr::EInvitationType inv_type = (LLIMMgr::EInvitationType)payload["inv_type"].asInteger();
- S32 option = LLNotification::getSelectedOption(notification, response);
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
switch(option)
{
case 0: // accept
@@ -304,16 +309,10 @@ bool inviteUserResponse(const LLSD& notification, const LLSD& response)
payload["session_handle"].asString(),
payload["session_uri"].asString());
- LLFloaterIMPanel* im_floater =
- gIMMgr->findFloaterBySession(
- session_id);
- if (im_floater)
- {
- im_floater->requestAutoConnect();
- LLFloaterIMPanel::onClickStartCall(im_floater);
- // always open IM window when connecting to voice
- LLFloaterChatterBox::showInstance(session_id);
- }
+ gIMMgr->startCall(session_id);
+
+ // always open IM window when connecting to voice
+ LLFloaterChatterBox::showInstance(session_id);
gIMMgr->clearPendingAgentListUpdates(session_id);
gIMMgr->clearPendingInvitation(session_id);
@@ -355,11 +354,8 @@ bool inviteUserResponse(const LLSD& notification, const LLSD& response)
{
if (type == IM_SESSION_P2P_INVITE)
{
- if(LLVoiceClient::instanceExists())
- {
- std::string s = payload["session_handle"].asString();
- LLVoiceClient::getInstance()->declineInvite(s);
- }
+ std::string s = payload["session_handle"].asString();
+ LLVoiceClient::getInstance()->declineInvite(s);
}
else
{
@@ -688,6 +684,22 @@ BOOL LLIMMgr::isIMSessionOpen(const LLUUID& uuid)
return FALSE;
}
+void LLIMMgr::autoStartCallOnStartup(const LLUUID& session_id)
+{
+ // Singu TODO: LLIMModel
+ LLFloaterIMPanel* floater = findFloaterBySession(session_id);
+ if (!floater) return;
+
+ if (floater->getSessionInitialized())
+ {
+ startCall(session_id);
+ }
+ else
+ {
+ floater->mStartCallOnInitialize = true;
+ }
+}
+
LLUUID LLIMMgr::addP2PSession(const std::string& name,
const LLUUID& other_participant_id,
const std::string& voice_session_handle,
@@ -1025,6 +1037,31 @@ void LLIMMgr::clearPendingInvitation(const LLUUID& session_id)
}
}
+void LLIMMgr::processAgentListUpdates(const LLUUID& session_id, const LLSD& body)
+{
+ LLFloaterIMPanel* im_floater = gIMMgr->findFloaterBySession(session_id);
+ if (!im_floater) return;
+ LLIMSpeakerMgr* speaker_mgr = im_floater->getSpeakerManager();
+ if (speaker_mgr)
+ {
+ speaker_mgr->updateSpeakers(body);
+
+ // also the same call is added into LLVoiceClient::participantUpdatedEvent because
+ // sometimes it is called AFTER LLViewerChatterBoxSessionAgentListUpdates::post()
+ // when moderation state changed too late. See EXT-3544.
+ speaker_mgr->update(true);
+ }
+ else
+ {
+ //we don't have a speaker manager yet..something went wrong
+ //we are probably receiving an update here before
+ //a start or an acceptance of an invitation. Race condition.
+ gIMMgr->addPendingAgentListUpdates(
+ session_id,
+ body);
+ }
+}
+
LLSD LLIMMgr::getPendingAgentListUpdates(const LLUUID& session_id)
{
if ( mPendingAgentListUpdates.has(session_id.asString()) )
@@ -1105,6 +1142,39 @@ void LLIMMgr::clearPendingAgentListUpdates(const LLUUID& session_id)
}
}
+bool LLIMMgr::startCall(const LLUUID& session_id, LLVoiceChannel::EDirection direction)
+{
+ // Singu TODO: LLIMModel
+ LLFloaterIMPanel* floater = gIMMgr->findFloaterBySession(session_id);
+ if (!floater) return false;
+
+ LLVoiceChannel* voice_channel = floater->getVoiceChannel();
+ if (!voice_channel) return false;
+
+ voice_channel->setCallDirection(direction);
+ voice_channel->activate();
+ return true;
+}
+
+bool LLIMMgr::endCall(const LLUUID& session_id)
+{
+ // Singu TODO: LLIMModel
+ LLFloaterIMPanel* floater = gIMMgr->findFloaterBySession(session_id);
+ if (!floater) return false;
+
+ LLVoiceChannel* voice_channel = floater->getVoiceChannel();
+ if (!voice_channel) return false;
+
+ voice_channel->deactivate();
+ /*LLIMModel::LLIMSession* im_session = LLIMModel::getInstance()->findIMSession(session_id);
+ if (im_session)*/
+ {
+ // need to update speakers' state
+ floater->getSpeakerManager()->update(FALSE);
+ }
+ return true;
+}
+
// create a floater and update internal representation for
// consistency. Returns the pointer, caller (the class instance since
// it is a private method) is not responsible for deleting the
@@ -1418,35 +1488,30 @@ public:
if ( success )
{
session_id = body["session_id"].asUUID();
- gIMMgr->updateFloaterSessionID(
- temp_session_id,
- session_id);
- LLFloaterIMPanel* floaterp = gIMMgr->findFloaterBySession(session_id);
- if (floaterp)
+ // Singu TODO: LLIMModel
+ gIMMgr->updateFloaterSessionID(temp_session_id, session_id);
+
+ LLFloaterIMPanel* im_floater = gIMMgr->findFloaterBySession(session_id);
+ LLIMSpeakerMgr* speaker_mgr = im_floater ? im_floater->getSpeakerManager() : NULL;
+ if (speaker_mgr)
{
- floaterp->setSpeakers(body);
-
- //apply updates we've possibly received previously
- floaterp->updateSpeakersList(
- gIMMgr->getPendingAgentListUpdates(session_id));
+ speaker_mgr->setSpeakers(body);
+ speaker_mgr->updateSpeakers(gIMMgr->getPendingAgentListUpdates(session_id));
+ }
+ if (im_floater)
+ {
if ( body.has("session_info") )
{
- floaterp->processSessionUpdate(body["session_info"]);
+ im_floater->processSessionUpdate(body["session_info"]);
}
-
- //apply updates we've possibly received previously
- floaterp->updateSpeakersList(
- gIMMgr->getPendingAgentListUpdates(session_id));
}
+
gIMMgr->clearPendingAgentListUpdates(session_id);
}
else
{
- //throw an error dialog and close the temp session's floater
- LLFloaterIMPanel* floater = gIMMgr->findFloaterBySession(temp_session_id);
-
- if ( floater )
+ if (LLFloaterIMPanel* floater = gIMMgr->findFloaterBySession(temp_session_id))
{
floater->showSessionStartError(body["error"].asString());
}
@@ -1526,21 +1591,8 @@ public:
const LLSD& context,
const LLSD& input) const
{
- LLFloaterIMPanel* floaterp = gIMMgr->findFloaterBySession(input["body"]["session_id"].asUUID());
- if (floaterp)
- {
- floaterp->updateSpeakersList(
- input["body"]);
- }
- else
- {
- //we don't have a floater yet..something went wrong
- //we are probably receiving an update here before
- //a start or an acceptance of an invitation. Race condition.
- gIMMgr->addPendingAgentListUpdates(
- input["body"]["session_id"].asUUID(),
- input["body"]);
- }
+ const LLUUID& session_id = input["body"]["session_id"].asUUID();
+ gIMMgr->processAgentListUpdates(session_id, input["body"]);
}
};
@@ -1553,12 +1605,12 @@ public:
const LLSD& input) const
{
LLUUID session_id = input["body"]["session_id"].asUUID();
- LLFloaterIMPanel* floaterp = gIMMgr->findFloaterBySession(session_id);
- if (floaterp)
+ LLFloaterIMPanel* im_floater = gIMMgr->findFloaterBySession(session_id);
+ if ( im_floater )
{
- floaterp->processSessionUpdate(input["body"]["info"]);
+ im_floater->processSessionUpdate(input["body"]["info"]);
}
- LLIMSpeakerMgr* im_mgr = floaterp ? floaterp->getSpeakerManager() : NULL; //LLIMModel::getInstance()->getSpeakerManager(session_id);
+ LLIMSpeakerMgr* im_mgr = im_floater ? im_floater->getSpeakerManager() : NULL; //LLIMModel::getInstance()->getSpeakerManager(session_id);
if (im_mgr)
{
im_mgr->processSessionUpdate(input["body"]["info"]);
@@ -1651,7 +1703,9 @@ public:
std::string saved;
if(offline == IM_OFFLINE)
{
- saved = llformat("(Saved %s) ", formatted_time(timestamp).c_str());
+ LLStringUtil::format_map_t args;
+ args["[LONG_TIMESTAMP]"] = formatted_time(timestamp);
+ saved = LLTrans::getString("Saved_message", args);
}
std::string buffer = separator_string + saved + message.substr(message_offset);
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index 4db4b75f9..3e7bc6fff 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -36,12 +36,12 @@
#include "llmultifloater.h"
#include "llinstantmessage.h"
#include "lluuid.h"
+#include "llvoicechannel.h"
+
class LLFloaterChatterBox;
-class LLUUID;
class LLFloaterIMPanel;
class LLFriendObserver;
-class LLFloaterIM;
class LLIMMgr : public LLSingleton
{
@@ -131,6 +131,9 @@ public:
void notifyNewIM();
void clearNewIMNotification();
+ // automatically start a call once the session has initialized
+ void autoStartCallOnStartup(const LLUUID& session_id);
+
// IM received that you haven't seen yet
BOOL getIMReceived() const;
int getIMUnreadCount();
@@ -163,6 +166,7 @@ public:
void clearPendingInvitation(const LLUUID& session_id);
+ void processAgentListUpdates(const LLUUID& session_id, const LLSD& body);
LLSD getPendingAgentListUpdates(const LLUUID& session_id);
void addPendingAgentListUpdates(
const LLUUID& sessioN_id,
@@ -178,6 +182,18 @@ public:
// Returns true if group chat is ignored for the UUID, false if not
bool getIgnoreGroup(const LLUUID& group_id) const;
+ /**
+ * Start call in a session
+ * @return false if voice channel doesn't exist
+ **/
+ bool startCall(const LLUUID& session_id, LLVoiceChannel::EDirection direction = LLVoiceChannel::OUTGOING_CALL);
+
+ /**
+ * End call in a session
+ * @return false if voice channel doesn't exist
+ **/
+ bool endCall(const LLUUID& session_id);
+
private:
// create a panel and update internal representation for
// consistency. Returns the pointer, caller (the class instance
diff --git a/indra/newview/llinventoryactions.cpp b/indra/newview/llinventoryactions.cpp
index fe07063bb..a02de1998 100644
--- a/indra/newview/llinventoryactions.cpp
+++ b/indra/newview/llinventoryactions.cpp
@@ -48,6 +48,7 @@
#include "llpreview.h" // For LLMultiPreview
#include "lltrans.h"
#include "llvoavatarself.h"
+#include "llnotifications.h"
extern LLUUID gAgentID;
diff --git a/indra/newview/lljoystickbutton.cpp b/indra/newview/lljoystickbutton.cpp
index 5e6f3e1b0..c33667061 100644
--- a/indra/newview/lljoystickbutton.cpp
+++ b/indra/newview/lljoystickbutton.cpp
@@ -331,9 +331,6 @@ LLXMLNodePtr LLJoystickAgentTurn::getXML(bool save_children) const
LLView* LLJoystickAgentTurn::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
{
- std::string name("button");
- node->getAttributeString("name", name);
-
std::string image_unselected;
if (node->hasAttribute("image_unselected")) node->getAttributeString("image_unselected",image_unselected);
@@ -343,7 +340,7 @@ LLView* LLJoystickAgentTurn::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrl
EJoystickQuadrant quad = JQ_ORIGIN;
if (node->hasAttribute("quadrant")) quad = selectQuadrant(node);
- LLJoystickAgentTurn *button = new LLJoystickAgentTurn(name,
+ LLJoystickAgentTurn *button = new LLJoystickAgentTurn("button",
LLRect(),
image_unselected,
image_selected,
@@ -449,9 +446,6 @@ LLXMLNodePtr LLJoystickAgentSlide::getXML(bool save_children) const
// static
LLView* LLJoystickAgentSlide::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
{
- std::string name("button");
- node->getAttributeString("name", name);
-
std::string image_unselected;
if (node->hasAttribute("image_unselected")) node->getAttributeString("image_unselected",image_unselected);
@@ -462,7 +456,7 @@ LLView* LLJoystickAgentSlide::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtr
EJoystickQuadrant quad = JQ_ORIGIN;
if (node->hasAttribute("quadrant")) quad = selectQuadrant(node);
- LLJoystickAgentSlide *button = new LLJoystickAgentSlide(name,
+ LLJoystickAgentSlide *button = new LLJoystickAgentSlide("button",
LLRect(),
image_unselected,
image_selected,
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..b6a7fdb07 100644
--- a/indra/newview/llmediactrl.cpp
+++ b/indra/newview/llmediactrl.cpp
@@ -40,97 +40,124 @@
#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),
+ mContextMenu()
{
+ {
+ 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 +167,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 +194,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 +232,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 +249,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 +269,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 +286,7 @@ BOOL LLMediaCtrl::handleRightMouseUp( S32 x, S32 y, MASK mask )
}
gFocusMgr.setMouseCapture( NULL );
- */
+
return TRUE;
}
@@ -263,7 +294,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);
@@ -278,6 +309,14 @@ BOOL LLMediaCtrl::handleRightMouseDown( S32 x, S32 y, MASK mask )
setFocus( TRUE );
}
+ LLMenuGL* menu = (LLMenuGL*)mContextMenu.get();
+ if (menu)
+ {
+ menu->buildDrawLabels();
+ menu->updateParent(LLMenuGL::sMenuContainer);
+ LLMenuGL::showPopup(this,menu, x, y);
+ }
+
return TRUE;
}
@@ -285,7 +324,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 +352,7 @@ void LLMediaCtrl::onFocusReceived()
LLEditMenuHandler::gEditMenuHandler = mMediaSource;
}
- LLUICtrl::onFocusReceived();
+ LLPanel::onFocusReceived();
}
////////////////////////////////////////////////////////////////////////////////
@@ -333,15 +372,20 @@ void LLMediaCtrl::onFocusLost()
gViewerWindow->focusClient();
- LLUICtrl::onFocusLost();
+ LLPanel::onFocusLost();
}
////////////////////////////////////////////////////////////////////////////////
//
-
BOOL LLMediaCtrl::postBuild ()
{
- //setVisibleCallback(boost::bind(&LLMediaCtrl::onVisibilityChange, this, _2));
+ LLMenuGL* menu = LLUICtrlFactory::getInstance()->buildMenu("menu_media_ctrl.xml",LLMenuGL::sMenuContainer);
+ if(menu)
+ {
+ mContextMenu = menu->getHandle();
+ }
+
+ setVisibleCallback(boost::bind(&LLMediaCtrl::onVisibilityChange, this, _2));
return true;
}
@@ -350,43 +394,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 +421,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 +437,9 @@ BOOL LLMediaCtrl::handleUnicodeCharHere(llwchar uni_char)
result = mMediaSource->handleUnicodeCharHere(uni_char);
}
+ if ( ! result )
+ result = LLPanel::handleUnicodeCharHere(uni_char);
+
return result;
}
@@ -444,8 +464,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 +517,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 +576,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 +611,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 +657,6 @@ void LLMediaCtrl::setTextureSize(S32 width, S32 height)
if(mMediaSource)
{
mMediaSource->setSize(mTextureWidth, mTextureHeight);
- mWebBrowserImage->resize( mTextureWidth, mTextureHeight );
mForceUpdate = true;
}
}
@@ -634,14 +674,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 +708,6 @@ bool LLMediaCtrl::ensureMediaSourceExists()
void LLMediaCtrl::unloadMediaSource()
{
mMediaSource = NULL;
- mWebBrowserImage = NULL; //release the dynamic texture too.
}
////////////////////////////////////////////////////////////////////////////////
@@ -672,15 +721,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 +747,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 +755,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 +861,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 +894,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 +934,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 +976,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 +1033,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 +1090,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 +1120,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 +1150,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.decouple_texture_size = 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..306d68650 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,43 @@ 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;
+ LLHandle mContextMenu;
};
#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/llnamebox.cpp b/indra/newview/llnamebox.cpp
index 449bf9329..28381301d 100644
--- a/indra/newview/llnamebox.cpp
+++ b/indra/newview/llnamebox.cpp
@@ -46,20 +46,18 @@
// statics
std::set LLNameBox::sInstances;
+static LLRegisterWidget r("name_box");
-LLNameBox::LLNameBox(const std::string& name, const LLRect& rect, const LLUUID& name_id, BOOL is_group, const LLFontGL* font, BOOL mouse_opaque)
-: LLTextBox(name, rect, std::string("(retrieving)"), font, mouse_opaque),
- mNameID(name_id)
+
+LLNameBox::LLNameBox(const std::string& name)
+: LLTextBox(name, LLRect(), "" , NULL, TRUE)
{
+ mNameID = LLUUID::null;
+ mLink = false;
+ //mParseHTML = mLink; // STORM-215
+ mInitialValue = "(retrieving)";
LLNameBox::sInstances.insert(this);
- if(!name_id.isNull())
- {
- setNameID(name_id, is_group);
- }
- else
- {
- setText(LLStringUtil::null);
- }
+ setText(LLStringUtil::null);
}
LLNameBox::~LLNameBox()
@@ -72,25 +70,30 @@ void LLNameBox::setNameID(const LLUUID& name_id, BOOL is_group)
mNameID = name_id;
std::string name;
+ BOOL got_name = FALSE;
if (!is_group)
{
- gCacheName->getFullName(name_id, name);
+ got_name = gCacheName->getFullName(name_id, name);
}
else
{
- gCacheName->getGroupName(name_id, name);
+ got_name = gCacheName->getGroupName(name_id, name);
}
- setText(name);
+ // Got the name already? Set it.
+ // Otherwise it will be set later in refresh().
+ if (got_name)
+ setName(name, is_group);
+ else
+ setText(mInitialValue);
}
void LLNameBox::refresh(const LLUUID& id, const std::string& full_name, bool is_group)
-
{
if (id == mNameID)
{
- setText(full_name);
+ setName(full_name, is_group);
}
}
@@ -105,3 +108,39 @@ void LLNameBox::refreshAll(const LLUUID& id, const std::string& full_name, bool
box->refresh(id, full_name, is_group);
}
}
+
+void LLNameBox::setName(const std::string& name, BOOL is_group)
+{
+ if (mLink)
+ {
+ std::string url;
+
+ if (is_group)
+ url = "[secondlife:///app/group/" + mNameID.asString() + "/about " + name + "]";
+ else
+ url = "[secondlife:///app/agent/" + mNameID.asString() + "/about " + name + "]";
+
+ setText(url);
+ }
+ else
+ {
+ setText(name);
+ }
+}
+
+// virtual
+void LLNameBox::initFromXML(LLXMLNodePtr node, LLView* parent)
+{
+ LLTextBox::initFromXML(node, parent);
+ node->getAttributeBOOL("link", mLink);
+ node->getAttributeString("initial_value", mInitialValue);
+}
+
+// static
+LLView* LLNameBox::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
+{
+ LLNameBox* name_box = new LLNameBox("name_box");
+ name_box->initFromXML(node,parent);
+ return name_box;
+}
+
diff --git a/indra/newview/llnamebox.h b/indra/newview/llnamebox.h
index cb968e78d..0d5ec6a83 100644
--- a/indra/newview/llnamebox.h
+++ b/indra/newview/llnamebox.h
@@ -44,10 +44,9 @@ class LLNameBox
: public LLTextBox
{
public:
- LLNameBox(const std::string& name, const LLRect& rect, const LLUUID& name_id = LLUUID::null, BOOL is_group = FALSE, const LLFontGL* font = NULL, BOOL mouse_opaque = TRUE );
- // By default, follows top and left and is mouse-opaque.
- // If no text, text = name.
- // If no font, uses default system font.
+ virtual void initFromXML(LLXMLNodePtr node, LLView* parent);
+ static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
+
virtual ~LLNameBox();
void setNameID(const LLUUID& name_id, BOOL is_group);
@@ -56,11 +55,19 @@ public:
static void refreshAll(const LLUUID& id, const std::string& full_name, bool is_group);
+protected:
+ LLNameBox (const std::string& name);
+
+ friend class LLUICtrlFactory;
private:
+ void setName(const std::string& name, BOOL is_group);
+
static std::set sInstances;
private:
LLUUID mNameID;
+ BOOL mLink;
+ std::string mInitialValue;
};
diff --git a/indra/newview/llnameeditor.cpp b/indra/newview/llnameeditor.cpp
index 1fac553c0..d7c948d36 100644
--- a/indra/newview/llnameeditor.cpp
+++ b/indra/newview/llnameeditor.cpp
@@ -132,9 +132,6 @@ LLXMLNodePtr LLNameEditor::getXML(bool save_children) const
LLView* LLNameEditor::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
{
- std::string name("name_editor");
- node->getAttributeString("name", name);
-
LLRect rect;
createRect(node, rect, parent, LLRect());
@@ -143,7 +140,7 @@ LLView* LLNameEditor::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory
LLFontGL* font = LLView::selectFont(node);
- LLNameEditor* line_editor = new LLNameEditor(name,
+ LLNameEditor* line_editor = new LLNameEditor("name_editor",
rect,
LLUUID::null, FALSE,
font,
diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp
index 7c2b128d6..49f26ad4e 100644
--- a/indra/newview/llnamelistctrl.cpp
+++ b/indra/newview/llnamelistctrl.cpp
@@ -319,9 +319,6 @@ LLXMLNodePtr LLNameListCtrl::getXML(bool save_children) const
LLView* LLNameListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
{
- std::string name("name_list");
- node->getAttributeString("name", name);
-
LLRect rect;
createRect(node, rect, parent, LLRect());
@@ -337,7 +334,7 @@ LLView* LLNameListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFacto
S32 name_column_index = 0;
node->getAttributeS32("name_column_index", name_column_index);
- LLNameListCtrl* name_list = new LLNameListCtrl(name,
+ LLNameListCtrl* name_list = new LLNameListCtrl("name_list",
rect,
multi_select,
draw_border,
diff --git a/indra/newview/lloverlaybar.cpp b/indra/newview/lloverlaybar.cpp
index 7997c8df0..114bc56f1 100644
--- a/indra/newview/lloverlaybar.cpp
+++ b/indra/newview/lloverlaybar.cpp
@@ -69,7 +69,7 @@
#include "llmediactrl.h"
#include "llselectmgr.h"
#include "wlfPanel_AdvSettings.h"
-
+#include "llpanelnearbymedia.h"
@@ -87,12 +87,6 @@
LLOverlayBar *gOverlayBar = NULL;
-extern S32 MENU_BAR_HEIGHT;
-extern ImportTracker gImportTracker;
-
-BOOL LLOverlayBar::sAdvSettingsPopup;
-BOOL LLOverlayBar::sChatVisible;
-
//
// Functions
//
@@ -115,9 +109,7 @@ void* LLOverlayBar::createVoiceRemote(void* userdata)
void* LLOverlayBar::createAdvSettings(void* userdata)
{
- LLOverlayBar *self = (LLOverlayBar*)userdata;
- self->mAdvSettings = new wlfPanel_AdvSettings();
- return self->mAdvSettings;
+ return wlfPanel_AdvSettings::getInstance();
}
void* LLOverlayBar::createAORemote(void* userdata)
@@ -134,7 +126,7 @@ void* LLOverlayBar::createChatBar(void* userdata)
}
LLOverlayBar::LLOverlayBar()
- : LLPanel(),
+ : LLLayoutPanel(),
mMediaRemote(NULL),
mVoiceRemote(NULL),
mAORemote(NULL),
@@ -156,23 +148,36 @@ LLOverlayBar::LLOverlayBar()
LLUICtrlFactory::getInstance()->buildPanel(this, "panel_overlaybar.xml", &factory_map);
}
-bool updateAdvSettingsPopup(const LLSD &data)
+bool LLOverlayBar::updateAdvSettingsPopup(const LLSD &data)
{
- LLOverlayBar::sAdvSettingsPopup = gSavedSettings.getBOOL("wlfAdvSettingsPopup");
- gOverlayBar->childSetVisible("AdvSettings_container", !LLOverlayBar::sAdvSettingsPopup);
- gOverlayBar->childSetVisible("AdvSettings_container_exp", LLOverlayBar::sAdvSettingsPopup);
+ bool wfl_adv_settings_popup = data.asBoolean();
+ wlfPanel_AdvSettings::updateClass();
+ LLLayoutPanel* layout_panel = dynamic_cast((LLPanel*)mAdvSettingsContainer);
+ if(layout_panel)
+ {
+ ((LLLayoutStack*)layout_panel->getParent())->collapsePanel(layout_panel,!wfl_adv_settings_popup);
+ if(wfl_adv_settings_popup)
+ layout_panel->setTargetDim(layout_panel->getChild("Adv_Settings")->getBoundingRect().getWidth());
+ }
+
return true;
}
-bool updateChatVisible(const LLSD &data)
+bool LLOverlayBar::updateChatVisible(const LLSD &data)
{
- LLOverlayBar::sChatVisible = data.asBoolean();
+ mChatBar->getParent()->setVisible(data.asBoolean());
return true;
}
-bool updateAORemote(const LLSD &data)
+bool LLOverlayBar::updateAORemoteVisible(const LLSD &data)
{
- gOverlayBar->childSetVisible("ao_remote_container", gSavedSettings.getBOOL("EnableAORemote"));
+ mAORemoteContainer->setVisible(data.asBoolean());
+ return true;
+}
+
+bool updateNearbyMediaFloater(const LLSD &data)
+{
+ LLFloaterNearbyMedia::updateClass();
return true;
}
@@ -185,12 +190,13 @@ BOOL LLOverlayBar::postBuild()
childSetAction("Stand Up",onClickStandUp,this);
childSetAction("Cancel TP",onClickCancelTP,this);
childSetAction("Flycam",onClickFlycam,this);
- childSetVisible("chat_bar", gSavedSettings.getBOOL("ChatVisible"));
mCancelBtn = getChild("Cancel TP");
setFocusRoot(TRUE);
mBuilt = true;
+ mUnreadCountStringPlural = getString("unread_count_string_plural");
+
mChatbarAndButtons.connect(this,"chatbar_and_buttons");
mNewIM.connect(this,"New IM");
mNotBusy.connect(this,"Set Not Busy");
@@ -199,20 +205,26 @@ BOOL LLOverlayBar::postBuild()
mFlyCam.connect(this,"Flycam");
mChatBar.connect(this,"chat_bar");
mVoiceRemoteContainer.connect(this,"voice_remote_container");
+ mStateManagementContainer.connect(this,"state_management_buttons_container");
+ mAORemoteContainer.connect(this,"ao_remote_container");
+ mAdvSettingsContainer.connect(this,"AdvSettings_container");
+ mMediaRemoteContainer.connect(this,"media_remote_container");
+
+ updateAdvSettingsPopup(gSavedSettings.getBOOL("wlfAdvSettingsPopup"));
+ updateChatVisible(gSavedSettings.getBOOL("ChatVisible"));
+ updateAORemoteVisible(gSavedSettings.getBOOL("EnableAORemote"));
mOriginalIMLabel = mNewIM->getLabelSelected();
layoutButtons();
- sAdvSettingsPopup = gSavedSettings.getBOOL("wlfAdvSettingsPopup");
- sChatVisible = gSavedSettings.getBOOL("ChatVisible");
+ gSavedSettings.getControl("wlfAdvSettingsPopup")->getSignal()->connect(boost::bind(&LLOverlayBar::updateAdvSettingsPopup,this,_2));
+ gSavedSettings.getControl("ChatVisible")->getSignal()->connect(boost::bind(&LLOverlayBar::updateChatVisible,this,_2));
+ gSavedSettings.getControl("EnableAORemote")->getSignal()->connect(boost::bind(&LLOverlayBar::updateAORemoteVisible,this,_2));
+ gSavedSettings.getControl("ShowNearbyMediaFloater")->getSignal()->connect(boost::bind(&updateNearbyMediaFloater,_2));
+
+ mAORemoteContainer->setVisible(gSavedSettings.getBOOL("EnableAORemote"));
- gSavedSettings.getControl("wlfAdvSettingsPopup")->getSignal()->connect(boost::bind(&updateAdvSettingsPopup,_2));
- gSavedSettings.getControl("ChatVisible")->getSignal()->connect(boost::bind(&updateChatVisible,_2));
- gSavedSettings.getControl("EnableAORemote")->getSignal()->connect(boost::bind(&updateAORemote,_2));
- childSetVisible("AdvSettings_container", !sAdvSettingsPopup);
- childSetVisible("AdvSettings_container_exp", sAdvSettingsPopup);
- childSetVisible("ao_remote_container", gSavedSettings.getBOOL("EnableAORemote"));
return TRUE;
@@ -242,12 +254,10 @@ void LLOverlayBar::reshape(S32 width, S32 height, BOOL called_from_parent)
void LLOverlayBar::layoutButtons()
{
- LLView* state_buttons_panel = getChildView("state_management_buttons_container");
-
- if (state_buttons_panel->getVisible())
+ if (mStateManagementContainer->getVisible())
{
U32 button_count = 0;
- const child_list_t& view_list = *(state_buttons_panel->getChildList());
+ const child_list_t& view_list = *(mStateManagementContainer->getChildList());
BOOST_FOREACH(LLView* viewp, view_list)
{
if(!viewp->getEnabled())
@@ -255,7 +265,7 @@ void LLOverlayBar::layoutButtons()
++button_count;
}
const S32 MAX_BAR_WIDTH = 600;
- S32 bar_width = llclamp(state_buttons_panel->getRect().getWidth(), 0, MAX_BAR_WIDTH);
+ S32 bar_width = llclamp(mStateManagementContainer->getRect().getWidth(), 0, MAX_BAR_WIDTH);
// calculate button widths
const S32 MAX_BUTTON_WIDTH = 150;
@@ -306,7 +316,7 @@ void LLOverlayBar::refresh()
if (unread_count > 1)
{
std::stringstream ss;
- ss << unread_count << " " << getString("unread_count_string_plural");
+ ss << unread_count << " " << mUnreadCountStringPlural;
button->setLabel(ss.str());
}
else
@@ -337,33 +347,17 @@ void LLOverlayBar::refresh()
if(last_mouselook != in_mouselook)
{
last_mouselook = in_mouselook;
- if (in_mouselook)
- {
- childSetVisible("media_remote_container", FALSE);
- childSetVisible("voice_remote_container", FALSE);
- childSetVisible("AdvSettings_container", FALSE);
- childSetVisible("AdvSettings_container_exp", FALSE);
- childSetVisible("ao_remote_container", FALSE);
- childSetVisible("state_management_buttons_container", FALSE);
- }
- else
- {
- // update "remotes"
- childSetVisible("media_remote_container", TRUE);
- childSetVisible("voice_remote_container", LLVoiceClient::getInstance()->voiceEnabled());
- childSetVisible("AdvSettings_container", !sAdvSettingsPopup);//!gSavedSettings.getBOOL("wlfAdvSettingsPopup"));
- childSetVisible("AdvSettings_container_exp", sAdvSettingsPopup);//gSavedSettings.getBOOL("wlfAdvSettingsPopup"));
- childSetVisible("ao_remote_container", gSavedSettings.getBOOL("EnableAORemote"));
- childSetVisible("state_management_buttons_container", TRUE);
- }
+
+ static const LLCachedControl enable_ao_remote("EnableAORemote", true);
+ mMediaRemoteContainer->setVisible(!in_mouselook);
+ mVoiceRemoteContainer->setVisible(!in_mouselook && LLVoiceClient::getInstance()->voiceEnabled());
+ mAdvSettingsContainer->setVisible(!in_mouselook);
+ mAORemoteContainer->setVisible(!in_mouselook && enable_ao_remote);
+ mStateManagementContainer->setVisible(!in_mouselook);
}
if(!in_mouselook)
mVoiceRemoteContainer->setVisible(LLVoiceClient::getInstance()->voiceEnabled());
- // always let user toggle into and out of chatbar
- static const LLCachedControl chat_visible("ChatVisible",true);
- mChatBar->setVisible(chat_visible);
-
if (buttons_changed)
{
layoutButtons();
diff --git a/indra/newview/lloverlaybar.h b/indra/newview/lloverlaybar.h
index 365b2ac41..a02977538 100644
--- a/indra/newview/lloverlaybar.h
+++ b/indra/newview/lloverlaybar.h
@@ -34,6 +34,7 @@
#define LL_LLOVERLAYBAR_H
#include "llpanel.h"
+#include "lllayoutstack.h"
// "Constants" loaded from settings.xml at start time
extern S32 STATUS_BAR_HEIGHT;
@@ -55,7 +56,7 @@ class AORemoteCtrl;
class LLChatBar;
class LLOverlayBar
-: public LLPanel
+: public LLLayoutPanel
{
public:
LLOverlayBar();
@@ -97,8 +98,6 @@ public:
void setCancelTPButtonVisible(BOOL b, const std::string& label);
- static BOOL sChatVisible;
- static BOOL sAdvSettingsPopup;
protected:
static void* createMediaRemote(void* userdata);
static void* createVoiceRemote(void* userdata);
@@ -109,15 +108,16 @@ protected:
void enableMediaButtons();
protected:
+ friend class LLFloaterNearbyMedia; //Crappy workaround to access mMediaRemote
LLMediaRemoteCtrl* mMediaRemote;
LLVoiceRemoteCtrl* mVoiceRemote;
LLButton* mCancelBtn;
- wlfPanel_AdvSettings* mAdvSettings;
AORemoteCtrl* mAORemote;
bool mBuilt; // dialog constructed yet?
enum { STOPPED=0, PLAYING=1, PAUSED=2 };
S32 mMusicState;
std::string mOriginalIMLabel;
+ std::string mUnreadCountStringPlural;
CachedUICtrl mChatbarAndButtons;
CachedUICtrl mNewIM;
@@ -127,12 +127,14 @@ protected:
CachedUICtrl mFlyCam;
CachedUICtrl mChatBar;
CachedUICtrl mVoiceRemoteContainer;
+ CachedUICtrl mStateManagementContainer;
+ CachedUICtrl mAORemoteContainer;
+ CachedUICtrl mAdvSettingsContainer;
+ CachedUICtrl mMediaRemoteContainer;
private:
-
-
- /*static void updateAdvSettingsPopup(const LLSD &data);
- static void updateChatVisible(const LLSD &data);*/
-
+ bool updateChatVisible(const LLSD &data);
+ bool updateAORemoteVisible(const LLSD &data);
+ bool updateAdvSettingsPopup(const LLSD &data);
};
extern LLOverlayBar* gOverlayBar;
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 d375b1dc1..bbf57a1b5 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/llpanelcontents.cpp b/indra/newview/llpanelcontents.cpp
index 5eda11310..c44a855b7 100644
--- a/indra/newview/llpanelcontents.cpp
+++ b/indra/newview/llpanelcontents.cpp
@@ -82,6 +82,13 @@
//
// Globals
//
+const char* LLPanelContents::TENTATIVE_SUFFIX = "_tentative";
+const char* LLPanelContents::PERMS_OWNER_INTERACT_KEY = "perms_owner_interact";
+const char* LLPanelContents::PERMS_OWNER_CONTROL_KEY = "perms_owner_control";
+const char* LLPanelContents::PERMS_GROUP_INTERACT_KEY = "perms_group_interact";
+const char* LLPanelContents::PERMS_GROUP_CONTROL_KEY = "perms_group_control";
+const char* LLPanelContents::PERMS_ANYONE_INTERACT_KEY = "perms_anyone_interact";
+const char* LLPanelContents::PERMS_ANYONE_CONTROL_KEY = "perms_anyone_control";
BOOL LLPanelContents::postBuild()
{
diff --git a/indra/newview/llpanelcontents.h b/indra/newview/llpanelcontents.h
index b7b103d5b..8e4aa7c4e 100644
--- a/indra/newview/llpanelcontents.h
+++ b/indra/newview/llpanelcontents.h
@@ -54,6 +54,17 @@ public:
static void onClickNewScript( void* userdata);
static void onClickPermissions( void* userdata);
+ // Key suffix for "tentative" fields
+ static const char* TENTATIVE_SUFFIX;
+
+ // These aren't fields in LLMediaEntry, so we have to define them ourselves for checkbox control
+ static const char* PERMS_OWNER_INTERACT_KEY;
+ static const char* PERMS_OWNER_CONTROL_KEY;
+ static const char* PERMS_GROUP_INTERACT_KEY;
+ static const char* PERMS_GROUP_CONTROL_KEY;
+ static const char* PERMS_ANYONE_INTERACT_KEY;
+ static const char* PERMS_ANYONE_CONTROL_KEY;
+
protected:
void getState(LLViewerObject *object);
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/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp
index f3b7f5af1..78ef25eed 100644
--- a/indra/newview/llpaneleditwearable.cpp
+++ b/indra/newview/llpaneleditwearable.cpp
@@ -45,6 +45,7 @@
#include "llscrollingpanelparam.h"
#include "llradiogroup.h"
#include "llnotificationsutil.h"
+#include "llnotifications.h"
#include "llcolorswatch.h"
#include "lltexturectrl.h"
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index be0ebbad9..c6ed7163f 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
@@ -75,6 +79,22 @@
BOOL LLPanelFace::postBuild()
{
+ childSetCommitCallback("combobox shininess",&LLPanelFace::onCommitShiny,this);
+ childSetCommitCallback("combobox bumpiness",&LLPanelFace::onCommitBump,this);
+
+ childSetCommitCallback("TexScaleU",&LLPanelFace::onCommitTextureInfo, this);
+ childSetCommitCallback("checkbox flip s",&LLPanelFace::onCommitTextureInfo, this);
+ childSetCommitCallback("TexScaleV",&LLPanelFace::onCommitTextureInfo, this);
+ childSetCommitCallback("checkbox flip t",&LLPanelFace::onCommitTextureInfo, this);
+ childSetCommitCallback("TexRot",&LLPanelFace::onCommitTextureInfo, this);
+ childSetAction("button apply",&LLPanelFace::onClickApply,this);
+ childSetCommitCallback("checkbox planar align",&LLPanelFace::onCommitPlanarAlign, this);
+ childSetCommitCallback("TexOffsetU",LLPanelFace::onCommitTextureInfo, this);
+ childSetCommitCallback("TexOffsetV",LLPanelFace::onCommitTextureInfo, this);
+ childSetAction("button align",&LLPanelFace::onClickAutoFix,this);
+ childSetAction("copytextures",&LLPanelFace::onClickCopy,this);
+ childSetAction("pastetextures",&LLPanelFace::onClickPaste,this);
+
LLTextureCtrl* mTextureCtrl;
LLColorSwatchCtrl* mColorSwatch;
@@ -165,20 +185,6 @@ BOOL LLPanelFace::postBuild()
mCtrlGlow->setCommitCallback(LLPanelFace::onCommitGlow, this);
}
- childSetCommitCallback("combobox shininess",&LLPanelFace::onCommitShiny,this);
- childSetCommitCallback("combobox bumpiness",&LLPanelFace::onCommitBump,this);
- childSetCommitCallback("checkbox planar align",&LLPanelFace::onCommitPlanarAlign, this);
- childSetCommitCallback("TexScaleU",&LLPanelFace::onCommitTextureInfo, this);
- childSetCommitCallback("checkbox flip s",&LLPanelFace::onCommitTextureInfo, this);
- childSetCommitCallback("TexScaleV",&LLPanelFace::onCommitTextureInfo, this);
- childSetCommitCallback("checkbox flip t",&LLPanelFace::onCommitTextureInfo, this);
- childSetCommitCallback("TexRot",&LLPanelFace::onCommitTextureInfo, this);
- childSetAction("button apply",&onClickApply,this);
- childSetCommitCallback("TexOffsetU",LLPanelFace::onCommitTextureInfo, this);
- childSetCommitCallback("TexOffsetV",LLPanelFace::onCommitTextureInfo, this);
- childSetAction("button align",onClickAutoFix,this);
- childSetAction("copytextures",onClickCopy,this);
- childSetAction("pastetextures",onClickPaste,this);
clearCtrls();
@@ -511,12 +517,9 @@ void LLPanelFace::getState()
{
BOOL editable = objectp->permModify() && !objectp->isPermanentEnforced();
-
// only turn on auto-adjust button if there is a media renderer and the media is loaded
- childSetEnabled("textbox autofix",FALSE);
- //mLabelTexAutoFix->setEnabled ( FALSE );
- childSetEnabled("button align",FALSE);
- //mBtnAutoFix->setEnabled ( FALSE );
+ getChildView("textbox autofix")->setEnabled(editable);
+ getChildView("button align")->setEnabled(editable);
//if ( LLMediaEngine::getInstance()->getMediaRenderer () )
// if ( LLMediaEngine::getInstance()->getMediaRenderer ()->isLoaded () )
@@ -533,7 +536,7 @@ void LLPanelFace::getState()
childSetEnabled("copytextures", single_volume && editable);
childSetEnabled("pastetextures", single_volume && editable);
childSetEnabled("textbox params", single_volume && editable);
- childSetEnabled("button apply",editable);
+ getChildView("button apply")->setEnabled(editable);
bool identical;
LLTextureCtrl* texture_ctrl = getChild("texture control");
@@ -543,20 +546,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
@@ -587,13 +613,6 @@ void LLPanelFace::getState()
}
}
}
-
- if(LLViewerMedia::textureHasMedia(id))
- {
- childSetEnabled("textbox autofix",editable);
- childSetEnabled("button align",editable);
- }
-
}
@@ -658,7 +677,7 @@ void LLPanelFace::getState()
// Texture scale
{
- childSetEnabled("tex scale",editable);
+ getChildView("tex scale")->setEnabled(editable);
//mLabelTexScale->setEnabled( editable );
F32 scale_s = 1.f;
struct f2 : public LLSelectedTEGetFunctor
@@ -670,12 +689,12 @@ void LLPanelFace::getState()
} func;
identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, scale_s );
identical = align_planar ? identical_planar_aligned : identical;
- childSetValue("TexScaleU",editable ? llabs(scale_s) : 0);
- childSetTentative("TexScaleU",LLSD((BOOL)(!identical)));
- childSetEnabled("TexScaleU",editable);
- childSetValue("checkbox flip s",LLSD((BOOL)(scale_s < 0 ? TRUE : FALSE )));
- childSetTentative("checkbox flip s",LLSD((BOOL)((!identical) ? TRUE : FALSE )));
- childSetEnabled("checkbox flip s",editable);
+ getChild("TexScaleU")->setValue(editable ? llabs(scale_s) : 0);
+ getChild("TexScaleU")->setTentative(LLSD((BOOL)(!identical)));
+ getChildView("TexScaleU")->setEnabled(editable);
+ getChild("checkbox flip s")->setValue(LLSD((BOOL)(scale_s < 0 ? TRUE : FALSE )));
+ getChild("checkbox flip s")->setTentative(LLSD((BOOL)((!identical) ? TRUE : FALSE )));
+ getChildView("checkbox flip s")->setEnabled(editable);
}
{
@@ -690,17 +709,17 @@ void LLPanelFace::getState()
identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, scale_t );
identical = align_planar ? identical_planar_aligned : identical;
- childSetValue("TexScaleV",llabs(editable ? llabs(scale_t) : 0));
- childSetTentative("TexScaleV",LLSD((BOOL)(!identical)));
- childSetEnabled("TexScaleV",editable);
- childSetValue("checkbox flip t",LLSD((BOOL)(scale_t< 0 ? TRUE : FALSE )));
- childSetTentative("checkbox flip t",LLSD((BOOL)((!identical) ? TRUE : FALSE )));
- childSetEnabled("checkbox flip t",editable);
+ getChild("TexScaleV")->setValue(llabs(editable ? llabs(scale_t) : 0));
+ getChild("TexScaleV")->setTentative(LLSD((BOOL)(!identical)));
+ getChildView("TexScaleV")->setEnabled(editable);
+ getChild("checkbox flip t")->setValue(LLSD((BOOL)(scale_t< 0 ? TRUE : FALSE )));
+ getChild("checkbox flip t")->setTentative(LLSD((BOOL)((!identical) ? TRUE : FALSE )));
+ getChildView("checkbox flip t")->setEnabled(editable);
}
// Texture offset
{
- childSetEnabled("tex offset",editable);
+ getChildView("tex offset")->setEnabled(editable);
F32 offset_s = 0.f;
struct f4 : public LLSelectedTEGetFunctor
{
@@ -711,9 +730,9 @@ void LLPanelFace::getState()
} func;
identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, offset_s );
identical = align_planar ? identical_planar_aligned : identical;
- childSetValue("TexOffsetU", editable ? offset_s : 0);
- childSetTentative("TexOffsetU",!identical);
- childSetEnabled("TexOffsetU",editable);
+ getChild("TexOffsetU")->setValue(editable ? offset_s : 0);
+ getChild("TexOffsetU")->setTentative(!identical);
+ getChildView("TexOffsetU")->setEnabled(editable);
}
{
@@ -727,14 +746,14 @@ void LLPanelFace::getState()
} func;
identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, offset_t );
identical = align_planar ? identical_planar_aligned : identical;
- childSetValue("TexOffsetV", editable ? offset_t : 0);
- childSetTentative("TexOffsetV",!identical);
- childSetEnabled("TexOffsetV",editable);
+ getChild("TexOffsetV")->setValue(editable ? offset_t : 0);
+ getChild("TexOffsetV")->setTentative(!identical);
+ getChildView("TexOffsetV")->setEnabled(editable);
}
// Texture rotation
{
- childSetEnabled("tex rotate",editable);
+ getChildView("tex rotate")->setEnabled(editable);
F32 rotation = 0.f;
struct f6 : public LLSelectedTEGetFunctor
{
@@ -745,9 +764,9 @@ void LLPanelFace::getState()
} func;
identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, rotation );
identical = align_planar ? identical_planar_aligned : identical;
- childSetValue("TexRot", editable ? rotation * RAD_TO_DEG : 0);
- childSetTentative("TexRot",!identical);
- childSetEnabled("TexRot",editable);
+ getChild("TexRot")->setValue(editable ? rotation * RAD_TO_DEG : 0);
+ getChild("TexRot")->setTentative(!identical);
+ getChildView("TexRot")->setEnabled(editable);
}
// Color swatch
@@ -773,13 +792,13 @@ void LLPanelFace::getState()
}
// Color transparency
{
- childSetEnabled("color trans",editable);
+ getChildView("color trans")->setEnabled(editable);
}
F32 transparency = (1.f - color.mV[VALPHA]) * 100.f;
{
- childSetValue("ColorTrans", editable ? transparency : 0);
- childSetEnabled("ColorTrans",editable);
+ getChild("ColorTrans")->setValue(editable ? transparency : 0);
+ getChildView("ColorTrans")->setEnabled(editable);
}
{
@@ -793,10 +812,10 @@ void LLPanelFace::getState()
} func;
identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, glow );
- childSetValue("glow",glow);
- childSetEnabled("glow",editable);
- childSetTentative("glow",!identical);
- childSetEnabled("glow label",editable);
+ getChild("glow")->setValue(glow);
+ getChildView("glow")->setEnabled(editable);
+ getChild("glow")->setTentative(!identical);
+ getChildView("glow label")->setEnabled(editable);
}
@@ -821,9 +840,9 @@ void LLPanelFace::getState()
{
llwarns << "failed childGetSelectionInterface for 'combobox shininess'" << llendl;
}
- childSetEnabled("combobox shininess",editable);
- childSetTentative("combobox shininess",!identical);
- childSetEnabled("label shininess",editable);
+ getChildView("combobox shininess")->setEnabled(editable);
+ getChild("combobox shininess")->setTentative(!identical);
+ getChildView("label shininess")->setEnabled(editable);
}
{
@@ -846,9 +865,9 @@ void LLPanelFace::getState()
{
llwarns << "failed childGetSelectionInterface for 'combobox bumpiness'" << llendl;
}
- childSetEnabled("combobox bumpiness",editable);
- childSetTentative("combobox bumpiness",!identical);
- childSetEnabled("label bumpiness",editable);
+ getChildView("combobox bumpiness")->setEnabled(editable);
+ getChild("combobox bumpiness")->setTentative(!identical);
+ getChildView("label bumpiness")->setEnabled(editable);
}
{
@@ -872,19 +891,21 @@ void LLPanelFace::getState()
{
llwarns << "failed childGetSelectionInterface for 'combobox texgen'" << llendl;
}
- childSetEnabled("combobox texgen",editable);
- childSetTentative("combobox texgen",!identical);
- childSetEnabled("tex gen",editable);
+ getChildView("combobox texgen")->setEnabled(editable);
+ getChild("combobox texgen")->setTentative(!identical);
+ getChildView("tex gen")->setEnabled(editable);
if (selected_texgen == 1)
{
- childSetText("tex scale",getString("string repeats per meter"));
- childSetValue("TexScaleU", 2.0f * childGetValue("TexScaleU").asReal() );
- childSetValue("TexScaleV", 2.0f * childGetValue("TexScaleV").asReal() );
+ getChild("TexScaleU")->setValue(2.0f * getChild("TexScaleU")->getValue().asReal() );
+ getChild("TexScaleV")->setValue(2.0f * getChild("TexScaleV")->getValue().asReal() );
+
+ // EXP-1507 (change label based on the mapping mode)
+ getChild("tex scale")->setValue(getString("string repeats per meter"));
}
else
{
- childSetText("tex scale",getString("string repeats per face"));
+ getChild("tex scale")->setValue(getString("string repeats per face"));
}
}
@@ -900,14 +921,14 @@ void LLPanelFace::getState()
} func;
identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, fullbrightf );
- childSetValue("checkbox fullbright",(S32)fullbrightf);
- childSetEnabled("checkbox fullbright",editable);
- childSetTentative("checkbox fullbright",!identical);
+ getChild("checkbox fullbright")->setValue((S32)fullbrightf);
+ getChildView("checkbox fullbright")->setEnabled(editable);
+ getChild("checkbox fullbright")->setTentative(!identical);
}
// Repeats per meter label
{
- childSetEnabled("rpt",editable);
+ getChildView("rpt")->setEnabled(editable);
}
// Repeats per meter
@@ -927,14 +948,14 @@ void LLPanelFace::getState()
} func;
identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, repeats );
- childSetValue("rptctrl", editable ? repeats : 0);
- childSetTentative("rptctrl",!identical);
+ getChild("rptctrl")->setValue(editable ? repeats : 0);
+ getChild("rptctrl")->setTentative(!identical);
LLComboBox* mComboTexGen = getChild("combobox texgen");
if (mComboTexGen)
{
BOOL enabled = editable && (!mComboTexGen || mComboTexGen->getCurrentIndex() != 1);
- childSetEnabled("rptctrl",enabled);
- childSetEnabled("button apply",enabled);
+ getChildView("rptctrl")->setEnabled(enabled);
+ getChildView("button apply")->setEnabled(enabled);
}
}
@@ -968,19 +989,21 @@ void LLPanelFace::getState()
mColorSwatch->setFallbackImageName("locked_image.j2c" );
mColorSwatch->setValid(FALSE);
}
- childSetEnabled("color trans",FALSE);
- childSetEnabled("rpt",FALSE);
- childSetEnabled("tex scale",FALSE);
- childSetEnabled("tex offset",FALSE);
- childSetEnabled("tex rotate",FALSE);
- childSetEnabled("tex gen",FALSE);
- childSetEnabled("label shininess",FALSE);
- childSetEnabled("label bumpiness",FALSE);
+ getChildView("color trans")->setEnabled(FALSE);
+ getChildView("rpt")->setEnabled(FALSE);
+ getChildView("tex scale")->setEnabled(FALSE);
+ getChildView("tex offset")->setEnabled(FALSE);
+ getChildView("tex rotate")->setEnabled(FALSE);
+ getChildView("tex gen")->setEnabled(FALSE);
+ getChildView("label shininess")->setEnabled(FALSE);
+ getChildView("label bumpiness")->setEnabled(FALSE);
- childSetEnabled("textbox autofix",FALSE);
+ getChildView("textbox autofix")->setEnabled(FALSE);
- childSetEnabled("button align",FALSE);
- childSetEnabled("button apply",FALSE);
+ getChildView("button align")->setEnabled(FALSE);
+ getChildView("button apply")->setEnabled(FALSE);
+ //getChildView("has media")->setEnabled(FALSE);
+ //getChildView("media info set")->setEnabled(FALSE);
// Set variable values for numeric expressions
@@ -1119,19 +1142,29 @@ void LLPanelFace::onClickApply(void* userdata)
gFocusMgr.setKeyboardFocus( NULL );
//F32 repeats_per_meter = self->mCtrlRepeatsPerMeter->get();
- F32 repeats_per_meter = (F32)self->childGetValue( "rptctrl" ).asReal();//self->mCtrlRepeatsPerMeter->get();
+ F32 repeats_per_meter = (F32)self->getChild("rptctrl")->getValue().asReal();//self->mCtrlRepeatsPerMeter->get();
LLSelectMgr::getInstance()->selectionTexScaleAutofit( repeats_per_meter );
}
-// commit the fit media texture to prim button
-
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();
@@ -1163,6 +1196,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 fac5e7fb0..52ccbaf10 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 drag should succeed.
static BOOL onDragTexture(LLUICtrl* ctrl, LLInventoryItem* item);
diff --git a/indra/newview/llpanelgeneral.cpp b/indra/newview/llpanelgeneral.cpp
index bd67c5284..559dba021 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"
@@ -48,6 +47,7 @@
#include "llavatarnamecache.h"
#include "llvoavatar.h"
#include "llcallingcard.h"
+#include "llnotifications.h"
LLPanelGeneral::LLPanelGeneral()
{
@@ -62,7 +62,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 +152,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 +169,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.cpp b/indra/newview/llpanelgroup.cpp
index ad8b2cd40..816ba6fba 100644
--- a/indra/newview/llpanelgroup.cpp
+++ b/indra/newview/llpanelgroup.cpp
@@ -119,9 +119,7 @@ void LLPanelGroupTab::handleClickHelp()
LLSD args;
args["MESSAGE"] = help_text;
LLFloater* parent_floater = gFloaterView->getParentFloater(this);
- LLNotification::Params params(parent_floater->contextualNotification("GenericAlert"));
- params.substitutions(args);
- LLNotifications::instance().add(params);
+ parent_floater->addContextualNotification("GenericAlert",args);
}
}
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/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp
index e524a280b..31482d15e 100644
--- a/indra/newview/llpanelgroupgeneral.cpp
+++ b/indra/newview/llpanelgroupgeneral.cpp
@@ -143,14 +143,7 @@ BOOL LLPanelGroupGeneral::postBuild()
mBtnInfo->setClickedCallback(boost::bind(LLGroupActions::show, mGroupID));
}
- LLTextBox* founder = getChild("founder_name");
- if (founder)
- {
- mFounderName = new LLNameBox(founder->getName(),founder->getRect(),LLUUID::null,FALSE,founder->getFont(),founder->getMouseOpaque());
- removeChild(founder);
- delete founder;
- addChild(mFounderName);
- }
+ mFounderName = getChild("founder_name");
mListVisibleMembers = getChild("visible_members", recurse);
if (mListVisibleMembers)
diff --git a/indra/newview/llpanellandmedia.cpp b/indra/newview/llpanellandmedia.cpp
index 152d1786f..a515eadc7 100644
--- a/indra/newview/llpanellandmedia.cpp
+++ b/indra/newview/llpanellandmedia.cpp
@@ -91,6 +91,7 @@ BOOL LLPanelLandMedia::postBuild()
mMediaTextureCtrl->setCommitCallback( onCommitAny, 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");
@@ -156,7 +157,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 );
@@ -202,17 +203,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)
@@ -326,7 +327,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 c18a52362..0986ac024 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";
@@ -135,7 +130,8 @@ static std::string nameJoin(const std::string& first,const std::string& last, bo
}
static std::string getDisplayString(const std::string& first, const std::string& last, const std::string& grid, bool is_secondlife) {
- if(grid == gHippoGridManager->getDefaultGridNick())
+ //grid comes via LLSavedLoginEntry, which uses full grid names, not nicks
+ if(grid == gHippoGridManager->getDefaultGridName())
return nameJoin(first, last, is_secondlife);
else
return nameJoin(first, last, is_secondlife) + " (" + grid + ")";
@@ -149,7 +145,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 +184,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 +200,6 @@ namespace {
boost::intrusive_ptr< LLIamHereLogin > gResponsePtr = 0;
};
-void set_start_location(const LLSD& value)
-{
- LLURLSimString::setString(value.asString());
-}
-
//---------------------------------------------------------------------------
// Public methods
//---------------------------------------------------------------------------
@@ -216,8 +209,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 +236,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(boost::bind(LLPanelLogin::onSelectLoginEntry, _1, this));
name_combo->setFocusLostCallback(boost::bind(&LLPanelLogin::onLoginComboLostFocus, this, name_combo));
@@ -270,72 +257,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 '"<