From 98fd90ddd6595f2ee7e626c14117f51def621ec5 Mon Sep 17 00:00:00 2001 From: Josh Bell <josh@lindenlab.com> Date: Thu, 14 Feb 2008 01:45:59 +0000 Subject: [PATCH] svn merge -r 79730:79944 svn+ssh://svn.lindenlab.com/svn/linden/branches/parcel_media/sl-parcelmedia-6 --> release QAR-275 Parcel Media Sam made me do it. --- etc/message.xml | 13 +- indra/llcommon/indra_constants.h | 4 + indra/llcommon/llclickaction.h | 2 + indra/llcommon/llpreprocessor.h | 27 - indra/llinventory/llparcel.cpp | 1402 +++++++++-------- indra/llinventory/llparcel.h | 22 + indra/llmessage/llhttpclient.cpp | 20 +- indra/llmessage/llhttpclient.h | 11 +- indra/llmessage/llurlrequest.cpp | 6 +- indra/llrender/llimagegl.cpp | 2 +- indra/llui/llcombobox.cpp | 31 +- indra/llui/llradiogroup.cpp | 4 +- indra/llui/llscrolllistctrl.cpp | 9 +- indra/llui/lluictrl.cpp | 18 +- indra/llui/lluictrl.h | 2 +- indra/llui/lluifwd.h | 40 + indra/llwindow/llwindow.h | 3 + indra/llwindow/llwindowmacosx.cpp | 9 + indra/llwindow/llwindowsdl.cpp | 32 +- indra/llwindow/llwindowwin32.cpp | 3 + indra/lscript/lscript_compile/indra.l | 14 + .../lscript_library/lscript_library.cpp | 12 +- indra/newview/app_settings/keywords.ini | 12 + .../cursors_mac/UI_CURSOR_TOOLMEDIAOPEN.tif | Bin 0 -> 41228 bytes .../cursors_mac/UI_CURSOR_TOOLPAUSE.tif | Bin 0 -> 41224 bytes .../cursors_mac/UI_CURSOR_TOOLPLAY.tif | Bin 0 -> 41224 bytes indra/newview/llappviewer.cpp | 70 +- indra/newview/llfirstuse.cpp | 11 + indra/newview/llfirstuse.h | 3 +- indra/newview/llfloaterabout.cpp | 24 +- indra/newview/llfloaterland.cpp | 350 +--- indra/newview/llfloaterland.h | 42 +- indra/newview/llfloaterpreference.cpp | 8 - indra/newview/llfloatertos.cpp | 17 - indra/newview/llfloaterurlentry.cpp | 268 ++++ indra/newview/llfloaterurlentry.h | 44 + indra/newview/llglsandbox.cpp | 4 +- indra/newview/llmimetypes.cpp | 241 +++ indra/newview/llmimetypes.h | 95 ++ indra/newview/lloverlaybar.cpp | 82 +- indra/newview/lloverlaybar.h | 11 +- indra/newview/llpanelavatar.cpp | 20 - indra/newview/llpanelavatar.h | 4 - indra/newview/llpanelface.cpp | 50 +- indra/newview/llpanelland.cpp | 2 +- indra/newview/llpanellandmedia.cpp | 378 +++++ indra/newview/llpanellandmedia.h | 58 + indra/newview/llpanellogin.cpp | 22 +- indra/newview/llpanellogin.h | 12 +- indra/newview/llparcelselection.cpp | 83 + indra/newview/llparcelselection.h | 63 + indra/newview/llpreviewscript.cpp | 14 +- indra/newview/llstartup.cpp | 186 +-- indra/newview/llstartup.h | 4 +- indra/newview/llstatusbar.cpp | 117 +- indra/newview/llstatusbar.h | 4 + indra/newview/lltoolpie.cpp | 176 ++- indra/newview/llurldispatcher.cpp | 3 +- indra/newview/llurlhistory.cpp | 110 ++ indra/newview/llurlhistory.h | 37 + indra/newview/llvieweraudio.cpp | 13 +- indra/newview/llviewercontrol.cpp | 11 +- indra/newview/llviewermedia.cpp | 608 +++++++ indra/newview/llviewermedia.h | 49 + indra/newview/llviewermenu.cpp | 9 +- indra/newview/llviewermessage.cpp | 2 +- indra/newview/llviewerobject.h | 2 - indra/newview/llviewerparcelmedia.cpp | 340 ++++ indra/newview/llviewerparcelmedia.h | 52 + indra/newview/llviewerparcelmediaautoplay.cpp | 129 ++ indra/newview/llviewerparcelmediaautoplay.h | 32 + indra/newview/llviewerparcelmgr.cpp | 303 +--- indra/newview/llviewerparcelmgr.h | 54 +- indra/newview/llviewerregion.cpp | 1 + indra/newview/llviewerwindow.cpp | 1 - indra/newview/llweb.cpp | 13 +- indra/newview/pipeline.cpp | 2 +- indra/newview/res-sdl/toolmediaopen.BMP | Bin 0 -> 3128 bytes indra/newview/res-sdl/toolpause.BMP | Bin 0 -> 3128 bytes indra/newview/res-sdl/toolplay.BMP | Bin 0 -> 3128 bytes indra/newview/res/resource.h | 2 + indra/newview/res/toolmediaopen.cur | Bin 0 -> 2238 bytes indra/newview/res/toolpause.cur | Bin 0 -> 2238 bytes indra/newview/res/toolplay.cur | Bin 0 -> 2238 bytes indra/test/llhttpclient_tut.cpp | 32 +- scripts/messages/message_template.msg | 8 + 86 files changed, 4185 insertions(+), 1789 deletions(-) create mode 100644 indra/llui/lluifwd.h create mode 100644 indra/newview/cursors_mac/UI_CURSOR_TOOLMEDIAOPEN.tif create mode 100644 indra/newview/cursors_mac/UI_CURSOR_TOOLPAUSE.tif create mode 100644 indra/newview/cursors_mac/UI_CURSOR_TOOLPLAY.tif create mode 100644 indra/newview/llfloaterurlentry.cpp create mode 100644 indra/newview/llfloaterurlentry.h create mode 100644 indra/newview/llmimetypes.cpp create mode 100644 indra/newview/llmimetypes.h create mode 100644 indra/newview/llpanellandmedia.cpp create mode 100644 indra/newview/llpanellandmedia.h create mode 100644 indra/newview/llparcelselection.cpp create mode 100644 indra/newview/llparcelselection.h create mode 100644 indra/newview/llurlhistory.cpp create mode 100644 indra/newview/llurlhistory.h create mode 100644 indra/newview/llviewermedia.cpp create mode 100644 indra/newview/llviewermedia.h create mode 100644 indra/newview/llviewerparcelmedia.cpp create mode 100644 indra/newview/llviewerparcelmedia.h create mode 100644 indra/newview/llviewerparcelmediaautoplay.cpp create mode 100644 indra/newview/llviewerparcelmediaautoplay.h create mode 100644 indra/newview/res-sdl/toolmediaopen.BMP create mode 100644 indra/newview/res-sdl/toolpause.BMP create mode 100644 indra/newview/res-sdl/toolplay.BMP create mode 100644 indra/newview/res/toolmediaopen.cur create mode 100644 indra/newview/res/toolpause.cur create mode 100644 indra/newview/res/toolplay.cur diff --git a/etc/message.xml b/etc/message.xml index ddbfa58ddbd..c9b9220ba21 100644 --- a/etc/message.xml +++ b/etc/message.xml @@ -357,6 +357,14 @@ <key>trusted-sender</key> <boolean>true</boolean> </map> + + <key>ParcelProperties</key> + <map> + <key>flavor</key> + <string>llsd</string> + <key>trusted-sender</key> + <boolean>true</boolean> + </map> <key>avatarnotesrequest</key> <map> @@ -514,7 +522,10 @@ <key>SearchStatTracking</key> <boolean>false</boolean> - + + <key>ParcelPropertiesUpdate</key> + <boolean>false</boolean> + </map> <key>messageBans</key> diff --git a/indra/llcommon/indra_constants.h b/indra/llcommon/indra_constants.h index 0195893b160..46f46e24337 100644 --- a/indra/llcommon/indra_constants.h +++ b/indra/llcommon/indra_constants.h @@ -323,6 +323,10 @@ const U32 PARCEL_MEDIA_COMMAND_TIME = 6; const U32 PARCEL_MEDIA_COMMAND_AGENT = 7; const U32 PARCEL_MEDIA_COMMAND_UNLOAD = 8; const U32 PARCEL_MEDIA_COMMAND_AUTO_ALIGN = 9; +const U32 PARCEL_MEDIA_COMMAND_TYPE = 10; +const U32 PARCEL_MEDIA_COMMAND_SIZE = 11; +const U32 PARCEL_MEDIA_COMMAND_DESC = 12; +const U32 PARCEL_MEDIA_COMMAND_LOOP_SET = 13; // map item types const U32 MAP_ITEM_TELEHUB = 0x01; diff --git a/indra/llcommon/llclickaction.h b/indra/llcommon/llclickaction.h index be343c67853..e2ba02465d8 100644 --- a/indra/llcommon/llclickaction.h +++ b/indra/llcommon/llclickaction.h @@ -39,5 +39,7 @@ const U8 CLICK_ACTION_SIT = 1; const U8 CLICK_ACTION_BUY = 2; const U8 CLICK_ACTION_PAY = 3; const U8 CLICK_ACTION_OPEN = 4; +const U8 CLICK_ACTION_PLAY = 5; +const U8 CLICK_ACTION_OPEN_MEDIA = 6; #endif diff --git a/indra/llcommon/llpreprocessor.h b/indra/llcommon/llpreprocessor.h index 459d086cda6..ac06b431c1a 100644 --- a/indra/llcommon/llpreprocessor.h +++ b/indra/llcommon/llpreprocessor.h @@ -52,33 +52,6 @@ #define LL_FORCE_INLINE __forceinline #endif -// Per-OS feature switches. - -#if LL_DARWIN - #define LL_QUICKTIME_ENABLED 1 - #define LL_LIBXUL_ENABLED 1 -#elif LL_WINDOWS - #define LL_QUICKTIME_ENABLED 1 - #define LL_LIBXUL_ENABLED 1 -#elif LL_LINUX - #define LL_QUICKTIME_ENABLED 0 - #ifndef LL_LIBXUL_ENABLED - #define LL_LIBXUL_ENABLED 1 - #endif // def LL_LIBXUL_ENABLED -#elif LL_SOLARIS - #define LL_QUICKTIME_ENABLED 0 - #ifndef LL_LIBXUL_ENABLED - #define LL_LIBXUL_ENABLED 0 - #endif // def LL_LIBXUL_ENABLED -#endif - -#if LL_LIBXUL_ENABLED && !defined(MOZILLA_INTERNAL_API) - // Without this, nsTAString.h errors out with: - // "Cannot use internal string classes without MOZILLA_INTERNAL_API defined. Use the frozen header nsStringAPI.h instead." - // It might be worth our while to figure out if we can use the frozen apis at some point... - #define MOZILLA_INTERNAL_API 1 -#endif - // Figure out differences between compilers #if defined(__GNUC__) #define GCC_VERSION (__GNUC__ * 10000 \ diff --git a/indra/llinventory/llparcel.cpp b/indra/llinventory/llparcel.cpp index b6a90b64e8d..792bb1be90f 100644 --- a/indra/llinventory/llparcel.cpp +++ b/indra/llinventory/llparcel.cpp @@ -42,6 +42,7 @@ #include "llsdutil.h" #include "lltransactiontypes.h" #include "lltransactionflags.h" +#include "llsdutil.h" #include "message.h" #include "u64.h" @@ -170,73 +171,80 @@ void LLParcel::init(const LLUUID &owner_id, S32 rent_price_per_meter, S32 area, S32 sim_object_limit, F32 parcel_object_bonus, BOOL is_group_owned) { - mID.setNull(); - mOwnerID = owner_id; - mGroupOwned = is_group_owned; - mClaimDate = claim_date; - mClaimPricePerMeter = claim_price_per_meter; - mRentPricePerMeter = rent_price_per_meter; - mArea = area; - mDiscountRate = 1.0f; - mDrawDistance = 512.f; - - mUserLookAt.setVec(0.0f, 0.f, 0.f); - // Default to using the parcel's landing point, if any. - mLandingType = L_LANDING_POINT; - - // *FIX: if owner_id != null, should be owned or sale pending, - // investigate init callers. - mStatus = OS_NONE; - mCategory = C_NONE; - mAuthBuyerID.setNull(); - //mBuyerID.setNull(); - //mJoinNeighbors = 0x0; - mSaleTimerExpires.setTimerExpirySec(0); - mSaleTimerExpires.stop(); - mGraceExtension = 0; - //mExpireAction = STEA_REVERT; - mRecordTransaction = FALSE; - - mAuctionID = 0; - mInEscrow = false; - - mParcelFlags = PF_DEFAULT; - setParcelFlag(PF_CREATE_OBJECTS, modify); - setParcelFlag(PF_ALLOW_TERRAFORM, terraform); - setParcelFlag(PF_ALLOW_DAMAGE, damage); - - mSalePrice = 10000; - setName(NULL); - setDesc(NULL); - setMusicURL(NULL); - setMediaURL(NULL); - mMediaID.setNull(); - mMediaAutoScale = 0; - - mGroupID.setNull(); - - mPassPrice = PARCEL_PASS_PRICE_DEFAULT; - mPassHours = PARCEL_PASS_HOURS_DEFAULT; - - mAABBMin.setVec(SOME_BIG_NUMBER, SOME_BIG_NUMBER, SOME_BIG_NUMBER); - mAABBMax.setVec(SOME_BIG_NEG_NUMBER, SOME_BIG_NEG_NUMBER, SOME_BIG_NEG_NUMBER); - - mLocalID = 0; - - //mSimWidePrimCorrection = 0; - setMaxPrimCapacity((S32)(sim_object_limit * area / (F32)(REGION_WIDTH_METERS * REGION_WIDTH_METERS))); - setSimWideMaxPrimCapacity(0); - setSimWidePrimCount(0); - setOwnerPrimCount(0); - setGroupPrimCount(0); - setOtherPrimCount(0); - setSelectedPrimCount(0); - setTempPrimCount(0); - setCleanOtherTime(0); - setParcelPrimBonus(parcel_object_bonus); - - setPreviousOwnerID(LLUUID::null); - setPreviouslyGroupOwned(FALSE); + mID.setNull(); + mOwnerID = owner_id; + mGroupOwned = is_group_owned; + mClaimDate = claim_date; + mClaimPricePerMeter = claim_price_per_meter; + mRentPricePerMeter = rent_price_per_meter; + mArea = area; + mDiscountRate = 1.0f; + mDrawDistance = 512.f; + + mUserLookAt.setVec(0.0f, 0.f, 0.f); + // Default to using the parcel's landing point, if any. + mLandingType = L_LANDING_POINT; + + // *FIX: if owner_id != null, should be owned or sale pending, + // investigate init callers. + mStatus = OS_NONE; + mCategory = C_NONE; + mAuthBuyerID.setNull(); + //mBuyerID.setNull(); + //mJoinNeighbors = 0x0; + mSaleTimerExpires.setTimerExpirySec(0); + mSaleTimerExpires.stop(); + mGraceExtension = 0; + //mExpireAction = STEA_REVERT; + mRecordTransaction = FALSE; + + mAuctionID = 0; + mInEscrow = false; + + mParcelFlags = PF_DEFAULT; + setParcelFlag(PF_CREATE_OBJECTS, modify); + setParcelFlag(PF_ALLOW_TERRAFORM, terraform); + setParcelFlag(PF_ALLOW_DAMAGE, damage); + + mSalePrice = 10000; + setName(NULL); + setDesc(NULL); + setMusicURL(NULL); + setMediaURL(NULL); + setMediaDesc(NULL); + setMediaType(NULL); + mMediaID.setNull(); + mMediaAutoScale = 0; + mMediaLoop = TRUE; + mObscureMedia = 0; + mObscureMusic = 0; + mMediaWidth = 0; + mMediaHeight = 0; + + mGroupID.setNull(); + + mPassPrice = PARCEL_PASS_PRICE_DEFAULT; + mPassHours = PARCEL_PASS_HOURS_DEFAULT; + + mAABBMin.setVec(SOME_BIG_NUMBER, SOME_BIG_NUMBER, SOME_BIG_NUMBER); + mAABBMax.setVec(SOME_BIG_NEG_NUMBER, SOME_BIG_NEG_NUMBER, SOME_BIG_NEG_NUMBER); + + mLocalID = 0; + + //mSimWidePrimCorrection = 0; + setMaxPrimCapacity((S32)(sim_object_limit * area / (F32)(REGION_WIDTH_METERS * REGION_WIDTH_METERS))); + setSimWideMaxPrimCapacity(0); + setSimWidePrimCount(0); + setOwnerPrimCount(0); + setGroupPrimCount(0); + setOtherPrimCount(0); + setSelectedPrimCount(0); + setTempPrimCount(0); + setCleanOtherTime(0); + setParcelPrimBonus(parcel_object_bonus); + + setPreviousOwnerID(LLUUID::null); + setPreviouslyGroupOwned(FALSE); } void LLParcel::overrideOwner(const LLUUID& owner_id, BOOL is_group_owned) @@ -260,7 +268,21 @@ void LLParcel::overrideParcelFlags(U32 flags) { mParcelFlags = flags; } - +void set_std_string(const char* src, std::string& dest) +{ + if(src) + { + dest.assign(src); + } + else + { +#if (LL_LINUX && __GNUC__ < 3) + dest.assign(std::string("")); +#else + dest.clear(); +#endif + } +} void LLParcel::setName(const LLString& name) { // The escaping here must match the escaping in the database @@ -297,6 +319,28 @@ void LLParcel::setMediaURL(const LLString& url) LLStringFn::replace_nonprintable(mMediaURL, LL_UNKNOWN_CHAR); } +void LLParcel::setMediaDesc(const char* desc) +{ + // The escaping here must match the escaping in the database + // abstraction layer. + set_std_string(desc, mMediaDesc); + mMediaDesc = rawstr_to_utf8(mMediaDesc); +} +void LLParcel::setMediaType(const char* type) +{ + // The escaping here must match the escaping in the database + // abstraction layer. + set_std_string(type, mMediaType); + mMediaType = rawstr_to_utf8(mMediaType); +} +void LLParcel::setMediaWidth(S32 width) +{ + mMediaWidth = width; +} +void LLParcel::setMediaHeight(S32 height) +{ + mMediaHeight = height; +} // virtual void LLParcel::setLocalID(S32 local_id) { @@ -512,338 +556,367 @@ void LLParcel::setDiscountRate(F32 rate) // WARNING: Area will be wrong until you calculate it. BOOL LLParcel::importStream(std::istream& input_stream) { - U32 setting; - S32 secs_until_revert = 0; - - skip_to_end_of_next_keyword("{", input_stream); - if (!input_stream.good()) - { - llwarns << "LLParcel::importStream() - bad input_stream" << llendl; - return FALSE; - } - - while (input_stream.good()) - { - skip_comments_and_emptyspace(input_stream); - LLString line, keyword, value; - get_line(line, input_stream, MAX_STRING); - get_keyword_and_value(keyword, value, line); - - if ("}" == keyword) - { - break; - } - else if ("parcel_id" == keyword) - { - mID.set(value.c_str()); - } - else if ("status" == keyword) - { - mStatus = ownership_string_to_status(value.c_str()); - } - else if ("category" == keyword) - { - mCategory = category_string_to_category(value.c_str()); - } - else if ("local_id" == keyword) - { - LLString::convertToS32(value, mLocalID); - } - else if ("name" == keyword) - { - setName( value ); - } - else if ("desc" == keyword) - { - setDesc( value ); - } - else if ("music_url" == keyword) - { - setMusicURL( value ); - } - else if ("media_url" == keyword) - { - setMediaURL( value ); - } - else if ("media_id" == keyword) - { - mMediaID.set( value.c_str() ); - } - else if ("media_auto_scale" == keyword) - { - LLString::convertToU8(value, mMediaAutoScale); - } - else if ("owner_id" == keyword) - { - mOwnerID.set( value.c_str() ); - } - else if ("group_owned" == keyword) - { - LLString::convertToBOOL(value, mGroupOwned); - } - else if ("clean_other_time" == keyword) - { - S32 time; - LLString::convertToS32(value, time); - setCleanOtherTime(time); - } - else if ("auth_buyer_id" == keyword) - { - mAuthBuyerID.set(value.c_str()); - } - else if ("snapshot_id" == keyword) - { - mSnapshotID.set(value.c_str()); - } - else if ("user_location" == keyword) - { - sscanf(value.c_str(), "%f %f %f", - &mUserLocation.mV[VX], - &mUserLocation.mV[VY], - &mUserLocation.mV[VZ]); - } - else if ("user_look_at" == keyword) - { - sscanf(value.c_str(), "%f %f %f", - &mUserLookAt.mV[VX], - &mUserLookAt.mV[VY], - &mUserLookAt.mV[VZ]); - } - else if ("landing_type" == keyword) - { - S32 landing_type = 0; - LLString::convertToS32(value, landing_type); - mLandingType = (ELandingType) landing_type; - } - else if ("join_neighbors" == keyword) - { - llinfos << "found deprecated keyword join_neighbors" << llendl; - } - else if ("revert_sale" == keyword) - { - LLString::convertToS32(value, secs_until_revert); - if (secs_until_revert > 0) - { - mSaleTimerExpires.start(); - mSaleTimerExpires.setTimerExpirySec((F32)secs_until_revert); - } - } - else if("extended_grace" == keyword) - { - LLString::convertToS32(value, mGraceExtension); - } - else if ("user_list_type" == keyword) - { - // deprecated - } - else if("auction_id" == keyword) - { - LLString::convertToU32(value, mAuctionID); - } - else if ("allow_modify" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_CREATE_OBJECTS, setting); - } - else if ("allow_group_modify" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_CREATE_GROUP_OBJECTS, setting); - } - else if ("allow_all_object_entry" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_ALLOW_ALL_OBJECT_ENTRY, setting); - } - else if ("allow_group_object_entry" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_ALLOW_GROUP_OBJECT_ENTRY, setting); - } - else if ("allow_deed_to_group" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_ALLOW_DEED_TO_GROUP, setting); - } - else if("contribute_with_deed" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_CONTRIBUTE_WITH_DEED, setting); - } - else if ("allow_terraform" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_ALLOW_TERRAFORM, setting); - } - else if ("allow_damage" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_ALLOW_DAMAGE, setting); - } - else if ("allow_fly" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_ALLOW_FLY, setting); - } - else if ("allow_landmark" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_ALLOW_LANDMARK, setting); - } - else if ("sound_local" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_SOUND_LOCAL, setting); - } - else if ("allow_group_scripts" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_ALLOW_GROUP_SCRIPTS, setting); - } - else if ("allow_voice_chat" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_ALLOW_VOICE_CHAT, setting); - } - else if ("use_estate_voice_chan" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_USE_ESTATE_VOICE_CHAN, setting); - } - else if ("allow_scripts" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_ALLOW_OTHER_SCRIPTS, setting); - } - else if ("for_sale" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_FOR_SALE, setting); - } - else if ("sell_w_objects" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_SELL_PARCEL_OBJECTS, setting); - } - else if ("use_pass_list" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_USE_PASS_LIST, setting); - } - else if ("show_directory" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_SHOW_DIRECTORY, setting); - } - else if ("allow_publish" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_ALLOW_PUBLISH, setting); - } - else if ("mature_publish" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_MATURE_PUBLISH, setting); - } - else if ("claim_date" == keyword) - { - // BUG: This will fail when time rolls over in 2038. - S32 time; - LLString::convertToS32(value, time); - mClaimDate = time; - } - else if ("claim_price" == keyword) - { - LLString::convertToS32(value, mClaimPricePerMeter); - } - else if ("rent_price" == keyword) - { - LLString::convertToS32(value, mRentPricePerMeter); - } - else if ("discount_rate" == keyword) - { - LLString::convertToF32(value, mDiscountRate); - } - else if ("draw_distance" == keyword) - { - LLString::convertToF32(value, mDrawDistance); - } - else if ("sale_price" == keyword) - { - LLString::convertToS32(value, mSalePrice); - } - else if ("pass_price" == keyword) - { - LLString::convertToS32(value, mPassPrice); - } - else if ("pass_hours" == keyword) - { - LLString::convertToF32(value, mPassHours); - } - else if ("box" == keyword) - { - // deprecated - } - else if ("aabb_min" == keyword) - { - sscanf(value.c_str(), "%f %f %f", - &mAABBMin.mV[VX], &mAABBMin.mV[VY], &mAABBMin.mV[VZ]); - } - else if ("use_access_group" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_USE_ACCESS_GROUP, setting); - } - else if ("use_access_list" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_USE_ACCESS_LIST, setting); - } - else if ("use_ban_list" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_USE_BAN_LIST, setting); - } - else if ("group_name" == keyword) - { - llinfos << "found deprecated keyword group_name" << llendl; - } - else if ("group_id" == keyword) - { - mGroupID.set( value.c_str() ); - } - // TODO: DEPRECATED FLAG - // Flag removed from simstate files in 1.11.1 - // Keep if statement until we have guarenteed this flag - // no longer exists anywhere in simstate files. - else if ("require_identified" == keyword) - { -// LLString::convertToU32(value, setting); -// setParcelFlag(PF_DENY_ANONYMOUS, setting); - } - // TODO: DEPRECATED FLAG - // Flag removed from simstate files in 1.11.1 - // Keep if statement until we have guarenteed this flag - // no longer exists anywhere in simstate files. - else if ("require_transacted" == keyword) - { -// LLString::convertToU32(value, setting); -// setParcelFlag(PF_DENY_ANONYMOUS, setting); -// setParcelFlag(PF_DENY_IDENTIFIED, setting); - } - else if ("restrict_pushobject" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_RESTRICT_PUSHOBJECT, setting); - } - else if ("deny_anonymous" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_DENY_ANONYMOUS, setting); - } - // TODO: DEPRECATED FLAG - // Keep if statement until we have guarenteed this flag - // no longer exists anywhere in simstate files. + U32 setting; + S32 secs_until_revert = 0; + + skip_to_end_of_next_keyword("{", input_stream); + if (!input_stream.good()) + { + llwarns << "LLParcel::importStream() - bad input_stream" << llendl; + return FALSE; + } + + while (input_stream.good()) + { + skip_comments_and_emptyspace(input_stream); + LLString line, keyword, value; + get_line(line, input_stream, MAX_STRING); + get_keyword_and_value(keyword, value, line); + + if ("}" == keyword) + { + break; + } + else if ("parcel_id" == keyword) + { + mID.set(value.c_str()); + } + else if ("status" == keyword) + { + mStatus = ownership_string_to_status(value.c_str()); + } + else if ("category" == keyword) + { + mCategory = category_string_to_category(value.c_str()); + } + else if ("local_id" == keyword) + { + LLString::convertToS32(value, mLocalID); + } + else if ("name" == keyword) + { + setName( value ); + } + else if ("desc" == keyword) + { + setDesc( value ); + } + else if ("music_url" == keyword) + { + setMusicURL( value ); + } + else if ("media_url" == keyword) + { + setMediaURL( value ); + } + else if ("media_desc" == keyword) + { + setMediaDesc( value.c_str() ); + } + else if ("media_type" == keyword) + { + setMediaType( value.c_str() ); + } + else if ("media_width" == keyword) + { + S32 width; + LLString::convertToS32(value, width); + setMediaWidth( width ); + } + else if ("media_height" == keyword) + { + S32 height; + LLString::convertToS32(value, height); + setMediaHeight( height ); + } + else if ("media_id" == keyword) + { + mMediaID.set( value.c_str() ); + } + else if ("media_auto_scale" == keyword) + { + LLString::convertToU8(value, mMediaAutoScale); + } + else if ("media_loop" == keyword) + { + LLString::convertToU8(value, mMediaLoop); + } + else if ("obscure_media" == keyword) + { + LLString::convertToU8(value, mObscureMedia); + } + else if ("obscure_music" == keyword) + { + LLString::convertToU8(value, mObscureMusic); + } + else if ("owner_id" == keyword) + { + mOwnerID.set( value.c_str() ); + } + else if ("group_owned" == keyword) + { + LLString::convertToBOOL(value, mGroupOwned); + } + else if ("clean_other_time" == keyword) + { + S32 time; + LLString::convertToS32(value, time); + setCleanOtherTime(time); + } + else if ("auth_buyer_id" == keyword) + { + mAuthBuyerID.set(value.c_str()); + } + else if ("snapshot_id" == keyword) + { + mSnapshotID.set(value.c_str()); + } + else if ("user_location" == keyword) + { + sscanf(value.c_str(), "%f %f %f", + &mUserLocation.mV[VX], + &mUserLocation.mV[VY], + &mUserLocation.mV[VZ]); + } + else if ("user_look_at" == keyword) + { + sscanf(value.c_str(), "%f %f %f", + &mUserLookAt.mV[VX], + &mUserLookAt.mV[VY], + &mUserLookAt.mV[VZ]); + } + else if ("landing_type" == keyword) + { + S32 landing_type = 0; + LLString::convertToS32(value, landing_type); + mLandingType = (ELandingType) landing_type; + } + else if ("join_neighbors" == keyword) + { + llinfos << "found deprecated keyword join_neighbors" << llendl; + } + else if ("revert_sale" == keyword) + { + LLString::convertToS32(value, secs_until_revert); + if (secs_until_revert > 0) + { + mSaleTimerExpires.start(); + mSaleTimerExpires.setTimerExpirySec((F32)secs_until_revert); + } + } + else if("extended_grace" == keyword) + { + LLString::convertToS32(value, mGraceExtension); + } + else if ("user_list_type" == keyword) + { + // deprecated + } + else if("auction_id" == keyword) + { + LLString::convertToU32(value, mAuctionID); + } + else if ("allow_modify" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_CREATE_OBJECTS, setting); + } + else if ("allow_group_modify" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_CREATE_GROUP_OBJECTS, setting); + } + else if ("allow_all_object_entry" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_ALLOW_ALL_OBJECT_ENTRY, setting); + } + else if ("allow_group_object_entry" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_ALLOW_GROUP_OBJECT_ENTRY, setting); + } + else if ("allow_deed_to_group" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_ALLOW_DEED_TO_GROUP, setting); + } + else if("contribute_with_deed" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_CONTRIBUTE_WITH_DEED, setting); + } + else if ("allow_terraform" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_ALLOW_TERRAFORM, setting); + } + else if ("allow_damage" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_ALLOW_DAMAGE, setting); + } + else if ("allow_fly" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_ALLOW_FLY, setting); + } + else if ("allow_landmark" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_ALLOW_LANDMARK, setting); + } + else if ("sound_local" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_SOUND_LOCAL, setting); + } + else if ("allow_group_scripts" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_ALLOW_GROUP_SCRIPTS, setting); + } + else if ("allow_voice_chat" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_ALLOW_VOICE_CHAT, setting); + } + else if ("use_estate_voice_chan" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_USE_ESTATE_VOICE_CHAN, setting); + } + else if ("allow_scripts" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_ALLOW_OTHER_SCRIPTS, setting); + } + else if ("for_sale" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_FOR_SALE, setting); + } + else if ("sell_w_objects" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_SELL_PARCEL_OBJECTS, setting); + } + else if ("use_pass_list" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_USE_PASS_LIST, setting); + } + else if ("show_directory" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_SHOW_DIRECTORY, setting); + } + else if ("allow_publish" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_ALLOW_PUBLISH, setting); + } + else if ("mature_publish" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_MATURE_PUBLISH, setting); + } + else if ("claim_date" == keyword) + { + // BUG: This will fail when time rolls over in 2038. + S32 time; + LLString::convertToS32(value, time); + mClaimDate = time; + } + else if ("claim_price" == keyword) + { + LLString::convertToS32(value, mClaimPricePerMeter); + } + else if ("rent_price" == keyword) + { + LLString::convertToS32(value, mRentPricePerMeter); + } + else if ("discount_rate" == keyword) + { + LLString::convertToF32(value, mDiscountRate); + } + else if ("draw_distance" == keyword) + { + LLString::convertToF32(value, mDrawDistance); + } + else if ("sale_price" == keyword) + { + LLString::convertToS32(value, mSalePrice); + } + else if ("pass_price" == keyword) + { + LLString::convertToS32(value, mPassPrice); + } + else if ("pass_hours" == keyword) + { + LLString::convertToF32(value, mPassHours); + } + else if ("box" == keyword) + { + // deprecated + } + else if ("aabb_min" == keyword) + { + sscanf(value.c_str(), "%f %f %f", + &mAABBMin.mV[VX], &mAABBMin.mV[VY], &mAABBMin.mV[VZ]); + } + else if ("use_access_group" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_USE_ACCESS_GROUP, setting); + } + else if ("use_access_list" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_USE_ACCESS_LIST, setting); + } + else if ("use_ban_list" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_USE_BAN_LIST, setting); + } + else if ("group_name" == keyword) + { + llinfos << "found deprecated keyword group_name" << llendl; + } + else if ("group_id" == keyword) + { + mGroupID.set( value.c_str() ); + } + // TODO: DEPRECATED FLAG + // Flag removed from simstate files in 1.11.1 + // Remove at some point where we have guarenteed this flag + // no longer exists anywhere in simstate files. + else if ("require_identified" == keyword) + { + // LLString::convertToU32(value, setting); + // setParcelFlag(PF_DENY_ANONYMOUS, setting); + } + // TODO: DEPRECATED FLAG + // Flag removed from simstate files in 1.11.1 + // Remove at some point where we have guarenteed this flag + // no longer exists anywhere in simstate files. + else if ("require_transacted" == keyword) + { + // LLString::convertToU32(value, setting); + // setParcelFlag(PF_DENY_ANONYMOUS, setting); + // setParcelFlag(PF_DENY_IDENTIFIED, setting); + } + else if ("restrict_pushobject" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_RESTRICT_PUSHOBJECT, setting); + } + else if ("deny_anonymous" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_DENY_ANONYMOUS, setting); + } else if ("deny_identified" == keyword) { // LLString::convertToU32(value, setting); @@ -1018,211 +1091,223 @@ BOOL LLParcel::importAccessEntry(std::istream& input_stream, LLAccessEntry* entr BOOL LLParcel::exportStream(std::ostream& output_stream) { - S32 setting; - char id_string[MAX_STRING]; /* Flawfinder: ignore */ - - std::ios::fmtflags old_flags = output_stream.flags(); - output_stream.setf(std::ios::showpoint); - output_stream << "\t{\n"; - - mID.toString(id_string); - output_stream << "\t\t parcel_id " << id_string << "\n"; - output_stream << "\t\t status " << ownership_status_to_string(mStatus) << "\n"; - output_stream << "\t\t category " << category_to_string(mCategory) << "\n"; - - output_stream << "\t\t local_id " << mLocalID << "\n"; - - const char* name = (mName.empty() ? "" : mName.c_str() ); - output_stream << "\t\t name " << name << "\n"; - - const char* desc = (mDesc.empty() ? "" : mDesc.c_str() ); - output_stream << "\t\t desc " << desc << "\n"; - - const char* music_url = (mMusicURL.empty() ? "" : mMusicURL.c_str() ); - output_stream << "\t\t music_url " << music_url << "\n"; - - const char* media_url = (mMediaURL.empty() ? "" : mMediaURL.c_str() ); - output_stream << "\t\t media_url " << media_url << "\n"; - - output_stream << "\t\t media_auto_scale " << (mMediaAutoScale ? 1 : 0) << "\n"; - - mMediaID.toString(id_string); - output_stream << "\t\t media_id " << id_string << "\n"; - - mOwnerID.toString(id_string); - output_stream << "\t\t owner_id " << id_string << "\n"; - output_stream << "\t\t group_owned " << (mGroupOwned ? 1 : 0) << "\n"; - output_stream << "\t\t clean_other_time " << getCleanOtherTime() << "\n"; - - if(!mAuthBuyerID.isNull()) - { - mAuthBuyerID.toString(id_string); - output_stream << "\t\t auth_buyer_id " << id_string << "\n"; - } - if (!mSnapshotID.isNull()) - { - mSnapshotID.toString(id_string); - output_stream << "\t\t snapshot_id " << id_string << "\n"; - } - if (!mUserLocation.isExactlyZero()) - { - output_stream << "\t\t user_location " - << (F64)mUserLocation.mV[VX] - << " " << (F64)mUserLocation.mV[VY] - << " " << (F64)mUserLocation.mV[VZ] << "\n"; - output_stream << "\t\t user_look_at " - << (F64)mUserLookAt.mV[VX] - << " " << (F64)mUserLookAt.mV[VY] - << " " << (F64)mUserLookAt.mV[VZ] << "\n"; - } - output_stream << "\t\t landing_type " << mLandingType << "\n"; - //if(mJoinNeighbors) - //{ - // output_stream << "\t\t join_neighbors " << mJoinNeighbors << "\n"; - //} - if(mSaleTimerExpires.getStarted()) - { - S32 dt_sec = (S32) mSaleTimerExpires.getRemainingTimeF32()+60; // Add a minute to prevent race conditions - output_stream << "\t\t revert_sale " << dt_sec << "\n"; - //output_stream << "\t\t revert_action " << revert_action_to_string(mExpireAction) << "\n"; - output_stream << "\t\t extended_grace " << mGraceExtension << "\n"; - } - - if(0 != mAuctionID) - { - output_stream << "\t\t auction_id " << mAuctionID << "\n"; - } - - output_stream << "\t\t allow_modify " << getAllowModify() << "\n"; - output_stream << "\t\t allow_group_modify " << getAllowGroupModify() << "\n"; - output_stream << "\t\t allow_all_object_entry " << getAllowAllObjectEntry() << "\n"; - output_stream << "\t\t allow_group_object_entry " << getAllowGroupObjectEntry() << "\n"; - output_stream << "\t\t allow_terraform " << getAllowTerraform() << "\n"; - output_stream << "\t\t allow_deed_to_group " << getAllowDeedToGroup() << "\n"; - output_stream << "\t\t contribute_with_deed " << getContributeWithDeed() << "\n"; - output_stream << "\t\t allow_damage " << getAllowDamage() << "\n"; - output_stream << "\t\t claim_date " << (S32)mClaimDate << "\n"; - output_stream << "\t\t claim_price " << mClaimPricePerMeter << "\n"; - output_stream << "\t\t rent_price " << mRentPricePerMeter << "\n"; - output_stream << "\t\t discount_rate " << mDiscountRate << "\n"; - output_stream << "\t\t allow_fly " << (getAllowFly() ? 1 : 0) << "\n"; - output_stream << "\t\t allow_landmark " << (getAllowLandmark() ? 1 : 0) << "\n"; - output_stream << "\t\t sound_local " << (getSoundLocal() ? 1 : 0) << "\n"; - output_stream << "\t\t allow_scripts " << (getAllowOtherScripts() ? 1 : 0) << "\n"; - output_stream << "\t\t allow_group_scripts " << (getAllowGroupScripts() ? 1 : 0) << "\n"; - output_stream << "\t\t allow_voice_chat " << (getVoiceEnabled() ? 1 : 0) << "\n"; - output_stream << "\t\t use_estate_voice_chan " << (getVoiceUseEstateChannel() ? 1 : 0) << "\n"; - output_stream << "\t\t for_sale " << (getForSale() ? 1 : 0) << "\n"; - output_stream << "\t\t sell_w_objects " << (getSellWithObjects() ? 1 : 0) << "\n"; - output_stream << "\t\t draw_distance " << mDrawDistance << "\n"; - output_stream << "\t\t sale_price " << mSalePrice << "\n"; - - setting = (getParcelFlag(PF_USE_ACCESS_GROUP) ? 1 : 0); - output_stream << "\t\t use_access_group " << setting << "\n"; - - setting = (getParcelFlag(PF_USE_ACCESS_LIST) ? 1 : 0); - output_stream << "\t\t use_access_list " << setting << "\n"; - - setting = (getParcelFlag(PF_USE_BAN_LIST) ? 1 : 0); - output_stream << "\t\t use_ban_list " << setting << "\n"; - - mGroupID.toString(id_string); - output_stream << "\t\t group_id " << id_string << "\n"; - - //const char* group_name - // = (mGroupName.isEmpty() ? "" : mGroupName.c_str() ); - //output_stream << "\t\t group_name " << group_name << "\n"; - - setting = (getParcelFlag(PF_USE_PASS_LIST) ? 1 : 0); - output_stream << "\t\t use_pass_list " << setting << "\n"; - - output_stream << "\t\t pass_price " << mPassPrice << "\n"; - output_stream << "\t\t pass_hours " << mPassHours << "\n"; - - setting = (getParcelFlag(PF_SHOW_DIRECTORY) ? 1 : 0); - output_stream << "\t\t show_directory " << setting << "\n"; - - setting = (getParcelFlag(PF_ALLOW_PUBLISH) ? 1 : 0); - output_stream << "\t\t allow_publish " << setting << "\n"; - - setting = (getParcelFlag(PF_MATURE_PUBLISH) ? 1 : 0); - output_stream << "\t\t mature_publish " << setting << "\n"; - - setting = (getParcelFlag(PF_DENY_ANONYMOUS) ? 1 : 0); - output_stream << "\t\t deny_anonymous " << setting << "\n"; - -// setting = (getParcelFlag(PF_DENY_IDENTIFIED) ? 1 : 0); -// output_stream << "\t\t deny_identified " << setting << "\n"; - -// setting = (getParcelFlag(PF_DENY_TRANSACTED) ? 1 : 0); -// output_stream << "\t\t deny_transacted " << setting << "\n"; - - setting = (getParcelFlag(PF_DENY_AGEUNVERIFIED) ? 1 : 0); - output_stream << "\t\t deny_age_unverified " << setting << "\n"; - - setting = (getParcelFlag(PF_RESTRICT_PUSHOBJECT) ? 1 : 0); - output_stream << "\t\t restrict_pushobject " << setting << "\n"; - - output_stream << "\t\t aabb_min " - << mAABBMin.mV[VX] - << " " << mAABBMin.mV[VY] - << " " << mAABBMin.mV[VZ] << "\n"; - - if (!mAccessList.empty()) - { - output_stream << "\t\t access_list " << mAccessList.size() << "\n"; - access_map_const_iterator cit = mAccessList.begin(); - access_map_const_iterator end = mAccessList.end(); - - for ( ; cit != end; ++cit) - { - output_stream << "\t\t{\n"; - const LLAccessEntry& entry = (*cit).second; - entry.mID.toString(id_string); - output_stream << "\t\t\tid " << id_string << "\n"; - output_stream << "\t\t\ttime " << entry.mTime << "\n"; - output_stream << "\t\t\tflags " << entry.mFlags << "\n"; - output_stream << "\t\t}\n"; - } - } - - if (!mBanList.empty()) - { - output_stream << "\t\t ban_list " << mBanList.size() << "\n"; - access_map_const_iterator cit = mBanList.begin(); - access_map_const_iterator end = mBanList.end(); - - for ( ; cit != end; ++cit) - { - output_stream << "\t\t{\n"; - const LLAccessEntry& entry = (*cit).second; - entry.mID.toString(id_string); - output_stream << "\t\t\tid " << id_string << "\n"; - output_stream << "\t\t\ttime " << entry.mTime << "\n"; - output_stream << "\t\t\tflags " << entry.mFlags << "\n"; - output_stream << "\t\t}\n"; - } - } - - /*if (mRenterList.count() > 0) - { - output_stream << "\t\t renter_list " << mRenterList.count() << "\n"; - for (i = 0; i < mRenterList.count(); i++) - { - output_stream << "\t\t{\n"; - const LLAccessEntry& entry = mRenterList.get(i); - entry.mID.toString(id_string); - output_stream << "\t\t\tid " << id_string << "\n"; - output_stream << "\t\t\ttime " << entry.mTime << "\n"; - output_stream << "\t\t\tflags " << entry.mFlags << "\n"; - output_stream << "\t\t}\n"; - } - }*/ - - output_stream << "\t}\n"; - output_stream.flags(old_flags); - - return TRUE; + S32 setting; + char id_string[MAX_STRING]; /* Flawfinder: ignore */ + + std::ios::fmtflags old_flags = output_stream.flags(); + output_stream.setf(std::ios::showpoint); + output_stream << "\t{\n"; + + mID.toString(id_string); + output_stream << "\t\t parcel_id " << id_string << "\n"; + output_stream << "\t\t status " << ownership_status_to_string(mStatus) << "\n"; + output_stream << "\t\t category " << category_to_string(mCategory) << "\n"; + + output_stream << "\t\t local_id " << mLocalID << "\n"; + + const char* name = (mName.empty() ? "" : mName.c_str() ); + output_stream << "\t\t name " << name << "\n"; + + const char* desc = (mDesc.empty() ? "" : mDesc.c_str() ); + output_stream << "\t\t desc " << desc << "\n"; + + const char* music_url = (mMusicURL.empty() ? "" : mMusicURL.c_str() ); + output_stream << "\t\t music_url " << music_url << "\n"; + + const char* media_url = (mMediaURL.empty() ? "" : mMediaURL.c_str() ); + output_stream << "\t\t media_url " << media_url << "\n"; + + const char* media_type = (mMediaType.empty() ? "" : mMediaType.c_str() ); + output_stream << "\t\t media_type " << media_type << "\n"; + + const char* media_desc = (mMediaDesc.empty() ? "" : mMediaDesc.c_str() ); + output_stream << "\t\t media_desc " << media_desc << "\n"; + + output_stream << "\t\t media_auto_scale " << (mMediaAutoScale ? 1 : 0) << "\n"; + output_stream << "\t\t media_loop " << (mMediaLoop ? 1 : 0) << "\n"; + output_stream << "\t\t obscure_media " << (mObscureMedia ? 1 : 0) << "\n"; + output_stream << "\t\t obscure_music " << (mObscureMusic ? 1 : 0) << "\n"; + + mMediaID.toString(id_string); + output_stream << "\t\t media_id " << id_string << "\n"; + + output_stream << "\t\t media_width " << mMediaWidth << "\n"; + output_stream << "\t\t media_height " << mMediaHeight << "\n"; + + mOwnerID.toString(id_string); + output_stream << "\t\t owner_id " << id_string << "\n"; + output_stream << "\t\t group_owned " << (mGroupOwned ? 1 : 0) << "\n"; + output_stream << "\t\t clean_other_time " << getCleanOtherTime() << "\n"; + + if(!mAuthBuyerID.isNull()) + { + mAuthBuyerID.toString(id_string); + output_stream << "\t\t auth_buyer_id " << id_string << "\n"; + } + if (!mSnapshotID.isNull()) + { + mSnapshotID.toString(id_string); + output_stream << "\t\t snapshot_id " << id_string << "\n"; + } + if (!mUserLocation.isExactlyZero()) + { + output_stream << "\t\t user_location " + << (F64)mUserLocation.mV[VX] + << " " << (F64)mUserLocation.mV[VY] + << " " << (F64)mUserLocation.mV[VZ] << "\n"; + output_stream << "\t\t user_look_at " + << (F64)mUserLookAt.mV[VX] + << " " << (F64)mUserLookAt.mV[VY] + << " " << (F64)mUserLookAt.mV[VZ] << "\n"; + } + output_stream << "\t\t landing_type " << mLandingType << "\n"; + //if(mJoinNeighbors) + //{ + // output_stream << "\t\t join_neighbors " << mJoinNeighbors << "\n"; + //} + if(mSaleTimerExpires.getStarted()) + { + S32 dt_sec = (S32) mSaleTimerExpires.getRemainingTimeF32()+60; // Add a minute to prevent race conditions + output_stream << "\t\t revert_sale " << dt_sec << "\n"; + //output_stream << "\t\t revert_action " << revert_action_to_string(mExpireAction) << "\n"; + output_stream << "\t\t extended_grace " << mGraceExtension << "\n"; + } + + if(0 != mAuctionID) + { + output_stream << "\t\t auction_id " << mAuctionID << "\n"; + } + + output_stream << "\t\t allow_modify " << getAllowModify() << "\n"; + output_stream << "\t\t allow_group_modify " << getAllowGroupModify() << "\n"; + output_stream << "\t\t allow_all_object_entry " << getAllowAllObjectEntry() << "\n"; + output_stream << "\t\t allow_group_object_entry " << getAllowGroupObjectEntry() << "\n"; + output_stream << "\t\t allow_terraform " << getAllowTerraform() << "\n"; + output_stream << "\t\t allow_deed_to_group " << getAllowDeedToGroup() << "\n"; + output_stream << "\t\t contribute_with_deed " << getContributeWithDeed() << "\n"; + output_stream << "\t\t allow_damage " << getAllowDamage() << "\n"; + output_stream << "\t\t claim_date " << (S32)mClaimDate << "\n"; + output_stream << "\t\t claim_price " << mClaimPricePerMeter << "\n"; + output_stream << "\t\t rent_price " << mRentPricePerMeter << "\n"; + output_stream << "\t\t discount_rate " << mDiscountRate << "\n"; + output_stream << "\t\t allow_fly " << (getAllowFly() ? 1 : 0) << "\n"; + output_stream << "\t\t allow_landmark " << (getAllowLandmark() ? 1 : 0) << "\n"; + output_stream << "\t\t sound_local " << (getSoundLocal() ? 1 : 0) << "\n"; + output_stream << "\t\t allow_scripts " << (getAllowOtherScripts() ? 1 : 0) << "\n"; + output_stream << "\t\t allow_group_scripts " << (getAllowGroupScripts() ? 1 : 0) << "\n"; + output_stream << "\t\t allow_voice_chat " << (getVoiceEnabled() ? 1 : 0) << "\n"; + output_stream << "\t\t use_estate_voice_chan " << (getVoiceUseEstateChannel() ? 1 : 0) << "\n"; + output_stream << "\t\t for_sale " << (getForSale() ? 1 : 0) << "\n"; + output_stream << "\t\t sell_w_objects " << (getSellWithObjects() ? 1 : 0) << "\n"; + output_stream << "\t\t draw_distance " << mDrawDistance << "\n"; + output_stream << "\t\t sale_price " << mSalePrice << "\n"; + + setting = (getParcelFlag(PF_USE_ACCESS_GROUP) ? 1 : 0); + output_stream << "\t\t use_access_group " << setting << "\n"; + + setting = (getParcelFlag(PF_USE_ACCESS_LIST) ? 1 : 0); + output_stream << "\t\t use_access_list " << setting << "\n"; + + setting = (getParcelFlag(PF_USE_BAN_LIST) ? 1 : 0); + output_stream << "\t\t use_ban_list " << setting << "\n"; + + mGroupID.toString(id_string); + output_stream << "\t\t group_id " << id_string << "\n"; + + //const char* group_name + // = (mGroupName.isEmpty() ? "" : mGroupName.c_str() ); + //output_stream << "\t\t group_name " << group_name << "\n"; + + setting = (getParcelFlag(PF_USE_PASS_LIST) ? 1 : 0); + output_stream << "\t\t use_pass_list " << setting << "\n"; + + output_stream << "\t\t pass_price " << mPassPrice << "\n"; + output_stream << "\t\t pass_hours " << mPassHours << "\n"; + + setting = (getParcelFlag(PF_SHOW_DIRECTORY) ? 1 : 0); + output_stream << "\t\t show_directory " << setting << "\n"; + + setting = (getParcelFlag(PF_ALLOW_PUBLISH) ? 1 : 0); + output_stream << "\t\t allow_publish " << setting << "\n"; + + setting = (getParcelFlag(PF_MATURE_PUBLISH) ? 1 : 0); + output_stream << "\t\t mature_publish " << setting << "\n"; + + setting = (getParcelFlag(PF_DENY_ANONYMOUS) ? 1 : 0); + output_stream << "\t\t deny_anonymous " << setting << "\n"; + +// setting = (getParcelFlag(PF_DENY_IDENTIFIED) ? 1 : 0); +// output_stream << "\t\t deny_identified " << setting << "\n"; + +// setting = (getParcelFlag(PF_DENY_TRANSACTED) ? 1 : 0); +// output_stream << "\t\t deny_transacted " << setting << "\n"; + + setting = (getParcelFlag(PF_DENY_AGEUNVERIFIED) ? 1 : 0); + output_stream << "\t\t deny_age_unverified " << setting << "\n"; + + setting = (getParcelFlag(PF_RESTRICT_PUSHOBJECT) ? 1 : 0); + output_stream << "\t\t restrict_pushobject " << setting << "\n"; + + output_stream << "\t\t aabb_min " + << mAABBMin.mV[VX] + << " " << mAABBMin.mV[VY] + << " " << mAABBMin.mV[VZ] << "\n"; + + if (!mAccessList.empty()) + { + output_stream << "\t\t access_list " << mAccessList.size() << "\n"; + access_map_const_iterator cit = mAccessList.begin(); + access_map_const_iterator end = mAccessList.end(); + + for ( ; cit != end; ++cit) + { + output_stream << "\t\t{\n"; + const LLAccessEntry& entry = (*cit).second; + entry.mID.toString(id_string); + output_stream << "\t\t\tid " << id_string << "\n"; + output_stream << "\t\t\ttime " << entry.mTime << "\n"; + output_stream << "\t\t\tflags " << entry.mFlags << "\n"; + output_stream << "\t\t}\n"; + } + } + + if (!mBanList.empty()) + { + output_stream << "\t\t ban_list " << mBanList.size() << "\n"; + access_map_const_iterator cit = mBanList.begin(); + access_map_const_iterator end = mBanList.end(); + + for ( ; cit != end; ++cit) + { + output_stream << "\t\t{\n"; + const LLAccessEntry& entry = (*cit).second; + entry.mID.toString(id_string); + output_stream << "\t\t\tid " << id_string << "\n"; + output_stream << "\t\t\ttime " << entry.mTime << "\n"; + output_stream << "\t\t\tflags " << entry.mFlags << "\n"; + output_stream << "\t\t}\n"; + } + } + + /*if (mRenterList.count() > 0) + { + output_stream << "\t\t renter_list " << mRenterList.count() << "\n"; + for (i = 0; i < mRenterList.count(); i++) + { + output_stream << "\t\t{\n"; + const LLAccessEntry& entry = mRenterList.get(i); + entry.mID.toString(id_string); + output_stream << "\t\t\tid " << id_string << "\n"; + output_stream << "\t\t\ttime " << entry.mTime << "\n"; + output_stream << "\t\t\tflags " << entry.mFlags << "\n"; + output_stream << "\t\t}\n"; + } + }*/ + + output_stream << "\t}\n"; + output_stream.flags(old_flags); + + return TRUE; } @@ -1248,6 +1333,37 @@ void LLParcel::packMessage(LLMessageSystem* msg) msg->addU8Fast( _PREHASH_LandingType, (U8)mLandingType); } +// Assumes we are in a block "ParcelData" +void LLParcel::packMessage(LLSD& msg) +{ + msg["local_id"] = getLocalID(); + msg["flags"] = ll_sd_from_U32(getParcelFlags()); + msg["sale_price"] = getSalePrice(); + msg["name"] = getName(); + msg["description"] = getDesc(); + msg["music_url"] = getMusicURL(); + msg["media_url"] = getMediaURL(); + msg["media_desc"] = getMediaDesc(); + msg["media_type"] = getMediaType(); + msg["media_width"] = getMediaWidth(); + msg["media_height"] = getMediaHeight(); + msg["auto_scale"] = getMediaAutoScale(); + msg["media_loop"] = getMediaLoop(); + msg["obscure_media"] = getObscureMedia(); + msg["obscure_music"] = getObscureMusic(); + msg["media_id"] = getMediaID(); + msg["group_id"] = getGroupID(); + msg["pass_price"] = mPassPrice; + msg["pass_hours"] = mPassHours; + msg["category"] = (U8)mCategory; + msg["auth_buyer_id"] = mAuthBuyerID; + msg["snapshot_id"] = mSnapshotID; + msg["snapshot_id"] = mSnapshotID; + msg["user_location"] = ll_sd_from_vector3(mUserLocation); + msg["user_look_at"] = ll_sd_from_vector3(mUserLookAt); + msg["landing_type"] = (U8)mLandingType; +} + void LLParcel::unpackMessage(LLMessageSystem* msg) { @@ -1281,8 +1397,30 @@ void LLParcel::unpackMessage(LLMessageSystem* msg) U8 landing_type; msg->getU8Fast( _PREHASH_ParcelData,_PREHASH_LandingType, landing_type); mLandingType = (ELandingType)landing_type; -} + // New Media Data + // Note: the message has been converted to TCP + if(msg->getNumberOfBlocks("MediaData") > 0) + { + msg->getString("MediaData", "MediaDesc", 256, buffer); + setMediaDesc(buffer); + msg->getString("MediaData", "MediaType", 256, buffer); + setMediaType(buffer); + msg->getS32("MediaData", "MediaWidth", mMediaWidth); + msg->getS32("MediaData", "MediaHeight", mMediaHeight); + msg->getU8 ( "MediaData", "MediaLoop", mMediaLoop ); + msg->getU8 ( "MediaData", "ObscureMedia", mObscureMedia ); + msg->getU8 ( "MediaData", "ObscureMusic", mObscureMusic ); + } + else + { + setMediaType("video/vnd.secondlife.qt.legacy"); + setMediaDesc("No Description available without Server Upgrade"); + mMediaLoop = true; + mObscureMedia = true; + mObscureMusic = true; + } +} void LLParcel::packAccessEntries(LLMessageSystem* msg, const std::map<LLUUID,LLAccessEntry>& list) @@ -1702,27 +1840,34 @@ BOOL LLParcel::isBuyerAuthorized(const LLUUID& buyer_id) const void LLParcel::clearParcel() { - overrideParcelFlags(PF_DEFAULT); - setName(NULL); - setDesc(NULL); - setMusicURL(NULL); - setMediaURL(NULL); - setMediaID(LLUUID::null); - setMediaAutoScale(0); - setInEscrow(FALSE); - setAuthorizedBuyerID(LLUUID::null); - setCategory(C_NONE); - setSnapshotID(LLUUID::null); - setUserLocation(LLVector3::zero); - setUserLookAt(LLVector3::x_axis); - setLandingType(L_LANDING_POINT); - setAuctionID(0); - setGroupID(LLUUID::null); - setPassPrice(0); - setPassHours(0.f); - mAccessList.clear(); - mBanList.clear(); - //mRenterList.reset(); + overrideParcelFlags(PF_DEFAULT); + setName(NULL); + setDesc(NULL); + setMediaURL(NULL); + setMediaType(NULL); + setMediaID(LLUUID::null); + setMediaDesc(NULL); + setMediaAutoScale(0); + setMediaLoop(TRUE); + mObscureMedia = 0; + mObscureMusic = 0; + mMediaWidth = 0; + mMediaHeight = 0; + setMusicURL(NULL); + setInEscrow(FALSE); + setAuthorizedBuyerID(LLUUID::null); + setCategory(C_NONE); + setSnapshotID(LLUUID::null); + setUserLocation(LLVector3::zero); + setUserLookAt(LLVector3::x_axis); + setLandingType(L_LANDING_POINT); + setAuctionID(0); + setGroupID(LLUUID::null); + setPassPrice(0); + setPassHours(0.f); + mAccessList.clear(); + mBanList.clear(); + //mRenterList.reset(); } void LLParcel::dump() @@ -1826,6 +1971,3 @@ LLParcel::ECategory category_ui_string_to_category(const char* s) // is a distinct option from "None" and "Other" return LLParcel::C_ANY; } - - - diff --git a/indra/llinventory/llparcel.h b/indra/llinventory/llparcel.h index a8143f27dc4..ac5e1a1eae8 100644 --- a/indra/llinventory/llparcel.h +++ b/indra/llinventory/llparcel.h @@ -211,8 +211,15 @@ class LLParcel void setDesc(const LLString& desc); void setMusicURL(const LLString& url); void setMediaURL(const LLString& url); + void setMediaType(const char* type); + void setMediaDesc(const char* desc); void setMediaID(const LLUUID& id) { mMediaID = id; } void setMediaAutoScale ( U8 flagIn ) { mMediaAutoScale = flagIn; } + void setMediaLoop (U8 loop) { mMediaLoop = loop; } + void setObscureMedia( U8 flagIn ) { mObscureMedia = flagIn; } + void setObscureMusic( U8 flagIn ) { mObscureMusic = flagIn; } + void setMediaWidth(S32 width); + void setMediaHeight(S32 height); virtual void setLocalID(S32 local_id); // blow away all the extra crap lurking in parcels, including urls, access lists, etc @@ -268,6 +275,7 @@ class LLParcel BOOL exportStream(std::ostream& output_stream); void packMessage(LLMessageSystem* msg); + void packMessage(LLSD& msg); void unpackMessage(LLMessageSystem* msg); void packAccessEntries(LLMessageSystem* msg, @@ -299,8 +307,15 @@ class LLParcel const LLString& getDesc() const { return mDesc; } const LLString& getMusicURL() const { return mMusicURL; } const LLString& getMediaURL() const { return mMediaURL; } + const char* getMediaDesc() const { return mMediaDesc.c_str(); } + const char* getMediaType() const { return mMediaType.c_str(); } const LLUUID& getMediaID() const { return mMediaID; } + S32 getMediaWidth() const { return mMediaWidth; } + S32 getMediaHeight() const { return mMediaHeight; } U8 getMediaAutoScale() const { return mMediaAutoScale; } + U8 getMediaLoop() const { return mMediaLoop; } + U8 getObscureMedia() const { return mObscureMedia; } + U8 getObscureMusic() const { return mObscureMusic; } S32 getLocalID() const { return mLocalID; } const LLUUID& getOwnerID() const { return mOwnerID; } const LLUUID& getGroupID() const { return mGroupID; } @@ -576,7 +591,14 @@ class LLParcel LLString mDesc; LLString mMusicURL; LLString mMediaURL; + std::string mMediaDesc; + std::string mMediaType; + S32 mMediaWidth; + S32 mMediaHeight; U8 mMediaAutoScale; + U8 mMediaLoop; + U8 mObscureMedia; + U8 mObscureMusic; LLUUID mMediaID; S32 mPassPrice; F32 mPassHours; diff --git a/indra/llmessage/llhttpclient.cpp b/indra/llmessage/llhttpclient.cpp index 9f6115a0e41..23295476ffd 100644 --- a/indra/llmessage/llhttpclient.cpp +++ b/indra/llmessage/llhttpclient.cpp @@ -38,6 +38,7 @@ #include "llurlrequest.h" #include "llbufferstream.h" #include "llsdserialize.h" +#include "llsdutil.h" #include "llvfile.h" #include "llvfs.h" #include "lluri.h" @@ -112,7 +113,11 @@ void LLHTTPClient::Responder::completed( } } +// virtual +void LLHTTPClient::Responder::completedHeader(U32 status, const std::string& reason, const LLSD& content) +{ +} namespace { class LLHTTPClientURLAdaptor : public LLURLRequestComplete @@ -140,13 +145,19 @@ namespace if (mResponder.get()) { mResponder->completedRaw(mStatus, mReason, channels, buffer); + mResponder->completedHeader(mStatus, mReason, mHeaderOutput); } } + virtual void header(const std::string& header, const std::string& value) + { + mHeaderOutput[header] = value; + } private: LLHTTPClient::ResponderPtr mResponder; U32 mStatus; std::string mReason; + LLSD mHeaderOutput; }; class Injector : public LLIOPipe @@ -340,11 +351,18 @@ void LLHTTPClient::get(const std::string& url, ResponderPtr responder, const LLS { request(url, LLURLRequest::HTTP_GET, NULL, responder, headers, timeout); } - +void LLHTTPClient::getHeaderOnly(const std::string& url, ResponderPtr responder, const LLSD& headers, const F32 timeout) +{ + request(url, LLURLRequest::HTTP_HEAD, NULL, responder, headers, timeout); +} void LLHTTPClient::get(const std::string& url, ResponderPtr responder, const F32 timeout) { get(url, responder, LLSD(), timeout); } +void LLHTTPClient::getHeaderOnly(const std::string& url, ResponderPtr responder, const F32 timeout) +{ + getHeaderOnly(url, responder, LLSD(), timeout); +} void LLHTTPClient::get(const std::string& url, const LLSD& query, ResponderPtr responder, const LLSD& headers, const F32 timeout) { diff --git a/indra/llmessage/llhttpclient.h b/indra/llmessage/llhttpclient.h index 983ff46e034..1fbf0c36dc0 100644 --- a/indra/llmessage/llhttpclient.h +++ b/indra/llmessage/llhttpclient.h @@ -89,7 +89,11 @@ class LLHTTPClient * result(), or * error() */ - + + // Override to handle parsing of the header only. Note: this is the only place where the contents + // of the header can be parsed. In the ::completed call above only the body is contained in the LLSD. + virtual void completedHeader(U32 status, const std::string& reason, const LLSD& content); + public: /* but not really -- don't touch this */ U32 mReferenceCount; }; @@ -102,7 +106,10 @@ class LLHTTPClient static void get(const std::string& url, const LLSD& query, ResponderPtr, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS); static void get(const std::string& url, const LLSD& query, ResponderPtr, const LLSD& headers, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS); static void put(const std::string& url, const LLSD& body, ResponderPtr, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS); - ///< non-blocking + static void getHeaderOnly(const std::string& url, ResponderPtr, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS); + static void getHeaderOnly(const std::string& url, ResponderPtr, const LLSD& headers, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS); + + ///< non-blocking static void post(const std::string& url, const LLSD& body, ResponderPtr, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS); static void post(const std::string& url, const U8* data, S32 size, ResponderPtr responder, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS); static void postFile(const std::string& url, const std::string& filename, ResponderPtr, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS); diff --git a/indra/llmessage/llurlrequest.cpp b/indra/llmessage/llurlrequest.cpp index 1cdaa1687df..631eea3e882 100644 --- a/indra/llmessage/llurlrequest.cpp +++ b/indra/llmessage/llurlrequest.cpp @@ -429,12 +429,10 @@ bool LLURLRequest::configure() switch(mAction) { case HTTP_HEAD: + // These are in addition to the HTTP_GET options. curl_easy_setopt(mDetail->mCurl, CURLOPT_HEADER, 1); curl_easy_setopt(mDetail->mCurl, CURLOPT_NOBODY, 1); - curl_easy_setopt(mDetail->mCurl, CURLOPT_FOLLOWLOCATION, 1); - rv = true; - break; - + case HTTP_GET: curl_easy_setopt(mDetail->mCurl, CURLOPT_HTTPGET, 1); curl_easy_setopt(mDetail->mCurl, CURLOPT_FOLLOWLOCATION, 1); diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 00f167c3236..748e405065d 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -686,7 +686,7 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3 return FALSE; } - if (x_pos == 0 && y_pos == 0 && width == getWidth() && height == getHeight()) + if (x_pos == 0 && y_pos == 0 && width == getWidth() && height == getHeight() && data_width == width && data_height == height) { setImage(datap, FALSE); } diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp index b4fdbfeb0e6..28237823dd6 100644 --- a/indra/llui/llcombobox.cpp +++ b/indra/llui/llcombobox.cpp @@ -640,12 +640,6 @@ void LLComboBox::showList() // NB: this call will trigger the focuslost callback which will hide the list, so do it first // before finally showing the list - if (!mList->getFirstSelected()) - { - // if nothing is selected, select the first item - // so that the callback is not immediately triggered on setFocus() - mList->selectFirstItem(); - } mList->setFocus(TRUE); // Show the list and push the button down @@ -714,7 +708,7 @@ void LLComboBox::onButtonDown(void *userdata) else { self->hideList(); - } + } } @@ -737,30 +731,35 @@ void LLComboBox::onItemSelected(LLUICtrl* item, void *userdata) self->mTextEntry->selectAll(); } } - else - { - // invalid selection, just restore existing value - LLString orig_selection = self->mAllowTextEntry ? self->mTextEntry->getText() : self->mButton->getLabelSelected(); - - self->mList->selectItemByLabel(orig_selection); - } - self->onCommit(); + // hiding the list reasserts the old value stored in the text editor/dropdown button self->hideList(); + + // commit does the reverse, asserting the value in the list + self->onCommit(); } BOOL LLComboBox::handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect_screen) { LLString tool_tip; + if(LLUICtrl::handleToolTip(x, y, msg, sticky_rect_screen)) + { + return TRUE; + } + if (LLUI::sShowXUINames) { tool_tip = getShowNamesToolTip(); } - else + else if (!mToolTipMsg.empty()) { tool_tip = mToolTipMsg; } + else + { + tool_tip = getValue().asString(); + } if( !tool_tip.empty() ) { diff --git a/indra/llui/llradiogroup.cpp b/indra/llui/llradiogroup.cpp index 53541f51286..6fba415d35f 100644 --- a/indra/llui/llradiogroup.cpp +++ b/indra/llui/llradiogroup.cpp @@ -245,7 +245,9 @@ void LLRadioGroup::draw() radio->setValue( selected ); if (take_focus && selected && !gFocusMgr.childHasKeyboardFocus(radio)) { - radio->focusFirstItem(); + // don't flash keyboard focus when navigating via keyboard + BOOL DONT_FLASH = FALSE; + radio->focusFirstItem(FALSE, DONT_FLASH); } current_button++; } diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index c29789e0837..9d38bd0dab6 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -1381,6 +1381,8 @@ LLScrollListItem* LLScrollListCtrl::addSeparator(EAddPosition pos) // Returns false if item not found. BOOL LLScrollListCtrl::selectItemByLabel(const LLString& label, BOOL case_sensitive) { + // ensure that no stale items are selected, even if we don't find a match + deselectAllItems(TRUE); //RN: assume no empty items if (label.empty()) { @@ -1762,10 +1764,9 @@ BOOL LLScrollListCtrl::handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky { LLScrollListCell* hit_cell = hit_item->getColumn(column_index); if (!hit_cell) return FALSE; - S32 cell_required_width = hit_cell->getContentWidth(); + //S32 cell_required_width = hit_cell->getContentWidth(); if (hit_cell - && hit_cell->isText() - && cell_required_width > columnp->mWidth) + && hit_cell->isText()) { S32 rect_left = getColumnOffsetFromIndex(column_index) + mItemListRect.mLeft; @@ -1781,8 +1782,8 @@ BOOL LLScrollListCtrl::handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky &(sticky_rect_screen->mRight), &(sticky_rect_screen->mTop) ); msg = hit_cell->getValue().asString(); - handled = TRUE; } + handled = TRUE; } // otherwise, look for a tooltip associated with this column diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp index 241adb667ee..ee6176fff65 100644 --- a/indra/llui/lluictrl.cpp +++ b/indra/llui/lluictrl.cpp @@ -285,8 +285,6 @@ void LLUICtrl::setIsChrome(BOOL is_chrome) // virtual BOOL LLUICtrl::getIsChrome() const { - // am I or any of my ancestors flagged as "chrome"? - if (mIsChrome) return TRUE; LLView* parent_ctrl = getParent(); while(parent_ctrl) @@ -300,11 +298,12 @@ BOOL LLUICtrl::getIsChrome() const if(parent_ctrl) { - // recurse into parent_ctrl and ask if it is in a chrome subtree - return ((LLUICtrl*)parent_ctrl)->getIsChrome(); + return mIsChrome || ((LLUICtrl*)parent_ctrl)->getIsChrome(); + } + else + { + return mIsChrome ; } - - return FALSE; } // this comparator uses the crazy disambiguating logic of LLCompareByTabOrder, @@ -341,7 +340,7 @@ class DefaultTabGroupFirstSorter : public LLQuerySorter, public LLSingleton<Defa }; -BOOL LLUICtrl::focusFirstItem(BOOL prefer_text_fields) +BOOL LLUICtrl::focusFirstItem(BOOL prefer_text_fields, BOOL focus_flash) { // try to select default tab group child LLCtrlQuery query = LLView::getTabOrderQuery(); @@ -355,7 +354,10 @@ BOOL LLUICtrl::focusFirstItem(BOOL prefer_text_fields) { ctrl->setFocus(TRUE); ctrl->onTabInto(); - gFocusMgr.triggerFocusFlash(); + if(focus_flash) + { + gFocusMgr.triggerFocusFlash(); + } } return TRUE; } diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h index ae360f401f4..e47ee318bef 100644 --- a/indra/llui/lluictrl.h +++ b/indra/llui/lluictrl.h @@ -155,7 +155,7 @@ class LLUICtrl virtual void setMinValue(LLSD min_value); virtual void setMaxValue(LLSD max_value); - /*virtual*/ BOOL focusFirstItem(BOOL prefer_text_fields = FALSE ); + /*virtual*/ BOOL focusFirstItem(BOOL prefer_text_fields = FALSE, BOOL focus_flash = TRUE ); class LLTextInputFilter : public LLQueryFilter, public LLSingleton<LLTextInputFilter> { diff --git a/indra/llui/lluifwd.h b/indra/llui/lluifwd.h new file mode 100644 index 00000000000..23f441ffead --- /dev/null +++ b/indra/llui/lluifwd.h @@ -0,0 +1,40 @@ +/** + * @file lluifwd.h + * @author James Cook + * @brief Forward declarations of common LLUI widget types. + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ +#ifndef LLUIFWD_H +#define LLUIFWD_H + +class LLButton; +class LLCheckBoxCtrl; +class LLComboBox; +class LLDragHandle; +class LLFloater; +class LLIconCtrl; +class LLLineEditor; +class LLMenuGL; +class LLPanel; +class LLRadioGroup; +class LLResizeBar; +class LLResizeHandle; +class LLScrollbar; +class LLScrollContainer; +class LLScrollingPanelList; +class LLScrollListCtrl; +class LLSlider; +class LLSliderCtrl; +class LLSpinCtrl; +class LLTabContainer; +class LLTabContainerVertical; +class LLTextBox; +class LLTextEditor; +class LLTextureCtrl; +class LLUICtrl; +class LLView; +class LLViewBorder; + +#endif diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h index 8ef7066a314..0554d3a8db9 100644 --- a/indra/llwindow/llwindow.h +++ b/indra/llwindow/llwindow.h @@ -73,6 +73,9 @@ enum ECursorType { UI_CURSOR_TOOLBUY, UI_CURSOR_TOOLPAY, UI_CURSOR_TOOLOPEN, + UI_CURSOR_TOOLPLAY, + UI_CURSOR_TOOLPAUSE, + UI_CURSOR_TOOLMEDIAOPEN, UI_CURSOR_PIPETTE, UI_CURSOR_COUNT // Number of elements in this enum (NOT a cursor) }; diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 0a2f9cfb6c6..fe127b407ed 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -2738,6 +2738,9 @@ const char* cursorIDToName(int id) case UI_CURSOR_TOOLBUY: return "UI_CURSOR_TOOLBUY"; case UI_CURSOR_TOOLPAY: return "UI_CURSOR_TOOLPAY"; case UI_CURSOR_TOOLOPEN: return "UI_CURSOR_TOOLOPEN"; + case UI_CURSOR_TOOLPLAY: return "UI_CURSOR_TOOLPLAY"; + case UI_CURSOR_TOOLPAUSE: return "UI_CURSOR_TOOLPAUSE"; + case UI_CURSOR_TOOLMEDIAOPEN: return "UI_CURSOR_TOOLMEDIAOPEN"; case UI_CURSOR_PIPETTE: return "UI_CURSOR_PIPETTE"; } @@ -2834,6 +2837,9 @@ void LLWindowMacOSX::setCursor(ECursorType cursor) case UI_CURSOR_TOOLBUY: case UI_CURSOR_TOOLPAY: case UI_CURSOR_TOOLOPEN: + case UI_CURSOR_TOOLPLAY: + case UI_CURSOR_TOOLPAUSE: + case UI_CURSOR_TOOLMEDIAOPEN: result = setImageCursor(gCursors[cursor]); break; @@ -2876,6 +2882,9 @@ void LLWindowMacOSX::initCursors() initPixmapCursor(UI_CURSOR_TOOLBUY, 1, 1); initPixmapCursor(UI_CURSOR_TOOLPAY, 1, 1); initPixmapCursor(UI_CURSOR_TOOLOPEN, 1, 1); + initPixmapCursor(UI_CURSOR_TOOLPLAY, 1, 1); + initPixmapCursor(UI_CURSOR_TOOLPAUSE, 1, 1); + initPixmapCursor(UI_CURSOR_TOOLMEDIAOPEN, 1, 1); initPixmapCursor(UI_CURSOR_SIZENWSE, 10, 10); initPixmapCursor(UI_CURSOR_SIZENESW, 10, 10); diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp index cbf4b7dc3ab..e7475d577db 100644 --- a/indra/llwindow/llwindowsdl.cpp +++ b/indra/llwindow/llwindowsdl.cpp @@ -116,7 +116,9 @@ BOOL ll_try_gtk_init(void) if (!tried_gtk_init) { tried_gtk_init = TRUE; +#if LL_GSTREAMER_ENABLED if (!g_thread_supported ()) g_thread_init (NULL); +#endif // LL_GSTREAMER_ENABLED maybe_lock_display(); gtk_is_good = gtk_init_check(NULL, NULL); maybe_unlock_display(); @@ -1985,7 +1987,7 @@ void LLWindowSDL::gatherInput() static Uint32 lastRightDown = 0; SDL_Event event; -#if LL_GTK && LL_LIBXUL_ENABLED +#if LL_GTK && LL_LLMOZLIB_ENABLED // Pump GTK events so embedded Gecko doesn't starve. if (ll_try_gtk_init()) { @@ -2004,7 +2006,7 @@ void LLWindowSDL::gatherInput() setlocale(LC_ALL, saved_locale.c_str() ); } -#endif // LL_GTK && LL_LIBXUL_ENABLED +#endif // LL_GTK && LL_LLMOZLIB_ENABLED // Handle all outstanding SDL events while (SDL_PollEvent(&event)) @@ -2358,6 +2360,9 @@ void LLWindowSDL::initCursors() mSDLCursors[UI_CURSOR_TOOLBUY] = makeSDLCursorFromBMP("toolbuy.BMP",0,0); mSDLCursors[UI_CURSOR_TOOLPAY] = makeSDLCursorFromBMP("toolpay.BMP",0,0); mSDLCursors[UI_CURSOR_TOOLOPEN] = makeSDLCursorFromBMP("toolopen.BMP",0,0); + mSDLCursors[UI_CURSOR_TOOLPLAY] = makeSDLCursorFromBMP("toolplay.BMP",0,0); + mSDLCursors[UI_CURSOR_TOOLPAUSE] = makeSDLCursorFromBMP("toolpause.BMP",0,0); + mSDLCursors[UI_CURSOR_TOOLMEDIAOPEN] = makeSDLCursorFromBMP("toolmediaopen.BMP",0,0); mSDLCursors[UI_CURSOR_PIPETTE] = makeSDLCursorFromBMP("lltoolpipette.BMP",2,28); } @@ -2744,20 +2749,27 @@ void spawn_web_browser(const char* escaped_url) void *LLWindowSDL::getPlatformWindow() { -#if LL_GTK && LL_LIBXUL_ENABLED +#if LL_GTK && LL_LLMOZLIB_ENABLED if (ll_try_gtk_init()) { maybe_lock_display(); - GtkWidget *win = gtk_window_new(GTK_WINDOW_TOPLEVEL); - // show the hidden-widget while debugging (needs mozlib change) - //gtk_widget_show_all(GTK_WIDGET(win)); - - gtk_widget_realize(GTK_WIDGET(win)); + GtkWidget *owin = gtk_window_new(GTK_WINDOW_POPUP); + // Why a layout widget? A MozContainer would be ideal, but + // it involves exposing Mozilla headers to mozlib-using apps. + // A layout widget with a GtkWindow parent has the desired + // properties of being plain GTK, having a window, and being + // derived from a GtkContainer. + GtkWidget *rtnw = gtk_layout_new(NULL, NULL); + gtk_container_add(GTK_CONTAINER(owin), rtnw); + gtk_widget_realize(rtnw); + GTK_WIDGET_UNSET_FLAGS(GTK_WIDGET(rtnw), GTK_NO_WINDOW); + maybe_unlock_display(); - return win; + + return rtnw; } -#endif // LL_GTK && LL_LIBXUL_ENABLED +#endif // LL_GTK && LL_LLMOZLIB_ENABLED // Unixoid mozilla really needs GTK. return NULL; } diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 736ff9df97d..7e93d3ecf48 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -1907,6 +1907,9 @@ void LLWindowWin32::initCursors() mCursor[UI_CURSOR_TOOLBUY] = loadColorCursor(TEXT("TOOLBUY")); mCursor[UI_CURSOR_TOOLPAY] = loadColorCursor(TEXT("TOOLPAY")); mCursor[UI_CURSOR_TOOLOPEN] = loadColorCursor(TEXT("TOOLOPEN")); + mCursor[UI_CURSOR_TOOLPLAY] = loadColorCursor(TEXT("TOOLPLAY")); + mCursor[UI_CURSOR_TOOLPAUSE] = loadColorCursor(TEXT("TOOLPAUSE")); + mCursor[UI_CURSOR_TOOLMEDIAOPEN] = loadColorCursor(TEXT("TOOLMEDIAOPEN")); // Note: custom cursors that are not found make LoadCursor() return NULL. for( S32 i = 0; i < UI_CURSOR_COUNT; i++ ) diff --git a/indra/lscript/lscript_compile/indra.l b/indra/lscript/lscript_compile/indra.l index 57aef07e184..c8458a3ff04 100644 --- a/indra/lscript/lscript_compile/indra.l +++ b/indra/lscript/lscript_compile/indra.l @@ -36,6 +36,7 @@ FS (f|F) #include "llparcelflags.h" #include "llregionflags.h" #include "lscript_http.h" +#include "llclickaction.h" void count(); void comment(); @@ -522,6 +523,10 @@ extern "C" { int yyerror(const char *fmt, ...); } "PARCEL_MEDIA_COMMAND_AGENT" { count(); yylval.ival = PARCEL_MEDIA_COMMAND_AGENT; return(INTEGER_CONSTANT); } "PARCEL_MEDIA_COMMAND_UNLOAD" { count(); yylval.ival = PARCEL_MEDIA_COMMAND_UNLOAD; return(INTEGER_CONSTANT); } "PARCEL_MEDIA_COMMAND_AUTO_ALIGN" { count(); yylval.ival = PARCEL_MEDIA_COMMAND_AUTO_ALIGN; return(INTEGER_CONSTANT); } +"PARCEL_MEDIA_COMMAND_TYPE" { count(); yylval.ival = PARCEL_MEDIA_COMMAND_TYPE; return(INTEGER_CONSTANT); } +"PARCEL_MEDIA_COMMAND_SIZE" { count(); yylval.ival = PARCEL_MEDIA_COMMAND_SIZE; return(INTEGER_CONSTANT); } +"PARCEL_MEDIA_COMMAND_DESC" { count(); yylval.ival = PARCEL_MEDIA_COMMAND_DESC; return(INTEGER_CONSTANT); } +"PARCEL_MEDIA_COMMAND_LOOP_SET" { count(); yylval.ival = PARCEL_MEDIA_COMMAND_LOOP_SET; return(INTEGER_CONSTANT); } "LIST_STAT_MAX" { count(); yylval.ival = LIST_STAT_MAX; return(INTEGER_CONSTANT); } "LIST_STAT_MIN" { count(); yylval.ival = LIST_STAT_MIN; return(INTEGER_CONSTANT); } @@ -587,6 +592,15 @@ extern "C" { int yyerror(const char *fmt, ...); } "STRING_TRIM_TAIL" { count(); yylval.ival = STRING_TRIM_TAIL; return(INTEGER_CONSTANT); } "STRING_TRIM" { count(); yylval.ival = STRING_TRIM; return(INTEGER_CONSTANT); } +"CLICK_ACTION_NONE" { count(); yylval.ival = CLICK_ACTION_NONE; return(INTEGER_CONSTANT); } +"CLICK_ACTION_TOUCH" { count(); yylval.ival = CLICK_ACTION_TOUCH; return(INTEGER_CONSTANT); } +"CLICK_ACTION_SIT" { count(); yylval.ival = CLICK_ACTION_SIT; return(INTEGER_CONSTANT); } +"CLICK_ACTION_BUY" { count(); yylval.ival = CLICK_ACTION_BUY; return(INTEGER_CONSTANT); } +"CLICK_ACTION_PAY" { count(); yylval.ival = CLICK_ACTION_PAY; return(INTEGER_CONSTANT); } +"CLICK_ACTION_OPEN" { count(); yylval.ival = CLICK_ACTION_OPEN; return(INTEGER_CONSTANT); } +"CLICK_ACTION_PLAY" { count(); yylval.ival = CLICK_ACTION_PLAY; return(INTEGER_CONSTANT); } +"CLICK_ACTION_OPEN_MEDIA" { count(); yylval.ival = CLICK_ACTION_OPEN_MEDIA; return(INTEGER_CONSTANT); } + {L}({L}|{N})* { count(); yylval.sval = new char[strlen(yytext) + 1]; strcpy(yylval.sval, yytext); return(IDENTIFIER); } {N}+{E} { count(); yylval.fval = (F32)atof(yytext); return(FP_CONSTANT); } diff --git a/indra/lscript/lscript_library/lscript_library.cpp b/indra/lscript/lscript_library/lscript_library.cpp index e0822203538..47ea62b8886 100644 --- a/indra/lscript/lscript_library/lscript_library.cpp +++ b/indra/lscript/lscript_library/lscript_library.cpp @@ -29,7 +29,15 @@ * $/LicenseInfo$ */ -// *WARNING* + +// ## ## ### ######## ## ## #### ## ## ###### #### #### +// ## ## ## ## ## ## ## ### ## ## ### ## ## ## #### #### +// ## ## ## ## ## ## ## #### ## ## #### ## ## #### #### +// ## ## ## ## ## ######## ## ## ## ## ## ## ## ## #### ## ## +// ## ## ## ######### ## ## ## #### ## ## #### ## ## +// ## ## ## ## ## ## ## ## ### ## ## ### ## ## #### #### +// ### ### ## ## ## ## ## ## #### ## ## ###### #### #### +// // When adding functions, they <b>MUST</b> be appended to the end of // the init() method. The init() associates the name with a number, // which is then serialized into the bytecode. Inserting a new @@ -431,6 +439,8 @@ void LLScriptLibrary::init() addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetObjectDetails", "l", "kl", "list llGetObjectDetails(key id, list params)\nGets the object details specified in params for the object with key id.\nDetails are OBJECT_NAME, _DESC, _POS, _ROT, _VELOCITY, _OWNER, _GROUP, _CREATOR.")); + addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetClickAction", NULL, "i", "llSetClickAction(integer action)\nSets the action performed when a prim is clicked upon.")); + // energy, sleep, dummy_func, name, return type, parameters, help text, gods-only // IF YOU ADD NEW SCRIPT CALLS, YOU MUST PUT THEM AT THE END OF THIS LIST. diff --git a/indra/newview/app_settings/keywords.ini b/indra/newview/app_settings/keywords.ini index 5a68c5b1632..08006470681 100644 --- a/indra/newview/app_settings/keywords.ini +++ b/indra/newview/app_settings/keywords.ini @@ -422,7 +422,10 @@ PARCEL_MEDIA_COMMAND_PLAY Play media stream PARCEL_MEDIA_COMMAND_LOOP Loop media stream PARCEL_MEDIA_COMMAND_TEXTURE Get or set the parcel's media texture PARCEL_MEDIA_COMMAND_URL Get or set the parcel's media url +PARCEL_MEDIA_COMMAND_TYPE Get or set the parcel's media mimetype +PARCEL_MEDIA_COMMAND_DESC Get or set the parcel's media description PARCEL_MEDIA_COMMAND_TIME Set media stream to specific time +PARCEL_MEDIA_COMMAND_SIZE Get or set the parcel's media pixel resolution PARCEL_MEDIA_COMMAND_AGENT Allows media stream commands to apply to only one agent PARCEL_MEDIA_COMMAND_UNLOAD Unloads the media stream PARCEL_MEDIA_COMMAND_AUTO_ALIGN Auto aligns the media stream to the texture size. May cause a performance hit and loss of some visual quality. @@ -492,6 +495,15 @@ STRING_TRIM_HEAD Used with llStringTrim to trim leading spaces from a string. STRING_TRIM_TAIL Used with llStringTrim to trim trailing spaces from a string. STRING_TRIM Used with llStringTrim to trim both leading and trailing spaces from a string. +CLICK_ACTION_NONE Used with llSetClickAction to disable the click action +CLICK_ACTION_TOUCH Used with llSetClickAction to set touch as the default action when object is clicked +CLICK_ACTION_SIT Used with llSetClickAction to set sit as the default action when object is clicked +CLICK_ACTION_BUY Used with llSetClickAction to set buy as the default action when object is clicked +CLICK_ACTION_PAY Used with llSetClickAction to set pay as the default action when object is clicked +CLICK_ACTION_OPEN Used with llSetClickAction to set open as the default action when object is clicked +CLICK_ACTION_PLAY Used with llSetClickAction to set play as the default action when object is clicked +CLICK_ACTION_OPEN_MEDIA Used with llSetClickAction to set open-media as the default action when object is clicked + # string constants [word .1, .3, .5] NULL_KEY Indicates an empty key diff --git a/indra/newview/cursors_mac/UI_CURSOR_TOOLMEDIAOPEN.tif b/indra/newview/cursors_mac/UI_CURSOR_TOOLMEDIAOPEN.tif new file mode 100644 index 0000000000000000000000000000000000000000..7c0bcfcbc5002fc613707ffd69ea8ed14e31a1c1 GIT binary patch literal 41228 zcmeHQYiu0Xb-qhc57M?|JBgE~ZZct-G;o*P7s=%^6fM41VoS;dNjY|4)EVv$R~yaF zY-eXhQUy}M1==78@}te4wg&w8=OO_D{V<B!tz{rJ5+p(Y*hUc)iDMLS(4<X@AhrCQ ze&@{G+1ceTwIh<UWY1m9eVlvlx#yla_uLonaB)%GBZN32J}TZ7y@<u|kavIs1@TxQ z-otU=#Rg&rJUEbJhrD<X;&(_oe=-!iGl26EFHWWJ^5R7QqZ0pi5&O6}=vE)QC-%F3 zJRQ3`K<9H_oa#ym_~H|YjmOd)|1jbY#FiWQJ<n2eCVl|8{uj@1T_`g-_LuVn|K$H5 ze&Vmnk_RLCHxG%!LZrVXgz*q)lWg2y|JxUZ_=DSp7fuz;HBDJMYuaY*tXWlNRx-+> zS|}To7U^ViY&@ABPmU_7?06<MJ~ARE?%k}ag>#y%tZAjPaeUxc&pbDvl#9m)zA&<w zT&&J$XUnH9SlY^k)2oFG=L)&vz`c|G6Px3km1;$^Rb{iH8@2Jx;{z(yJ&rhm69WpP z*yoN9xJ*5;xTMUOmZl63r3MSh%&0OvI+V_iX4A>IvS=DgURzUAIR#8+m2`SMl^Gw- zD4rXb>_=?EDz1+&&*r^4kvcwb*0!tTiNwan#?VG)$h1m{R4$iGB-4p>dJq_cwJpO| zHwTT{r(GhF&a74|Smml+M%6@DT{G+U@qq!V$ah}j)av4*UzJfC;-(H2%t~TYttL`K z$wZ}+XjigkFKZ1Z+m@`YZdJ9!vQ{(eRzU-LgHNzAfeIEE$7jt#y`mZR{On}CUM`Mj zW-_VF$lO#iH9I;xlS<{rMzgcYk*VRC{8)B6pPC@Xn#(oX<<XosYPM<=G@s^dcQga# zw$Yr`tnzuSn77Od3$?0RHH{j0d_cC)e+#aVCs;(|<yK~<ug1)_at&rkZf<t5Rc=$= zkqwk<koASyXe6s8RhJ+Y3aFHy(E`7ks@diB4*EhltZG34P7ri_zM_`2FO-Y+*~v_L zBGC#9w4jl-pc$oY_#Uvez;xNJEos(@TB+)qY?=4^sC_HipEg5DB9x(*C&ygTAl9H7 zD7wEGZr#o7dGhJhCRd^}W~FLrwHl1WBsvp|EeLD0#l>ff3%h5P3-gApStx9)WLhTW z`{<0(O3M{934E!%sp*r$Uj41`)^ba_YN*zXX{?t^b<3??^4>15wfqCrL-jgy4WkT~ zNRjVVAIxqo`ryt*gW0V`8zs*eW!o253%Iq^eO4LPu(^#vSS$W%pq|%e%O$ObIz~q0 z>5(j+F+90=dNdtRXNU0sHZ~j|$t3Zl5C?oL6Hn(x<C$bCo=J`2$;C&~crt0gKqs5T z1Kcd7N05&vGn`3(esp?nWGa^*o*kYZ8y=mS8=D(Rj-;m2xw+xF{K%Mmt4*AFZ10&h z!62~nu+?NsfIYrw7R&2fv#PC4(rjTcnI24zuFBcMAk8135G|MiX;aROrKz@Qt(vAj zx#NVyB@{$&M@j338z$mnw$NBaPb{jo+6|Q^+`WDo+Ge?fX{Vg+rk$YUGp24@E102a zlY{8Yt*}5_Ig2gE1G8n!71(ysaL_iRZNUdS6%1sw7Hrbr%;?zYaC|tK8%?s0K9fzQ zT|dnb*Utbxl5%l|<5VikKKd8>4j}LW86F!+vX8!nIC>U*^u=rjJ(Yam!_SdF22A)= zR|fr-e5xgb{!Bi~!soK+&BLi-<dP3=;k%G5$H&Oeflv61lN&)in<jV`Js&>o!!V{? z1jodSeJYz9Bb?kA;pB3RlS^@&sO6YiE=M)ym}ZVRNhedIaoCVJ>`r_%o{f*ib8(0! zm5Qg*@l+<B8ji!J04bG?!vJBnoQ7F~Rf549f$f6nft7;s`FwURJvBEyHZwJn%qQn& zrjyenqcgK($=qx*l^q?P^;DthjqSCP7Yn|@sn#u>C*;LKLen*xzSf}SsYH{}DHg`p zO{=2XlVzI4@K8IEXh8Rx!Kz#v`Fu9b%Khx^{n5{IJ0&coHkp}7v;zk^NhAAIxdyAa zm5>vm_Ez47Vv&PIR>EIp$ujQDX}|mi+xt}m=th-<5^f}}NL-;L5DGccu1H*=BoGQY z(ymBcp(GFrInu63T%jZo3OUlQNL-;L5DGccu1H*=BoGQY(ymBcp(GFrInu63T%jZo z3OUlQNL-;L5DGccu1H*=BoGQY(ymBcp(GFrInu63T%jZo3OUlQNL-;L5DGccu1H*= zBoGQY(ymBcp(GFrInu63T%jZo3OUlQNL-;L5DGccu1H*=BoGQY(ymBcp(GFrc}MN) zZ`@nf3|v;;z^!C)H||i=)$6h8`NdwkH!j5CCfH{fcKgr&_o3e;p8wbrPySiy+y7d8 z>7NMyz<*KR$8HDRimsg3EV@5)d;oWQ2NcaH;98VXIzDh_H9t7U7oa~id*96JgG+Nt zRmb1;D@$jl7v^V_fx$##s)}2ZiNx&ctg^H)zp|>({oush=>a8pSy?44zCsMdT4KpE ztD0qREr8e{3JewPBJN2{xYV220kl{y*pvNz6X&$8N!&sna*0(f-18n<!YztC->4W` zT0CW1<qIZm%IUaJH<2KG6!VI=FK?IWHuzA%y~HKU^x;A+$d>}uec4=daVHX9UVq<? zB+Ir|nX)W(t3gzyBv?X0$y5g#S8o;(0n_?q7MGqlLUecJ2p6DjEw8I3pCjNyh+0Xr zCUMVAMw!8c<ZvP(*~UecZr?=UcA~7zZ*trBcr(0*HjN^QOR?d?nvC8^uVSU3>QLqP z&ueIDklzs?{~N9!+z%^P#tV2~*`qd%@?XLYX^kYqEt+%lTci#R^WVk|(j{v3wN-bV zt*RLJA1)i~=EHI{Z8u6UEiNt1E)nhw?j4?1E1EQ4fsr%JIMVHazT^10eMIk@kYgi> zT#lF&r&jII3PSOw5eu4)PbdUu6|#KmT*n(D+YRH5QK)4c@AC(3)aZ}o0jS66YS}EQ zEb*IH+8x>ukhP%>>NkM6TVHI`Y;UUg<$BH5iUeHN3ii#Y`PbG!dQpM?gcOhG$sy=; zV`RSyIGe$@CbnabWJjC8fxdA4yIYsyf%$u%D?n=tJ7~aQioUBuiyfX=OAY7%&Su+d zK&}~lgJ}RnF^^#ptJs^`3U62Kof>vCnC1rmXAJdyX`8!hVTZ2yK`_qk<pb#Z$2xb{ z#11;p!47u--`wW8S}neRO?0Qm1<drB73D@)u(S>{-qL7lX&y^r+RJXtn!ROKGC7pS zJhHpJTN~eS+(x0bP9CRe%y!qd0owkWYo{gZc3$O*u$9%Fs02Bc<+n2`_sCm0m5k!M zKD4ht+0SPK|LvX|h*Jn-_<13pGkliwj<V0*y%*gRhy(bFE8K0ju3D;5!<R5|jIiaN zO?-rN@P$}$n^+Z=P=z6CqKeQG8sY`9<<a;RV}iQla7>6|%%w5H={w-#i?Q2se~)wd z41~G7%};M~`gi>FC%A>b;dCGS@Vq+uISu-RgRjhz>!<qI#kk~eIetnc*4L4v!$0Ka zdXOjn_V0X18aXlXMfehjS`ib24G7b`g0z4<(5`mwz|SeWU5?}ICXecNkBxAQbc9oM zoW$Sq<*<Xtm`Tn&7Hf9yyQ20{n@MuxjD3V5qz8cYoNyn`2Z%99I|P3L*iC<&k_Q&y zxw50A5Q_KQ3Z1D#duqaj|1j%P9Vrd@@_ixdyC6&fl%6IRM35Pz03O_^>pD^-o<sO> zu2HPrxAx^iBY(MIr;uW4uHr+)x@nY<X1AcN+rjj-ZC1RrLI}&HvofF3hiZDcpw;fz z7ivhwn(8^oc>v#u=P)PcX9Khkmn^ehZ2}#_kr+O7tQqwR%G^4)Lez1P0T|M^sdd{t zsTmqRps5uB5cKt054qn(CJ5!sS4s+k{cisOd`E3{?txWQ6%c+iWU*G#njnW%-Ck8o zO|YW{P1jeoO?$p}YISj84c})Zf=48{3AyjAX<eAo%OxqPV{YSdqUeHA@^DdGSL?cs zXy1A4>$gFt{a6M!qu;Vt;x8KpgnNfefBK}Kfg<9xX^^b@Y_ob_-L7d;F(|KJhazo* z-nwSmP^fM2Tkwj{wxV-S`y3Gyx8jN2`)iK7J&tTEV4f|+H@x9Up%=K+r#O8EJ}`th zCZ<FYoo@|YP7zDuEaEnv8pmMD#D}hep@<o=A~Hmf>p%85qC#A$s785yIlqkfFRA7! zW0pF?5Akg8ko1LgF_m8l%1Pw0kZ#+3gx8I!0ffa}=kBeg*Eqdmx9@ba6nE}?t*LjR zZcBD%A|mp&yd~?Vjwz`x%oqV4sa?w^n-teFq9nnNJ;6louB=;S#K_zP+U)iRISw%9 zd*D(1sFvAy531*iss8th2igAjiig(vueTi9)qg#C=v4pp;$f%yuLloTtAD?F=u|(! zTOD}Wb4PW6Xt4hW<9l9TD?wSm7hZRJMD>!Be0lNfCWBzzA$edPQKnreNnKOer3~8D zD`D4EZ?F*YAYBmNCNAp?hHcPx1q#xpxOA;>nU?u`6-rU~AqdO5+J$>nucYJGOOXzB z6RymY<@PG{>krf+>!MIP36tr)3Om;C$z!kT=|sn`->Z+?DS;>yltCvNyMfE9+J+y5 z`n@(v{c0EPM!r$mNCJ@r-Wv%Vc-;Gca5S<#-Xs5Snou4;(1^RNwf;jA`Jc5E{C^Nt znbyt1Io^3#T(xLFkmC#LmWBVmHiS){hEot#L@$q}k1+TV-j8^McPSpB-3tSMhVNj* z9M0QU64+~^5?6nY;ZKz7n-3T2R?V~?UMmqjy>8Gh$nWDhCUjB8NkLs~Vz;+>?{`gL ztCjJ$%Cv<^`!vTXUC`HP)3%qkdnk>+I^6W~IepGJX9m-Ht-9WnF6fX0{_~vYh{pP+ zMVni+E3>n6CFSm?_pqdTSW-Pi#g){@h{At(WV)8r(TN0JkY*{o*E{L9+?A99T1Ul% zNQecTt!!ay&cZt@!8akfD*oXf>c+pXqgM6m*j?mwLu!MZt`%s9lcadSP47x7q(dY@ zI-$AC)1PU?g*eYrInPo#Pc^wxVR8SGF+}(Jb9AkaZBPT6qZG`ld+y}vj{;gpu~Ava z1|@A#8qgrp83lS|LMmG=QsDj0{nQ<~>ncO=cPE}(@X)Ephnl1`%~G0XDNQ$|1a%R8 z7vYiXT6Yds)p`vZ%-rJj%{2D3S=^uz*k|;1Ne>d~m4dFEG3@-Om#o5x2MNONXhp@J zC|dakRyN9Z;jG+S7b|AI+;n2W5ELPG5}Ki|`KXIU1vicOR6<Pa2A%YX)7VU<@V;un zZd0q6(JiH!{PM}^85H1s;AK!On)NlJAl*sJ*an-{+u`N)X38h6Jn_QjOft??uZ8iG zmRj`4_lc9}kScc1%Y67roel1!RU`w<LO)$m6z_E6Fm}o5V2c!&4shUrnU{j2IKgIW z_6mjbhHa4uPJD+_u7l9z#&&OW6OkjkdY7U-VZI{Cf)7`;L6{V65EeM}pjvR$E5w<a z#r!T5Y$I@fB^HZSnNIJTSK~_}cF|?m=QRNHc@4n2<MlAVr9I{KoYH&QWwjw!{qX}Q zJebdG<rQ~G0lZ6Ic@W=IUIX&lTe-TUYJk^IQu8r0k^0-ytP{u~E#l7K$z*h|Vd1E4 z;}ymfM^Q#eXTycaiTf`Sh+Xhqq0g=oaKW$?3YX7YHQy>u=_SKYbTGc+zV({jEQuw< zCR(f;r>qNxZ#?gsyz6TlpZOZqbH8O5eE26OzVO9w|KRTlo`)H4rbZBC;9u}IY&ONk zioK;v(?f@D1jETAn;@{T>gTz(Q>>uB6HeDAbC$4Ow{k)8MxISQFj97Ds3a8%eI;GG zoRDz8Lw)Jbe|3?8JSK9(V_yg0Fr^C>RxlO>W|0Ic)`}a*&fw{Btu<matz?^kkR4%G z>bfFg&q<Is2i;w9v!qk)_uy&N&Rfv`^3QGs_%FYPK&7<rAz@{=)E{206q*<;wx*q@ zH+-6l$tI$i)HtffZzPxEl>ty)*Yn(SJaKWiUnG=5E^V&U%zglmKOd$%*E!&$;RxTG z$x)v>82nog&TGtH=P13OGq=l%%h!o`gTJO&7qfo;!<J{gQr9+fb7%WklSZ7S<Id)9 zMSU#ks#>eL@LkR7n;PxSSKWc>W?AceJ|La<cCGVDSY7Dz*E()*@_Gj?C;Qs0bKKc} zqnFI?cQ29FT87{&20QRugfvKgN*rWc@dDyPyufDS1s=LyaNY&v9^%hk3!;07zVE>M zFrGW{+=hob(4AZ=#LB0)s;e~f<hLHJd>{$wXr0qM{6{OFHjB#OipHN%1Xe@-gdzY7 z&ibO24`#aU<QlDfuzk60H4&|R+HE^UE1zad-L6APyH25RsG^n6&g-QcedR;*_g<`g zblTVFIZR_dH*-z%xk{<RG~qG55N99H{ThW}vrY{C1G#Ux{G6wiKFy?gH-Hd)*X^q4 zAH5P?uZo&xb?&NYCrR;L1U*_2;XSoE{rO{853c?6N6z;zyQ3MsOxk>;TQ+q6MxJX- zA`a8UGx(D{?>|X32Tp%NpNSp8*Tiu4W6~xCx5Cv0S~VQuGakBSM5jKc;QK&&qxZ}c z{(kNmw2=y}Vn|Q#!t)Vt^?U+xA+ju$EK4QZB9&JdBgC4gpQVBiDwrEVsn9yHKOhyl zg+(WX8!WkoWKQk3WKMVux=in>o$JDGP-8@RyFrpcL2hx-ZqRukbfrZSf5hoMup4c3 zLAIOvOuwfKd=f97WL<cYb>T_k!0jP?AoZVKv92xUEgNN{Xl~RVuG&_h)pvu=En<Vu z*6BLO29BEOHkA#HaHZ4Ghdh<r&z^Gmvu>*{6IacSq;rcWohoNtV(DCB>0D|^=Llu~ zJ7a|CDTga+p+z#JlZSESrs9;ilSB^fw?w>lG=dn~yQ|;NoZbB(^<C93dVco3-TfjC ze)c_IA!4{4+39^865_Xx5WjKS|J+<i^AN_!Lv4NprA<3*$6tEgiCsdaMDN;sp9WL> zK-Eg8BksY<HHNtS_QM}K4!q}|f8KH6J^l34jsp*~Z^wc6*kg}54!m!E^P7$X@2g+^ zs^h@>%2&SPIPipc`Q?`#2i}i<^drZC_ucP)*Ky!I^UO1j1MkwMOO6BYsi&TD9C(jD z`l#c;`^GoE;W+Sw_{A@N;W+SKd+jyHf%odGuR0FApZw$}jsx$<KmM`fz<cq<7aa%Q z_rL#r$AS0kv(GvXJYQ#JB+}g-`_m25V>(%vJ%hjG?Duc?BSuFX>r3G!vERR_6<2=? zF2;VpiI-r({*BJAou7`8VSmHm1Mt75vu^T`{ON>;B8{CN#;`}S?RN!a-f`X%Z(xK7 zK36bs1Rv-?u<T*XP!Ee<!gxo#)q+dVH!*g%1XR@xOok>Mz2cAq*6Ddiyp1!#w>T~k z?}4P>M#_P>-p1Q@AhbYh4zdDJdFM^!H6DoJO>qT3BG?0wKw1r1UXNl@0UEW+H%T_6 z7jrQBVIBs367Par(ucRv$hRPbHz5Sl3wo!oJFh#Gei!j~SQHM2&>(~m68mp)J~n!= zhIU=ABclf#86^l(aGclhIPKvh@L~vM%#nn9;TVB(DBnx@K!Q^x9Qv39#AYG*m4w{V z1aCo)ICN##S%%wns<&0Au0S8&fM&c2oq7v8^)`2|H=svXphK_YJ^UZE>K#w3-bLpj zt-^6UYn8)V<p|O$pdweQGv1&dM?}Uc^x_=2@qi!5^rD0>qlmas)&@6&0R(rG%!7;) zH(tCY$_=4hE>4*)1&+0pp(HsD+<3qbWO~tHal}1bX1T%62Z&?Z4Ov*Mor4IE1|*)o Y2ms|RskV(M$MY^8c0v6&lcv1?2SgZ2&Hw-a literal 0 HcmV?d00001 diff --git a/indra/newview/cursors_mac/UI_CURSOR_TOOLPAUSE.tif b/indra/newview/cursors_mac/UI_CURSOR_TOOLPAUSE.tif new file mode 100644 index 0000000000000000000000000000000000000000..3431887aff812a2194c31c925cee38ab8b205c06 GIT binary patch literal 41224 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 BT{8dx literal 0 HcmV?d00001 diff --git a/indra/newview/cursors_mac/UI_CURSOR_TOOLPLAY.tif b/indra/newview/cursors_mac/UI_CURSOR_TOOLPLAY.tif new file mode 100644 index 0000000000000000000000000000000000000000..796bbb78e3c7a0682ade747d306f48668d5096c8 GIT binary patch literal 41224 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 literal 0 HcmV?d00001 diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index fe9b90ae600..075a7089de3 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -47,6 +47,7 @@ #include "llpumpio.h" #include "llfloateractivespeakers.h" #include "llimpanel.h" +#include "llmimetypes.h" #include "llstartup.h" #include "llfocusmgr.h" #include "llviewerjoystick.h" @@ -59,6 +60,7 @@ #include "llworldmap.h" #include "llmutelist.h" #include "llurldispatcher.h" +#include "llurlhistory.h" #include "llweb.h" #include "llsecondlifeurls.h" @@ -76,7 +78,6 @@ #include "llnotify.h" -#include "llmediaengine.h" #include "llviewerkeyboard.h" #include "lllfsthread.h" #include "llworkerthread.h" @@ -97,7 +98,6 @@ #include "llviewermenu.h" #include "llselectmgr.h" #include "lltracker.h" -#include "llmozlib.h" #include "llviewerparcelmgr.h" #include "llworldmapview.h" @@ -169,21 +169,6 @@ static char** gTempArgV; #if LL_WINDOWS && LL_LCD_COMPILE #include "lllcd.h" #endif -// -#if LL_QUICKTIME_ENABLED - #if LL_DARWIN - #include <QuickTime/QuickTime.h> - #else - // quicktime specific includes - #include "MacTypes.h" - #include "QTML.h" - #include "Movies.h" - #include "FixMath.h" - #endif -#endif -// -////// - //---------------------------------------------------------------------------- // viewer.cpp - these are only used in viewer, should be easily moved. @@ -228,10 +213,6 @@ extern BOOL gbCapturing; extern BOOL gRandomizeFramerate; extern BOOL gPeriodicSlowFrame; -#if LL_GSTREAMER_ENABLED -void UnloadGStreamer(); -#endif - //////////////////////////////////////////////////////////// // All from the last globals push... bool gVerifySSLCert = true; @@ -257,6 +238,7 @@ BOOL gShowObjectUpdates = FALSE; BOOL gLogMessages = FALSE; std::string gChannelName = LL_CHANNEL; BOOL gUseAudio = TRUE; +BOOL gUseQuickTime = TRUE; LLString gCmdLineFirstName; LLString gCmdLineLastName; LLString gCmdLinePassword; @@ -1174,6 +1156,9 @@ bool LLAppViewer::init() LLAgent::parseTeleportMessages("teleport_strings.xml"); + // load MIME type -> media impl mappings + LLMIMETypes::parseMIMETypes( "mime_types.xml" ); + mCrashBehavior = gCrashSettings.getS32(CRASH_BEHAVIOR_SETTING); LLVectorPerformanceOptions::initClass(); @@ -1574,32 +1559,6 @@ bool LLAppViewer::cleanup() llwarns << "Hack, skipping audio engine cleanup" << llendflush; #endif - - // moved to main application shutdown for now because it's non-trivial and only needs to be done once - // (even though it goes against the media framework design) - - LLMediaEngine::cleanupClass(); - -#if LL_QUICKTIME_ENABLED - if (gQuickTimeInitialized) - { - // clean up media stuff - llinfos << "Cleaning up QuickTime" << llendl; - ExitMovies (); - #if LL_WINDOWS - // Only necessary/available on Windows. - TerminateQTML (); - #endif - } - llinfos << "Quicktime cleaned up" << llendflush; -#endif - -#if LL_GSTREAMER_ENABLED - llinfos << "Cleaning up GStreamer" << llendl; - UnloadGStreamer(); - llinfos << "GStreamer cleaned up" << llendflush; -#endif - llinfos << "Cleaning up feature manager" << llendflush; delete gFeatureManagerp; gFeatureManagerp = NULL; @@ -1661,18 +1620,12 @@ bool LLAppViewer::cleanup() LLTracker::cleanupInstance(); -#if LL_LIBXUL_ENABLED - // this must be done after floater cleanup (delete gViewerWindow) since - // floaters potentially need the manager to destroy their contents. - LLMozLib::getInstance()->reset(); -#endif - // *FIX: This is handled in LLAppViewerWin32::cleanup(). // I'm keeping the comment to remember its order in cleanup, // in case of unforseen dependency. -//#if LL_WINDOWS -// gDXHardware.cleanup(); -//#endif // LL_WINDOWS + //#if LL_WINDOWS + // gDXHardware.cleanup(); + //#endif // LL_WINDOWS #if LL_WINDOWS && LL_LCD_COMPILE // shut down the LCD window on a logitech keyboard, if there is one @@ -1729,6 +1682,9 @@ bool LLAppViewer::cleanup() gColors.cleanup(); gCrashSettings.cleanup(); + // Save URL history file + LLURLHistory::saveFile("url_history.xml"); + if (gMuteListp) { // save mute list @@ -2368,8 +2324,6 @@ bool LLAppViewer::initWindow() LLAlertDialog::parseAlerts("alerts.xml"); LLNotifyBox::parseNotify("notify.xml"); - LLMediaEngine::initClass(); - // // Clean up the feature manager lookup table - settings were updated // in the LLViewerWindow constructor diff --git a/indra/newview/llfirstuse.cpp b/indra/newview/llfirstuse.cpp index 2772a134166..97ebc02ba18 100644 --- a/indra/newview/llfirstuse.cpp +++ b/indra/newview/llfirstuse.cpp @@ -264,3 +264,14 @@ void LLFirstUse::useVoice() LLFloaterVoiceWizard::showInstance(); } } + +// static +void LLFirstUse::useMedia() +{ + if (gSavedSettings.getWarning("FirstMedia")) + { + gSavedSettings.setWarning("FirstMedia", FALSE); + + LLNotifyBox::showXml("FirstMedia"); + } +} diff --git a/indra/newview/llfirstuse.h b/indra/newview/llfirstuse.h index b5cf1482852..5510ce02b92 100644 --- a/indra/newview/llfirstuse.h +++ b/indra/newview/llfirstuse.h @@ -105,7 +105,8 @@ class LLFirstUse static void useDebugMenus(); static void useSculptedPrim(); static void useVoice(); - + static void useMedia(); + protected: static std::set<LLString> sConfigVariables; }; diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp index 01e529078f7..7da2ac79b1a 100644 --- a/indra/newview/llfloaterabout.cpp +++ b/indra/newview/llfloaterabout.cpp @@ -48,12 +48,9 @@ #include "llviewerbuild.h" #include "llvieweruictrlfactory.h" #include "llappviewer.h" - -#if LL_LIBXUL_ENABLED -#include "llmozlib.h" -#endif // LL_LIBXUL_ENABLED - #include "llglheaders.h" +#include "llmediamanager.h" + extern LLCPUInfo gSysCPU; extern LLMemoryInfo gSysMemory; @@ -147,11 +144,18 @@ LLFloaterAbout::LLFloaterAbout() support.append( (const char*) glGetString(GL_VERSION) ); support.append("\n"); -#if LL_LIBXUL_ENABLED - support.append("LLMozLib Version: "); - support.append( (const char*) LLMozLib::getInstance()->getVersion().c_str() ); - support.append("\n"); -#endif // LL_LIBXUL_ENABLED + LLMediaManager *mgr = LLMediaManager::getInstance(); + if (mgr) + { + LLMediaBase *media_source = mgr->createSourceFromMimeType("http", "text/html"); + if (media_source) + { + support.append("LLMozLib Version: "); + support.append((const char*) media_source->getVersion().c_str()); + support.append("\n"); + mgr->destroySource(media_source); + } + } if (gViewerStats && gPacketsIn > 0) diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index 6dd55c169ba..f340ff25697 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -31,8 +31,6 @@ #include "llviewerprecompiledheaders.h" -#include <sstream> - #include "llfloaterland.h" #include "llcachename.h" @@ -53,6 +51,7 @@ #include "lllineeditor.h" #include "llnamelistctrl.h" #include "llnotify.h" +#include "llpanellandmedia.h" #include "llradiogroup.h" #include "llscrolllistctrl.h" #include "llselectmgr.h" @@ -68,10 +67,39 @@ #include "llviewerstats.h" #include "llviewertexteditor.h" #include "llviewerwindow.h" -#include "llmediaengine.h" #include "llviewercontrol.h" #include "roles_constants.h" +#include <sstream> +#include <time.h> + +static const S32 EDIT_HEIGHT = 16; +static const S32 LEFT = HPAD; +static const S32 BOTTOM = VPAD; +static const S32 RULER0 = LEFT; +static const S32 RULER05 = RULER0 + 24; +static const S32 RULER1 = RULER05 + 16; +static const S32 RULER15 = RULER1 + 20; +static const S32 RULER2 = RULER1 + 32; +static const S32 RULER205= RULER2 + 32; +static const S32 RULER20 = RULER2 + 64; +static const S32 RULER21 = RULER20 + 16; +static const S32 RULER22 = RULER21 + 32; +static const S32 RULER225 = RULER20 + 64; +static const S32 RULER23 = RULER22 + 64; +static const S32 RULER24 = RULER23 + 26; +static const S32 RULER3 = RULER2 + 102; +static const S32 RULER4 = RULER3 + 8; +static const S32 RULER5 = RULER4 + 50; +static const S32 RULER6 = RULER5 + 52; +static const S32 RULER7 = RULER6 + 24; +static const S32 RIGHT = LEFT + 278; +static const S32 FAR_RIGHT = LEFT + 324 + 40; + +static const char PRICE[] = "Price:"; +static const char NO_PRICE[] = ""; +static const char AREA[] = "Area:"; + static const char OWNER_ONLINE[] = "0"; static const char OWNER_OFFLINE[] = "1"; static const char OWNER_GROUP[] = "2"; @@ -80,16 +108,7 @@ static const char OWNER_GROUP[] = "2"; static const BOOL BUY_GROUP_LAND = TRUE; static const BOOL BUY_PERSONAL_LAND = FALSE; -// Values for the parcel voice settings radio group -enum -{ - kRadioVoiceChatEstate = 0, - kRadioVoiceChatPrivate = 1, - kRadioVoiceChatDisable = 2 -}; - // Statics -LLFloaterLand* LLFloaterLand::sInstance = NULL; LLParcelSelectionObserver* LLFloaterLand::sObserver = NULL; S32 LLFloaterLand::sLastTab = 0; @@ -150,64 +169,42 @@ void send_parcel_select_objects(S32 parcel_local_id, S32 return_type, } -// static -void LLFloaterLand::show() -{ - if (!sInstance) - { - sInstance = new LLFloaterLand(); - - // Select tab from last view - sInstance->mTabLand->selectTab(sLastTab); - - sObserver = new LLParcelSelectionObserver(); - gParcelMgr->addObserver( sObserver ); - } - - sInstance->open(); /*Flawfinder: ignore*/ - - // Done automatically when the selected parcel's properties arrive - // (and hence we have the local id). - // gParcelMgr->sendParcelAccessListRequest(AL_ACCESS | AL_BAN | AL_RENTER); - - sInstance->mParcel = gParcelMgr->getFloatingParcelSelection(); - - // Refresh even if not over a region so we don't get an - // uninitialized dialog. The dialog is 0-region aware. - sInstance->refresh(); -} - //static LLPanelLandObjects* LLFloaterLand::getCurrentPanelLandObjects() { - if (!sInstance) - { - return NULL; - } - - return sInstance->mPanelObjects; + return LLFloaterLand::getInstance()->mPanelObjects; } //static LLPanelLandCovenant* LLFloaterLand::getCurrentPanelLandCovenant() { - if (!sInstance) - { - return NULL; - } - - return sInstance->mPanelCovenant; + return LLFloaterLand::getInstance()->mPanelCovenant; } // static void LLFloaterLand::refreshAll() { - if (sInstance) - { - sInstance->refresh(); - } + LLFloaterLand::getInstance()->refresh(); +} + +void LLFloaterLand::onOpen() +{ + // Select tab from last view + mTabLand->selectTab(sLastTab); + + + // Done automatically when the selected parcel's properties arrive + // (and hence we have the local id). + // gParcelMgr->sendParcelAccessListRequest(AL_ACCESS | AL_BAN | AL_RENTER); + + mParcel = gParcelMgr->getFloatingParcelSelection(); + + // Refresh even if not over a region so we don't get an + // uninitialized dialog. The dialog is 0-region aware. + refresh(); } + // virtual void LLFloaterLand::onClose(bool app_quitting) { @@ -225,7 +222,7 @@ void LLFloaterLand::onClose(bool app_quitting) } -LLFloaterLand::LLFloaterLand() +LLFloaterLand::LLFloaterLand(const LLSD& seed) : LLFloater("floaterland", "FloaterLandRect5", "About Land") { @@ -242,7 +239,12 @@ LLFloaterLand::LLFloaterLand() gUICtrlFactory->buildFloater(this, "floater_about_land.xml", &factory_map); + sObserver = new LLParcelSelectionObserver(); + gParcelMgr->addObserver( sObserver ); +} +BOOL LLFloaterLand::postBuild() +{ LLTabContainerCommon* tab = LLUICtrlFactory::getTabContainerByName(this, "landtab"); mTabLand = (LLTabContainer*) tab; @@ -252,16 +254,16 @@ LLFloaterLand::LLFloaterLand() { tab->selectTab(sLastTab); } + + return TRUE; } // virtual LLFloaterLand::~LLFloaterLand() { - sInstance = NULL; } - // public void LLFloaterLand::refresh() { @@ -2214,239 +2216,7 @@ void LLPanelLandOptions::onClickPublishHelp(void*) } } -//--------------------------------------------------------------------------- -// LLPanelLandMedia -//--------------------------------------------------------------------------- - -LLPanelLandMedia::LLPanelLandMedia(LLParcelSelectionHandle& parcel) -: LLPanel("land_media_panel"), mParcel(parcel) -{ -} - - - -BOOL LLPanelLandMedia::postBuild() -{ - - mCheckSoundLocal = LLUICtrlFactory::getCheckBoxByName(this, "check sound local"); - childSetCommitCallback("check sound local", onCommitAny, this); - - mRadioVoiceChat = LLUICtrlFactory::getRadioGroupByName(this, "parcel_voice_channel"); - childSetCommitCallback("parcel_voice_channel", onCommitAny, this); - - mMusicURLEdit = LLUICtrlFactory::getLineEditorByName(this, "music_url"); - childSetCommitCallback("music_url", onCommitAny, this); - - - mMediaTextureCtrl = LLUICtrlFactory::getTexturePickerByName(this, "media texture"); - if (mMediaTextureCtrl) - { - mMediaTextureCtrl->setCommitCallback( onCommitAny ); - mMediaTextureCtrl->setCallbackUserData( this ); - mMediaTextureCtrl->setAllowNoTexture ( TRUE ); - mMediaTextureCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER); - mMediaTextureCtrl->setNonImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER); - } - else - { - llwarns << "LLUICtrlFactory::getTexturePickerByName() returned NULL for 'media texure'" << llendl; - } - - mMediaAutoScaleCheck = LLUICtrlFactory::getCheckBoxByName(this, "media_auto_scale"); - childSetCommitCallback("media_auto_scale", onCommitAny, this); - - mMediaURLEdit = LLUICtrlFactory::getLineEditorByName(this, "media_url"); - childSetCommitCallback("media_url", onCommitAny, this); - - return TRUE; -} - - -// virtual -LLPanelLandMedia::~LLPanelLandMedia() -{ } - - -// public -void LLPanelLandMedia::refresh() -{ - LLParcel *parcel = mParcel->getParcel(); - - if (!parcel) - { - mCheckSoundLocal->set(FALSE); - mCheckSoundLocal->setEnabled(FALSE); - - mRadioVoiceChat->setSelectedIndex(kRadioVoiceChatEstate); - mRadioVoiceChat->setEnabled(FALSE); - - mMusicURLEdit->setText(LLString::null); - mMusicURLEdit->setEnabled(FALSE); - - mMediaURLEdit->setText(LLString::null); - mMediaURLEdit->setEnabled(FALSE); - - mMediaAutoScaleCheck->set ( FALSE ); - mMediaAutoScaleCheck->setEnabled(FALSE); - - mMediaTextureCtrl->clear(); - mMediaTextureCtrl->setEnabled(FALSE); - - #if 0 - mMediaStopButton->setEnabled ( FALSE ); - mMediaStartButton->setEnabled ( FALSE ); - #endif - } - else - { - // something selected, hooray! - - // Display options - BOOL can_change_media = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_CHANGE_MEDIA); - - mCheckSoundLocal->set( parcel->getSoundLocal() ); - mCheckSoundLocal->setEnabled( can_change_media ); - - LLViewerRegion* selection_region = gParcelMgr->getSelectionRegion(); - BOOL region_allows_voice = FALSE; - if (selection_region) - { - region_allows_voice = selection_region->isVoiceEnabled(); - } - - if(parcel->getVoiceEnabled()) - { - if(parcel->getVoiceUseEstateChannel()) - mRadioVoiceChat->setSelectedIndex(kRadioVoiceChatEstate); - else - mRadioVoiceChat->setSelectedIndex(kRadioVoiceChatPrivate); - } - else - { - mRadioVoiceChat->setSelectedIndex(kRadioVoiceChatDisable); - } - - mRadioVoiceChat->setEnabled( can_change_media && region_allows_voice ); - - // don't display urls if you're not able to change it - // much requested change in forums so people can't 'steal' urls - // NOTE: bug#2009 means this is still vunerable - however, bug - // should be closed since this bug opens up major security issues elsewhere. - if ( can_change_media ) - { - mMusicURLEdit->setDrawAsterixes ( FALSE ); - mMediaURLEdit->setDrawAsterixes ( FALSE ); - } - else - { - mMusicURLEdit->setDrawAsterixes ( TRUE ); - mMediaURLEdit->setDrawAsterixes ( TRUE ); - } - - mMusicURLEdit->setText(parcel->getMusicURL()); - mMusicURLEdit->setEnabled( can_change_media ); - - mMediaURLEdit->setText(parcel->getMediaURL()); - mMediaURLEdit->setEnabled( can_change_media ); - - mMediaAutoScaleCheck->set ( parcel->getMediaAutoScale () ); - mMediaAutoScaleCheck->setEnabled ( can_change_media ); - - LLUUID tmp = parcel->getMediaID(); - mMediaTextureCtrl->setImageAssetID ( parcel->getMediaID() ); - mMediaTextureCtrl->setEnabled( can_change_media ); - - #if 0 - // there is a media url and a media texture selected - if ( ( ! ( std::string ( parcel->getMediaURL() ).empty () ) ) && ( ! ( parcel->getMediaID ().isNull () ) ) ) - { - // turn on transport controls if allowed for this parcel - mMediaStopButton->setEnabled ( editable ); - mMediaStartButton->setEnabled ( editable ); - } - else - { - // no media url or no media texture - mMediaStopButton->setEnabled ( FALSE ); - mMediaStartButton->setEnabled ( FALSE ); - }; - #endif - } -} - -// static -void LLPanelLandMedia::onCommitAny(LLUICtrl *ctrl, void *userdata) -{ - LLPanelLandMedia *self = (LLPanelLandMedia *)userdata; - - LLParcel* parcel = self->mParcel->getParcel(); - if (!parcel) - { - return; - } - - // Extract data from UI - BOOL sound_local = self->mCheckSoundLocal->get(); - int voice_setting = self->mRadioVoiceChat->getSelectedIndex(); - std::string music_url = self->mMusicURLEdit->getText(); - std::string media_url = self->mMediaURLEdit->getText(); - U8 media_auto_scale = self->mMediaAutoScaleCheck->get(); - LLUUID media_id = self->mMediaTextureCtrl->getImageAssetID(); - - BOOL voice_enabled; - BOOL voice_estate_chan; - - switch(voice_setting) - { - default: - case kRadioVoiceChatEstate: - voice_enabled = TRUE; - voice_estate_chan = TRUE; - break; - case kRadioVoiceChatPrivate: - voice_enabled = TRUE; - voice_estate_chan = FALSE; - break; - case kRadioVoiceChatDisable: - voice_enabled = FALSE; - voice_estate_chan = FALSE; - break; - } - - // Remove leading/trailing whitespace (common when copying/pasting) - LLString::trim(music_url); - LLString::trim(media_url); - - // Push data into current parcel - parcel->setParcelFlag(PF_ALLOW_VOICE_CHAT, voice_enabled); - parcel->setParcelFlag(PF_USE_ESTATE_VOICE_CHAN, voice_estate_chan); - parcel->setParcelFlag(PF_SOUND_LOCAL, sound_local); - parcel->setMusicURL(music_url.c_str()); - parcel->setMediaURL(media_url.c_str()); - parcel->setMediaID(media_id); - parcel->setMediaAutoScale ( media_auto_scale ); - - // Send current parcel data upstream to server - gParcelMgr->sendParcelPropertiesUpdate( parcel ); - - // Might have changed properties, so let's redraw! - self->refresh(); -} - -void LLPanelLandMedia::onClickStopMedia ( void* data ) -{ - LLMediaEngine::getInstance ()->stop (); -} - -void LLPanelLandMedia::onClickStartMedia ( void* data ) -{ - // force a commit - gFocusMgr.setKeyboardFocus ( NULL ); - - // force a reload - LLMediaEngine::getInstance ()->convertImageAndLoadUrl ( true, false, std::string()); -} //--------------------------------------------------------------------------- // LLPanelLandAccess diff --git a/indra/newview/llfloaterland.h b/indra/newview/llfloaterland.h index 8b77bb990a1..e504e27f21e 100644 --- a/indra/newview/llfloaterland.h +++ b/indra/newview/llfloaterland.h @@ -68,13 +68,9 @@ class LLPanelLandRenters; class LLPanelLandCovenant; class LLFloaterLand -: public LLFloater +: public LLFloater, public LLUISingleton<LLFloaterLand> { public: - // Call show() to open a land floater. - // Will query the viewer parcel manager to see what is selected. - static void show(); - static BOOL floaterVisible() { return sInstance && sInstance->getVisible(); } static void refreshAll(); static LLPanelLandObjects* getCurrentPanelLandObjects(); @@ -82,11 +78,15 @@ class LLFloaterLand // Destroys itself on close. virtual void onClose(bool app_quitting); + virtual void onOpen(); + virtual BOOL postBuild(); protected: + friend class LLUISingleton<LLFloaterLand>; + // Does its own instance management, so clients not allowed // to allocate or destroy. - LLFloaterLand(); + LLFloaterLand(const LLSD& seed); virtual ~LLFloaterLand(); void refresh(); @@ -102,7 +102,6 @@ class LLFloaterLand protected: - static LLFloaterLand* sInstance; static LLParcelSelectionObserver* sObserver; static S32 sLastTab; @@ -344,35 +343,6 @@ class LLPanelLandOptions }; -class LLPanelLandMedia -: public LLPanel -{ -public: - LLPanelLandMedia(LLHandle<LLParcelSelection>& parcelp); - virtual ~LLPanelLandMedia(); - void refresh(); - - static void onCommitAny(LLUICtrl* ctrl, void *userdata); - static void onClickStopMedia ( void* data ); - static void onClickStartMedia ( void* data ); - - virtual BOOL postBuild(); - -protected: - LLCheckBoxCtrl* mCheckSoundLocal; - LLRadioGroup* mRadioVoiceChat; - LLLineEditor* mMusicURLEdit; - LLLineEditor* mMediaURLEdit; - LLTextureCtrl* mMediaTextureCtrl; - LLCheckBoxCtrl* mMediaAutoScaleCheck; - //LLButton* mMediaStopButton; - //LLButton* mMediaStartButton; - - LLHandle<LLParcelSelection>& mParcel; -}; - - - class LLPanelLandAccess : public LLPanel { diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 8d77d79d83b..060952667b7 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -150,11 +150,9 @@ LLPreferenceCore::LLPreferenceCore(LLTabContainerCommon* tab_container, LLButton mTabContainer->addTabPanel(mNetworkPanel, mNetworkPanel->getLabel(), FALSE, onTabChanged, mTabContainer); mNetworkPanel->setDefaultBtn(default_btn); - #if LL_LIBXUL_ENABLED mWebPanel = new LLPanelWeb(); mTabContainer->addTabPanel(mWebPanel, mWebPanel->getLabel(), FALSE, onTabChanged, mTabContainer); mWebPanel->setDefaultBtn(default_btn); - #endif mDisplayPanel = new LLPanelDisplay(); mTabContainer->addTabPanel(mDisplayPanel, mDisplayPanel->getLabel(), FALSE, onTabChanged, mTabContainer); @@ -257,13 +255,11 @@ LLPreferenceCore::~LLPreferenceCore() delete mMsgPanel; mMsgPanel = NULL; } - #if LL_LIBXUL_ENABLED if (mWebPanel) { delete mWebPanel; mWebPanel = NULL; } - #endif } @@ -279,9 +275,7 @@ void LLPreferenceCore::apply() mPrefsVoice->apply(); mPrefsIM->apply(); mMsgPanel->apply(); - #if LL_LIBXUL_ENABLED mWebPanel->apply(); - #endif #if LL_WINDOWS && LL_LCD_COMPILE // only add this option if we actually have a logitech keyboard / speaker set if (gLcdScreen->Enabled()) @@ -306,9 +300,7 @@ void LLPreferenceCore::cancel() mPrefsVoice->cancel(); mPrefsIM->cancel(); mMsgPanel->cancel(); - #if LL_LIBXUL_ENABLED mWebPanel->cancel(); - #endif #if LL_WINDOWS && LL_LCD_COMPILE // only add this option if we actually have a logitech keyboard / speaker set if (gLcdScreen->Enabled()) diff --git a/indra/newview/llfloatertos.cpp b/indra/newview/llfloatertos.cpp index 20f9e1ecd40..bdf583126f9 100644 --- a/indra/newview/llfloatertos.cpp +++ b/indra/newview/llfloatertos.cpp @@ -145,7 +145,6 @@ BOOL LLFloaterTOS::postBuild() return TRUE; } -#if LL_LIBXUL_ENABLED // disable Agree to TOS radio button until the page has fully loaded LLRadioGroup* tos_agreement = LLUICtrlFactory::getRadioGroupByName(this, "tos_agreement"); if ( tos_agreement ) @@ -172,18 +171,6 @@ BOOL LLFloaterTOS::postBuild() gResponsePtr = LLIamHere::build( this ); LLHTTPClient::get( childGetValue( "real_url" ).asString(), gResponsePtr ); }; -#else - LLTextEditor *Editor = LLUICtrlFactory::getTextEditorByName(this, "tos_text"); - if (Editor) - { - Editor->setHandleEditKeysDirectly( TRUE ); - Editor->setEnabled( FALSE ); - Editor->setReadOnlyFgColor(LLColor4::white); - Editor->setWordWrap(TRUE); - Editor->setFocus(TRUE); - } - childSetValue("tos_text", LLSD(mMessage)); -#endif return TRUE; } @@ -193,7 +180,6 @@ void LLFloaterTOS::setSiteIsAlive( bool alive ) // only do this for TOS pages if ( mType == TOS_TOS ) { -#if LL_LIBXUL_ENABLED LLWebBrowserCtrl* web_browser = LLUICtrlFactory::getWebBrowserCtrlByName(this, "tos_html"); // if the contents of the site was retrieved if ( alive ) @@ -220,20 +206,17 @@ void LLFloaterTOS::setSiteIsAlive( bool alive ) web_browser->setVisible( FALSE ); }; }; -#endif // LL_LIBXUL_ENABLED }; } LLFloaterTOS::~LLFloaterTOS() { -#if LL_LIBXUL_ENABLED // stop obsaerving events LLWebBrowserCtrl* web_browser = LLUICtrlFactory::getWebBrowserCtrlByName(this, "tos_html"); if ( web_browser ) { web_browser->addObserver( this ); }; -#endif // LL_LIBXUL_ENABLED // tell the responder we're not here anymore if ( gResponsePtr ) diff --git a/indra/newview/llfloaterurlentry.cpp b/indra/newview/llfloaterurlentry.cpp new file mode 100644 index 00000000000..1ad9e0577c0 --- /dev/null +++ b/indra/newview/llfloaterurlentry.cpp @@ -0,0 +1,268 @@ +/** + * @file llfloaterurlentry.cpp + * @brief LLFloaterURLEntry class implementation + * + * Copyright (c) 2002-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloaterurlentry.h" + +#include "llpanellandmedia.h" + +// project includes +#include "llcombobox.h" +#include "llurlhistory.h" +#include "llvieweruictrlfactory.h" +#include "llwindow.h" +#include "llviewerwindow.h" + +static LLFloaterURLEntry* sInstance = NULL; + +// Move this to its own file. +// helper class that tries to download a URL from a web site and calls a method +// on the Panel Land Media and to discover the MIME type +class LLMediaTypeResponder : public LLHTTPClient::Responder +{ +public: + LLMediaTypeResponder( LLViewHandle parent ) : + mParent( parent ) + {} + + LLViewHandle mParent; + + + virtual void completedHeader(U32 status, const std::string& reason, const LLSD& content) + { + std::string media_type = content["content-type"].asString(); + std::string::size_type idx1 = media_type.find_first_of(";"); + std::string mime_type = media_type.substr(0, idx1); + completeAny(status, mime_type); + } + + virtual void error( U32 status, const std::string& reason ) + { + completeAny(status, "none/none"); + } + + void completeAny(U32 status, const std::string& mime_type) + { + LLFloaterURLEntry* floater_url_entry = + (LLFloaterURLEntry*)LLFloater::getFloaterByHandle(mParent); + if ( floater_url_entry ) + floater_url_entry->headerFetchComplete( status, mime_type ); + } +}; + +//----------------------------------------------------------------------------- +// LLFloaterURLEntry() +//----------------------------------------------------------------------------- +LLFloaterURLEntry::LLFloaterURLEntry(LLViewHandle parent) + : + LLFloater(), + mPanelLandMediaHandle(parent) +{ + gUICtrlFactory->buildFloater(this, "floater_url_entry.xml"); + + mMediaURLEdit = LLUICtrlFactory::getComboBoxByName(this, "media_entry"); + + // Cancel button + childSetAction("cancel_btn", onBtnCancel, this); + + // Cancel button + childSetAction("clear_btn", onBtnClear, this); + + // clear media list button + LLSD parcel_history = LLURLHistory::getURLHistory("parcel"); + bool enable_clear_button = parcel_history.size() > 0 ? true : false; + childSetEnabled( "clear_btn", enable_clear_button ); + + // OK button + childSetAction("ok_btn", onBtnOK, this); + + setDefaultBtn("ok_btn"); + buildURLHistory(); + + sInstance = this; +} + +//----------------------------------------------------------------------------- +// ~LLFloaterURLEntry() +//----------------------------------------------------------------------------- +LLFloaterURLEntry::~LLFloaterURLEntry() +{ + sInstance = NULL; +} + +void LLFloaterURLEntry::buildURLHistory() +{ + LLCtrlListInterface* url_list = childGetListInterface("media_entry"); + if (url_list) + { + url_list->operateOnAll(LLCtrlListInterface::OP_DELETE); + } + + // Get all of the entries in the "parcel" collection + LLSD parcel_history = LLURLHistory::getURLHistory("parcel"); + + LLSD::array_iterator iter_history = + parcel_history.beginArray(); + LLSD::array_iterator end_history = + parcel_history.endArray(); + for(; iter_history != end_history; ++iter_history) + { + url_list->addSimpleElement((*iter_history).asString()); + } +} + +void LLFloaterURLEntry::headerFetchComplete(U32 status, const std::string& mime_type) +{ + LLPanelLandMedia* panel_media = (LLPanelLandMedia*)LLPanel::getPanelByHandle(mPanelLandMediaHandle); + if (panel_media) + { + // status is ignored for now -- error = "none/none" + panel_media->setMediaType(mime_type); + panel_media->setMediaURL(mMediaURLEdit->getValue().asString()); + } + // Decrement the cursor + getWindow()->decBusyCount(); + childSetVisible("loading_label", false); + close(); +} + +// static +LLViewHandle LLFloaterURLEntry::show(LLViewHandle parent) +{ + if (sInstance) + { + sInstance->open(); + } + else + { + sInstance = new LLFloaterURLEntry(parent); + } + sInstance->updateFromLandMediaPanel(); + return sInstance->getHandle(); +} + +void LLFloaterURLEntry::updateFromLandMediaPanel() +{ + LLPanelLandMedia* panel_media = (LLPanelLandMedia*)LLPanel::getPanelByHandle(mPanelLandMediaHandle); + if (panel_media) + { + std::string media_url = panel_media->getMediaURL(); + addURLToCombobox(media_url); + } +} + +bool LLFloaterURLEntry::addURLToCombobox(const std::string& media_url) +{ + if(! mMediaURLEdit->setSimple( media_url ) && ! media_url.empty()) + { + mMediaURLEdit->add( media_url ); + mMediaURLEdit->setSimple( media_url ); + return true; + } + + // URL was not added for whatever reason (either it was empty or already existed) + return false; +} + +// static +//----------------------------------------------------------------------------- +// onBtnOK() +//----------------------------------------------------------------------------- +void LLFloaterURLEntry::onBtnOK( void* userdata ) +{ + LLFloaterURLEntry *self =(LLFloaterURLEntry *)userdata; + + std::string media_url = self->mMediaURLEdit->getValue().asString(); + self->mMediaURLEdit->remove(media_url); + LLURLHistory::removeURL("parcel", media_url); + if(self->addURLToCombobox(media_url)) + { + // Add this url to the parcel collection + LLURLHistory::addURL("parcel", media_url); + } + + // leading whitespace causes problems with the MIME-type detection so strip it + LLString::trim( media_url ); + + // First check the URL scheme + LLURI url(media_url); + std::string scheme = url.scheme(); + + // We assume that an empty scheme is an http url, as this is how we will treat it. + if(scheme == "") + { + scheme = "http"; + } + + // Discover the MIME type only for "http" scheme. + if(scheme == "http") + { + LLHTTPClient::getHeaderOnly( media_url, + new LLMediaTypeResponder(self->getHandle())); + } + else + { + self->headerFetchComplete(0, scheme); + } + + // Grey the buttons until we get the header response + self->childSetEnabled("ok_btn", false); + self->childSetEnabled("cancel_btn", false); + self->childSetEnabled("media_entry", false); + + // show progress bar here? + getWindow()->incBusyCount(); + self->childSetVisible("loading_label", true); +} + +// static +//----------------------------------------------------------------------------- +// onBtnCancel() +//----------------------------------------------------------------------------- +void LLFloaterURLEntry::onBtnCancel( void* userdata ) +{ + LLFloaterURLEntry *self =(LLFloaterURLEntry *)userdata; + self->close(); +} + +// static +//----------------------------------------------------------------------------- +// onBtnClear() +//----------------------------------------------------------------------------- +void LLFloaterURLEntry::onBtnClear( void* userdata ) +{ + gViewerWindow->alertXml( "ConfirmClearMediaUrlList", callback_clear_url_list, userdata ); +} + +void LLFloaterURLEntry::callback_clear_url_list(S32 option, void* userdata) +{ + if ( option == 0 ) // YES + { + LLFloaterURLEntry *self =(LLFloaterURLEntry *)userdata; + + if ( self ) + { + // clear saved list + LLCtrlListInterface* url_list = self->childGetListInterface("media_entry"); + if ( url_list ) + { + url_list->operateOnAll( LLCtrlListInterface::OP_DELETE ); + } + + // clear current contents of combo box + self->mMediaURLEdit->clear(); + + // clear stored version of list + LLURLHistory::clear("parcel"); + + // cleared the list so disable Clear button + self->childSetEnabled( "clear_btn", false ); + } + } +} diff --git a/indra/newview/llfloaterurlentry.h b/indra/newview/llfloaterurlentry.h new file mode 100644 index 00000000000..022c1eddd70 --- /dev/null +++ b/indra/newview/llfloaterurlentry.h @@ -0,0 +1,44 @@ +/** + * @file llfloaternamedesc.h + * @brief LLFloaterNameDesc class definition + * + * Copyright (c) 2002-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#ifndef LL_LLFLOATERURLENTRY_H +#define LL_LLFLOATERURLENTRY_H + +#include "llfloater.h" + +class LLLineEditor; + +class LLFloaterURLEntry : public LLFloater +{ +public: + // Can only be shown by LLPanelLandMedia, and pushes data back into + // that panel via the handle. + static LLViewHandle show(LLViewHandle panel_land_media_handle); + + void updateFromLandMediaPanel(); + + void headerFetchComplete(U32 status, const std::string& mime_type); + + bool addURLToCombobox(const std::string& media_url); + +private: + LLFloaterURLEntry(LLViewHandle parent); + /*virtual*/ ~LLFloaterURLEntry(); + void buildURLHistory(); + +private: + LLComboBox* mMediaURLEdit; + LLViewHandle mPanelLandMediaHandle; + + static void onBtnOK(void*); + static void onBtnCancel(void*); + static void onBtnClear(void*); + static void callback_clear_url_list(S32 option, void* userdata); +}; + +#endif // LL_LLFLOATERURLENTRY_H diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp index ba56d70c0a7..29b739bca36 100644 --- a/indra/newview/llglsandbox.cpp +++ b/indra/newview/llglsandbox.cpp @@ -851,11 +851,11 @@ void LLViewerParcelMgr::renderCollisionSegments(U8* segments, BOOL use_pass, LLV if (use_pass && (mCollisionBanned == BA_NOT_ON_LIST)) { - LLViewerImage::bindTexture(mPassImage); + LLViewerImage::bindTexture( getPassImage() ); } else { - LLViewerImage::bindTexture(mBlockedImage); + LLViewerImage::bindTexture( getBlockedImage() ); } glBegin(GL_QUADS); diff --git a/indra/newview/llmimetypes.cpp b/indra/newview/llmimetypes.cpp new file mode 100644 index 00000000000..3c4dab8e049 --- /dev/null +++ b/indra/newview/llmimetypes.cpp @@ -0,0 +1,241 @@ +/** + * @file llmimetypes.cpp + * @author James Cook + * @brief Translates a MIME type like "video/quicktime" into a + * localizable user-friendly string like "QuickTime Movie" + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ +#include "llviewerprecompiledheaders.h" + +#include "llmimetypes.h" + +#include "llvieweruictrlfactory.h" + +LLMIMETypes::mime_info_map_t LLMIMETypes::sMap; +LLMIMETypes::mime_widget_set_map_t LLMIMETypes::sWidgetMap; + +LLString sDefaultLabel; + // Returned when we don't know what to do with the mime type +LLString sDefaultWidgetType; + // Returned when we don't know what widget set to use +LLString sDefaultImpl; + // Returned when we don't know what impl to use + +///////////////////////////////////////////////////////////////////////////// + +// static +bool LLMIMETypes::parseMIMETypes(const LLString& xml_filename) +{ + LLXMLNodePtr root; + bool success = LLViewerUICtrlFactory::getLayeredXMLNode(xml_filename, root); + if (!success || !root || !root->hasName("mimetypes")) + { + llwarns << "Unable to read MIME type file: " + << xml_filename << llendl; + return false; + } + + for (LLXMLNode* node = root->getFirstChild(); + node != NULL; + node = node->getNextSibling()) + { + if (node->hasName("defaultlabel")) + { + sDefaultLabel = node->getTextContents(); + } + else if (node->hasName("defaultwidget")) + { + sDefaultWidgetType = node->getTextContents(); + } + else if (node->hasName("defaultimpl")) + { + sDefaultImpl = node->getTextContents(); + } + else if (node->hasName("mimetype") || node->hasName("scheme")) + { + LLString mime_type; + node->getAttributeString("name", mime_type); + LLMIMEInfo info; + for (LLXMLNode* child = node->getFirstChild(); + child != NULL; + child = child->getNextSibling()) + { + if (child->hasName("label")) + { + info.mLabel = child->getTextContents(); + } + else if (child->hasName("widgettype")) + { + info.mWidgetType = child->getTextContents(); + } + else if (child->hasName("impl")) + { + info.mImpl = child->getTextContents(); + } + } + sMap[mime_type] = info; + } + else if (node->hasName("widgetset")) + { + LLString set_name; + node->getAttributeString("name", set_name); + LLMIMEWidgetSet info; + for (LLXMLNode* child = node->getFirstChild(); + child != NULL; + child = child->getNextSibling()) + { + if (child->hasName("label")) + { + info.mLabel = child->getTextContents(); + } + if (child->hasName("icon")) + { + info.mIcon = child->getTextContents(); + } + if (child->hasName("default_type")) + { + info.mDefaultMimeType = child->getTextContents(); + } + if (child->hasName("tooltip")) + { + info.mToolTip = child->getTextContents(); + } + if (child->hasName("playtip")) + { + info.mPlayTip = child->getTextContents(); + } + if (child->hasName("allow_resize")) + { + child->getBoolValue( 1, (BOOL*)&( info.mAllowResize ) ); + } + if (child->hasName("allow_looping")) + { + child->getBoolValue( 1, (BOOL*)&( info.mAllowLooping ) ); + } + } + sWidgetMap[set_name] = info; + } + } + return true; +} + +// static +LLString LLMIMETypes::translate(const LLString& mime_type) +{ + mime_info_map_t::const_iterator it = sMap.find(mime_type); + if (it != sMap.end()) + { + return it->second.mLabel; + } + else + { + return sDefaultLabel; + } +} + +// static +LLString LLMIMETypes::widgetType(const LLString& mime_type) +{ + mime_info_map_t::const_iterator it = sMap.find(mime_type); + if (it != sMap.end()) + { + return it->second.mWidgetType; + } + else + { + return sDefaultWidgetType; + } +} + +// static +LLString LLMIMETypes::implType(const LLString& mime_type) +{ + mime_info_map_t::const_iterator it = sMap.find(mime_type); + if (it != sMap.end()) + { + return it->second.mImpl; + } + else + { + return sDefaultImpl; + } +} + +// static +LLString LLMIMETypes::findIcon(const LLString& mime_type) +{ + LLString icon = ""; + LLString widget_type = LLMIMETypes::widgetType(mime_type); + mime_widget_set_map_t::iterator it = sWidgetMap.find(widget_type); + if(it != sWidgetMap.end()) + { + icon = it->second.mIcon; + } + return icon; +} + +// static +LLString LLMIMETypes::findDefaultMimeType(const LLString& widget_type) +{ + LLString mime_type = "none/none"; + mime_widget_set_map_t::iterator it = sWidgetMap.find(widget_type); + if(it != sWidgetMap.end()) + { + mime_type = it->second.mDefaultMimeType; + } + return mime_type; +} + +// static +LLString LLMIMETypes::findToolTip(const LLString& mime_type) +{ + LLString tool_tip = ""; + LLString widget_type = LLMIMETypes::widgetType(mime_type); + mime_widget_set_map_t::iterator it = sWidgetMap.find(widget_type); + if(it != sWidgetMap.end()) + { + tool_tip = it->second.mToolTip; + } + return tool_tip; +} + +// static +LLString LLMIMETypes::findPlayTip(const LLString& mime_type) +{ + LLString play_tip = ""; + LLString widget_type = LLMIMETypes::widgetType(mime_type); + mime_widget_set_map_t::iterator it = sWidgetMap.find(widget_type); + if(it != sWidgetMap.end()) + { + play_tip = it->second.mPlayTip; + } + return play_tip; +} + +// static +bool LLMIMETypes::findAllowResize(const LLString& mime_type) +{ + bool allow_resize = false; + LLString widget_type = LLMIMETypes::widgetType(mime_type); + mime_widget_set_map_t::iterator it = sWidgetMap.find(widget_type); + if(it != sWidgetMap.end()) + { + allow_resize = it->second.mAllowResize; + } + return allow_resize; +} + +// static +bool LLMIMETypes::findAllowLooping(const LLString& mime_type) +{ + bool allow_looping = false; + LLString widget_type = LLMIMETypes::widgetType(mime_type); + mime_widget_set_map_t::iterator it = sWidgetMap.find(widget_type); + if(it != sWidgetMap.end()) + { + allow_looping = it->second.mAllowLooping; + } + return allow_looping; +} diff --git a/indra/newview/llmimetypes.h b/indra/newview/llmimetypes.h new file mode 100644 index 00000000000..1c309477a21 --- /dev/null +++ b/indra/newview/llmimetypes.h @@ -0,0 +1,95 @@ +/** + * @file llmimetypes.h + * @author James Cook + * @brief Translates a MIME type like "video/quicktime" into a + * localizable user-friendly string like "QuickTime Movie" + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ +#ifndef LLMIMETYPES_H +#define LLMIMETYPES_H + +#include "llstring.h" // because XML parsing lib uses LLString, ugh +#include <map> + +class LLMIMETypes +{ +public: + static bool parseMIMETypes(const LLString& xml_file_path); + // Loads the MIME string definition XML file, usually + // from the application skins directory + + static LLString translate(const LLString& mime_type); + // Returns "QuickTime Movie" from "video/quicktime" + + static LLString widgetType(const LLString& mime_type); + // Type of control widgets for this MIME type + // Returns "movie" from "video/quicktime" + + static LLString implType(const LLString& mime_type); + // Type of Impl to use for decoding media. + + static LLString findIcon(const LLString& mime_type); + // Icon from control widget type for this MIME type + + static LLString findToolTip(const LLString& mime_type); + // Tool tip from control widget type for this MIME type + + static LLString findPlayTip(const LLString& mime_type); + // Play button tool tip from control widget type for this MIME type + + static LLString findDefaultMimeType(const LLString& widget_type); + // Canonical mime type associated with this widget set + + static bool findAllowResize(const LLString& mime_type); + // accessor for flag to enable/disable media size edit fields + + static bool LLMIMETypes::findAllowLooping(const LLString& mime_type); + // accessor for flag to enable/disable media looping checkbox + +public: + struct LLMIMEInfo + { + LLString mLabel; + // friendly label like "QuickTime Movie" + + LLString mWidgetType; + // "web" means use web media UI widgets + + LLString mImpl; + // which impl to use with this mime type + }; + struct LLMIMEWidgetSet + { + LLString mLabel; + // friendly label like "QuickTime Movie" + + LLString mIcon; + // Name of icon asset to display in toolbar + + LLString mDefaultMimeType; + // Mime type string to use in absence of a specific one + + LLString mToolTip; + // custom tool tip for this mime type + + LLString mPlayTip; + // custom tool tip to display for Play button + + bool mAllowResize; + // enable/disable media size edit fields + + bool mAllowLooping; + // enable/disable media looping checkbox + }; + typedef std::map< LLString, LLMIMEInfo > mime_info_map_t; + typedef std::map< LLString, LLMIMEWidgetSet > mime_widget_set_map_t; + + // Public so users can iterate over it + static mime_info_map_t sMap; + static mime_widget_set_map_t sWidgetMap; +private: +}; + +#endif diff --git a/indra/newview/lloverlaybar.cpp b/indra/newview/lloverlaybar.cpp index 15195d8f02b..2c33cccf718 100644 --- a/indra/newview/lloverlaybar.cpp +++ b/indra/newview/lloverlaybar.cpp @@ -42,7 +42,6 @@ #include "llchatbar.h" #include "llfocusmgr.h" #include "llimview.h" -#include "llmediaengine.h" #include "llmediaremotectrl.h" #include "llpanelaudiovolume.h" #include "llparcel.h" @@ -50,7 +49,10 @@ #include "llui.h" #include "llviewercontrol.h" #include "llviewerimagelist.h" +#include "llviewermedia.h" #include "llviewermenu.h" // handle_reset_view() +#include "llviewermedia.h" +#include "llviewerparcelmedia.h" #include "llviewerparcelmgr.h" #include "llvieweruictrlfactory.h" #include "llviewerwindow.h" @@ -97,7 +99,6 @@ LLOverlayBar::LLOverlayBar() : LLPanel(), mMediaRemote(NULL), mVoiceRemote(NULL), - mMediaState(STOPPED), mMusicState(STOPPED) { setMouseOpaque(FALSE); @@ -220,7 +221,7 @@ void LLOverlayBar::refresh() BOOL controls_grabbed = gAgent.anyControlGrabbed(); button = LLUICtrlFactory::getButtonByName(this, "Release Keys"); - + if (button && button->getVisible() != controls_grabbed) { button->setVisible(controls_grabbed); @@ -231,7 +232,7 @@ void LLOverlayBar::refresh() BOOL mouselook_grabbed; mouselook_grabbed = gAgent.isControlGrabbed(CONTROL_ML_LBUTTON_DOWN_INDEX) - || gAgent.isControlGrabbed(CONTROL_ML_LBUTTON_UP_INDEX); + || gAgent.isControlGrabbed(CONTROL_ML_LBUTTON_UP_INDEX); button = LLUICtrlFactory::getButtonByName(this, "Mouselook"); if (button && button->getVisible() != mouselook_grabbed) @@ -257,7 +258,6 @@ void LLOverlayBar::refresh() buttons_changed = TRUE; } - enableMediaButtons(); moveChildToBackOfTabGroup(mMediaRemote); moveChildToBackOfTabGroup(mVoiceRemote); @@ -340,24 +340,40 @@ void LLOverlayBar::mediaPlay(void*) return; } - if (gOverlayBar->mMediaState != PLAYING) + + if (LLViewerMedia::isMediaPaused()) + { + LLViewerParcelMedia::start(); + } + else if(LLViewerMedia::isMediaPlaying()) + { + LLViewerParcelMedia::pause(); + } + else { - gOverlayBar->mMediaState = PLAYING; // desired state LLParcel* parcel = gParcelMgr->getAgentParcel(); if (parcel) { - LLString path(""); - LLMediaEngine::getInstance()->convertImageAndLoadUrl( true, false, path ); + LLViewerParcelMedia::play(parcel); } } - else +} + +//static +void LLOverlayBar::mediaPause(void*) +{ + + LLViewerParcelMedia::pause(); +} + +//static +void LLOverlayBar::mediaStop(void*) +{ + if (!gOverlayBar) { - gOverlayBar->mMediaState = PAUSED; // desired state - LLMediaEngine::getInstance()->pause(); + return; } - - //gOverlayBar->mMediaState = STOPPED; // desired state - //LLMediaEngine::getInstance()->stop(); + LLViewerParcelMedia::stop(); } //static @@ -403,39 +419,3 @@ void LLOverlayBar::musicPlay(void*) } } -void LLOverlayBar::enableMediaButtons() -{ - if (mMediaRemote) - { - // Music - LLParcel* parcel = gParcelMgr->getAgentParcel(); - if (parcel - && gAudiop - && !parcel->getMusicURL().empty() - && gSavedSettings.getBOOL("AudioStreamingMusic")) - { - mMediaRemote->childSetEnabled("music_play", TRUE); - } - else - { - mMediaRemote->childSetEnabled("music_play", FALSE); - } - - // Media - // if there is a url and a texture and media is enabled and available and media streaming is on... (phew!) - if (LLMediaEngine::getInstance() - && LLMediaEngine::getInstance()->getUrl ().length () - && LLMediaEngine::getInstance()->getImageUUID ().notNull () - && LLMediaEngine::getInstance()->isEnabled () - && LLMediaEngine::getInstance()->isAvailable () - && gSavedSettings.getBOOL ( "AudioStreamingVideo" ) ) - { - mMediaRemote->childSetEnabled("media_play", TRUE); - } - else - { - mMediaRemote->childSetEnabled("media_play", FALSE); - } - } -} - diff --git a/indra/newview/lloverlaybar.h b/indra/newview/lloverlaybar.h index 90886e1c729..90ab8d057a6 100644 --- a/indra/newview/lloverlaybar.h +++ b/indra/newview/lloverlaybar.h @@ -67,7 +67,6 @@ class LLOverlayBar void layoutButtons(); // helpers for returning desired state - BOOL mediaPlaying() { return mMediaState == PLAYING; } BOOL musicPlaying() { return mMusicState == PLAYING; } static void onClickIMReceived(void* data); @@ -79,7 +78,14 @@ class LLOverlayBar //static media helper functions static void mediaPlay(void*); + static void mediaPause(void*); + static void mediaStop(void*); + static void musicPlay(void*); + static void musicPause(void*); + static void musicStop(void*); + + static void toggleAudioVolumeFloater(void*); protected: static void* createMediaRemote(void* userdata); @@ -93,8 +99,7 @@ class LLOverlayBar LLVoiceRemoteCtrl* mVoiceRemote; bool mBuilt; // dialog constructed yet? enum { STOPPED=0, PLAYING=1, PAUSED=2 }; - BOOL mMediaState; - BOOL mMusicState; + S32 mMusicState; }; extern LLOverlayBar* gOverlayBar; diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index 0146214c4bd..d9416bbf373 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -495,7 +495,6 @@ BOOL LLPanelAvatarWeb::postBuild(void) childSetControlName("auto_load","AutoLoadWebProfiles"); -#if LL_LIBXUL_ENABLED mWebBrowser = (LLWebBrowserCtrl*)getChildByName("profile_html"); // links open in internally @@ -503,7 +502,6 @@ BOOL LLPanelAvatarWeb::postBuild(void) // observe browser events mWebBrowser->addObserver( this ); -#endif // LL_LIBXUL_ENABLED return TRUE; } @@ -563,13 +561,11 @@ LLPanelAvatarWeb::LLPanelAvatarWeb(const std::string& name, const LLRect& rect, LLPanelAvatarWeb::~LLPanelAvatarWeb() { -#if LL_LIBXUL_ENABLED // stop observing browser events if ( mWebBrowser ) { mWebBrowser->remObserver( this ); }; -#endif } void LLPanelAvatarWeb::enableControls(BOOL self) @@ -606,12 +602,6 @@ void LLPanelAvatarWeb::setWebURL(std::string url) childSetVisible("profile_html",false); } -#if !LL_LIBXUL_ENABLED - childSetVisible("load",false); - childSetVisible("profile_html",false); - childSetVisible("status_text",false); -#endif - } // static @@ -627,18 +617,13 @@ void LLPanelAvatarWeb::onCommitURL(LLUICtrl* ctrl, void* data) // static void LLPanelAvatarWeb::onClickWebProfileHelp(void *) { -#if LL_LIBXUL_ENABLED gViewerWindow->alertXml("ClickWebProfileHelpAvatar"); -#else - gViewerWindow->alertXml("ClickWebProfileNoWebHelpAvatar"); -#endif } void LLPanelAvatarWeb::load(std::string url) { bool have_url = (!url.empty()); -#if LL_LIBXUL_ENABLED if (have_url) { llinfos << "Loading " << url << llendl; @@ -658,9 +643,6 @@ void LLPanelAvatarWeb::load(std::string url) childSetEnabled("home",use_home); childSetEnabled("open",have_url); -#else - childSetEnabled("open",have_url); -#endif } void LLPanelAvatarWeb::load() @@ -692,7 +674,6 @@ void LLPanelAvatarWeb::onClickOpen(void* data) } } -#if LL_LIBXUL_ENABLED void LLPanelAvatarWeb::onStatusTextChange( const EventType& eventIn ) { childSetText("status_text", eventIn.getStringValue() ); @@ -702,7 +683,6 @@ void LLPanelAvatarWeb::onLocationChange( const EventType& eventIn ) { childSetText("url_edit", eventIn.getStringValue() ); } -#endif //----------------------------------------------------------------------------- diff --git a/indra/newview/llpanelavatar.h b/indra/newview/llpanelavatar.h index 7d491c61436..d992c29304e 100644 --- a/indra/newview/llpanelavatar.h +++ b/indra/newview/llpanelavatar.h @@ -137,9 +137,7 @@ class LLPanelAvatarSecondLife // WARNING! The order of the inheritance here matters!! Do not change. - KLW class LLPanelAvatarWeb : public LLPanelAvatarTab -#if LL_LIBXUL_ENABLED , public LLWebBrowserCtrlObserver -#endif { public: LLPanelAvatarWeb(const std::string& name, const LLRect& rect, LLPanelAvatar* panel_avatar); @@ -157,11 +155,9 @@ class LLPanelAvatarWeb : static void onCommitURL(LLUICtrl* ctrl, void* data); static void onClickWebProfileHelp(void *); -#if LL_LIBXUL_ENABLED // browser observer impls virtual void onStatusTextChange( const EventType& eventIn ); virtual void onLocationChange( const EventType& eventIn ); -#endif private: std::string mURL; diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 8ce2ae5d9cd..83fc991ae04 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -57,10 +57,9 @@ #include "lltooldraganddrop.h" #include "llui.h" #include "llviewercontrol.h" +#include "llviewermedia.h" #include "llviewerobject.h" #include "llviewerstats.h" -#include "llmediaengine.h" - #include "llvieweruictrlfactory.h" // @@ -374,14 +373,19 @@ void LLPanelFace::getState() childSetEnabled("button align",FALSE); //mBtnAutoFix->setEnabled ( FALSE ); - if ( LLMediaEngine::getInstance()->getMediaRenderer () ) - if ( LLMediaEngine::getInstance()->getMediaRenderer ()->isLoaded () ) - { - childSetEnabled("textbox autofix",editable); - //mLabelTexAutoFix->setEnabled ( editable ); - childSetEnabled("button align",editable); - //mBtnAutoFix->setEnabled ( editable ); - } + if(LLViewerMedia::hasMedia()) + { + childSetEnabled("textbox autofix",editable); + childSetEnabled("button align",editable); + } + //if ( LLMediaEngine::getInstance()->getMediaRenderer () ) + // if ( LLMediaEngine::getInstance()->getMediaRenderer ()->isLoaded () ) + // { + // + // //mLabelTexAutoFix->setEnabled ( editable ); + // + // //mBtnAutoFix->setEnabled ( editable ); + // } childSetEnabled("button apply",editable); bool identical; @@ -884,27 +888,25 @@ struct LLPanelFaceSetMediaFunctor : public LLSelectedTEFunctor virtual bool apply(LLViewerObject* object, S32 te) { // only do this if it's a media texture - if ( object->getTE ( te )->getID() == LLMediaEngine::getInstance()->getImageUUID () ) + if ( object->getTE ( te )->getID() == LLViewerMedia::getMediaTextureID() ) { - // make sure we're valid - if ( LLMediaEngine::getInstance()->getMediaRenderer() ) + S32 media_width, media_height; + S32 texture_width, texture_height; + if ( LLViewerMedia::getMediaSize( &media_width, &media_height ) + && LLViewerMedia::getTextureSize( &texture_width, &texture_height ) ) { - // calculate correct scaling based on media dimensions and next-power-of-2 texture dimensions - F32 scaleS = (F32)LLMediaEngine::getInstance()->getMediaRenderer()->getMediaWidth() / - (F32)LLMediaEngine::getInstance()->getMediaRenderer()->getTextureWidth(); - - F32 scaleT = (F32)LLMediaEngine::getInstance()->getMediaRenderer()->getMediaHeight() / - (F32)LLMediaEngine::getInstance()->getMediaRenderer()->getTextureHeight(); + F32 scale_s = (F32)media_width / (F32)texture_width; + F32 scale_t = (F32)media_height / (F32)texture_height; // set scale and adjust offset - object->setTEScaleS( te, scaleS ); - object->setTEScaleT( te, scaleT ); // don't need to flip Y anymore since QT does this for us now. - object->setTEOffsetS( te, -( 1.0f - scaleS ) / 2.0f ); - object->setTEOffsetT( te, -( 1.0f - scaleT ) / 2.0f ); + object->setTEScaleS( te, scale_s ); + object->setTEScaleT( te, scale_t ); // don't need to flip Y anymore since QT does this for us now. + object->setTEOffsetS( te, -( 1.0f - scale_s ) / 2.0f ); + object->setTEOffsetT( te, -( 1.0f - scale_t ) / 2.0f ); } } return true; - } + }; }; void LLPanelFace::onClickAutoFix(void* userdata) diff --git a/indra/newview/llpanelland.cpp b/indra/newview/llpanelland.cpp index d86f81d21d4..45e78f257f4 100644 --- a/indra/newview/llpanelland.cpp +++ b/indra/newview/llpanelland.cpp @@ -253,5 +253,5 @@ void LLPanelLandInfo::onClickAbout(void*) gParcelMgr->selectParcelInRectangle(); } - LLFloaterLand::show(); + LLFloaterLand::showInstance(); } diff --git a/indra/newview/llpanellandmedia.cpp b/indra/newview/llpanellandmedia.cpp new file mode 100644 index 00000000000..1ac95c9a821 --- /dev/null +++ b/indra/newview/llpanellandmedia.cpp @@ -0,0 +1,378 @@ +/** + * @file llpanellandmedia.cpp + * @author Callum Prentice, Sam Kolb, James Cook + * @brief Allows configuration of "media" for a land parcel, + * for example movies, web pages, and audio. + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ +#include "llviewerprecompiledheaders.h" + +#include "llpanellandmedia.h" + +// viewer includes +#include "llmimetypes.h" +#include "llviewerparcelmgr.h" +#include "llvieweruictrlfactory.h" + +// library includes +#include "llcheckboxctrl.h" +#include "llcombobox.h" +#include "llfloaterurlentry.h" +#include "llfocusmgr.h" +#include "lllineeditor.h" +#include "llparcel.h" +#include "lltextbox.h" +#include "llradiogroup.h" +#include "llspinctrl.h" +#include "llsdutil.h" +#include "lltexturectrl.h" +#include "roles_constants.h" + +// Values for the parcel voice settings radio group +enum +{ + kRadioVoiceChatEstate = 0, + kRadioVoiceChatPrivate = 1, + kRadioVoiceChatDisable = 2 +}; + +//--------------------------------------------------------------------------- +// LLPanelLandMedia +//--------------------------------------------------------------------------- + +LLPanelLandMedia::LLPanelLandMedia(LLParcelSelectionHandle& parcel) +: LLPanel("land_media_panel"), mParcel(parcel) +{ +} + + +// virtual +LLPanelLandMedia::~LLPanelLandMedia() +{ + // close LLFloaterURLEntry? +} + + +BOOL LLPanelLandMedia::postBuild() +{ + mCheckSoundLocal = LLUICtrlFactory::getCheckBoxByName(this, "check sound local"); + childSetCommitCallback("check sound local", onCommitAny, this); + + mRadioVoiceChat = LLUICtrlFactory::getRadioGroupByName(this, "parcel_voice_channel"); + childSetCommitCallback("parcel_voice_channel", onCommitAny, this); + + mMusicURLEdit = LLUICtrlFactory::getLineEditorByName(this, "music_url"); + childSetCommitCallback("music_url", onCommitAny, this); + + mMediaTextureCtrl = LLUICtrlFactory::getTexturePickerByName(this, "media texture"); + if (mMediaTextureCtrl) + { + mMediaTextureCtrl->setCommitCallback( onCommitAny ); + mMediaTextureCtrl->setCallbackUserData( this ); + mMediaTextureCtrl->setAllowNoTexture ( TRUE ); + mMediaTextureCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER); + mMediaTextureCtrl->setNonImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER); + } + else + { + llwarns << "LLUICtrlFactory::getTexturePickerByName() returned NULL for 'media texure'" << llendl; + } + + mMediaAutoScaleCheck = LLUICtrlFactory::getCheckBoxByName(this, "media_auto_scale"); + childSetCommitCallback("media_auto_scale", onCommitAny, this); + + mMediaLoopCheck = LLUICtrlFactory::getCheckBoxByName(this, "media_loop"); + childSetCommitCallback("media_loop", onCommitAny, this); + + mMediaUrlCheck = LLUICtrlFactory::getCheckBoxByName(this, "hide_media_url"); + childSetCommitCallback("hide_media_url", onCommitAny, this); + + mMusicUrlCheck = LLUICtrlFactory::getCheckBoxByName(this, "hide_music_url"); + childSetCommitCallback("hide_music_url", onCommitAny, this); + + mMediaURLEdit = LLUICtrlFactory::getLineEditorByName(this, "media_url"); + childSetCommitCallback("media_url", onCommitAny, this); + + mMediaDescEdit = LLUICtrlFactory::getLineEditorByName(this, "url_description"); + childSetCommitCallback("url_description", onCommitAny, this); + + mMediaTypeCombo = LLUICtrlFactory::getComboBoxByName(this, "media type"); + childSetCommitCallback("media type", onCommitType, this); + populateMIMECombo(); + mMediaTypeCombo->sortByName(); + + mMediaWidthCtrl = LLUICtrlFactory::getSpinnerByName(this, "media_size_width"); + childSetCommitCallback("media_size_width", onCommitAny, this); + mMediaHeightCtrl = LLUICtrlFactory::getSpinnerByName(this, "media_size_height"); + childSetCommitCallback("media_size_height", onCommitAny, this); + mMediaSizeCtrlLabel = LLUICtrlFactory::getTextBoxByName(this, "media_size"); + + mSetURLButton = LLUICtrlFactory::getButtonByName(this, "set_media_url"); + childSetAction("set_media_url", onSetBtn, this); + + return TRUE; +} + + +// public +void LLPanelLandMedia::refresh() +{ + LLParcel *parcel = mParcel->getParcel(); + + if (!parcel) + { + clearCtrls(); + } + else + { + // something selected, hooray! + + // Display options + BOOL can_change_media = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_CHANGE_MEDIA); + + mCheckSoundLocal->set( parcel->getSoundLocal() ); + mCheckSoundLocal->setEnabled( can_change_media ); + + if(parcel->getVoiceEnabled()) + { + if(parcel->getVoiceUseEstateChannel()) + mRadioVoiceChat->setSelectedIndex(kRadioVoiceChatEstate); + else + mRadioVoiceChat->setSelectedIndex(kRadioVoiceChatPrivate); + } + else + { + mRadioVoiceChat->setSelectedIndex(kRadioVoiceChatDisable); + } + + mRadioVoiceChat->setEnabled( can_change_media ); + + mMusicURLEdit->setText(parcel->getMusicURL()); + mMusicURLEdit->setEnabled( can_change_media ); + + mMediaURLEdit->setText(parcel->getMediaURL()); + mMediaURLEdit->setEnabled( FALSE ); + + mMediaDescEdit->setText(LLString(parcel->getMediaDesc())); + mMediaDescEdit->setEnabled( can_change_media ); + + std::string mime_type = parcel->getMediaType(); + if (mime_type.empty()) + { + mime_type = "none/none"; + } + setMediaType(mime_type); + mMediaTypeCombo->setEnabled( can_change_media ); + childSetText("mime_type", mime_type); + + mMediaUrlCheck->set( parcel->getObscureMedia() ); + mMediaUrlCheck->setEnabled( can_change_media ); + + mMusicUrlCheck->set( parcel->getObscureMusic() ); + mMusicUrlCheck->setEnabled( can_change_media ); + + // don't display urls if you're not able to change it + // much requested change in forums so people can't 'steal' urls + // NOTE: bug#2009 means this is still vunerable - however, bug + // should be closed since this bug opens up major security issues elsewhere. + bool obscure_media = ! can_change_media && parcel->getObscureMedia(); + bool obscure_music = ! can_change_media && parcel->getObscureMusic(); + + // Special code to disable asterixes for html type + if(mime_type == "text/html") + { + obscure_media = false; + mMediaUrlCheck->set( 0 ); + mMediaUrlCheck->setEnabled( false ); + } + + mMusicURLEdit->setDrawAsterixes( obscure_music ); + mMediaURLEdit->setDrawAsterixes( obscure_media ); + + mMediaAutoScaleCheck->set( parcel->getMediaAutoScale () ); + mMediaAutoScaleCheck->setEnabled ( can_change_media ); + + // Special code to disable looping checkbox for HTML MIME type + // (DEV-10042 -- Parcel Media: "Loop Media" should be disabled for static media types) + bool allow_looping = LLMIMETypes::findAllowLooping( mime_type ); + if ( allow_looping ) + mMediaLoopCheck->set( parcel->getMediaLoop () ); + else + mMediaLoopCheck->set( false ); + mMediaLoopCheck->setEnabled ( can_change_media && allow_looping ); + + // disallow media size change for mime types that don't allow it + bool allow_resize = LLMIMETypes::findAllowResize( mime_type ); + if ( allow_resize ) + mMediaWidthCtrl->setValue( parcel->getMediaWidth() ); + else + mMediaWidthCtrl->setValue( 0 ); + mMediaWidthCtrl->setEnabled ( can_change_media && allow_resize ); + + if ( allow_resize ) + mMediaHeightCtrl->setValue( parcel->getMediaHeight() ); + else + mMediaHeightCtrl->setValue( 0 ); + mMediaHeightCtrl->setEnabled ( can_change_media && allow_resize ); + + // enable/disable for text label for completeness + mMediaSizeCtrlLabel->setEnabled( can_change_media && allow_resize ); + + LLUUID tmp = parcel->getMediaID(); + mMediaTextureCtrl->setImageAssetID ( parcel->getMediaID() ); + mMediaTextureCtrl->setEnabled( can_change_media ); + + mSetURLButton->setEnabled( can_change_media ); + + #if 0 + // there is a media url and a media texture selected + if ( ( ! ( std::string ( parcel->getMediaURL() ).empty () ) ) && ( ! ( parcel->getMediaID ().isNull () ) ) ) + { + // turn on transport controls if allowed for this parcel + mMediaStopButton->setEnabled ( editable ); + mMediaStartButton->setEnabled ( editable ); + } + else + { + // no media url or no media texture + mMediaStopButton->setEnabled ( FALSE ); + mMediaStartButton->setEnabled ( FALSE ); + }; + #endif + + LLFloaterURLEntry* floater_url_entry = (LLFloaterURLEntry*)LLFloater::getFloaterByHandle(mURLEntryFloater); + if (floater_url_entry) + { + floater_url_entry->updateFromLandMediaPanel(); + } + } +} + +void LLPanelLandMedia::populateMIMECombo() +{ + LLMIMETypes::mime_widget_set_map_t::const_iterator it; + for (it = LLMIMETypes::sWidgetMap.begin(); it != LLMIMETypes::sWidgetMap.end(); ++it) + { + const LLString& mime_type = it->first; + const LLMIMETypes::LLMIMEWidgetSet& info = it->second; + mMediaTypeCombo->add(info.mLabel, mime_type); + } +} +void LLPanelLandMedia::setMediaType(const LLString& mime_type) +{ + LLParcel *parcel = mParcel->getParcel(); + if(parcel) + parcel->setMediaType(mime_type.c_str()); + + LLString media_key = LLMIMETypes::widgetType(mime_type); + mMediaTypeCombo->setValue(media_key); + childSetText("mime_type", mime_type); +} + +void LLPanelLandMedia::setMediaURL(const LLString& media_url) +{ + mMediaURLEdit->setText(media_url); + mMediaURLEdit->onCommit(); + +} + +// static +void LLPanelLandMedia::onCommitType(LLUICtrl *ctrl, void *userdata) +{ + LLPanelLandMedia *self = (LLPanelLandMedia *)userdata; + std::string current_type = LLMIMETypes::widgetType(self->childGetText("mime_type")); + std::string new_type = self->mMediaTypeCombo->getValue(); + if(current_type != new_type) + { + self->childSetText("mime_type", LLMIMETypes::findDefaultMimeType(new_type)); + } + onCommitAny(ctrl, userdata); + +} +// static +void LLPanelLandMedia::onCommitAny(LLUICtrl *ctrl, void *userdata) +{ + LLPanelLandMedia *self = (LLPanelLandMedia *)userdata; + + LLParcel* parcel = self->mParcel->getParcel(); + if (!parcel) + { + return; + } + + // Extract data from UI + BOOL sound_local = self->mCheckSoundLocal->get(); + int voice_setting = self->mRadioVoiceChat->getSelectedIndex(); + std::string music_url = self->mMusicURLEdit->getText(); + std::string media_url = self->mMediaURLEdit->getText(); + std::string media_desc = self->mMediaDescEdit->getText(); + std::string mime_type = self->childGetText("mime_type"); + U8 media_auto_scale = self->mMediaAutoScaleCheck->get(); + U8 media_loop = self->mMediaLoopCheck->get(); + U8 obscure_media = self->mMediaUrlCheck->get(); + U8 obscure_music = self->mMusicUrlCheck->get(); + S32 media_width = (S32)self->mMediaWidthCtrl->get(); + S32 media_height = (S32)self->mMediaHeightCtrl->get(); + LLUUID media_id = self->mMediaTextureCtrl->getImageAssetID(); + + self->childSetText("mime_type", mime_type); + + BOOL voice_enabled; + BOOL voice_estate_chan; + + switch(voice_setting) + { + default: + case kRadioVoiceChatEstate: + voice_enabled = TRUE; + voice_estate_chan = TRUE; + break; + case kRadioVoiceChatPrivate: + voice_enabled = TRUE; + voice_estate_chan = FALSE; + break; + case kRadioVoiceChatDisable: + voice_enabled = FALSE; + voice_estate_chan = FALSE; + break; + } + + // Remove leading/trailing whitespace (common when copying/pasting) + LLString::trim(music_url); + LLString::trim(media_url); + + // Push data into current parcel + parcel->setParcelFlag(PF_ALLOW_VOICE_CHAT, voice_enabled); + parcel->setParcelFlag(PF_USE_ESTATE_VOICE_CHAN, voice_estate_chan); + parcel->setParcelFlag(PF_SOUND_LOCAL, sound_local); + parcel->setMusicURL(music_url.c_str()); + parcel->setMediaURL(media_url.c_str()); + parcel->setMediaType(mime_type.c_str()); + parcel->setMediaDesc(media_desc.c_str()); + parcel->setMediaWidth(media_width); + parcel->setMediaHeight(media_height); + parcel->setMediaID(media_id); + parcel->setMediaAutoScale ( media_auto_scale ); + parcel->setMediaLoop ( media_loop ); + parcel->setObscureMedia( obscure_media ); + parcel->setObscureMusic( obscure_music ); + + // Send current parcel data upstream to server + gParcelMgr->sendParcelPropertiesUpdate( parcel ); + + // Might have changed properties, so let's redraw! + self->refresh(); +} +// static +void LLPanelLandMedia::onSetBtn(void *userdata) +{ + LLPanelLandMedia *self = (LLPanelLandMedia *)userdata; + self->mURLEntryFloater = LLFloaterURLEntry::show( self->getHandle() ); + LLFloater* parent_floater = gFloaterView->getParentFloater(self); + if (parent_floater) + { + parent_floater->addDependentFloater(LLFloater::getFloaterByHandle(self->mURLEntryFloater)); + } +} diff --git a/indra/newview/llpanellandmedia.h b/indra/newview/llpanellandmedia.h new file mode 100644 index 00000000000..aa84b245e24 --- /dev/null +++ b/indra/newview/llpanellandmedia.h @@ -0,0 +1,58 @@ +/** + * @file llpanellandmedia.h + * @author Callum Prentice, Sam Kolb, James Cook + * @brief Allows configuration of "media" for a land parcel, + * for example movies, web pages, and audio. + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ +#ifndef LLPANELLANDMEDIA_H +#define LLPANELLANDMEDIA_H + +#include "lllineeditor.h" +#include "llmemory.h" // LLHandle<> +#include "llpanel.h" +#include "llparcelselection.h" +#include "lluifwd.h" // widget pointer types + +class LLPanelLandMedia +: public LLPanel +{ +public: + LLPanelLandMedia(LLHandle<LLParcelSelection>& parcelp); + /*virtual*/ ~LLPanelLandMedia(); + /*virtual*/ BOOL postBuild(); + void refresh(); + void setMediaType(const LLString& media_type); + void setMediaURL(const LLString& media_type); + const LLString& getMediaURL() { return mMediaURLEdit->getText(); } + +private: + void populateMIMECombo(); + static void onCommitAny(LLUICtrl* ctrl, void *userdata); + static void onCommitType(LLUICtrl* ctrl, void *userdata); + static void onSetBtn(void* userdata); + +private: + LLCheckBoxCtrl* mCheckSoundLocal; + LLRadioGroup* mRadioVoiceChat; + LLLineEditor* mMusicURLEdit; + LLLineEditor* mMediaURLEdit; + LLLineEditor* mMediaDescEdit; + LLComboBox* mMediaTypeCombo; + LLButton* mSetURLButton; + LLSpinCtrl* mMediaHeightCtrl; + LLSpinCtrl* mMediaWidthCtrl; + LLTextBox* mMediaSizeCtrlLabel; + LLTextureCtrl* mMediaTextureCtrl; + LLCheckBoxCtrl* mMediaAutoScaleCheck; + LLCheckBoxCtrl* mMediaLoopCheck; + LLCheckBoxCtrl* mMediaUrlCheck; + LLCheckBoxCtrl* mMusicUrlCheck; + LLViewHandle mURLEntryFloater; + + LLHandle<LLParcelSelection>& mParcel; +}; + +#endif diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index bc6f6fedd82..a80765c8052 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -71,7 +71,8 @@ #include "llwebbrowserctrl.h" #include "llfloaterhtml.h" -//#include "llfloaterhtmlhelp.h" + +#include "llfloaterhtmlhelp.h" #include "llfloatertos.h" #include "llglheaders.h" @@ -95,12 +96,10 @@ class LLLoginRefreshHandler : public LLCommandHandler LLLoginRefreshHandler() : LLCommandHandler("login_refresh", false) { } bool handle(const LLSD& tokens, const LLSD& queryMap) { -#if LL_LIBXUL_ENABLED if (LLStartUp::getStartupState() < STATE_LOGIN_CLEANUP) { LLPanelLogin::loadLoginPage(); } -#endif return true; } }; @@ -438,7 +437,6 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, #endif // get the web browser control - #if LL_LIBXUL_ENABLED LLWebBrowserCtrl* web_browser = LLUICtrlFactory::getWebBrowserCtrlByName(this, "login_html"); if ( web_browser ) { @@ -475,9 +473,6 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, } LLHTTPClient::head( login_page, gResponsePtr ); }; - #else - mHtmlAvailable = FALSE; - #endif #if !USE_VIEWER_AUTH // Initialize visibility (and don't force visibility - use prefs) @@ -487,7 +482,6 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, void LLPanelLogin::setSiteIsAlive( bool alive ) { -#if LL_LIBXUL_ENABLED LLWebBrowserCtrl* web_browser = LLUICtrlFactory::getWebBrowserCtrlByName(this, "login_html"); // if the contents of the site was retrieved if ( alive ) @@ -523,10 +517,6 @@ void LLPanelLogin::setSiteIsAlive( bool alive ) } #endif } - -#else - mHtmlAvailable = FALSE; -#endif } void LLPanelLogin::mungePassword(LLUICtrl* caller, void* user_data) @@ -620,7 +610,6 @@ BOOL LLPanelLogin::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent) return TRUE; } -#if LL_LIBXUL_ENABLED if ( KEY_F1 == key ) { llinfos << "Spawning HTML help window" << llendl; @@ -636,7 +625,6 @@ BOOL LLPanelLogin::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent) tos_dialog->startModal(); return TRUE; } -# endif #endif if (!called_from_parent) @@ -917,14 +905,12 @@ void LLPanelLogin::setAlwaysRefresh(bool refresh) { if (LLStartUp::getStartupState() >= STATE_LOGIN_CLEANUP) return; -#if LL_LIBXUL_ENABLED LLWebBrowserCtrl* web_browser = LLUICtrlFactory::getWebBrowserCtrlByName(sInstance, "login_html"); if (web_browser) { web_browser->setAlwaysRefresh(refresh); } -#endif } @@ -1050,15 +1036,12 @@ void LLPanelLogin::loadLoginPage() #endif #endif -#if LL_LIBXUL_ENABLED LLWebBrowserCtrl* web_browser = LLUICtrlFactory::getWebBrowserCtrlByName(sInstance, "login_html"); // navigate to the "real" page web_browser->navigateTo( oStr.str() ); -#endif } -#if LL_LIBXUL_ENABLED void LLPanelLogin::onNavigateComplete( const EventType& eventIn ) { LLWebBrowserCtrl* web_browser = LLUICtrlFactory::getWebBrowserCtrlByName(sInstance, "login_html"); @@ -1074,7 +1057,6 @@ void LLPanelLogin::onNavigateComplete( const EventType& eventIn ) //web_browser->handleKey(KEY_TAB, MASK_NONE, false); } } -#endif //--------------------------------------------------------------------------- // Protected methods diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h index 3deb6fee515..76a16528cb1 100644 --- a/indra/newview/llpanellogin.h +++ b/indra/newview/llpanellogin.h @@ -64,11 +64,9 @@ class LLLoginHandler : public LLCommandHandler extern LLLoginHandler gLoginHandler; -class LLPanelLogin -: public LLPanel -#if LL_LIBXUL_ENABLED - , public LLWebBrowserCtrlObserver -#endif +class LLPanelLogin: + public LLPanel, + public LLWebBrowserCtrlObserver { public: LLPanelLogin(const LLRect &rect, BOOL show_server, @@ -111,11 +109,7 @@ class LLPanelLogin static void newAccountAlertCallback(S32 option, void*); static void onClickQuit(void*); static void onClickVersion(void*); - -#if LL_LIBXUL_ENABLED - // browser observer impls virtual void onNavigateComplete( const EventType& eventIn ); -#endif static void onClickForgotPassword(void*); static void onPassKey(LLLineEditor* caller, void* user_data); diff --git a/indra/newview/llparcelselection.cpp b/indra/newview/llparcelselection.cpp new file mode 100644 index 00000000000..5478a96b979 --- /dev/null +++ b/indra/newview/llparcelselection.cpp @@ -0,0 +1,83 @@ +/** + * @file llparcelselection.cpp + * @brief Information about the currently selected parcel + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llparcelselection.h" + +#include "llparcel.h" + + +// static +LLPointer<LLParcelSelection> LLParcelSelection::sNullSelection; + +template<> + const LLHandle<LLParcelSelection>::NullFunc + LLHandle<LLParcelSelection>::sNullFunc = + LLParcelSelection::getNullParcelSelection; + +// +// LLParcelSelection +// +LLParcelSelection::LLParcelSelection() : + mParcel(NULL), + mSelectedMultipleOwners(FALSE), + mWholeParcelSelected(FALSE), + mSelectedSelfCount(0), + mSelectedOtherCount(0), + mSelectedPublicCount(0) +{ +} + +LLParcelSelection::LLParcelSelection(LLParcel* parcel) : + mParcel(parcel), + mSelectedMultipleOwners(FALSE), + mWholeParcelSelected(FALSE), + mSelectedSelfCount(0), + mSelectedOtherCount(0), + mSelectedPublicCount(0) +{ +} + +LLParcelSelection::~LLParcelSelection() +{ +} + +BOOL LLParcelSelection::getMultipleOwners() const +{ + return mSelectedMultipleOwners; +} + + +BOOL LLParcelSelection::getWholeParcelSelected() const +{ + return mWholeParcelSelected; +} + + +S32 LLParcelSelection::getClaimableArea() const +{ + const S32 UNIT_AREA = S32( PARCEL_GRID_STEP_METERS * PARCEL_GRID_STEP_METERS ); + return mSelectedPublicCount * UNIT_AREA; +} + +bool LLParcelSelection::hasOthersSelected() const +{ + return mSelectedOtherCount != 0; +} + +// static +LLParcelSelection* LLParcelSelection::getNullParcelSelection() +{ + if (sNullSelection.isNull()) + { + sNullSelection = new LLParcelSelection; + } + + return sNullSelection; +} diff --git a/indra/newview/llparcelselection.h b/indra/newview/llparcelselection.h new file mode 100644 index 00000000000..579a0f2549f --- /dev/null +++ b/indra/newview/llparcelselection.h @@ -0,0 +1,63 @@ +/** + * @file llparcelselection.h + * @brief Information about the currently selected parcel + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#ifndef LLPARCELSELECTION_H +#define LLPARCELSELECTION_H + +#include "llmemory.h" + +class LLParcel; + +class LLParcelSelection : public LLRefCount +{ + friend class LLViewerParcelMgr; + +protected: + ~LLParcelSelection(); + +public: + LLParcelSelection(LLParcel* parcel); + LLParcelSelection(); + + // this can return NULL at any time, as parcel selection + // might have been invalidated. + LLParcel* getParcel() { return mParcel; } + + // Return the number of grid units that are owned by you within + // the selection (computed by server). + S32 getSelfCount() const { return mSelectedSelfCount; } + + // Returns area that will actually be claimed in meters squared. + S32 getClaimableArea() const; + bool hasOthersSelected() const; + + // Does the selection have multiple land owners in it? + BOOL getMultipleOwners() const; + + // Is the entire parcel selected, or just a part? + BOOL getWholeParcelSelected() const; + + static LLParcelSelection* getNullParcelSelection(); + +private: + void setParcel(LLParcel* parcel) { mParcel = parcel; } + +private: + LLParcel* mParcel; + BOOL mSelectedMultipleOwners; + BOOL mWholeParcelSelected; + S32 mSelectedSelfCount; + S32 mSelectedOtherCount; + S32 mSelectedPublicCount; + + static LLPointer<LLParcelSelection> sNullSelection; +}; + +typedef LLHandle<LLParcelSelection> LLParcelSelectionHandle; + +#endif diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index c6d721faebd..d3afd65cbef 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -471,14 +471,12 @@ void LLScriptEdCore::updateDynamicHelp(BOOL immediate) LLFloater* help_floater = LLFloater::getFloaterByHandle(mLiveHelpHandle); if (!help_floater) return; -#if LL_LIBXUL_ENABLED // update back and forward buttons LLButton* fwd_button = LLUICtrlFactory::getButtonByName(help_floater, "fwd_btn"); LLButton* back_button = LLUICtrlFactory::getButtonByName(help_floater, "back_btn"); LLWebBrowserCtrl* browser = LLUICtrlFactory::getWebBrowserCtrlByName(help_floater, "lsl_guide_html"); back_button->setEnabled(browser->canNavigateBack()); fwd_button->setEnabled(browser->canNavigateForward()); -#endif // LL_LIBXUL_ENABLED if (!immediate && !gSavedSettings.getBOOL("ScriptHelpFollowsCursor")) { @@ -546,9 +544,9 @@ void LLScriptEdCore::setHelpPage(const LLString& help_string) url_string.setArg("[LSL_STRING]", help_string); addHelpItemToHistory(help_string); -#if LL_LIBXUL_ENABLED + web_browser->navigateTo(url_string); -#endif // LL_LIBXUL_ENABLED + } void LLScriptEdCore::addHelpItemToHistory(const LLString& help_string) @@ -680,10 +678,8 @@ void LLScriptEdCore::onBtnDynamicHelp(void* userdata) live_help_floater->childSetAction("back_btn", onClickBack, userdata); live_help_floater->childSetAction("fwd_btn", onClickForward, userdata); -#if LL_LIBXUL_ENABLED LLWebBrowserCtrl* browser = LLUICtrlFactory::getWebBrowserCtrlByName(live_help_floater, "lsl_guide_html"); browser->setAlwaysRefresh(TRUE); -#endif // LL_LIBXUL_ENABLED LLComboBox* help_combo = LLUICtrlFactory::getComboBoxByName(live_help_floater, "history_combo"); LLKeywordToken *token; @@ -707,7 +703,6 @@ void LLScriptEdCore::onBtnDynamicHelp(void* userdata) //static void LLScriptEdCore::onClickBack(void* userdata) { -#if LL_LIBXUL_ENABLED LLScriptEdCore* corep = (LLScriptEdCore*)userdata; LLFloater* live_help_floater = LLFloater::getFloaterByHandle(corep->mLiveHelpHandle); if (live_help_floater) @@ -718,13 +713,11 @@ void LLScriptEdCore::onClickBack(void* userdata) browserp->navigateBack(); } } -#endif // LL_LIBXUL_ENABLED } //static void LLScriptEdCore::onClickForward(void* userdata) { -#if LL_LIBXUL_ENABLED LLScriptEdCore* corep = (LLScriptEdCore*)userdata; LLFloater* live_help_floater = LLFloater::getFloaterByHandle(corep->mLiveHelpHandle); if (live_help_floater) @@ -735,7 +728,6 @@ void LLScriptEdCore::onClickForward(void* userdata) browserp->navigateForward(); } } -#endif // LL_LIBXUL_ENABLED } // static @@ -772,13 +764,11 @@ void LLScriptEdCore::onHelpComboCommit(LLUICtrl* ctrl, void* userdata) corep->addHelpItemToHistory(help_string); -#if LL_LIBXUL_ENABLED LLWebBrowserCtrl* web_browser = gUICtrlFactory->getWebBrowserCtrlByName(live_help_floater, "lsl_guide_html"); LLUIString url_string = gSavedSettings.getString("LSLHelpURL"); url_string.setArg("[APP_DIRECTORY]", gDirUtilp->getWorkingDir()); url_string.setArg("[LSL_STRING]", help_string); web_browser->navigateTo(url_string); -#endif // LL_LIBXUL_ENABLED } } diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 8df34d39c66..423954800f0 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -134,6 +134,7 @@ #include "llui.h" #include "llurldispatcher.h" #include "llurlsimstring.h" +#include "llurlhistory.h" #include "llurlwhitelist.h" #include "lluserauth.h" #include "llvieweraudio.h" @@ -143,10 +144,12 @@ #include "llviewergenericmessage.h" #include "llviewergesture.h" #include "llviewerimagelist.h" +#include "llviewermedia.h" #include "llviewermenu.h" #include "llviewermessage.h" #include "llviewernetwork.h" #include "llviewerobjectlist.h" +#include "llviewerparcelmedia.h" #include "llviewerparcelmgr.h" #include "llviewerregion.h" #include "llviewerstats.h" @@ -160,7 +163,6 @@ #include "llxfermanager.h" #include "pipeline.h" #include "llappviewer.h" -#include "llmediaengine.h" #include "llfasttimerview.h" #include "llfloatermap.h" #include "llweb.h" @@ -169,27 +171,11 @@ #include "llnamebox.h" #include "llnameeditor.h" -#if LL_LIBXUL_ENABLED -#include "llmozlib.h" -#endif // LL_LIBXUL_ENABLED - #if LL_WINDOWS #include "llwindebug.h" #include "lldxhardware.h" #endif -#if LL_QUICKTIME_ENABLED -#if LL_DARWIN -#include <QuickTime/QuickTime.h> -#else -// quicktime specific includes -#include "MacTypes.h" -#include "QTML.h" -#include "Movies.h" -#include "FixMath.h" -#endif -#endif - // // exported globals // @@ -213,8 +199,6 @@ LLPointer<LLImageGL> gStartImageGL; static LLHost gAgentSimHost; static BOOL gSkipOptionalUpdate = FALSE; -bool gUseQuickTime = true; -bool gQuickTimeInitialized = false; static bool gGotUseCircuitCodeAck = false; LLString gInitialOutfit; LLString gInitialOutfitGender; // "male" or "female" @@ -545,59 +529,7 @@ BOOL idle_startup() // initialize the economy gGlobalEconomy = new LLGlobalEconomy(); - //--------------------------------------------------------------------- - // LibXUL (Mozilla) initialization - //--------------------------------------------------------------------- - #if LL_LIBXUL_ENABLED - set_startup_status(0.58f, "Initializing embedded web browser...", gAgent.mMOTD.c_str()); - display_startup(); - llinfos << "Initializing embedded web browser..." << llendl; - - #if LL_DARWIN - // For Mac OS, we store both the shared libraries and the runtime files (chrome/, plugins/, etc) in - // Second Life.app/Contents/MacOS/. This matches the way Firefox is distributed on the Mac. - std::string componentDir(gDirUtilp->getExecutableDir()); - #elif LL_WINDOWS - std::string componentDir( gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "" ) ); - componentDir += gDirUtilp->getDirDelimiter(); - #ifdef LL_DEBUG - componentDir += "mozilla_debug"; - #else - componentDir += "mozilla"; - #endif - #elif LL_LINUX - std::string componentDir( gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "" ) ); - componentDir += gDirUtilp->getDirDelimiter(); - componentDir += "mozilla-runtime-linux-i686"; - #else - std::string componentDir( gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "" ) ); - componentDir += gDirUtilp->getDirDelimiter(); - componentDir += "mozilla"; - #endif -#if LL_LINUX - // Yuck, Mozilla init plays with the locale - push/pop - // the locale to protect it, as exotic/non-C locales - // causes our code lots of general critical weirdness - // and crashness. (SL-35450) - std::string saved_locale = setlocale(LC_ALL, NULL); -#endif // LL_LINUX - - // initialize Mozilla - pass in executable dir, location of extra dirs (chrome/, greprefs/, plugins/ etc.) and path to profile dir) - LLMozLib::getInstance()->init( gDirUtilp->getExecutableDir(), componentDir, gDirUtilp->getExpandedFilename( LL_PATH_MOZILLA_PROFILE, "" ) ); - -#if LL_LINUX - setlocale(LC_ALL, saved_locale.c_str() ); -#endif // LL_LINUX - - std::ostringstream codec; - codec << "[Second Life "; - codec << "(" << gChannelName << ")"; - codec << " - " << LL_VERSION_MAJOR << "." << LL_VERSION_MINOR << "." << LL_VERSION_PATCH << "." << LL_VERSION_BUILD; - codec << "]"; - LLMozLib::getInstance()->setBrowserAgentId( codec.str() ); - LLMozLib::getInstance()->enableProxy( gSavedSettings.getBOOL("BrowserProxyEnabled"), gSavedSettings.getString("BrowserProxyAddress"), gSavedSettings.getS32("BrowserProxyPort") ); - #endif //------------------------------------------------- // Init audio, which may be needed for prefs dialog @@ -694,7 +626,29 @@ BOOL idle_startup() show_connect_box = TRUE; } + // Go to the next startup state + LLStartUp::setStartupState( STATE_MEDIA_INIT ); + return do_normal_idle; + } + + + //--------------------------------------------------------------------- + // LLMediaEngine Init + //--------------------------------------------------------------------- + if (STATE_MEDIA_INIT == LLStartUp::getStartupState()) + { + llinfos << "Initializing Multimedia...." << llendl; + set_startup_status(0.03f, "Initializing Multimedia...", gAgent.mMOTD.c_str()); + display_startup(); + LLViewerMedia::initClass(); + LLViewerParcelMedia::initClass(); + + if (gViewerWindow) + { + audio_update_volume(true); + } + LLStartUp::setStartupState( STATE_LOGIN_SHOW ); return do_normal_idle; } @@ -892,6 +846,9 @@ BOOL idle_startup() &LLURLDispatcher::dispatchFromTextEditor, &LLURLDispatcher::dispatchFromTextEditor ); + // Load URL History File + LLURLHistory::loadFile("url_history.xml"); + //------------------------------------------------- // Handle startup progress screen //------------------------------------------------- @@ -934,7 +891,7 @@ BOOL idle_startup() // Poke the VFS, which could potentially block for a while if // Windows XP is acting up - set_startup_status(0.05f, "Verifying cache files (can take 60-90 seconds)...", NULL); + set_startup_status(0.07f, "Verifying cache files (can take 60-90 seconds)...", NULL); display_startup(); gVFS->pokeFiles(); @@ -1774,7 +1731,7 @@ BOOL idle_startup() display_startup(); gImageList.decodeAllImages(1.f); } - LLStartUp::setStartupState( STATE_QUICKTIME_INIT ); + LLStartUp::setStartupState( STATE_WORLD_WAIT ); // JC - Do this as late as possible to increase likelihood Purify // will run. @@ -1808,79 +1765,8 @@ BOOL idle_startup() } //--------------------------------------------------------------------- - // LLMediaEngine Init - //--------------------------------------------------------------------- - if (STATE_QUICKTIME_INIT == LLStartUp::getStartupState()) - { - if (gViewerWindow) - { - audio_update_volume(true); - } - - #if LL_QUICKTIME_ENABLED // windows only right now but will be ported to mac - if (gUseQuickTime) - { - if(!gQuickTimeInitialized) - { - // initialize quicktime libraries (fails gracefully if quicktime not installed ($QUICKTIME) - llinfos << "Initializing QuickTime...." << llendl; - set_startup_status(0.57f, "Initializing QuickTime...", gAgent.mMOTD.c_str()); - display_startup(); - #if LL_WINDOWS - // Only necessary/available on Windows. - if ( InitializeQTML ( 0L ) != noErr ) - { - // quicktime init failed - turn off media engine support - LLMediaEngine::getInstance ()->setAvailable ( FALSE ); - llinfos << "...not found - unable to initialize." << llendl; - set_startup_status(0.57f, "QuickTime not found - unable to initialize.", gAgent.mMOTD.c_str()); - } - else - { - llinfos << "QUICKTIME> QuickTime version (hex) is " << std::hex << LLMediaEngine::getInstance()->getQuickTimeVersion() << llendl; - llinfos << "QUICKTIME> QuickTime version is " << std::dec << LLMediaEngine::getInstance()->getQuickTimeVersion() << llendl; - if ( LLMediaEngine::getInstance()->getQuickTimeVersion() < LL_MIN_QUICKTIME_VERSION ) - { - // turn off QuickTime if version is less than required - LLMediaEngine::getInstance ()->setAvailable ( FALSE ); - - // display a message here explaining why we disabled QuickTime - gViewerWindow->alertXml("QuickTimeOutOfDate"); - } - else - { - llinfos << ".. initialized successfully." << llendl; - set_startup_status(0.57f, "QuickTime initialized successfully.", gAgent.mMOTD.c_str()); - }; - }; - #elif LL_DARWIN - llinfos << "QUICKTIME> QuickTime version (hex) is " << std::hex << LLMediaEngine::getInstance()->getQuickTimeVersion() << llendl; - llinfos << "QUICKTIME> QuickTime version is " << std::dec << LLMediaEngine::getInstance()->getQuickTimeVersion() << llendl; - if ( LLMediaEngine::getInstance()->getQuickTimeVersion() < LL_MIN_QUICKTIME_VERSION ) - { - // turn off QuickTime if version is less than required - LLMediaEngine::getInstance ()->setAvailable ( FALSE ); - - // display a message here explaining why we disabled QuickTime - gViewerWindow->alertXml("QuickTimeOutOfDate"); - } - #endif - - EnterMovies (); - gQuickTimeInitialized = true; - } - } - else - { - LLMediaEngine::getInstance()->setAvailable( FALSE ); - } - #endif - LLStartUp::setStartupState( STATE_WORLD_WAIT ); - return do_normal_idle; - } - //--------------------------------------------------------------------- // Agent Send //--------------------------------------------------------------------- if(STATE_WORLD_WAIT == LLStartUp::getStartupState()) @@ -3126,18 +3012,6 @@ void register_viewer_callbacks(LLMessageSystem* msg) msg->setHandlerFunc("ParcelObjectOwnersReply", LLPanelLandObjects::processParcelObjectOwnersReply); - // Reponse to the "Refresh" button on land objects floater. - if (gSavedSettings.getBOOL("AudioStreamingVideo")) - { - msg->setHandlerFunc("ParcelMediaCommandMessage", LLMediaEngine::process_parcel_media); - msg->setHandlerFunc ( "ParcelMediaUpdate", LLMediaEngine::process_parcel_media_update ); - } - else - { - msg->setHandlerFunc("ParcelMediaCommandMessage", null_message_callback); - gMessageSystem->setHandlerFunc ( "ParcelMediaUpdate", null_message_callback ); - } - msg->setHandlerFunc("InitiateDownload", process_initiate_download); msg->setHandlerFunc("LandStatReply", LLFloaterTopObjects::handle_land_reply); msg->setHandlerFunc("GenericMessage", process_generic_message); diff --git a/indra/newview/llstartup.h b/indra/newview/llstartup.h index 08f2f6002ce..351d4b1a214 100644 --- a/indra/newview/llstartup.h +++ b/indra/newview/llstartup.h @@ -46,6 +46,7 @@ extern const char* SCREEN_LAST_FILENAME; enum EStartupState{ STATE_FIRST, // Initial startup + STATE_MEDIA_INIT, // Initialzie media library STATE_LOGIN_SHOW, // Show login screen STATE_LOGIN_WAIT, // Wait for user input at login screen STATE_LOGIN_CLEANUP, // Get rid of login screen and start login @@ -58,7 +59,6 @@ enum EStartupState{ STATE_WORLD_INIT, // Start building the world STATE_SEED_GRANTED_WAIT, // Wait for seed cap grant STATE_SEED_CAP_GRANTED, // Have seed cap grant - STATE_QUICKTIME_INIT, // Initialzie QT STATE_WORLD_WAIT, // Waiting for simulator STATE_AGENT_SEND, // Connect to a region STATE_AGENT_WAIT, // Wait for region @@ -72,8 +72,6 @@ enum EStartupState{ // exported symbols extern BOOL gAgentMovementCompleted; -extern bool gUseQuickTime; -extern bool gQuickTimeInitialized; extern LLPointer<LLImageGL> gStartImageGL; class LLStartUp diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp index 8c4fc833dbe..58039bf8781 100644 --- a/indra/newview/llstatusbar.cpp +++ b/indra/newview/llstatusbar.cpp @@ -49,6 +49,7 @@ #include "llfloaterbuycurrency.h" #include "llfloaterchat.h" #include "llfloaterdirectory.h" // to spawn search +#include "llfloaterlagmeter.h" #include "llfloaterland.h" #include "llfloaterregioninfo.h" #include "llfloaterscriptdebug.h" @@ -163,8 +164,49 @@ LLStatusBar::LLStatusBar(const std::string& name, const LLRect& rect) childSetCommitCallback("search_editor", onCommitSearch, this); childSetAction("search_btn", onClickSearch, this); + childSetVisible("search_editor", gSavedSettings.getBOOL("ShowSearchBar")); + childSetVisible("search_btn", gSavedSettings.getBOOL("ShowSearchBar")); + childSetActionTextbox("ParcelNameText", onClickParcelInfo ); childSetActionTextbox("BalanceText", onClickBalance ); + + // Adding Net Stat Graph + S32 x = mRect.getWidth() - 2; + S32 y = 0; + LLRect r; + r.set( x-SIM_STAT_WIDTH, y+MENU_BAR_HEIGHT-1, x, y+1); + mSGBandwidth = new LLStatGraph("BandwidthGraph", r); + mSGBandwidth->setFollows(FOLLOWS_BOTTOM | FOLLOWS_RIGHT); + mSGBandwidth->setStat(&gViewerStats->mKBitStat); + LLString text = childGetText("bandwidth_tooltip") + " "; + LLUIString bandwidth_tooltip = text; // get the text from XML until this widget is XML driven + mSGBandwidth->setLabel(bandwidth_tooltip.getString().c_str()); + mSGBandwidth->setUnits("Kbps"); + mSGBandwidth->setPrecision(0); + mSGBandwidth->setMouseOpaque(FALSE); + addChild(mSGBandwidth); + x -= SIM_STAT_WIDTH + 2; + + r.set( x-SIM_STAT_WIDTH, y+MENU_BAR_HEIGHT-1, x, y+1); + mSGPacketLoss = new LLStatGraph("PacketLossPercent", r); + mSGPacketLoss->setFollows(FOLLOWS_BOTTOM | FOLLOWS_RIGHT); + mSGPacketLoss->setStat(&gViewerStats->mPacketsLostPercentStat); + text = childGetText("packet_loss_tooltip") + " "; + LLUIString packet_loss_tooltip = text; // get the text from XML until this widget is XML driven + mSGPacketLoss->setLabel(packet_loss_tooltip.getString().c_str()); + mSGPacketLoss->setUnits("%"); + mSGPacketLoss->setMin(0.f); + mSGPacketLoss->setMax(5.f); + mSGPacketLoss->setThreshold(0, 0.5f); + mSGPacketLoss->setThreshold(1, 1.f); + mSGPacketLoss->setThreshold(2, 3.f); + mSGPacketLoss->setPrecision(1); + mSGPacketLoss->setMouseOpaque(FALSE); + mSGPacketLoss->mPerSec = FALSE; + addChild(mSGPacketLoss); + + childSetActionTextbox("stat_btn", onClickStatGraph); + } LLStatusBar::~LLStatusBar() @@ -212,6 +254,14 @@ void LLStatusBar::draw() // Per-frame updates of visibility void LLStatusBar::refresh() { + // Adding Net Stat Meter back in + F32 bwtotal = gViewerThrottle.getMaxBandwidth() / 1000.f; + mSGBandwidth->setMin(0.f); + mSGBandwidth->setMax(bwtotal*1.25f); + mSGBandwidth->setThreshold(0, bwtotal*0.75f); + mSGBandwidth->setThreshold(1, bwtotal); + mSGBandwidth->setThreshold(2, bwtotal); + // *TODO: Localize / translate time // Get current UTC time, adjusted for the user's clock @@ -262,6 +312,8 @@ void LLStatusBar::refresh() S32 x = MENU_RIGHT + MENU_PARCEL_SPACING; S32 y = 0; + bool search_visible = gSavedSettings.getBOOL("ShowSearchBar"); + // reshape menu bar to its content's width if (MENU_RIGHT != gMenuBarView->getRect().getWidth()) { @@ -534,14 +586,69 @@ void LLStatusBar::refresh() snprintf(mRegionDetails.mOwner, MAX_STRING, "Unknown"); mRegionDetails.mTraffic = 0.0f; } + mTextParcelName->setText(location_name); + + + // x = right edge + // loop through: stat graphs, search btn, search text editor, money, buy money, clock + // adjust rect + // finally adjust parcel name rect + + S32 new_right = getRect().getWidth(); + if (search_visible) + { + childGetRect("search_btn", r); + r.translate( new_right - r.mRight, 0); + childSetRect("search_btn", r); + new_right -= r.getWidth(); + + childGetRect("search_editor", r); + r.translate( new_right - r.mRight, 0); + childSetRect("search_editor", r); + new_right -= r.getWidth() + 6; + + } + else + { + childGetRect("stat_btn", r); + r.translate( new_right - r.mRight, 0); + childSetRect("stat_btn", r); + new_right -= r.getWidth() + 6; + } + + // Set rects of money, buy money, time + childGetRect("BalanceText", r); + r.translate( new_right - r.mRight, 0); + childSetRect("BalanceText", r); + new_right -= r.getWidth() - 18; + + childGetRect("buycurrency", r); + r.translate( new_right - r.mRight, 0); + childSetRect("buycurrency", r); + new_right -= r.getWidth() + 6; + + childGetRect("TimeText", r); + // mTextTime->getTextPixelWidth(); + r.translate( new_right - r.mRight, 0); + childSetRect("TimeText", r); + // new_right -= r.getWidth() + MENU_PARCEL_SPACING; + + // Adjust region name and parcel name x += 8; const S32 PARCEL_RIGHT = llmin(mTextTime->getRect().mLeft, mTextParcelName->getTextPixelWidth() + x + 5); r.set(x+4, mRect.getHeight() - 2, PARCEL_RIGHT, 0); mTextParcelName->setRect(r); + + // Set search bar visibility + childSetVisible("search_editor", search_visible); + childSetVisible("search_btn", search_visible); + mSGBandwidth->setVisible(! search_visible); + mSGPacketLoss->setVisible(! search_visible); + childSetEnabled("stat_btn", ! search_visible); } void LLStatusBar::setVisibleForMouselook(bool visible) @@ -551,6 +658,8 @@ void LLStatusBar::setVisibleForMouselook(bool visible) childSetVisible("buycurrency", visible); childSetVisible("search_editor", visible); childSetVisible("search_btn", visible); + mSGBandwidth->setVisible(visible); + mSGPacketLoss->setVisible(visible); setBackgroundVisible(visible); } @@ -662,7 +771,7 @@ static void onClickParcelInfo(void* data) { gParcelMgr->selectParcelAt(gAgent.getPositionGlobal()); - LLFloaterLand::show(); + LLFloaterLand::showInstance(); } static void onClickBalance(void* data) @@ -806,6 +915,12 @@ void LLStatusBar::onClickSearch(void* data) LLFloaterDirectory::showFindAll(search_text); } +// static +void LLStatusBar::onClickStatGraph(void* data) +{ + LLFloaterLagMeter::show(data); +} + BOOL can_afford_transaction(S32 cost) { return((cost <= 0)||((gStatusBar) && (gStatusBar->getBalance() >=cost))); diff --git a/indra/newview/llstatusbar.h b/indra/newview/llstatusbar.h index d0f3e66fa91..78f744c4b5a 100644 --- a/indra/newview/llstatusbar.h +++ b/indra/newview/llstatusbar.h @@ -120,6 +120,7 @@ class LLStatusBar static void onCommitSearch(LLUICtrl*, void* data); static void onClickSearch(void* data); + static void onClickStatGraph(void* data); private: LLTextBox *mTextBalance; @@ -128,6 +129,9 @@ class LLStatusBar LLTextBox* mTextParcelName; + LLStatGraph *mSGBandwidth; + LLStatGraph *mSGPacketLoss; + LLButton *mBtnBuyCurrency; S32 mBalance; diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index fa8213d6621..0c88442fd28 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -35,6 +35,7 @@ #include "indra_constants.h" #include "llclickaction.h" +#include "llmediabase.h" // for status codes #include "llparcel.h" #include "llagent.h" @@ -54,14 +55,17 @@ #include "lltoolmgr.h" #include "lltoolselect.h" #include "llviewercamera.h" +#include "llviewerparcelmedia.h" #include "llviewermenu.h" -#include "llviewerobject.h" #include "llviewerobjectlist.h" +#include "llviewerobject.h" #include "llviewerparcelmgr.h" #include "llviewerwindow.h" +#include "llviewermedia.h" #include "llvoavatar.h" #include "llworld.h" #include "llui.h" +#include "llweb.h" LLToolPie *gToolPie = NULL; @@ -73,6 +77,11 @@ extern void handle_buy(void*); extern BOOL gDebugClicks; +static void handle_click_action_play(); +static void handle_click_action_open_media(LLPointer<LLViewerObject> objectp); +static ECursorType cursor_from_parcel_media(U8 click_action); + + LLToolPie::LLToolPie() : LLTool("Select"), mPieMouseButtonDown( FALSE ), @@ -87,6 +96,7 @@ BOOL LLToolPie::handleMouseDown(S32 x, S32 y, MASK mask) { if (!gCamera) return FALSE; + gPickFaces = TRUE; //left mouse down always picks transparent gViewerWindow->hitObjectOrLandGlobalAsync(x, y, mask, leftMouseCallback, TRUE, TRUE); @@ -137,7 +147,7 @@ BOOL LLToolPie::pickAndShowMenu(S32 x, S32 y, MASK mask, BOOL always_show) else { // not selling passes, get info - LLFloaterLand::show(); + LLFloaterLand::showInstance(); } } @@ -211,6 +221,13 @@ BOOL LLToolPie::pickAndShowMenu(S32 x, S32 y, MASK mask, BOOL always_show) sLeftClickSelection = LLToolSelect::handleObjectSelection(parent, MASK_NONE, FALSE, TRUE); } return TRUE; + case CLICK_ACTION_PLAY: + handle_click_action_play(); + return TRUE; + case CLICK_ACTION_OPEN_MEDIA: + // sClickActionObject = object; + handle_click_action_open_media(object); + return TRUE; } } @@ -411,6 +428,47 @@ U8 final_click_action(LLViewerObject* obj) return click_action; } +ECursorType cursor_from_object(LLViewerObject* object) +{ + LLViewerObject* parent = NULL; + if (object) + { + parent = object->getRootEdit(); + } + U8 click_action = final_click_action(object); + ECursorType cursor = UI_CURSOR_ARROW; + switch(click_action) + { + case CLICK_ACTION_SIT: + cursor = UI_CURSOR_TOOLSIT; + break; + case CLICK_ACTION_BUY: + cursor = UI_CURSOR_TOOLBUY; + break; + case CLICK_ACTION_OPEN: + // Open always opens the parent. + if (parent && parent->allowOpen()) + { + cursor = UI_CURSOR_TOOLOPEN; + } + break; + case CLICK_ACTION_PAY: + if ((object && object->flagTakesMoney()) + || (parent && parent->flagTakesMoney())) + { + cursor = UI_CURSOR_TOOLPAY; + } + break; + case CLICK_ACTION_PLAY: + case CLICK_ACTION_OPEN_MEDIA: + cursor = cursor_from_parcel_media(click_action); + break; + default: + break; + } + return cursor; +} + // When we get object properties after left-clicking on an object // with left-click = buy, if it's the same object, do the buy. // static @@ -486,28 +544,7 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask) if (object && useClickAction(FALSE, mask, object, parent)) { - U8 click_action = final_click_action(object); - ECursorType cursor = UI_CURSOR_ARROW; - switch(click_action) - { - default: break; - case CLICK_ACTION_SIT: cursor = UI_CURSOR_TOOLSIT; break; - case CLICK_ACTION_BUY: cursor = UI_CURSOR_TOOLBUY; break; - case CLICK_ACTION_OPEN: - // Open always opens the parent. - if (parent && parent->allowOpen()) - { - cursor = UI_CURSOR_TOOLOPEN; - } - break; - case CLICK_ACTION_PAY: - if ((object && object->flagTakesMoney()) - || (parent && parent->flagTakesMoney())) - { - cursor = UI_CURSOR_TOOLPAY; - } - break; - } + ECursorType cursor = cursor_from_object(object); gViewerWindow->getWindow()->setCursor(cursor); lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPie (inactive)" << llendl; } @@ -677,4 +714,95 @@ void LLToolPie::render() return; } +static void handle_click_action_play() +{ + LLParcel* parcel = gParcelMgr->getAgentParcel(); + if (!parcel) return; + + LLMediaBase::EStatus status = LLViewerParcelMedia::getStatus(); + switch(status) + { + case LLMediaBase::STATUS_STARTED: + LLViewerParcelMedia::pause(); + break; + + case LLMediaBase::STATUS_PAUSED: + LLViewerParcelMedia::start(); + break; + + default: + LLViewerParcelMedia::play(parcel); + break; + } +} + +static void handle_click_action_open_media(LLPointer<LLViewerObject> objectp) +{ + //FIXME: how do we handle object in different parcel than us? + LLParcel* parcel = gParcelMgr->getAgentParcel(); + if (!parcel) return; + + // did we hit an object? + if (objectp.isNull()) return; + + // did we hit a valid face on the object? + if( gLastHitObjectFace < 0 || gLastHitObjectFace >= objectp->getNumTEs() ) return; + + // is media playing on this face? + if (!LLViewerMedia::isActiveMediaTexture(objectp->getTE(gLastHitObjectFace)->getID())) + { + handle_click_action_play(); + return; + } + + std::string media_url = std::string ( parcel->getMediaURL () ); + std::string media_type = std::string ( parcel->getMediaType() ); + LLString::trim(media_url); + + // Get the scheme, see if that is handled as well. + LLURI uri(media_url); + std::string media_scheme = uri.scheme() != "" ? uri.scheme() : "http"; + + // HACK: This is directly referencing an impl name. BAD! + // This can be removed when we have a truly generic media browser that only + // builds an impl based on the type of url it is passed. + if( LLMediaManager::getInstance()->supportsMediaType( "LLMediaImplLLMozLib", media_scheme, media_type ) ) + { + LLWeb::loadURL(media_url); + } +} + +static ECursorType cursor_from_parcel_media(U8 click_action) +{ + // HACK: This is directly referencing an impl name. BAD! + // This can be removed when we have a truly generic media browser that only + // builds an impl based on the type of url it is passed. + + //FIXME: how do we handle object in different parcel than us? + ECursorType open_cursor = UI_CURSOR_ARROW; + LLParcel* parcel = gParcelMgr->getAgentParcel(); + if (!parcel) return open_cursor; + + std::string media_url = std::string ( parcel->getMediaURL () ); + std::string media_type = std::string ( parcel->getMediaType() ); + LLString::trim(media_url); + + // Get the scheme, see if that is handled as well. + LLURI uri(media_url); + std::string media_scheme = uri.scheme() != "" ? uri.scheme() : "http"; + + if( LLMediaManager::getInstance()->supportsMediaType( "LLMediaImplLLMozLib", media_scheme, media_type ) ) + { + open_cursor = UI_CURSOR_TOOLMEDIAOPEN; + } + + LLMediaBase::EStatus status = LLViewerParcelMedia::getStatus(); + switch(status) + { + case LLMediaBase::STATUS_STARTED: + return click_action == CLICK_ACTION_PLAY ? UI_CURSOR_TOOLPAUSE : open_cursor; + default: + return UI_CURSOR_TOOLPLAY; + } +} diff --git a/indra/newview/llurldispatcher.cpp b/indra/newview/llurldispatcher.cpp index 82b2b597ca6..9e4f1966017 100644 --- a/indra/newview/llurldispatcher.cpp +++ b/indra/newview/llurldispatcher.cpp @@ -39,6 +39,7 @@ #include "llfloaterdirectory.h" #include "llfloaterhtml.h" #include "llfloaterworldmap.h" +#include "llfloaterhtmlhelp.h" #include "llpanellogin.h" #include "llstartup.h" // gStartupState #include "llurlsimstring.h" @@ -159,9 +160,7 @@ bool LLURLDispatcherImpl::dispatchHelp(const std::string& url, BOOL right_mouse) { if (matchPrefix(url, SLURL_SL_HELP_PREFIX)) { -#if LL_LIBXUL_ENABLED gViewerHtmlHelp.show(); -#endif // LL_LIBXUL_ENABLED return true; } return false; diff --git a/indra/newview/llurlhistory.cpp b/indra/newview/llurlhistory.cpp new file mode 100644 index 00000000000..86a12a73fae --- /dev/null +++ b/indra/newview/llurlhistory.cpp @@ -0,0 +1,110 @@ +/** + * @file llurlhistory.cpp + * @author Sam Kolb + * @brief Manages a list of recent URLs + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ +#include "llviewerprecompiledheaders.h" + +#include "llurlhistory.h" + +#include "lldir.h" +#include "llsdserialize.h" + +LLSD LLURLHistory::sHistorySD; + +const int MAX_URL_COUNT = 10; + +///////////////////////////////////////////////////////////////////////////// + +// static +bool LLURLHistory::loadFile(const LLString& filename) +{ + LLSD data; + { + LLString temp_str = gDirUtilp->getLindenUserDir() + gDirUtilp->getDirDelimiter(); + + llifstream file((temp_str + filename).c_str()); + + if (file.is_open()) + { + llinfos << "Loading history.xml file at " << filename << llendl; + LLSDSerialize::fromXML(data, file); + } + + if (data.isUndefined()) + { + llinfos << "file missing, ill-formed, " + "or simply undefined; not changing the" + " file" << llendl; + return false; + } + } + sHistorySD = data; + return true; +} + +// static +bool LLURLHistory::saveFile(const LLString& filename) +{ + LLString temp_str = gDirUtilp->getLindenUserDir() + gDirUtilp->getDirDelimiter(); + llofstream out((temp_str + filename).c_str()); + if (!out.good()) + { + llwarns << "Unable to open " << filename << " for output." << llendl; + return false; + } + + LLSDSerialize::toXML(sHistorySD, out); + + out.close(); + return true; +} +// static +// This function returns a portion of the history llsd that contains the collected +// url history +LLSD LLURLHistory::getURLHistory(const std::string& collection) +{ + if(sHistorySD.has(collection)) + { + return sHistorySD[collection]; + } + return LLSD(); +} + +// static +void LLURLHistory::addURL(const std::string& collection, const std::string& url) +{ + sHistorySD[collection].insert(0, url); + LLURLHistory::limitSize(collection); +} +// static +void LLURLHistory::removeURL(const std::string& collection, const std::string& url) +{ + LLSD::array_iterator iter = sHistorySD[collection].beginArray(); + LLSD::array_iterator end = sHistorySD[collection].endArray(); + for(int index = 0; index < sHistorySD[collection].size(); index++) + { + if(sHistorySD[collection].get(index).asString() == url) + { + sHistorySD[collection].erase(index); + } + } +} + +// static +void LLURLHistory::clear(const std::string& collection) +{ + sHistorySD[ collection ] = LLSD(); +} + +void LLURLHistory::limitSize(const std::string& collection) +{ + while(sHistorySD[collection].size() > MAX_URL_COUNT) + { + sHistorySD[collection].erase(MAX_URL_COUNT); + } +} + diff --git a/indra/newview/llurlhistory.h b/indra/newview/llurlhistory.h new file mode 100644 index 00000000000..210057f746e --- /dev/null +++ b/indra/newview/llurlhistory.h @@ -0,0 +1,37 @@ +/** + * @file llurlhistory.h + * @author Sam Kolb + * @brief Manages a list of recent URLs + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ +#ifndef LLURLHISTORY_H +#define LLURLHISTORY_H + +#include "llstring.h" + +class LLSD; + +class LLURLHistory +{ +public: + // Loads an xml file of URLs. Currently only supports Parcel URL history + static bool loadFile(const LLString& filename); + + // Saves the current history to XML + static bool saveFile(const LLString& filename); + + static LLSD getURLHistory(const std::string& collection); + + static void addURL(const std::string& collection, const std::string& url); + static void removeURL(const std::string& collection, const std::string& url); + static void clear(const std::string& collection); + + static void limitSize(const std::string& collection); + +private: + static LLSD sHistorySD; +}; + +#endif // LLURLHISTORY_H diff --git a/indra/newview/llvieweraudio.cpp b/indra/newview/llvieweraudio.cpp index b8c8e62c4b6..affce91b79c 100644 --- a/indra/newview/llvieweraudio.cpp +++ b/indra/newview/llvieweraudio.cpp @@ -35,12 +35,12 @@ #include "audiosettings.h" #include "llagent.h" #include "llappviewer.h" -#include "llmediaengine.h" #include "llvieweraudio.h" #include "llviewercamera.h" #include "llviewercontrol.h" #include "llviewerwindow.h" #include "llvoiceclient.h" +#include "llviewermedia.h" ///////////////////////////////////////////////////////// @@ -153,13 +153,10 @@ void audio_update_volume(bool force_update) } // Streaming Media - if(LLMediaEngine::getInstance()) - { - F32 media_volume = gSavedSettings.getF32("AudioLevelMedia"); - media_volume = mute_volume * master_volume * (media_volume*media_volume); - BOOL media_muted = gSavedSettings.getBOOL("MuteMedia"); - LLMediaEngine::getInstance()->setVolume(media_muted ? 0.f : media_volume); - } + F32 media_volume = gSavedSettings.getF32("AudioLevelMedia"); + BOOL media_muted = gSavedSettings.getBOOL("MuteMedia"); + media_volume = mute_volume * master_volume * (media_volume*media_volume); + LLViewerMedia::setVolume( media_muted ? 0.0f : media_volume ); // Voice if (gVoiceClient) diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 250b250a7a6..7180683a860 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -261,7 +261,6 @@ void LLFloaterSettingsDebug::updateControl(LLControlBase* controlp) spinner4->setVisible(FALSE); color_swatch->setVisible(FALSE); childSetVisible("val_text", FALSE); - childSetVisible("boolean_combo", FALSE); mComment->setText(LLString::null); if (controlp) @@ -299,6 +298,7 @@ void LLFloaterSettingsDebug::updateControl(LLControlBase* controlp) case TYPE_U32: spinner1->setVisible(TRUE); spinner1->setLabel(LLString("value")); // Debug, don't translate + childSetVisible("boolean_combo", FALSE); if (!spinner1->hasFocus()) { spinner1->setValue(sd); @@ -311,6 +311,7 @@ void LLFloaterSettingsDebug::updateControl(LLControlBase* controlp) case TYPE_S32: spinner1->setVisible(TRUE); spinner1->setLabel(LLString("value")); // Debug, don't translate + childSetVisible("boolean_combo", FALSE); if (!spinner1->hasFocus()) { spinner1->setValue(sd); @@ -323,6 +324,7 @@ void LLFloaterSettingsDebug::updateControl(LLControlBase* controlp) case TYPE_F32: spinner1->setVisible(TRUE); spinner1->setLabel(LLString("value")); // Debug, don't translate + childSetVisible("boolean_combo", FALSE); if (!spinner1->hasFocus()) { spinner1->setPrecision(3); @@ -346,6 +348,7 @@ void LLFloaterSettingsDebug::updateControl(LLControlBase* controlp) break; case TYPE_STRING: childSetVisible("val_text", TRUE); + childSetVisible("boolean_combo", FALSE); if (!childHasFocus("val_text")) { childSetValue("val_text", sd); @@ -353,6 +356,7 @@ void LLFloaterSettingsDebug::updateControl(LLControlBase* controlp) break; case TYPE_VEC3: { + childSetVisible("boolean_combo", FALSE); LLVector3 v; v.setValue(sd); spinner1->setVisible(TRUE); @@ -380,6 +384,7 @@ void LLFloaterSettingsDebug::updateControl(LLControlBase* controlp) } case TYPE_VEC3D: { + childSetVisible("boolean_combo", FALSE); LLVector3d v; v.setValue(sd); spinner1->setVisible(TRUE); @@ -407,6 +412,7 @@ void LLFloaterSettingsDebug::updateControl(LLControlBase* controlp) } case TYPE_RECT: { + childSetVisible("boolean_combo", FALSE); LLRect r; r.setValue(sd); spinner1->setVisible(TRUE); @@ -457,6 +463,7 @@ void LLFloaterSettingsDebug::updateControl(LLControlBase* controlp) } case TYPE_COL4: { + childSetVisible("boolean_combo", FALSE); LLColor4 clr; clr.setValue(sd); color_swatch->setVisible(TRUE); @@ -478,6 +485,7 @@ void LLFloaterSettingsDebug::updateControl(LLControlBase* controlp) } case TYPE_COL3: { + childSetVisible("boolean_combo", FALSE); LLColor3 clr; clr.setValue(sd); color_swatch->setVisible(TRUE); @@ -486,6 +494,7 @@ void LLFloaterSettingsDebug::updateControl(LLControlBase* controlp) } case TYPE_COL4U: { + childSetVisible("boolean_combo", FALSE); LLColor4U clr; clr.setValue(sd); color_swatch->setVisible(TRUE); diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp new file mode 100644 index 00000000000..7a86b1d67c5 --- /dev/null +++ b/indra/newview/llviewermedia.cpp @@ -0,0 +1,608 @@ +/** + * @file llviewermedia.cpp + * @author Callum Prentice & James Cook + * @brief Client interface to the media engine + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ +#include "llviewerprecompiledheaders.h" + +#include "llviewermedia.h" + +#include "llmimetypes.h" +#include "llviewercontrol.h" +#include "llviewerimage.h" +#include "llviewerwindow.h" +#include "llversionviewer.h" +#include "llviewerimagelist.h" + +#include "llevent.h" // LLSimpleListener +#include "llmediamanager.h" +#include "lluuid.h" + +// don't want to include llappviewer.h +extern std::string gChannelName; + +// Implementation functions not exported into header file +class LLViewerMediaImpl + : public LLMediaObserver +{ + public: + LLViewerMediaImpl() + : mMediaSource( NULL ), + mMovieImageID(), + mMovieImageHasMips(false) + { } + + void initControlListeners(); + + void destroyMediaSource(); + + void play(const std::string& media_url, + const std::string& mime_type, + const LLUUID& placeholder_texture_id, + S32 media_width, S32 media_height, U8 media_auto_scale, + U8 media_loop); + + void stop(); + void pause(); + void start(); + void seek(F32 time); + void setVolume(F32 volume); + LLMediaBase::EStatus getStatus(); + + /*virtual*/ void onMediaSizeChange(const EventType& event_in); + /*virtual*/ void onMediaContentsChange(const EventType& event_in); + + void updateMovieImage(const LLUUID& image_id, BOOL active); + void updateImagesMediaStreams(); + LLUUID getMediaTextureID(); + + public: + + // a single media url with some data and an impl. + LLMediaBase* mMediaSource; + LLUUID mMovieImageID; + bool mMovieImageHasMips; + std::string mMediaURL; + std::string mMimeType; + private: + void initializePlaceholderImage(LLViewerImage *placeholder_image, LLMediaBase *media_source); +}; + +static LLViewerMediaImpl sViewerMediaImpl; + +void LLViewerMediaImpl::destroyMediaSource() +{ + LLMediaManager* mgr = LLMediaManager::getInstance(); + if ( mMediaSource ) + { + bool was_playing = LLViewerMedia::isMediaPlaying(); + mMediaSource->remObserver(this); + mgr->destroySource( mMediaSource ); + + // Restore the texture + updateMovieImage(LLUUID::null, was_playing); + + } + mMediaSource = NULL; +} + +void LLViewerMediaImpl::play(const std::string& media_url, + const std::string& mime_type, + const LLUUID& placeholder_texture_id, + S32 media_width, S32 media_height, U8 media_auto_scale, + U8 media_loop) +{ + // first stop any previously playing media + stop(); + + // Save this first, as init/load below may fire events + mMovieImageID = placeholder_texture_id; + + // If the mime_type passed in is different than the cached one, and + // Auto-discovery is turned OFF, replace the cached mime_type with the new one. + if(mime_type != mMimeType && + ! gSavedSettings.getBOOL("AutoMimeDiscovery")) + { + mMimeType = mime_type; + } + LLURI url(media_url); + std::string scheme = url.scheme() != "" ? url.scheme() : "http"; + + LLMediaManager* mgr = LLMediaManager::getInstance(); + mMediaSource = mgr->createSourceFromMimeType(scheme, mMimeType ); + if ( !mMediaSource ) + { + llwarns << "media source create failed " << media_url + << " type " << mMimeType + << llendl; + return; + } + + if ((media_width != 0) && (media_height != 0)) + { + mMediaSource->setRequestedMediaSize(media_width, media_height); + } + + mMediaSource->setLooping(media_loop); + mMediaSource->setAutoScaled(media_auto_scale); + mMediaSource->addObserver( this ); + mMediaSource->navigateTo( media_url ); + mMediaSource->addCommand(LLMediaBase::COMMAND_START); + + // Store the URL and Mime Type + mMediaURL = media_url; + +} + +void LLViewerMediaImpl::stop() +{ + destroyMediaSource(); +} + +void LLViewerMediaImpl::pause() +{ + if(mMediaSource) + { + mMediaSource->addCommand(LLMediaBase::COMMAND_PAUSE); + } +} + +void LLViewerMediaImpl::start() +{ + if(mMediaSource) + { + mMediaSource->addCommand(LLMediaBase::COMMAND_START); + } +} + +void LLViewerMediaImpl::seek(F32 time) +{ + if(mMediaSource) + { + mMediaSource->seek(time); + } +} + +void LLViewerMediaImpl::setVolume(F32 volume) +{ + if(mMediaSource) + { + mMediaSource->setVolume( volume); + } +} + +LLMediaBase::EStatus LLViewerMediaImpl::getStatus() +{ + if (mMediaSource) + { + return mMediaSource->getStatus(); + } + else + { + return LLMediaBase::STATUS_UNKNOWN; + } +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMediaImpl::updateMovieImage(const LLUUID& uuid, BOOL active) +{ + // IF the media image hasn't changed, do nothing + if (mMovieImageID == uuid) + { + return; + } + // If we have changed media uuid, restore the old one + if (!mMovieImageID.isNull()) + { + LLViewerImage* oldImage = LLViewerImage::getImage( mMovieImageID ); + if (oldImage) + { + oldImage->reinit(mMovieImageHasMips); + oldImage->mIsMediaTexture = FALSE; + } + mMovieImageID.setNull(); + } + // If the movie is playing, set the new media image + if (active && !uuid.isNull()) + { + LLViewerImage* viewerImage = LLViewerImage::getImage( uuid ); + if( viewerImage ) + { + mMovieImageID = uuid; + // Can't use mipmaps for movies because they don't update the full image + mMovieImageHasMips = viewerImage->getUseMipMaps(); + viewerImage->reinit(FALSE); + viewerImage->mIsMediaTexture = TRUE; + } + } +} + + +////////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMediaImpl::updateImagesMediaStreams() +{ + LLMediaManager::updateClass(); +} + +void LLViewerMediaImpl::initializePlaceholderImage(LLViewerImage *placeholder_image, LLMediaBase *media_source) +{ + int media_width = media_source->getMediaWidth(); + int media_height = media_source->getMediaHeight(); + //int media_rowspan = media_source->getMediaRowSpan(); + + // if width & height are invalid, don't bother doing anything + if ( media_width < 1 || media_height < 1 ) + return; + + llinfos << "initializing media placeholder" << llendl; + llinfos << "movie image id " << mMovieImageID << llendl; + + int texture_width = LLMediaManager::textureWidthFromMediaWidth( media_width ); + int texture_height = LLMediaManager::textureHeightFromMediaHeight( media_height ); + int texture_depth = media_source->getMediaDepth(); + + // MEDIAOPT: check to see if size actually changed before doing work + placeholder_image->destroyGLTexture(); + // MEDIAOPT: apparently just calling setUseMipMaps(FALSE) doesn't work? + placeholder_image->reinit(FALSE); // probably not needed + + // MEDIAOPT: seems insane that we actually have to make an imageraw then + // immediately discard it + LLPointer<LLImageRaw> raw = new LLImageRaw(texture_width, texture_height, texture_depth); + raw->clear(0x0f, 0x0f, 0x0f, 0xff); + int discard_level = 0; + + // ask media source for correct GL image format constants + placeholder_image->setExplicitFormat(media_source->getTextureFormatInternal(), + media_source->getTextureFormatPrimary(), + media_source->getTextureFormatType()); + + placeholder_image->createGLTexture(discard_level, raw); + + // placeholder_image->setExplicitFormat() + placeholder_image->setUseMipMaps(FALSE); + + // MEDIAOPT: set this dynamically on play/stop + placeholder_image->mIsMediaTexture = true; +} + + + +// virtual +void LLViewerMediaImpl::onMediaContentsChange(const EventType& event_in) +{ + LLMediaBase* media_source = event_in.getSubject(); + LLViewerImage* placeholder_image = gImageList.getImage( mMovieImageID ); + if ((placeholder_image) && (placeholder_image->getHasGLTexture())) + { + if (placeholder_image->getUseMipMaps()) + { + // bad image! NO MIPMAPS! + initializePlaceholderImage(placeholder_image, media_source); + } + + U8* data = media_source->getMediaData(); + S32 x_pos = 0; + S32 y_pos = 0; + S32 width = media_source->getMediaWidth(); + S32 height = media_source->getMediaHeight(); + S32 data_width = media_source->getMediaDataWidth(); + S32 data_height = media_source->getMediaDataHeight(); + placeholder_image->setSubImage(data, data_width, data_height, + x_pos, y_pos, width, height); + } +} + + +// virtual +void LLViewerMediaImpl::onMediaSizeChange(const EventType& event_in) +{ + LLMediaBase* media_source = event_in.getSubject(); + LLViewerImage* placeholder_image = gImageList.getImage( mMovieImageID ); + if (placeholder_image) + { + initializePlaceholderImage(placeholder_image, media_source); + } + else + { + llinfos << "no placeholder image" << llendl; + } +} + + + // Get the image we're using + + /* + // update media stream if required + LLMediaEngine* media_engine = LLMediaEngine::getInstance(); + if (media_engine) + { + if ( media_engine->update() ) + { + LLUUID media_uuid = media_engine->getImageUUID(); + updateMovieImage(media_uuid, TRUE); + if (!media_uuid.isNull()) + { + LLViewerImage* viewerImage = getImage( media_uuid ); + if( viewerImage ) + { + LLMediaBase* renderer = media_engine->getMediaRenderer(); + if ((renderer->getTextureWidth() != viewerImage->getWidth()) || + (renderer->getTextureHeight() != viewerImage->getHeight()) || + (renderer->getTextureDepth() != viewerImage->getComponents()) || + (viewerImage->getHasGLTexture() == FALSE)) + { + // destroy existing GL image + viewerImage->destroyGLTexture(); + + // set new size + viewerImage->setSize( renderer->getTextureWidth(), + renderer->getTextureHeight(), + renderer->getTextureDepth() ); + + LLPointer<LLImageRaw> raw = new LLImageRaw(renderer->getTextureWidth(), + renderer->getTextureHeight(), + renderer->getTextureDepth()); + raw->clear(0x7f,0x7f,0x7f,0xff); + viewerImage->createGLTexture(0, raw); + } + + // Set the explicit format the instance wants + viewerImage->setExplicitFormat(renderer->getTextureFormatInternal(), + renderer->getTextureFormatPrimary(), + renderer->getTextureFormatType(), + renderer->getTextureFormatSwapBytes()); + // This should be redundant, but just in case: + viewerImage->setUseMipMaps(FALSE); + + LLImageRaw* rawImage = media_engine->getImageRaw(); + if ( rawImage ) + { + viewerImage->setSubImage(rawImage, 0, 0, + renderer->getMediaWidth(), + renderer->getMediaHeight()); + } + } + else + { + llwarns << "MediaEngine update unable to get viewer image for GL texture" << llendl; + } + } + } + else + { + LLUUID media_uuid = media_engine->getImageUUID(); + updateMovieImage(media_uuid, FALSE); + } + } + */ + + +////////////////////////////////////////////////////////////////////////////////////////// +LLUUID LLViewerMediaImpl::getMediaTextureID() +{ + return mMovieImageID; +} + +////////////////////////////////////////////////////////////////////////////////////////// +// Wrapper class +////////////////////////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::initClass() +{ + LLMediaManagerData* init_data = new LLMediaManagerData; + +// std::string executable_dir = std::string( arg0 ).substr( 0, std::string( arg0 ).find_last_of("\\/") ); +// std::string component_dir = std::string( executable_dir ).substr( 0, std::string( executable_dir ).find_last_of("\\/") ); +// component_dir = std::string( component_dir ).substr( 0, std::string( component_dir ).find_last_of("\\/") ); +// component_dir = std::string( component_dir ).substr( 0, std::string( component_dir ).find_last_of("\\/") ); +// component_dir += "\\newview\\app_settings\\mozilla"; + + +#if LL_DARWIN + // For Mac OS, we store both the shared libraries and the runtime files (chrome/, plugins/, etc) in + // Second Life.app/Contents/MacOS/. This matches the way Firefox is distributed on the Mac. + std::string component_dir(gDirUtilp->getExecutableDir()); +#elif LL_WINDOWS + std::string component_dir( gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "" ) ); + component_dir += gDirUtilp->getDirDelimiter(); + #ifdef LL_DEBUG + component_dir += "mozilla_debug"; + #else // LL_DEBUG + component_dir += "mozilla"; + #endif // LL_DEBUG +#elif LL_LINUX + std::string component_dir( gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "" ) ); + component_dir += gDirUtilp->getDirDelimiter(); + component_dir += "mozilla-runtime-linux-i686"; +#else + std::string component_dir( gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "" ) ); + component_dir += gDirUtilp->getDirDelimiter(); + component_dir += "mozilla"; +#endif + + // append our magic version number string to the browser user agent id + std::ostringstream codec; + codec << "[Second Life "; + codec << "(" << gChannelName << ")"; + codec << " - " << LL_VERSION_MAJOR << "." << LL_VERSION_MINOR << "." << LL_VERSION_PATCH << "." << LL_VERSION_BUILD; + codec << "]"; + init_data->setBrowserUserAgentId( codec.str() ); + + std::string application_dir = gDirUtilp->getExecutableDir(); + + init_data->setBrowserApplicationDir( application_dir ); + std::string profile_dir = gDirUtilp->getExpandedFilename( LL_PATH_MOZILLA_PROFILE, "" ); + init_data->setBrowserProfileDir( profile_dir ); + init_data->setBrowserComponentDir( component_dir ); + std::string profile_name("Second Life"); + init_data->setBrowserProfileName( profile_name ); + init_data->setBrowserParentWindow( gViewerWindow->getPlatformWindow() ); + + LLMediaManager::initClass( init_data ); + + LLMediaManager* mm = LLMediaManager::getInstance(); + LLMIMETypes::mime_info_map_t::const_iterator it; + for (it = LLMIMETypes::sMap.begin(); it != LLMIMETypes::sMap.end(); ++it) + { + const LLString& mime_type = it->first; + const LLMIMETypes::LLMIMEInfo& info = it->second; + mm->addMimeTypeImplNameMap( mime_type, info.mImpl ); + } +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::cleanupClass() +{ + LLMediaManager::cleanupClass(); +} + +// static +void LLViewerMedia::play(const std::string& media_url, + const std::string& mime_type, + const LLUUID& placeholder_texture_id, + S32 media_width, S32 media_height, U8 media_auto_scale, + U8 media_loop) +{ + sViewerMediaImpl.play(media_url, mime_type, placeholder_texture_id, + media_width, media_height, media_auto_scale, media_loop); +} + +// static +void LLViewerMedia::stop() +{ + sViewerMediaImpl.stop(); +} + +// static +void LLViewerMedia::pause() +{ + sViewerMediaImpl.pause(); +} + +// static +void LLViewerMedia::start() +{ + sViewerMediaImpl.start(); +} + +// static +void LLViewerMedia::seek(F32 time) +{ + sViewerMediaImpl.seek(time); +} + +// static +void LLViewerMedia::setVolume(F32 volume) +{ + sViewerMediaImpl.setVolume(volume); +} + +// static +LLMediaBase::EStatus LLViewerMedia::getStatus() +{ + return sViewerMediaImpl.getStatus(); +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +LLUUID LLViewerMedia::getMediaTextureID() +{ + return sViewerMediaImpl.getMediaTextureID(); +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +bool LLViewerMedia::getMediaSize(S32 *media_width, S32 *media_height) +{ + // make sure we're valid + + if ( sViewerMediaImpl.mMediaSource != NULL ) + { + *media_width = sViewerMediaImpl.mMediaSource->getMediaWidth(); + *media_height = sViewerMediaImpl.mMediaSource->getMediaHeight(); + return true; + } + return false; +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +bool LLViewerMedia::getTextureSize(S32 *texture_width, S32 *texture_height) +{ + if ( sViewerMediaImpl.mMediaSource != NULL ) + { + S32 media_width = sViewerMediaImpl.mMediaSource->getMediaWidth(); + S32 media_height = sViewerMediaImpl.mMediaSource->getMediaHeight(); + *texture_width = LLMediaManager::textureWidthFromMediaWidth( media_width ); + *texture_height = LLMediaManager::textureHeightFromMediaHeight( media_height ); + return true; + } + return false; +} + + +////////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::updateImagesMediaStreams() +{ + sViewerMediaImpl.updateImagesMediaStreams(); +} +////////////////////////////////////////////////////////////////////////////////////////// +// static +bool LLViewerMedia::isMediaPlaying() +{ + LLMediaBase::EStatus status = sViewerMediaImpl.getStatus(); + return (status == LLMediaBase::STATUS_STARTED ); +} +////////////////////////////////////////////////////////////////////////////////////////// +// static +bool LLViewerMedia::isMediaPaused() +{ + LLMediaBase::EStatus status = sViewerMediaImpl.getStatus(); + return (status == LLMediaBase::STATUS_PAUSED); +} +////////////////////////////////////////////////////////////////////////////////////////// +// static +bool LLViewerMedia::hasMedia() +{ + return sViewerMediaImpl.mMediaSource != NULL; +} + +////////////////////////////////////////////////////////////////////////////////////////// +//static +bool LLViewerMedia::isActiveMediaTexture(const LLUUID& id) +{ + return (id.notNull() + && id == getMediaTextureID() + && isMediaPlaying()); +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +std::string LLViewerMedia::getMediaURL() +{ + return sViewerMediaImpl.mMediaURL; +} +////////////////////////////////////////////////////////////////////////////////////////// +// static +std::string LLViewerMedia::getMimeType() +{ + return sViewerMediaImpl.mMimeType; +} +////////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::setMimeType(std::string mime_type) +{ + sViewerMediaImpl.mMimeType = mime_type; +} + + diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h new file mode 100644 index 00000000000..6ecaea54ce3 --- /dev/null +++ b/indra/newview/llviewermedia.h @@ -0,0 +1,49 @@ +/** + * @file llviewermedia.h + * @author Callum Prentice & James Cook + * @brief Client interface to the media engine + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ +#ifndef LLVIEWERMEDIA_H +#define LLVIEWERMEDIA_H + +#include "llmediabase.h" // for status codes + +class LLUUID; + +class LLViewerMedia +{ + public: + static void initClass(); + static void cleanupClass(); + + static void play(const std::string& media_url, + const std::string& mime_type, + const LLUUID& placeholder_texture_id, + S32 media_width, S32 media_height, U8 media_auto_scale, + U8 media_loop); + static void stop(); + static void pause(); + static void start(); + static void seek(F32 time); + static void setVolume(F32 volume); + static LLMediaBase::EStatus getStatus(); + + static LLUUID getMediaTextureID(); + static bool getMediaSize(S32 *media_width, S32 *media_height); + static bool getTextureSize(S32 *texture_width, S32 *texture_height); + static bool isMediaPlaying(); + static bool isMediaPaused(); + static bool hasMedia(); + static bool isActiveMediaTexture(const LLUUID& id); + + static std::string getMediaURL(); + static std::string getMimeType(); + static void setMimeType(std::string mime_type); + + static void updateImagesMediaStreams(); +}; + +#endif // LLVIEWERMEDIA_H diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index f732b0fda02..9c94306fb76 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -104,6 +104,7 @@ #include "llfloatergroupinvite.h" #include "llfloatergroups.h" #include "llfloaterhtml.h" +#include "llfloaterhtmlhelp.h" #include "llfloaterinspect.h" #include "llfloaterlagmeter.h" #include "llfloaterland.h" @@ -5340,7 +5341,7 @@ class LLShowFloater : public view_listener_t gParcelMgr->selectParcelAt(gAgent.getPositionGlobal()); } - LLFloaterLand::show(); + LLFloaterLand::showInstance(); } else if (floater_name == "buy land") { @@ -5365,25 +5366,19 @@ class LLShowFloater : public view_listener_t } else if (floater_name == "help f1") { -#if LL_LIBXUL_ENABLED gViewerHtmlHelp.show( gSavedSettings.getString("HelpHomeURL") ); -#endif } else if (floater_name == "help in-world") { -#if LL_LIBXUL_ENABLED const bool open_app_slurls = true; LLFloaterHtml::getInstance()->show( "in-world_help", open_app_slurls ); -#endif } else if (floater_name == "help additional") { -#if LL_LIBXUL_ENABLED const bool open_app_slurls = true; LLFloaterHtml::getInstance()->show( "additional_help", open_app_slurls ); -#endif } else if (floater_name == "complaint reporter") { diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 6b18fb46bee..5e3ffb5e049 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -5039,7 +5039,7 @@ void callback_load_url(S32 option, void* data) if (0 == option) { - LLWeb::loadURL(infop->mUrl); + LLWeb::loadURL(infop->mUrl); } delete infop; diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index f2ddc173a08..42124610eb9 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -156,8 +156,6 @@ class LLViewerObject : public LLPrimitive, public LLRefCount // Return codes for processUpdateMessage enum { MEDIA_URL_REMOVED = 0x1, MEDIA_URL_ADDED = 0x2, MEDIA_URL_UPDATED = 0x4 }; - enum { CLICK_ACTION_TOUCH = 0, CLICK_ACTION_SIT = 1, CLICK_ACTION_BUY = 2 }; - virtual U32 processUpdateMessage(LLMessageSystem *mesgsys, void **user_data, U32 block_num, diff --git a/indra/newview/llviewerparcelmedia.cpp b/indra/newview/llviewerparcelmedia.cpp new file mode 100644 index 00000000000..33c8ed919c0 --- /dev/null +++ b/indra/newview/llviewerparcelmedia.cpp @@ -0,0 +1,340 @@ +/** + * @file llviewerparcelmedia.cpp + * @author Callum Prentice & James Cook + * @brief Handlers for multimedia on a per-parcel basis + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ +#include "llviewerprecompiledheaders.h" +#include "llviewerparcelmedia.h" + +#include "llagent.h" +#include "llviewercontrol.h" +#include "llviewermedia.h" +#include "llviewerregion.h" +#include "llparcel.h" +#include "llviewerparcelmgr.h" +#include "lluuid.h" +#include "message.h" +#include "llviewerparcelmediaautoplay.h" +#include "llfirstuse.h" + +// Static Variables + +S32 LLViewerParcelMedia::sMediaParcelLocalID = 0; +LLUUID LLViewerParcelMedia::sMediaRegionID; + +// Move this to its own file. +// helper class that tries to download a URL from a web site and calls a method +// on the Panel Land Media and to discover the MIME type +class LLMimeDiscoveryResponder : public LLHTTPClient::Responder +{ +public: + LLMimeDiscoveryResponder( ) + {} + + + + virtual void completedHeader(U32 status, const std::string& reason, const LLSD& content) + { + std::string media_type = content["content-type"].asString(); + std::string::size_type idx1 = media_type.find_first_of(";"); + std::string mime_type = media_type.substr(0, idx1); + completeAny(status, mime_type); + } + + virtual void error( U32 status, const std::string& reason ) + { + completeAny(status, "none/none"); + } + + void completeAny(U32 status, const std::string& mime_type) + { + LLViewerMedia::setMimeType(mime_type); + } +}; + +// static +void LLViewerParcelMedia::initClass() +{ + LLMessageSystem* msg = gMessageSystem; + msg->setHandlerFunc("ParcelMediaCommandMessage", processParcelMediaCommandMessage ); + msg->setHandlerFunc("ParcelMediaUpdate", processParcelMediaUpdate ); + LLViewerParcelMediaAutoPlay::initClass(); +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerParcelMedia::update(LLParcel* parcel) +{ + if (/*LLViewerMedia::hasMedia()*/ true) + { + // we have a player + if (parcel) + { + // we're in a parcel + bool new_parcel = false; + S32 parcelid = parcel->getLocalID(); + LLUUID regionid = gAgent.getRegion()->getRegionID(); + if (parcelid != sMediaParcelLocalID || regionid != sMediaRegionID) + { + sMediaParcelLocalID = parcelid; + sMediaRegionID = regionid; + new_parcel = true; + } + + std::string mediaUrl = std::string ( parcel->getMediaURL () ); + LLString::trim(mediaUrl); + + // has something changed? + if ( ( LLViewerMedia::getMediaURL() != mediaUrl ) + || ( LLViewerMedia::getMediaTextureID() != parcel->getMediaID () ) ) + { + bool video_was_playing = FALSE; + bool same_media_id = LLViewerMedia::getMediaTextureID() == parcel->getMediaID (); + + if (LLViewerMedia::isMediaPlaying()) + { + video_was_playing = TRUE; + } + + if ( !mediaUrl.empty() && same_media_id && ! new_parcel) + { + // Someone has "changed the channel", changing the URL of a video + // you were already watching. Automatically play provided the texture ID is the same + if (video_was_playing) + { + // Poke the mime type in before calling play. + // This is necessary because in this instance we are not waiting + // for the results of a header curl. In order to change the channel + // a mime type MUST be provided. + LLViewerMedia::setMimeType(parcel->getMediaType()); + play(parcel); + } + } + else + { + stop(); + } + + // Discover the MIME type + // Disabled for the time being. Get the mime type from the parcel. + if(gSavedSettings.getBOOL("AutoMimeDiscovery")) + { + LLHTTPClient::getHeaderOnly( mediaUrl, new LLMimeDiscoveryResponder()); + } + else + { + LLViewerMedia::setMimeType(parcel->getMediaType()); + } + + } + } + else + { + stop(); + } + } + /* + else + { + // no audio player, do a first use dialog if their is media here + if (parcel) + { + std::string mediaUrl = std::string ( parcel->getMediaURL () ); + if (!mediaUrl.empty ()) + { + if (gSavedSettings.getWarning("QuickTimeInstalled")) + { + gSavedSettings.setWarning("QuickTimeInstalled", FALSE); + + LLNotifyBox::showXml("NoQuickTime" ); + }; + } + } + } + */ +} + +// static +void LLViewerParcelMedia::play(LLParcel* parcel) +{ + llinfos << "play" << llendl; + + if (!parcel) return; + + if (!gSavedSettings.getBOOL("AudioStreamingVideo")) + return; + + std::string media_url = parcel->getMediaURL(); + std::string mime_type = parcel->getMediaType(); + LLUUID placeholder_texture_id = parcel->getMediaID(); + U8 media_auto_scale = parcel->getMediaAutoScale(); + U8 media_loop = parcel->getMediaLoop(); + S32 media_width = parcel->getMediaWidth(); + S32 media_height = parcel->getMediaHeight(); + LLViewerMedia::play(media_url, mime_type, placeholder_texture_id, + media_width, media_height, media_auto_scale, + media_loop); + LLFirstUse::useMedia(); + + LLViewerParcelMediaAutoPlay::playStarted(); +} + +// static +void LLViewerParcelMedia::stop() +{ + + LLViewerMedia::stop(); +} + +// static +void LLViewerParcelMedia::pause() +{ + LLViewerMedia::pause(); +} + +// static +void LLViewerParcelMedia::start() +{ + LLViewerMedia::start(); + LLFirstUse::useMedia(); + + LLViewerParcelMediaAutoPlay::playStarted(); +} + +// static +void LLViewerParcelMedia::seek(F32 time) +{ + LLViewerMedia::seek(time); +} + + +// static +LLMediaBase::EStatus LLViewerParcelMedia::getStatus() +{ + return LLViewerMedia::getStatus(); +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerParcelMedia::processParcelMediaCommandMessage( LLMessageSystem *msg, void ** ) +{ + // extract the agent id + // LLUUID agent_id; + // msg->getUUID( agent_id ); + + U32 flags; + U32 command; + F32 time; + msg->getU32( "CommandBlock", "Flags", flags ); + msg->getU32( "CommandBlock", "Command", command); + msg->getF32( "CommandBlock", "Time", time ); + + if (flags &( (1<<PARCEL_MEDIA_COMMAND_STOP) + | (1<<PARCEL_MEDIA_COMMAND_PAUSE) + | (1<<PARCEL_MEDIA_COMMAND_PLAY) + | (1<<PARCEL_MEDIA_COMMAND_LOOP) + | (1<<PARCEL_MEDIA_COMMAND_UNLOAD) )) + { + // stop + if( command == PARCEL_MEDIA_COMMAND_STOP ) + { + stop(); + } + else + // pause + if( command == PARCEL_MEDIA_COMMAND_PAUSE ) + { + pause(); + } + else + // play + if( command == PARCEL_MEDIA_COMMAND_PLAY ) + { + if (LLViewerMedia::isMediaPaused()) + { + start(); + } + else + { + LLParcel *parcel = gParcelMgr->getAgentParcel(); + play(parcel); + } + } + else + // loop + if( command == PARCEL_MEDIA_COMMAND_LOOP ) + { + //llinfos << ">>> LLMediaEngine::process_parcel_media with command = " <<( '0' + command ) << llendl; + + // huh? what is play? + //convertImageAndLoadUrl( play ); + //convertImageAndLoadUrl( true, false, std::string() ); + } + else + // unload + if( command == PARCEL_MEDIA_COMMAND_UNLOAD ) + { + stop(); + } + } + + if (flags & (1<<PARCEL_MEDIA_COMMAND_TIME)) + { + if(! LLViewerMedia::hasMedia()) + { + LLParcel *parcel = gParcelMgr->getAgentParcel(); + play(parcel); + } + seek(time); + } +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerParcelMedia::processParcelMediaUpdate( LLMessageSystem *msg, void ** ) +{ + LLUUID media_id; + std::string media_url; + std::string media_type; + S32 media_width = 0; + S32 media_height = 0; + U8 media_auto_scale = FALSE; + U8 media_loop = FALSE; + + msg->getUUID( "DataBlock", "MediaID", media_id ); + char media_url_buffer[257]; + msg->getString( "DataBlock", "MediaURL", 255, media_url_buffer ); + media_url = media_url_buffer; + msg->getU8("DataBlock", "MediaAutoScale", media_auto_scale); + + if (msg->getNumberOfBlocks("DataBlockExtended")) // do we have the extended data? + { + char media_type_buffer[257]; + msg->getString("DataBlockExtended", "MediaType", 255, media_type_buffer); + media_type = media_type_buffer; + msg->getU8("DataBlockExtended", "MediaLoop", media_loop); + msg->getS32("DataBlockExtended", "MediaWidth", media_width); + msg->getS32("DataBlockExtended", "MediaHeight", media_height); + } + + LLParcel *parcel = gParcelMgr->getAgentParcel(); + BOOL same = FALSE; + if (parcel) + { + same = ((parcel->getMediaURL() == media_url) && + (parcel->getMediaType() == media_type) && + (parcel->getMediaID() == media_id) && + (parcel->getMediaWidth() == media_width) && + (parcel->getMediaHeight() == media_height) && + (parcel->getMediaAutoScale() == media_auto_scale) && + (parcel->getMediaLoop() == media_loop)); + } + + if (!same) + LLViewerMedia::play(media_url, media_type, media_id, + media_auto_scale, media_width, media_height, + media_loop); +} diff --git a/indra/newview/llviewerparcelmedia.h b/indra/newview/llviewerparcelmedia.h new file mode 100644 index 00000000000..bf391a83cb8 --- /dev/null +++ b/indra/newview/llviewerparcelmedia.h @@ -0,0 +1,52 @@ +/** + * @file llviewerparcelmedia.h + * @author Callum Prentice & James Cook + * @brief Handlers for multimedia on a per-parcel basis + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ +#ifndef LLVIEWERPARCELMEDIA_H +#define LLVIEWERPARCELMEDIA_H + +#include "llmediabase.h" + +class LLMessageSystem; +class LLParcel; + +// This class understands land parcels, network traffic, LSL media +// transport commands, and talks to the LLViewerMedia class to actually +// do playback. It allows us to remove code from LLViewerParcelMgr. +class LLViewerParcelMedia +{ + public: + static void initClass(); + + static void update(LLParcel* parcel); + // called when the agent's parcel has a new URL, or the agent has + // walked on to a new parcel with media + + static void play(LLParcel* parcel); + // user clicked play button in media transport controls + + static void stop(); + // user clicked stop button in media transport controls + + static void pause(); + static void start(); + // restart after pause - no need for all the setup + + static void seek(F32 time); + // jump to timecode time + + static LLMediaBase::EStatus getStatus(); + + static void processParcelMediaCommandMessage( LLMessageSystem *msg, void ** ); + static void processParcelMediaUpdate( LLMessageSystem *msg, void ** ); + + public: + static S32 sMediaParcelLocalID; + static LLUUID sMediaRegionID; +}; + +#endif diff --git a/indra/newview/llviewerparcelmediaautoplay.cpp b/indra/newview/llviewerparcelmediaautoplay.cpp new file mode 100644 index 00000000000..112c6dfcea9 --- /dev/null +++ b/indra/newview/llviewerparcelmediaautoplay.cpp @@ -0,0 +1,129 @@ +/** + * @file llviewerparcelmediaautoplay.cpp + * @author Karl Stiefvater + * @brief timer to automatically play media in a parcel + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llviewerparcelmediaautoplay.h" +#include "llviewerparcelmedia.h" +#include "llviewercontrol.h" +#include "llviewermedia.h" +#include "llparcel.h" +#include "llviewerparcelmgr.h" +#include "lluuid.h" +#include "message.h" +#include "llviewerimagelist.h" // for texture stats +#include "llagent.h" + +const F32 AUTOPLAY_TIME = 5; // how many seconds before we autoplay +const F32 AUTOPLAY_SIZE = 24*24; // how big the texture must be (pixel area) before we autoplay +const F32 AUTOPLAY_SPEED = 0.1f; // how slow should the agent be moving to autoplay + +LLViewerParcelMediaAutoPlay::LLViewerParcelMediaAutoPlay() : + LLEventTimer(1), + mPlayed(FALSE), + mTimeInParcel(0) +{ +} + +static LLViewerParcelMediaAutoPlay *sAutoPlay = NULL; + +// static +void LLViewerParcelMediaAutoPlay::initClass() +{ + if (!sAutoPlay) + sAutoPlay = new LLViewerParcelMediaAutoPlay; +} + +// static +void LLViewerParcelMediaAutoPlay::cleanupClass() +{ + if (sAutoPlay) + delete sAutoPlay; +} + +// static +void LLViewerParcelMediaAutoPlay::playStarted() +{ + if (sAutoPlay) + { + sAutoPlay->mPlayed = TRUE; + } +} + +BOOL LLViewerParcelMediaAutoPlay::tick() +{ + LLParcel *this_parcel = NULL; + std::string this_media_url; + LLUUID this_media_texture_id; + S32 this_parcel_id = 0; + + if (gParcelMgr) + { + this_parcel = gParcelMgr->getAgentParcel(); + } + + if (this_parcel) + { + this_media_url = std::string(this_parcel->getMediaURL()); + + this_media_texture_id = this_parcel->getMediaID(); + + this_parcel_id = this_parcel->getLocalID(); + } + + if (this_parcel_id != mLastParcelID) + { + // we've entered a new parcel + mPlayed = FALSE; // we haven't autoplayed yet + mTimeInParcel = 0; // reset our timer + mLastParcelID = this_parcel_id; + } + + mTimeInParcel += mPeriod; // increase mTimeInParcel by the amount of time between ticks + + if ((!mPlayed) && // if we've never played + (mTimeInParcel > AUTOPLAY_TIME) && // and if we've been here for so many seconds + (this_media_url.size() != 0) && // and if the parcel has media + (!LLViewerMedia::isMediaPlaying())) // and if the media is not already playing + { + if (this_media_texture_id.notNull()) // and if the media texture is good + { + LLViewerImage *image = gImageList.getImage(this_media_texture_id, FALSE); + + F32 image_size = 0; + + if (image) + { + image_size = image->mMaxVirtualSize; + } + + if (gAgent.getVelocity().magVec() < AUTOPLAY_SPEED) // and if the agent is stopped (slow enough) + { + if (image_size > AUTOPLAY_SIZE) // and if the target texture is big enough on screen + { + if (this_parcel) + { + if (gSavedSettings.getBOOL("ParcelMediaAutoPlayEnable")) + { + // and last but not least, only play when autoplay is enabled + LLViewerParcelMedia::play(this_parcel); + } + } + + mPlayed = TRUE; + } + } + } + } + + + return FALSE; // continue ticking forever please. +} + + + diff --git a/indra/newview/llviewerparcelmediaautoplay.h b/indra/newview/llviewerparcelmediaautoplay.h new file mode 100644 index 00000000000..20b132c8279 --- /dev/null +++ b/indra/newview/llviewerparcelmediaautoplay.h @@ -0,0 +1,32 @@ +/** + * @file llviewerparcelmediaautoplay.h + * @author Karl Stiefvater + * @brief timer to automatically play media in a parcel + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ +#ifndef LLVIEWERPARCELMEDIAAUTOPLAY_H +#define LLVIEWERPARCELMEDIAAUTOPLAY_H + +#include "llmediabase.h" +#include "lltimer.h" + +// timer to automatically play media +class LLViewerParcelMediaAutoPlay : LLEventTimer +{ + public: + LLViewerParcelMediaAutoPlay(); + virtual BOOL tick(); + static void initClass(); + static void cleanupClass(); + static void playStarted(); + + private: + S32 mLastParcelID; + BOOL mPlayed; + F32 mTimeInParcel; +}; + + +#endif // LLVIEWERPARCELMEDIAAUTOPLAY_H diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index eaea0438faa..e027588eaa0 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -38,7 +38,6 @@ #include "indra_constants.h" #include "llcachename.h" #include "llgl.h" -#include "llmediaengine.h" #include "llparcel.h" #include "llsecondlifeurls.h" #include "message.h" @@ -55,14 +54,16 @@ #include "llfloatersellland.h" #include "llfloatertools.h" #include "llnotify.h" +#include "llparcelselection.h" #include "llresmgr.h" #include "llstatusbar.h" #include "llui.h" +#include "llviewerimage.h" #include "llviewerimagelist.h" #include "llviewermenu.h" +#include "llviewerparcelmedia.h" #include "llviewerparceloverlay.h" #include "llviewerregion.h" -//#include "llwebbrowserctrl.h" #include "llworld.h" #include "lloverlaybar.h" #include "roles_constants.h" @@ -78,11 +79,8 @@ U8* LLViewerParcelMgr::sPackedOverlay = NULL; LLUUID gCurrentMovieID = LLUUID::null; -static LLParcelSelection* get_null_parcel_selection(); -template<> - const LLHandle<LLParcelSelection>::NullFunc - LLHandle<LLParcelSelection>::sNullFunc = get_null_parcel_selection; - +LLPointer<LLViewerImage> sBlockedImage; +LLPointer<LLViewerImage> sPassImage; // Local functions void optionally_start_music(const LLString& music_url); @@ -141,10 +139,10 @@ LLViewerParcelMgr::LLViewerParcelMgr() resetSegments(mCollisionSegments); mBlockedImageID.set(gViewerArt.getString("noentrylines.tga")); - mBlockedImage = gImageList.getImage(mBlockedImageID, TRUE, TRUE); + sBlockedImage = gImageList.getImage(mBlockedImageID, TRUE, TRUE); mPassImageID.set(gViewerArt.getString("noentrypasslines.tga")); - mPassImage = gImageList.getImage(mPassImageID, TRUE, TRUE); + sPassImage = gImageList.getImage(mPassImageID, TRUE, TRUE); S32 overlay_size = mParcelsPerEdge * mParcelsPerEdge / PARCEL_OVERLAY_CHUNKS; sPackedOverlay = new U8[overlay_size]; @@ -189,6 +187,9 @@ LLViewerParcelMgr::~LLViewerParcelMgr() delete[] mAgentParcelOverlay; mAgentParcelOverlay = NULL; + + sBlockedImage = NULL; + sPassImage = NULL; } void LLViewerParcelMgr::dump() @@ -1255,30 +1256,45 @@ const LLString& LLViewerParcelMgr::getAgentParcelName() const } -void LLViewerParcelMgr::sendParcelPropertiesUpdate(LLParcel* parcel) +void LLViewerParcelMgr::sendParcelPropertiesUpdate(LLParcel* parcel, bool use_agent_region) { if (!parcel) return; if(!gWorldp) return; - LLViewerRegion *region = gWorldp->getRegionFromPosGlobal( mWestSouth ); + LLViewerRegion *region = use_agent_region ? gAgent.getRegion() : gWorldp->getRegionFromPosGlobal( mWestSouth ); if (!region) return; - LLMessageSystem *msg = gMessageSystem; + LLSD body; + std::string url = gAgent.getRegion()->getCapability("ParcelPropertiesUpdate"); + if (!url.empty()) + { + parcel->packMessage(body); - msg->newMessageFast(_PREHASH_ParcelPropertiesUpdate); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->nextBlockFast(_PREHASH_ParcelData); - msg->addS32Fast(_PREHASH_LocalID, parcel->getLocalID() ); + llinfos << "Sending parcel properties update via capability to:" << url << llendl; - U32 flags = 0x0; - // request new properties update from simulator - flags |= 0x01; - msg->addU32("Flags", flags); + LLHTTPClient::post(url, body, new LLHTTPClient::Responder()); + } + else + { + LLMessageSystem *msg = gMessageSystem; + + msg->newMessageFast(_PREHASH_ParcelPropertiesUpdate); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->nextBlockFast(_PREHASH_ParcelData); + msg->addS32Fast(_PREHASH_LocalID, parcel->getLocalID() ); + + U32 flags = 0x0; + // request new properties update from simulator + flags |= 0x01; + msg->addU32("Flags", flags); + + parcel->packMessage(msg); + + msg->sendReliable( region->getHost() ); + } - parcel->packMessage(msg); - msg->sendReliable( region->getHost() ); } @@ -1363,7 +1379,6 @@ void LLViewerParcelMgr::processParcelOverlay(LLMessageSystem *msg, void **user) } } - // static void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **user) { @@ -1657,19 +1672,6 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use } else { - // It's the agent parcel - BOOL new_parcel = parcel ? FALSE : TRUE; - if (parcel) - { - S32 parcelid = parcel->getLocalID(); - U64 regionid = gAgent.getRegion()->getHandle(); - if (parcelid != gParcelMgr->mMediaParcelId || regionid != gParcelMgr->mMediaRegionId) - { - gParcelMgr->mMediaParcelId = parcelid; - gParcelMgr->mMediaRegionId = regionid; - new_parcel = TRUE; - } - } // look for music. if (gAudiop) { @@ -1714,75 +1716,7 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use }//if gAudiop // now check for video - if (LLMediaEngine::getInstance ()->isAvailable ()) - { - // we have a player - if (parcel) - { - // we're in a parcel - std::string mediaUrl = std::string ( parcel->getMediaURL () ); - LLString::trim(mediaUrl); - - // clean spaces and whatnot - mediaUrl = LLWeb::escapeURL(mediaUrl); - - - // something changed - LLMediaEngine* me = LLMediaEngine::getInstance(); - if ( ( me->getUrl () != mediaUrl ) - || ( me->getImageUUID () != parcel->getMediaID () ) - || ( me->isAutoScaled () != parcel->getMediaAutoScale () ) ) - { - BOOL video_was_playing = FALSE; - LLMediaBase* renderer = me->getMediaRenderer(); - if (renderer && (renderer->isPlaying() || renderer->isLooping())) - { - video_was_playing = TRUE; - } - - stop_video(); - - if ( !mediaUrl.empty () ) - { - // Someone has "changed the channel", changing the URL of a video - // you were already watching. Do we want to automatically start playing? JC - if (!new_parcel - && gSavedSettings.getBOOL("AudioStreamingVideo") - && video_was_playing) - { - start_video(parcel); - } - else - { - // "Prepare" the media engine, but don't auto-play. JC - optionally_prepare_video(parcel); - } - } - } - } - else - { - stop_video(); - } - } - else - { - // no audio player, do a first use dialog if their is media here - if (parcel) - { - std::string mediaUrl = std::string ( parcel->getMediaURL () ); - if (!mediaUrl.empty ()) - { - if (gSavedSettings.getWarning("QuickTimeInstalled")) - { - gSavedSettings.setWarning("QuickTimeInstalled", FALSE); - - LLNotifyBox::showXml("NoQuickTime" ); - }; - } - } - } - + LLViewerParcelMedia::update( parcel ); }; } @@ -1832,94 +1766,6 @@ void callback_start_music(S32 option, void* data) music_url = NULL; } -void prepare_video(const LLParcel *parcel) -{ - std::string mediaUrl; - if (parcel->getParcelFlag(PF_URL_RAW_HTML)) - { - mediaUrl = std::string("data:"); - mediaUrl.append(parcel->getMediaURL()); - } - else - { - mediaUrl = std::string ( parcel->getMediaURL () ); - } - - // clean spaces and whatnot - mediaUrl = LLWeb::escapeURL(mediaUrl); - - LLMediaEngine::getInstance ()->setUrl ( mediaUrl ); - LLMediaEngine::getInstance ()->setImageUUID ( parcel->getMediaID () ); - LLMediaEngine::getInstance ()->setAutoScaled ( parcel->getMediaAutoScale () ? TRUE : FALSE ); // (U8 instead of BOOL for future expansion) -} - -void start_video(const LLParcel *parcel) -{ - prepare_video(parcel); - std::string path( "" ); - LLMediaEngine::getInstance ()->convertImageAndLoadUrl ( true, false, path); -} - -void stop_video() -{ - // set up remote control so stop is selected - LLMediaEngine::getInstance ()->stop (); - if (gOverlayBar) - { - gOverlayBar->refresh (); - } - - if (LLMediaEngine::getInstance ()->isLoaded()) - { - LLMediaEngine::getInstance ()->unload (); - - gImageList.updateMovieImage(LLUUID::null, FALSE); - gCurrentMovieID.setNull(); - } - - LLMediaEngine::getInstance ()->setUrl ( "" ); - LLMediaEngine::getInstance ()->setImageUUID ( LLUUID::null ); - -} - -void optionally_prepare_video(const LLParcel *parcelp) -{ - if (gSavedSettings.getWarning("FirstStreamingVideo")) - { - gViewerWindow->alertXml("ParcelCanPlayMedia", - callback_prepare_video, - (void*)parcelp); - } - else - { - llinfos << "Entering parcel " << parcelp->getLocalID() << " with video " << parcelp->getMediaURL() << llendl; - prepare_video(parcelp); - } -} - - -void callback_prepare_video(S32 option, void* data) -{ - const LLParcel *parcelp = (const LLParcel *)data; - - if (0 == option) - { - gSavedSettings.setBOOL("AudioStreamingVideo", TRUE); - llinfos << "Starting parcel video " << parcelp->getMediaURL() << " on parcel " << parcelp->getLocalID() << llendl; - gMessageSystem->setHandlerFunc("ParcelMediaCommandMessage", LLMediaEngine::process_parcel_media); - gMessageSystem->setHandlerFunc ( "ParcelMediaUpdate", LLMediaEngine::process_parcel_media_update ); - prepare_video(parcelp); - } - else - { - gMessageSystem->setHandlerFunc("ParcelMediaCommandMessage", null_message_callback); - gMessageSystem->setHandlerFunc ( "ParcelMediaUpdate", null_message_callback ); - gSavedSettings.setBOOL("AudioStreamingVideo", FALSE); - } - - gSavedSettings.setWarning("FirstStreamingVideo", FALSE); -} - // static void LLViewerParcelMgr::processParcelAccessListReply(LLMessageSystem *msg, void **user) { @@ -2548,71 +2394,20 @@ void sanitize_corners(const LLVector3d &corner1, east_north_top.mdV[VZ] = llmax( corner1.mdV[VZ], corner2.mdV[VZ] ); } -// -// LLParcelSelection -// -LLParcelSelection::LLParcelSelection() : - mParcel(NULL), - mSelectedMultipleOwners(FALSE), - mWholeParcelSelected(FALSE), - mSelectedSelfCount(0), - mSelectedOtherCount(0), - mSelectedPublicCount(0) -{ -} - -LLParcelSelection::LLParcelSelection(LLParcel* parcel) : - mParcel(parcel), - mSelectedMultipleOwners(FALSE), - mWholeParcelSelected(FALSE), - mSelectedSelfCount(0), - mSelectedOtherCount(0), - mSelectedPublicCount(0) -{ -} -LLParcelSelection::~LLParcelSelection() -{ -} - -BOOL LLParcelSelection::getMultipleOwners() const -{ - return mSelectedMultipleOwners; -} - - -BOOL LLParcelSelection::getWholeParcelSelected() const -{ - return mWholeParcelSelected; -} - - -S32 LLParcelSelection::getClaimableArea() const -{ - const S32 UNIT_AREA = S32( PARCEL_GRID_STEP_METERS * PARCEL_GRID_STEP_METERS ); - return mSelectedPublicCount * UNIT_AREA; -} - -bool LLParcelSelection::hasOthersSelected() const +void LLViewerParcelMgr::cleanupGlobals() { - return mSelectedOtherCount != 0; + delete gParcelMgr; + gParcelMgr = NULL; + LLParcelSelection::sNullSelection = NULL; } -static LLPointer<LLParcelSelection> sNullSelection; - -LLParcelSelection* get_null_parcel_selection() +LLViewerImage* LLViewerParcelMgr::getBlockedImage() const { - if (sNullSelection.isNull()) - { - sNullSelection = new LLParcelSelection; - } - - return sNullSelection; + return sBlockedImage; } -void LLViewerParcelMgr::cleanupGlobals() +LLViewerImage* LLViewerParcelMgr::getPassImage() const { - delete gParcelMgr; - gParcelMgr = NULL; - sNullSelection = NULL; + return sPassImage; } diff --git a/indra/newview/llviewerparcelmgr.h b/indra/newview/llviewerparcelmgr.h index 640c8c5c57c..efea18158c7 100644 --- a/indra/newview/llviewerparcelmgr.h +++ b/indra/newview/llviewerparcelmgr.h @@ -36,11 +36,12 @@ #include "lldarray.h" #include "llframetimer.h" #include "llmemory.h" -#include "llviewerimage.h" +#include "llparcelselection.h" class LLUUID; class LLMessageSystem; class LLParcel; +class LLViewerImage; class LLViewerRegion; // Constants for sendLandOwner @@ -72,49 +73,6 @@ class LLParcelObserver virtual void changed() = 0; }; -class LLParcelSelection : public LLRefCount -{ - friend class LLViewerParcelMgr; - -protected: - ~LLParcelSelection(); - -public: - LLParcelSelection(LLParcel* parcel); - LLParcelSelection(); - - // this can return NULL at any time, as parcel selection - // might have been invalidated. - LLParcel* getParcel() { return mParcel; } - - // Return the number of grid units that are owned by you within - // the selection (computed by server). - S32 getSelfCount() const { return mSelectedSelfCount; } - - // Returns area that will actually be claimed in meters squared. - S32 getClaimableArea() const; - bool hasOthersSelected() const; - - // Does the selection have multiple land owners in it? - BOOL getMultipleOwners() const; - - // Is the entire parcel selected, or just a part? - BOOL getWholeParcelSelected() const; - -protected: - void setParcel(LLParcel* parcel) { mParcel = parcel; } - -protected: - - LLParcel* mParcel; - BOOL mSelectedMultipleOwners; - BOOL mWholeParcelSelected; - S32 mSelectedSelfCount; - S32 mSelectedOtherCount; - S32 mSelectedPublicCount; -}; - -typedef LLHandle<LLParcelSelection> LLParcelSelectionHandle; class LLViewerParcelMgr { @@ -231,7 +189,7 @@ class LLViewerParcelMgr // containing the southwest corner of the selection. // If want_reply_to_update, simulator will send back a ParcelProperties // message. - void sendParcelPropertiesUpdate(LLParcel* parcel); + void sendParcelPropertiesUpdate(LLParcel* parcel, bool use_agent_region = false); // Takes an Access List flag, like AL_ACCESS or AL_BAN void sendParcelAccessListUpdate(U32 which); @@ -300,7 +258,7 @@ class LLViewerParcelMgr static BOOL isParcelOwnedByAgent(const LLParcel* parcelp, U64 group_proxy_power); static BOOL isParcelModifiableByAgent(const LLParcel* parcelp, U64 group_proxy_power); -protected: +private: static void releaseAlertCB(S32 option, void *data); // If the user is claiming land and the current selection @@ -322,6 +280,8 @@ class LLViewerParcelMgr static void callbackJoinLand(S32 option, void* data); //void finishClaim(BOOL user_to_user_sale, U32 join); + LLViewerImage* getBlockedImage() const; + LLViewerImage* getPassImage() const; private: BOOL mSelected; @@ -367,8 +327,6 @@ class LLViewerParcelMgr LLFrameTimer mCollisionTimer; LLUUID mBlockedImageID; LLUUID mPassImageID; - LLPointer<LLViewerImage> mBlockedImage; - LLPointer<LLViewerImage> mPassImage; // Media S32 mMediaParcelId; diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 2a7d2c13677..9f343abdaeb 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1360,6 +1360,7 @@ void LLViewerRegion::setSeedCapability(const std::string& url) capabilityNames.append("MapLayerGod"); capabilityNames.append("NewFileAgentInventory"); capabilityNames.append("ParcelGodReserveForNewbie"); + capabilityNames.append("ParcelPropertiesUpdate"); capabilityNames.append("ParcelVoiceInfoRequest"); capabilityNames.append("ProvisionVoiceAccountRequest"); capabilityNames.append("RemoteParcelRequest"); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 49d4d726475..95adf32ed51 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -60,7 +60,6 @@ #include "linked_lists.h" #include "llassetstorage.h" #include "llfontgl.h" -#include "llmediaengine.h" // mute on minimize #include "llrect.h" #include "llsky.h" #include "llstring.h" diff --git a/indra/newview/llweb.cpp b/indra/newview/llweb.cpp index eac24cebf55..21be9369609 100644 --- a/indra/newview/llweb.cpp +++ b/indra/newview/llweb.cpp @@ -36,8 +36,8 @@ #include "llwindow.h" -//#include "llfloaterhtml.h" #include "llviewercontrol.h" +#include "llfloaterhtmlhelp.h" // static void LLWeb::initClass() @@ -48,7 +48,14 @@ void LLWeb::initClass() // static void LLWeb::loadURL(const std::string& url) { - loadURLExternal(url); + if (gSavedSettings.getBOOL("UseExternalBrowser")) + { + loadURLExternal(url); + } + else + { + LLFloaterMediaBrowser::showInstance(url); + } } @@ -56,9 +63,7 @@ void LLWeb::loadURL(const std::string& url) void LLWeb::loadURLExternal(const std::string& url) { std::string escaped_url = escapeURL(url); -#if LL_LIBXUL_ENABLED spawn_web_browser(escaped_url.c_str()); -#endif } diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 0f17310840f..8c5ad393ab6 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -638,7 +638,7 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerImage* image bool alpha = te->getColor().mV[3] < 0.999f; if (imagep) { - alpha = alpha || (imagep->getComponents() == 4) || (imagep->getComponents() == 2); + alpha = alpha || (imagep->getComponents() == 4 && ! imagep->mIsMediaTexture) || (imagep->getComponents() == 2); } if (alpha) diff --git a/indra/newview/res-sdl/toolmediaopen.BMP b/indra/newview/res-sdl/toolmediaopen.BMP new file mode 100644 index 0000000000000000000000000000000000000000..ac4b231994c1f3ccd69b04c35759fac271b1dbc4 GIT binary patch literal 3128 zcmeH{y$-@K41^8o1``t_BTs;s*?Di?3Qj$+EH^SVI7mpfl+?}7ch2?aay@Tlj1&4J z+Tqz&vPUMe#{6!>HV&Y>EwMQ8pANiU;mS4TK;YhMk@eO5l24C#n)Lb!SBVt!0Rd18 zwi4uX<QpyJL&fruQ=Lh(gyl~qsMrkG3N44Z?Hl;RFj%G|SU7Sw`}P)aK2s!au_FgH z*o}@;N=fIdL{PjfX;w}qCHnE<Ne?(qs#w~t=3^W&%Zln^KrGqjUHK{Sz@O@28wRKT mWL3^$96uNC{K3cD;6S`3_#wm_Kb)mM>9(jk$o=3@5qSVkjf<oJ literal 0 HcmV?d00001 diff --git a/indra/newview/res-sdl/toolpause.BMP b/indra/newview/res-sdl/toolpause.BMP new file mode 100644 index 0000000000000000000000000000000000000000..dd2c6857d28b9eb531819e1774e609e994e4bb37 GIT binary patch literal 3128 zcmeH{Jrcqo5Jpkxw6e0a^aPHzy_e+_xs|@j5{i{DLY6K&1IhC9KJpQGy`N_{$AkJ# zxutS&SKgdE(tkNgnH#94J$fBjEUZ0y*%Qzh<EI)7=-xplR@td@J0F6C5SJ{ellED} z#5JIj+xf~6mG1s1LsYuapZY07tD8UQeh49m1OL>miw7=-@X|WBI9_qQ_vZX8VZM02 zNSGoqj*llJ;CcP(Cr3-7xMfX^a1=bJbTy%hgV*>ba1@JtD|nG_2><2V!WEyxON(uo UUkGY>vcKlGWEIHc;HWtF1ys3!wEzGB literal 0 HcmV?d00001 diff --git a/indra/newview/res-sdl/toolplay.BMP b/indra/newview/res-sdl/toolplay.BMP new file mode 100644 index 0000000000000000000000000000000000000000..9c40d7dbecab270979b9a06fe4a7a0fe5ac1a56c GIT binary patch literal 3128 zcmds%F>As=6vxwoLuiK3DT6}=3H<<4x*4*GG?U;e_yK}zhKvpoH^Eh$0!ro#0SA{3 zet>+2Oo4m=`^Q%fNz<6vm!%KxIPSgs{V)H^o%!*uNSAm+|BCkV-5w+jBT0Hh{`ra8 zWdhyjzmCJ<(ChUUi$!x^2@fsHYPZ|7*$i^*Lg1gz=QxgS+g221JRS!@z^FoeNFdTQ z^*pcB=@^EwUawhHuKA>b-uL}}zpv}M<2c9T@h?J!d=fgHPSfdBRn^I45{BV@DkXeU zNs`2M-BznL7z{R>O<k4h{NZr8-EJBA!XLQA>(6etGfk8Ie6uWDE|=YI7ysvKwW@1H zVLkaz_e+*#+^_w9Us!qHB>1DzNYgaD4^b4|2Ps*F_ia9(mlV`ZiA!2{VU>EoVF&_) zD)l#Oa-1gkLV_KRuOlW&G{+~yFUGSuPe&v6OmGsyq==g*SY7~*Am;{1m9MRm{f*B8 j#|8@dT<}6ZBm5_y7oOv@!>{>Gzy-e{IPsf<gD**6!DY&` literal 0 HcmV?d00001 diff --git a/indra/newview/res/resource.h b/indra/newview/res/resource.h index 2a6a113cb99..4f2e88f7f20 100644 --- a/indra/newview/res/resource.h +++ b/indra/newview/res/resource.h @@ -50,6 +50,7 @@ #define IDC_CURSOR4 153 #define IDC_CURSOR5 154 #define IDI_LCD_LL_ICON 157 +#define IDC_CURSOR6 158 #define IDC_RADIO_56 1000 #define IDC_RADIO_128 1001 #define IDC_RADIO_256 1002 @@ -182,6 +183,7 @@ // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 159 #define _APS_NEXT_RESOURCE_VALUE 167 #define _APS_NEXT_COMMAND_VALUE 40002 #define _APS_NEXT_CONTROL_VALUE 1139 diff --git a/indra/newview/res/toolmediaopen.cur b/indra/newview/res/toolmediaopen.cur new file mode 100644 index 0000000000000000000000000000000000000000..7609989ba7346729af3aaadb6a9412465ad6316a GIT binary patch literal 2238 zcmeHIF%H5o47|jZ!Uhv7Y%ubJ@*BRufK(>l!V?*g%sFk580_vSmab8KzDsgL3uGkh z_uw<(xdOHTjs#mc6A5evB_im$4yqbVHL4}h5@-qhYXbZVTDjL7>5vCPy;(<kck4<- zXRFRj1A%=GI8s@}o2dO1@Ei!_<njV9k=(RaIXefOc=v!a@5sOYUO=PXQ`ft@dz+`} zlV{F;5N%aieo=Y3%o_gl{kr$6KN$FaAr3@QeH48UMPIj~SK>sc4Uq`+69%qRPq<R0 JYhp+A#0O5hX7T_4 literal 0 HcmV?d00001 diff --git a/indra/newview/res/toolpause.cur b/indra/newview/res/toolpause.cur new file mode 100644 index 0000000000000000000000000000000000000000..7a6e85566b195ddd569688529257bb2accfc744b GIT binary patch literal 2238 zcmeHIyAHxI5OW?<*<fO&BO`xMK8vk<4s*Yb0qJl;N)#zM#K1&Oa?_sAPU@irEDXjG zyc*m#z#hPnU<+r$fK8>GbMW3{Sr&+hGTEt~Ku@42@Ph;#zd)&6&3+}rTIbn~)W7mM zp;|s_zP6^wJ?njIBKD2Kb3l=kvmbb`$%8hOwT%NNzInivZ^+;NIgIk|rEjU@yEpd^ zPC;)<%i>9iHqM3ov})zDYWTm;bshNkcVFRwLGH82g*ee^M;HQA!pt@G=q%hpw#0#$ Fh$r?fUF!e< literal 0 HcmV?d00001 diff --git a/indra/newview/res/toolplay.cur b/indra/newview/res/toolplay.cur new file mode 100644 index 0000000000000000000000000000000000000000..0776a17bbc4ca6103218276a2e6ff67ca8f6f1f8 GIT binary patch literal 2238 zcmeHIJ8pwO6rBA8oERyo(uOi6H*hXQ@6Ndbw@A$uC^!Z8a1m)UyT%|S-m~nqJZbp6 zc{A)z!2%WrWeHvles;h+fKP%gd=Un0D&?Gm_a0f6(WgXJRjBJ4P1B%lTXbEAzV9&% z140Oj(?)FxYzb@$JdnVym}>QJHL-kHvyc4K{xT);@Xu*L<bga6C_J)%@lN;mFY5Yk z?JtRi^{M&VwH?nrTNKhn>KldUfFdVnZ}5dCkJ?z)3JV;0ae-G}kWc<|7|W-NUQ(yM zi{Fk;QE!%(i#H|OG#B&JO3LM`;dwsSch1w@-GyJ|;d~0=NK|xsBMgDVh!gK)kIsQ# L2(QEkaUlKxbhK{} literal 0 HcmV?d00001 diff --git a/indra/test/llhttpclient_tut.cpp b/indra/test/llhttpclient_tut.cpp index a4b2f451448..a177d5f2ea0 100644 --- a/indra/test/llhttpclient_tut.cpp +++ b/indra/test/llhttpclient_tut.cpp @@ -116,7 +116,7 @@ namespace tut LLTimer timer; timer.setTimerExpirySec(timeout); - while(!mSawCompleted && !timer.hasExpired()) + while(!mSawCompleted && !mSawCompletedHeader && !timer.hasExpired()) { if (mServerPump) { @@ -167,13 +167,19 @@ namespace tut { return mResult; } + LLSD getHeader() + { + return mHeader; + } protected: bool mSawError; U32 mStatus; std::string mReason; bool mSawCompleted; + bool mSawCompletedHeader; LLSD mResult; + LLSD mHeader; bool mResultDeleted; class Result : public LLHTTPClient::Responder @@ -216,6 +222,14 @@ namespace tut mClient.mSawCompleted = true; } + virtual void completedHeader( + U32 status, const std::string& reason, + const LLSD& content) + { + mClient.mHeader = content; + mClient.mSawCompletedHeader = true; + } + private: HTTPClientTestData& mClient; }; @@ -228,7 +242,9 @@ namespace tut mSawError = false; mStatus = 0; mSawCompleted = false; + mSawCompletedHeader = false; mResult.clear(); + mHeader.clear(); mResultDeleted = false; return Result::build(*this); @@ -344,9 +360,19 @@ namespace tut LLSD body = result["body"]; ensure_equals("echoed result matches", body.size(), expected.size()); } - template<> template<> - void HTTPClientTestObject::test<8>() + void HTTPClientTestObject::test<8>() + { + // This is testing for the presence of the Header in the returned results + // from an HTTP::get call. + LLHTTPClient::get("http://www.secondlife.com/", newResult()); + runThePump(); + ensureStatusOK(); + LLSD header = getHeader(); + ensure_equals("got a header", header.emptyMap().asBoolean(), FALSE); + } + template<> template<> + void HTTPClientTestObject::test<9>() { LLHTTPClient::head("http://www.secondlife.com/", newResult()); runThePump(); diff --git a/scripts/messages/message_template.msg b/scripts/messages/message_template.msg index 5332b1263df..b9c694bbbf1 100644 --- a/scripts/messages/message_template.msg +++ b/scripts/messages/message_template.msg @@ -8714,6 +8714,14 @@ version 2.0 { MediaID LLUUID } { MediaAutoScale U8 } } + { + DataBlockExtended Single + { MediaType Variable 1 } + { MediaDesc Variable 1 } + { MediaWidth S32 } + { MediaHeight S32 } + { MediaLoop U8 } + } } // LandStatRequest -- GitLab