diff options
Diffstat (limited to 'indra/newview')
74 files changed, 2311 insertions, 934 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index e62e4be0f1..21e491e1b5 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -127,6 +127,7 @@ set(viewer_SOURCE_FILES llfloateravatartextures.cpp llfloaterbeacons.cpp llfloaterbuildoptions.cpp + llfloaterbulkpermission.cpp llfloaterbump.cpp llfloaterbuycontents.cpp llfloaterbuy.cpp @@ -150,9 +151,11 @@ set(viewer_SOURCE_FILES llfloatergroupinfo.cpp llfloatergroupinvite.cpp llfloatergroups.cpp + llfloaterhandler.cpp llfloaterhardwaresettings.cpp llfloaterhtml.cpp llfloaterhtmlhelp.cpp + llfloaterhtmlsimple.cpp llfloaterhud.cpp llfloaterimagepreview.cpp llfloaterinspect.cpp @@ -166,9 +169,11 @@ set(viewer_SOURCE_FILES llfloatermute.cpp llfloaternamedesc.cpp llfloaternewim.cpp + llfloaterobjectiminfo.cpp llfloateropenobject.cpp llfloaterparcel.cpp llfloaterpermissionsmgr.cpp + llfloaterperms.cpp llfloaterpostcard.cpp llfloaterpostprocess.cpp llfloaterpreference.cpp @@ -224,6 +229,7 @@ set(viewer_SOURCE_FILES lljoystickbutton.cpp lllandmarklist.cpp lllogchat.cpp + llloginhandler.cpp llmanip.cpp llmaniprotate.cpp llmanipscale.cpp @@ -522,6 +528,7 @@ set(viewer_HEADER_FILES llfloateravatartextures.h llfloaterbeacons.h llfloaterbuildoptions.h + llfloaterbulkpermission.h llfloaterbump.h llfloaterbuy.h llfloaterbuycontents.h @@ -545,9 +552,11 @@ set(viewer_HEADER_FILES llfloatergroupinfo.h llfloatergroupinvite.h llfloatergroups.h + llfloaterhandler.h llfloaterhardwaresettings.h llfloaterhtml.h llfloaterhtmlhelp.h + llfloaterhtmlsimple.h llfloaterhud.h llfloaterimagepreview.h llfloaterinspect.h @@ -561,12 +570,14 @@ set(viewer_HEADER_FILES llfloatermute.h llfloaternamedesc.h llfloaternewim.h + llfloaterobjectiminfo.h llfloateropenobject.h llfloaterparcel.h llfloaterpermissionsmgr.h llfloaterpostcard.h llfloaterpostprocess.h llfloaterpreference.h + llfloaterperms.h llfloaterproperties.h llfloaterregioninfo.h llfloaterreporter.h @@ -618,6 +629,7 @@ set(viewer_HEADER_FILES lllandmarklist.h lllightconstants.h lllogchat.h + llloginhandler.h llmanip.h llmaniprotate.h llmanipscale.h @@ -1030,6 +1042,7 @@ set(viewer_XUI_FILES skins/default/xui/en-us/floater_avatar_textures.xml skins/default/xui/en-us/floater_beacons.xml skins/default/xui/en-us/floater_build_options.xml + skins/default/xui/en-us/floater_bulk_perms.xml skins/default/xui/en-us/floater_bumps.xml skins/default/xui/en-us/floater_buy_contents.xml skins/default/xui/en-us/floater_buy_currency.xml @@ -1052,6 +1065,7 @@ set(viewer_XUI_FILES skins/default/xui/en-us/floater_group_info.xml skins/default/xui/en-us/floater_hardware_settings.xml skins/default/xui/en-us/floater_html.xml + skins/default/xui/en-us/floater_html_simple.xml skins/default/xui/en-us/floater_hud.xml skins/default/xui/en-us/floater_image_preview.xml skins/default/xui/en-us/floater_import.xml @@ -1077,11 +1091,13 @@ set(viewer_XUI_FILES skins/default/xui/en-us/floater_name_description.xml skins/default/xui/en-us/floater_new_im.xml skins/default/xui/en-us/floater_new_outfit_dialog.xml + skins/default/xui/en-us/floater_object_im_info.xml skins/default/xui/en-us/floater_openobject.xml skins/default/xui/en-us/floater_pay_object.xml skins/default/xui/en-us/floater_pay.xml skins/default/xui/en-us/floater_postcard.xml skins/default/xui/en-us/floater_post_process.xml + skins/default/xui/en-us/floater_perm_prefs.xml skins/default/xui/en-us/floater_preferences.xml skins/default/xui/en-us/floater_preview_animation.xml skins/default/xui/en-us/floater_preview_classified.xml diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index e6943869db..a13d883682 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -906,6 +906,204 @@ <key>Value</key> <real>16.0</real> </map> + <key>BulkChangeIncludeAnimations</key> + <map> + <key>Comment</key> + <string>Bulk permission changes affect animations</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>BulkChangeIncludeAnimations</key> + <map> + <key>Comment</key> + <string>Bulk permission changes affect animations</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>BulkChangeIncludeAnimations</key> + <map> + <key>Comment</key> + <string>Bulk permission changes affect animations</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>BulkChangeIncludeAnimations</key> + <map> + <key>Comment</key> + <string>Bulk permission changes affect animations</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>BulkChangeIncludeBodyParts</key> + <map> + <key>Comment</key> + <string>Bulk permission changes affect body parts</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>BulkChangeIncludeClothing</key> + <map> + <key>Comment</key> + <string>Bulk permission changes affect clothing</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>BulkChangeIncludeGestures</key> + <map> + <key>Comment</key> + <string>Bulk permission changes affect gestures</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>BulkChangeIncludeLandmarks</key> + <map> + <key>Comment</key> + <string>Bulk permission changes affect landmarks</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>BulkChangeIncludeNotecards</key> + <map> + <key>Comment</key> + <string>Bulk permission changes affect notecards</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>BulkChangeIncludeObjects</key> + <map> + <key>Comment</key> + <string>Bulk permission changes affect objects</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>BulkChangeIncludeScripts</key> + <map> + <key>Comment</key> + <string>Bulk permission changes affect scripts</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>BulkChangeIncludeSounds</key> + <map> + <key>Comment</key> + <string>Bulk permission changes affect sounds</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>BulkChangeIncludeTextures</key> + <map> + <key>Comment</key> + <string>Bulk permission changes affect textures</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>BulkChangeEveryoneCopy</key> + <map> + <key>Comment</key> + <string>Bulk changed objects can be copied by everyone</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>BulkChangeNextOwnerCopy</key> + <map> + <key>Comment</key> + <string>Bulk changed objects can be copied by next owner</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>BulkChangeNextOwnerModify</key> + <map> + <key>Comment</key> + <string>Bulk changed objects can be modified by next owner</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>BulkChangeNextOwnerTransfer</key> + <map> + <key>Comment</key> + <string>Bulk changed objects can be resold or given away by next owner</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>BulkChangeShareWithGroup</key> + <map> + <key>Comment</key> + <string>Bulk changed objects are shared with the currently active group</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>ButtonFlashCount</key> <map> <key>Comment</key> @@ -1016,6 +1214,17 @@ <key>Value</key> <integer>1</integer> </map> + <key>CameraAngle</key> + <map> + <key>Comment</key> + <string>Camera field of view angle (Radians)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>1.047197551</real> + </map> <key>CameraOffset</key> <map> <key>Comment</key> @@ -2404,6 +2613,17 @@ <key>Value</key> <integer>175</integer> </map> + <key>EveryoneCopy</key> + <map> + <key>Comment</key> + <string>Everyone can copy the newly created objects</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>FPSLogFrequency</key> <map> <key>Comment</key> @@ -3100,7 +3320,24 @@ <integer>0</integer> </array> </map> - <key>FloaterOpenObjectRect</key> + + <key>FloaterObjectIMInfo</key> + <map> + <key>Comment</key> + <string>Rectangle for floater object im info windows</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Rect</string> + <key>Value</key> + <array> + <integer>0</integer> + <integer>300</integer> + <integer>300</integer> + <integer>0</integer> + </array> + </map> + <key>FloaterOpenObjectRect</key> <map> <key>Comment</key> <string>Rectangle for Open Object window</string> @@ -3132,6 +3369,22 @@ <integer>0</integer> </array> </map> + <key>FloaterPermPrefsRect</key> + <map> + <key>Comment</key> + <string>Rectangle for initial permissions preferences</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Rect</string> + <key>Value</key> + <array> + <integer>200</integer> + <integer>250</integer> + <integer>250</integer> + <integer>200</integer> + </array> + </map> <key>FloaterRegionInfo</key> <map> <key>Comment</key> @@ -3971,18 +4224,18 @@ <key>Value</key> <real>0.0</real> </map> - <key>InstallLanguage</key> - <map> - <key>Comment</key> - <string>Language passed from installer (for UI)</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>String</string> - <key>Value</key> - <string>default</string> - </map> - <key>InventoryAutoOpenDelay</key> + <key>InstallLanguage</key> + <map> + <key>Comment</key> + <string>Language passed from installer (for UI)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>String</string> + <key>Value</key> + <string>default</string> + </map> + <key>InventoryAutoOpenDelay</key> <map> <key>Comment</key> <string>Seconds before automatically opening inventory when mouse is over inventory button when performing inventory drag and drop</string> @@ -4966,6 +5219,39 @@ <key>Value</key> <integer>1</integer> </map> + <key>NextOwnerCopy</key> + <map> + <key>Comment</key> + <string>Newly created objects can be copied by next owner</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>NextOwnerModify</key> + <map> + <key>Comment</key> + <string>Newly created objects can be modified by next owner</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>NextOwnerTransfer</key> + <map> + <key>Comment</key> + <string>Newly created objects can be resold or given away by next owner</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> <key>NewCacheLocation</key> <map> <key>Comment</key> @@ -6858,6 +7144,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>ShareWithGroup</key> + <map> + <key>Comment</key> + <string>Newly created objects are shared with the currently active group</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>ShowActiveSpeakers</key> <map> <key>Comment</key> @@ -7858,17 +8155,6 @@ <integer>100</integer> </array> </map> - <key>ToolboxShowMore</key> - <map> - <key>Comment</key> - <string>Whether to show additional build tool controls</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> <key>TrackFocusObject</key> <map> <key>Comment</key> diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index ab2f06ef53..7eca956f7d 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -5830,18 +5830,18 @@ bool LLAgent::teleportCore(bool is_local) return false; } - // Stop all animation before actual teleporting + // Stop all animation before actual teleporting LLVOAvatar* avatarp = gAgent.getAvatarObject(); - if (avatarp) + if (avatarp) { - for ( LLVOAvatar::AnimIterator anim_it= avatarp->mPlayingAnimations.begin() - ; anim_it != avatarp->mPlayingAnimations.end() - ; anim_it++) - { - avatarp->stopMotion(anim_it->first); - } - avatarp->processAnimationStateChanges(); - } + for ( LLVOAvatar::AnimIterator anim_it= avatarp->mPlayingAnimations.begin(); + anim_it != avatarp->mPlayingAnimations.end(); + ++anim_it) + { + avatarp->stopMotion(anim_it->first); + } + avatarp->processAnimationStateChanges(); + } // Don't call LLFirstUse::useTeleport because we don't know // yet if the teleport will succeed. Look in @@ -6020,6 +6020,42 @@ void LLAgent::setTeleportState(ETeleportState state) } } +void LLAgent::stopCurrentAnimations() +{ + // This function stops all current overriding animations on this + // avatar, propagating this change back to the server. + + LLVOAvatar* avatarp = gAgent.getAvatarObject(); + if (avatarp) + { + for ( LLVOAvatar::AnimIterator anim_it = + avatarp->mPlayingAnimations.begin(); + anim_it != avatarp->mPlayingAnimations.end(); + anim_it++) + { + if (anim_it->first == + ANIM_AGENT_SIT_GROUND_CONSTRAINED) + { + // don't cancel a ground-sit anim, as viewers + // use this animation's status in + // determining whether we're sitting. ick. + } + else + { + // stop this animation locally + avatarp->stopMotion(anim_it->first, TRUE); + // ...and tell the server to tell everyone. + sendAnimationRequest(anim_it->first, ANIM_REQUEST_STOP); + } + } + + // re-assert at least the default standing animation, because + // viewers get confused by avs with no associated anims. + sendAnimationRequest(ANIM_AGENT_STAND, + ANIM_REQUEST_START); + } +} + void LLAgent::fidget() { if (!getAFK()) diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index e8537f2fba..f561f55e46 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -372,6 +372,7 @@ public: BOOL canFly(); // Animation functions + void stopCurrentAnimations(); void requestStopMotion( LLMotion* motion ); void onAnimStop(const LLUUID& id); diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp index 3f6a30cf32..2a5f0ea270 100644 --- a/indra/newview/llappviewerlinux.cpp +++ b/indra/newview/llappviewerlinux.cpp @@ -425,8 +425,10 @@ gboolean viewer_app_api_GoSLURL(ViewerAppAPI *obj, gchar *slurl, gboolean **succ llinfos << "Was asked to go to slurl: " << slurl << llendl; - const bool from_external_browser = true; - if (LLURLDispatcher::dispatch(slurl, from_external_browser)) + std::string url = slurl; + LLWebBrowserCtrl* web = NULL; + const bool trusted_browser = false; + if (LLURLDispatcher::dispatch(url, web, trusted_browser)) { // bring window to foreground, as it has just been "launched" from a URL // todo: hmm, how to get there from here? diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp index bad4746870..81990b0464 100644 --- a/indra/newview/llappviewermacosx.cpp +++ b/indra/newview/llappviewermacosx.cpp @@ -48,6 +48,9 @@ #include "llurldispatcher.h" #include <Carbon/Carbon.h> #include "lldir.h" + +class LLWebBrowserCtrl; // for LLURLDispatcher + namespace { // The command line args stored. @@ -260,8 +263,21 @@ OSErr AEGURLHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn) if(result == noErr) { std::string url = buffer; - const bool from_external_browser = true; - LLURLDispatcher::dispatch(url, from_external_browser); + + // Safari 3.2 silently mangles secondlife:///app/ URLs into + // secondlife:/app/ (only one leading slash). + // Fix them up to meet the URL specification. JC + const std::string prefix = "secondlife:/app/"; + std::string test_prefix = url.substr(0, prefix.length()); + LLStringUtil::toLower(test_prefix); + if (test_prefix == prefix) + { + url.replace(0, prefix.length(), "secondlife:///app/"); + } + + LLWebBrowserCtrl* web = NULL; + const bool trusted_browser = false; + LLURLDispatcher::dispatch(url, web, trusted_browser); } return(result); diff --git a/indra/newview/llassetuploadresponders.cpp b/indra/newview/llassetuploadresponders.cpp index 962066471f..d25f827a72 100644 --- a/indra/newview/llassetuploadresponders.cpp +++ b/indra/newview/llassetuploadresponders.cpp @@ -48,12 +48,17 @@ #include "llpreviewgesture.h" #include "llgesturemgr.h" #include "llscrolllistctrl.h" +#include "llsdserialize.h" #include "lluploaddialog.h" #include "llviewerobject.h" +#include "llviewercontrol.h" #include "llviewerobjectlist.h" #include "llviewermenufile.h" #include "llviewerwindow.h" +// When uploading multiple files, don't display any of them when uploading more than this number. +static const S32 FILE_COUNT_DISPLAY_THRESHOLD = 5; + void dialog_refresh_all(); LLAssetUploadResponder::LLAssetUploadResponder(const LLSD &post_data, @@ -193,6 +198,10 @@ LLNewAgentInventoryResponder::LLNewAgentInventoryResponder(const LLSD& post_data void LLNewAgentInventoryResponder::uploadComplete(const LLSD& content) { lldebugs << "LLNewAgentInventoryResponder::result from capabilities" << llendl; + + //std::ostringstream llsdxml; + //LLSDSerialize::toXML(content, llsdxml); + //llinfos << "upload complete content:\n " << llsdxml.str() << llendl; LLAssetType::EType asset_type = LLAssetType::lookup(mPostData["asset_type"].asString()); LLInventoryType::EType inventory_type = LLInventoryType::lookup(mPostData["inventory_type"].asString()); @@ -221,23 +230,39 @@ void LLNewAgentInventoryResponder::uploadComplete(const LLSD& content) << content["new_asset"].asUUID() << " to inventory." << llendl; if(mPostData["folder_id"].asUUID().notNull()) { - LLPermissions perm; - U32 next_owner_perm; - perm.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null); - if (mPostData["inventory_type"].asString() == "snapshot") + //std::ostringstream out; + //LLSDXMLFormatter *formatter = new LLSDXMLFormatter; + //formatter->format(mPostData, out, LLSDFormatter::OPTIONS_PRETTY); + //llinfos << "Post Data: " << out.str() << llendl; + + U32 everyone_perms = PERM_NONE; + U32 group_perms = PERM_NONE; + U32 next_owner_perms = PERM_ALL; + if(content.has("new_next_owner_mask")) { - next_owner_perm = PERM_ALL; + // This is a new sim that provides creation perms so use them. + // Do not assume we got the perms we asked for in mPostData + // since the sim may not have granted them all. + everyone_perms = content["new_everyone_mask"].asInteger(); + group_perms = content["new_group_mask"].asInteger(); + next_owner_perms = content["new_next_owner_mask"].asInteger(); } - else + else { - next_owner_perm = PERM_MOVE | PERM_TRANSFER; + // This old sim doesn't provide creation perms so use old assumption-based perms. + if(mPostData["inventory_type"].asString() != "snapshot") + { + next_owner_perms = PERM_MOVE | PERM_TRANSFER; + } } - perm.initMasks(PERM_ALL, PERM_ALL, PERM_NONE, PERM_NONE, next_owner_perm); + LLPermissions new_perms; + new_perms.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null); + new_perms.initMasks(PERM_ALL, PERM_ALL, everyone_perms, group_perms, next_owner_perms); S32 creation_date_now = time_corrected(); LLPointer<LLViewerInventoryItem> item = new LLViewerInventoryItem(content["new_inventory_item"].asUUID(), mPostData["folder_id"].asUUID(), - perm, + new_perms, content["new_asset"].asUUID(), asset_type, inventory_type, @@ -255,10 +280,9 @@ void LLNewAgentInventoryResponder::uploadComplete(const LLSD& content) if(view) { LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus(); - view->getPanel()->setSelection(content["new_inventory_item"].asUUID(), TAKE_FOCUS_NO); - if((LLAssetType::AT_TEXTURE == asset_type) - || (LLAssetType::AT_SOUND == asset_type)) + if((LLAssetType::AT_TEXTURE == asset_type || LLAssetType::AT_SOUND == asset_type) + && LLFilePicker::instance().getFileCount() <= FILE_COUNT_DISPLAY_THRESHOLD) { view->getPanel()->openSelected(); } @@ -289,8 +313,15 @@ void LLNewAgentInventoryResponder::uploadComplete(const LLSD& content) LLStringUtil::stripNonprintable(asset_name); LLStringUtil::trim(asset_name); + // Continuing the horrible hack above, we need to extract the originally requested permissions data, if any, + // and use them for each next file to be uploaded. Note the requested perms are not the same as the + // granted ones found in the given "content" structure but can still be found in mPostData. -MG + U32 everyone_perms = mPostData.has("everyone_mask") ? mPostData.get("everyone_mask" ).asInteger() : PERM_NONE; + U32 group_perms = mPostData.has("group_mask") ? mPostData.get("group_mask" ).asInteger() : PERM_NONE; + U32 next_owner_perms = mPostData.has("next_owner_mask") ? mPostData.get("next_owner_mask").asInteger() : PERM_NONE; upload_new_resource(next_file, asset_name, asset_name, - 0, LLAssetType::AT_NONE, LLInventoryType::IT_NONE); + 0, LLAssetType::AT_NONE, LLInventoryType::IT_NONE, + next_owner_perms, group_perms, everyone_perms); } } diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp index 2844b888dc..c7a55c969a 100644 --- a/indra/newview/llchatbar.cpp +++ b/indra/newview/llchatbar.cpp @@ -684,10 +684,11 @@ class LLChatHandler : public LLCommandHandler { public: // not allowed from outside the app - LLChatHandler() : LLCommandHandler("chat", false) { } + LLChatHandler() : LLCommandHandler("chat", true) { } // Your code here - bool handle(const LLSD& tokens, const LLSD& queryMap) + bool handle(const LLSD& tokens, const LLSD& query_map, + LLWebBrowserCtrl* web) { if (tokens.size() < 2) return false; S32 channel = tokens[0].asInteger(); diff --git a/indra/newview/llcolorswatch.cpp b/indra/newview/llcolorswatch.cpp index 57f65fed38..2732a17d3a 100644 --- a/indra/newview/llcolorswatch.cpp +++ b/indra/newview/llcolorswatch.cpp @@ -199,7 +199,6 @@ BOOL LLColorSwatchCtrl::handleMouseUp(S32 x, S32 y, MASK mask) return TRUE; } - // assumes GL state is set for 2D void LLColorSwatchCtrl::draw() { @@ -231,10 +230,23 @@ void LLColorSwatchCtrl::draw() } else { - // Draw grey and an X - gl_rect_2d(interior, LLColor4::grey, TRUE); - - gl_draw_x(interior, LLColor4::black); + if (!mFallbackImageName.empty()) + { + LLPointer<LLViewerImage> fallback_image = gImageList.getImageFromFile(mFallbackImageName); + if( fallback_image->getComponents() == 4 ) + { + gl_rect_2d_checkerboard( interior ); + } + gl_draw_scaled_image( interior.mLeft, interior.mBottom, interior.getWidth(), interior.getHeight(), fallback_image); + fallback_image->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) ); + } + else + { + // Draw grey and an X + gl_rect_2d(interior, LLColor4::grey, TRUE); + + gl_draw_x(interior, LLColor4::black); + } } LLUICtrl::draw(); diff --git a/indra/newview/llcolorswatch.h b/indra/newview/llcolorswatch.h index 4b69df8dbb..4f5360b25c 100644 --- a/indra/newview/llcolorswatch.h +++ b/indra/newview/llcolorswatch.h @@ -77,6 +77,7 @@ public: void setCanApplyImmediately(BOOL apply) { mCanApplyImmediately = apply; } void setOnCancelCallback(LLUICtrlCallback cb) { mOnCancelCallback = cb; } void setOnSelectCallback(LLUICtrlCallback cb) { mOnSelectCallback = cb; } + void setFallbackImageName(const std::string& name) { mFallbackImageName = name; } void showPicker(BOOL take_focus); @@ -104,6 +105,7 @@ protected: LLUICtrlCallback mOnSelectCallback; LLPointer<LLUIImage> mAlphaGradientImage; + std::string mFallbackImageName; }; #endif // LL_LLBUTTON_H diff --git a/indra/newview/llcommandhandler.cpp b/indra/newview/llcommandhandler.cpp index 8b86b1be5d..cfe91bc5b5 100644 --- a/indra/newview/llcommandhandler.cpp +++ b/indra/newview/llcommandhandler.cpp @@ -42,7 +42,7 @@ //--------------------------------------------------------------------------- struct LLCommandHandlerInfo { - bool mAllowFromExternalBrowser; + bool mRequireTrustedBrowser; LLCommandHandler* mHandler; // safe, all of these are static objects }; @@ -50,8 +50,12 @@ class LLCommandHandlerRegistry { public: static LLCommandHandlerRegistry& instance(); - void add(const char* cmd, bool allow_from_external_browser, LLCommandHandler* handler); - bool dispatch(const std::string& cmd, bool from_external_browser, const LLSD& params, const LLSD& queryMap); + void add(const char* cmd, bool require_trusted_browser, LLCommandHandler* handler); + bool dispatch(const std::string& cmd, + const LLSD& params, + const LLSD& query_map, + LLWebBrowserCtrl* web, + bool trusted_browser); private: std::map<std::string, LLCommandHandlerInfo> mMap; @@ -67,40 +71,44 @@ LLCommandHandlerRegistry& LLCommandHandlerRegistry::instance() return instance; } -void LLCommandHandlerRegistry::add(const char* cmd, bool allow_from_external_browser, LLCommandHandler* handler) +void LLCommandHandlerRegistry::add(const char* cmd, bool require_trusted_browser, LLCommandHandler* handler) { LLCommandHandlerInfo info; - info.mAllowFromExternalBrowser = allow_from_external_browser; + info.mRequireTrustedBrowser = require_trusted_browser; info.mHandler = handler; mMap[cmd] = info; } bool LLCommandHandlerRegistry::dispatch(const std::string& cmd, - bool from_external_browser, const LLSD& params, - const LLSD& queryMap) + const LLSD& query_map, + LLWebBrowserCtrl* web, + bool trusted_browser) { std::map<std::string, LLCommandHandlerInfo>::iterator it = mMap.find(cmd); if (it == mMap.end()) return false; const LLCommandHandlerInfo& info = it->second; - if (from_external_browser && !info.mAllowFromExternalBrowser) + if (!trusted_browser && info.mRequireTrustedBrowser) { // block request from external browser, but report as // "handled" because it was well formatted. + LL_WARNS_ONCE("SLURL") << "Blocked SLURL command from untrusted browser" << LL_ENDL; return true; } if (!info.mHandler) return false; - return info.mHandler->handle(params, queryMap); + return info.mHandler->handle(params, query_map, web); } //--------------------------------------------------------------------------- // Automatic registration of commands, runs before main() //--------------------------------------------------------------------------- -LLCommandHandler::LLCommandHandler(const char* cmd, bool allow_from_external_browser) +LLCommandHandler::LLCommandHandler(const char* cmd, + bool require_trusted_browser) { - LLCommandHandlerRegistry::instance().add(cmd, allow_from_external_browser, this); + LLCommandHandlerRegistry::instance().add( + cmd, require_trusted_browser, this); } LLCommandHandler::~LLCommandHandler() @@ -115,9 +123,11 @@ LLCommandHandler::~LLCommandHandler() // static bool LLCommandDispatcher::dispatch(const std::string& cmd, - bool from_external_browser, - const LLSD& params, const LLSD& queryMap) + const LLSD& params, + const LLSD& query_map, + LLWebBrowserCtrl* web, + bool trusted_browser) { return LLCommandHandlerRegistry::instance().dispatch( - cmd, from_external_browser, params, queryMap); + cmd, params, query_map, web, trusted_browser); } diff --git a/indra/newview/llcommandhandler.h b/indra/newview/llcommandhandler.h index 8fe40a9a02..bb77b5a542 100644 --- a/indra/newview/llcommandhandler.h +++ b/indra/newview/llcommandhandler.h @@ -33,34 +33,38 @@ #ifndef LLCOMMANDHANDLER_H #define LLCOMMANDHANDLER_H -/* To implement a command "foo" that takes one parameter, - a UUID, do this: +/* Example: secondlife:///app/foo/<uuid> + Command "foo" that takes one parameter, a UUID. class LLFooHandler : public LLCommandHandler { public: // Inform the system you handle commands starting - // with "foo" and they are not allowed from external web - // browser links. - LLFooHandler() : LLCommandHandler("foo", false) { } + // with "foo" and they are only allowed from + // "trusted" (pointed at Linden content) browsers + LLFooHandler() : LLCommandHandler("foo", true) { } // Your code here - bool handle(const LLSD& tokens, const LLSD& queryMap) + bool handle(const LLSD& tokens, const LLSD& query_map, + LLWebBrowserCtrl* web) { if (tokens.size() < 1) return false; LLUUID id( tokens[0] ); - return doFoo(id); + return do_foo(id); } }; -// Creating the object registers with the dispatcher. +// *NOTE: Creating the object registers with the dispatcher. LLFooHandler gFooHandler; + */ +class LLWebBrowserCtrl; + class LLCommandHandler { public: - LLCommandHandler(const char* command, bool allow_from_external_browser); + LLCommandHandler(const char* command, bool allow_from_untrusted_browser); // Automatically registers object to get called when // command is executed. All commands can be processed // in links from LLWebBrowserCtrl, but some (like teleport) @@ -69,9 +73,12 @@ public: virtual ~LLCommandHandler(); virtual bool handle(const LLSD& params, - const LLSD& queryMap) = 0; - // Execute the command with a provided (possibly empty) - // list of parameters. + const LLSD& query_map, + LLWebBrowserCtrl* web) = 0; + // For URL secondlife:///app/foo/bar/baz?cat=1&dog=2 + // @params - array of "bar", "baz", possibly empty + // @query_map - map of "cat" -> 1, "dog" -> 2, possibly empty + // @web - pointer to web browser control, possibly NULL // Return true if you did something, false if the parameters // are invalid or on error. }; @@ -81,9 +88,10 @@ class LLCommandDispatcher { public: static bool dispatch(const std::string& cmd, - bool from_external_browser, const LLSD& params, - const LLSD& queryMap); + const LLSD& query_map, + LLWebBrowserCtrl* web, + bool trusted_browser); // Execute a command registered via the above mechanism, // passing string parameters. // Returns true if command was found and executed correctly. diff --git a/indra/newview/lldynamictexture.h b/indra/newview/lldynamictexture.h index 2e7ba1d422..e5bc3d3170 100644 --- a/indra/newview/lldynamictexture.h +++ b/indra/newview/lldynamictexture.h @@ -33,7 +33,6 @@ #define LL_LLDYNAMICTEXTURE_H #include "llgl.h" -#include "llcamera.h" #include "llcoord.h" #include "llimagegl.h" diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp index 7ac50d7610..91f88277a4 100644 --- a/indra/newview/llfilepicker.cpp +++ b/indra/newview/llfilepicker.cpp @@ -115,7 +115,7 @@ const std::string LLFilePicker::getFirstFile() const std::string LLFilePicker::getNextFile() { - if (mCurrentFile >= (S32)mFiles.size()) + if (mCurrentFile >= getFileCount()) { mLocked = FALSE; return std::string(); @@ -128,7 +128,7 @@ const std::string LLFilePicker::getNextFile() const std::string LLFilePicker::getCurFile() { - if (mCurrentFile >= (S32)mFiles.size()) + if (mCurrentFile >= getFileCount()) { mLocked = FALSE; return std::string(); @@ -824,7 +824,7 @@ BOOL LLFilePicker::getOpenFile(ELoadFilter filter) send_agent_resume(); if (error == noErr) { - if (mFiles.size()) + if (getFileCount()) success = true; } @@ -853,9 +853,9 @@ BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter) send_agent_resume(); if (error == noErr) { - if (mFiles.size()) + if (getFileCount()) success = true; - if (mFiles.size() > 1) + if (getFileCount() > 1) mLocked = TRUE; } @@ -883,7 +883,7 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename) send_agent_resume(); if (error == noErr) { - if (mFiles.size()) + if (getFileCount()) success = true; } @@ -1147,7 +1147,7 @@ BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename gtk_widget_show_all(GTK_WIDGET(picker)); gtk_main(); - rtn = (mFiles.size() == 1); + rtn = (getFileCount() == 1); } gViewerWindow->mWindow->afterDialog(); @@ -1191,7 +1191,7 @@ BOOL LLFilePicker::getOpenFile( ELoadFilter filter ) gtk_widget_show_all(GTK_WIDGET(picker)); gtk_main(); - rtn = (mFiles.size() == 1); + rtn = (getFileCount() == 1); } gViewerWindow->mWindow->afterDialog(); diff --git a/indra/newview/llfilepicker.h b/indra/newview/llfilepicker.h index 83a9357523..4c9b9d590d 100644 --- a/indra/newview/llfilepicker.h +++ b/indra/newview/llfilepicker.h @@ -130,6 +130,11 @@ public: // doing any incrementing. const std::string getCurFile(); + // Returns the index of the current file. + S32 getCurFileNum() const { return mCurrentFile; } + + S32 getFileCount() const { return (S32)mFiles.size(); } + // See llvfs/lldir.h : getBaseFileName and getDirName to extract base or directory names // clear any lists of buffers or whatever, and make sure the file diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp index a686353156..21535895bd 100644 --- a/indra/newview/llfloaterabout.cpp +++ b/indra/newview/llfloaterabout.cpp @@ -116,7 +116,7 @@ LLFloaterAbout::LLFloaterAbout() __DATE__, __TIME__, gSavedSettings.getString("VersionChannelName").c_str()); support_widget->appendColoredText(version, FALSE, FALSE, gColors.getColor("TextFgReadOnlyColor")); - support_widget->appendStyledText(LLTrans::getString("ReleaseNotes"), FALSE, FALSE, &viewer_link_style); + support_widget->appendStyledText(LLTrans::getString("ReleaseNotes"), false, false, viewer_link_style); std::string support; support.append("\n\n"); @@ -152,7 +152,7 @@ LLFloaterAbout::LLFloaterAbout() support.append("\n"); support_widget->appendColoredText(support, FALSE, FALSE, gColors.getColor("TextFgReadOnlyColor")); - support_widget->appendStyledText(LLTrans::getString("ReleaseNotes"), FALSE, FALSE, &server_link_style); + support_widget->appendStyledText(LLTrans::getString("ReleaseNotes"), false, false, server_link_style); support = "\n\n"; } diff --git a/indra/newview/llfloateranimpreview.cpp b/indra/newview/llfloateranimpreview.cpp index 6c42a71fe6..c7e35bcfb5 100644 --- a/indra/newview/llfloateranimpreview.cpp +++ b/indra/newview/llfloateranimpreview.cpp @@ -52,6 +52,7 @@ #include "llfocusmgr.h" #include "llkeyframemotion.h" #include "lllineeditor.h" +#include "llfloaterperms.h" #include "llsliderctrl.h" #include "llspinctrl.h" #include "lltextbox.h" @@ -994,7 +995,7 @@ void LLFloaterAnimPreview::onBtnOK(void* userdata) 0, LLAssetType::AT_NONE, LLInventoryType::IT_ANIMATION, - PERM_NONE, + LLFloaterPerms::getNextOwnerPerms(), LLFloaterPerms::getGroupPerms(), LLFloaterPerms::getEveryonePerms(), name); } else diff --git a/indra/newview/llfloaterbulkpermission.cpp b/indra/newview/llfloaterbulkpermission.cpp new file mode 100644 index 0000000000..b07fa025d1 --- /dev/null +++ b/indra/newview/llfloaterbulkpermission.cpp @@ -0,0 +1,366 @@ +/** + * @file llfloaterbulkpermissions.cpp + * @author Michelle2 Zenovka + * @brief A floater which allows task inventory item's properties to be changed on mass. + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + + +#include "llviewerprecompiledheaders.h" +#include "llfloaterbulkpermission.h" +#include "llfloaterperms.h" // for utilities +#include "llagent.h" +#include "llchat.h" +#include "llviewerwindow.h" +#include "llviewerobject.h" +#include "llviewerobjectlist.h" +#include "llviewerregion.h" +#include "lscript_rt_interface.h" +#include "llviewercontrol.h" +#include "llviewerobject.h" +#include "llviewerregion.h" +#include "llresmgr.h" +#include "llbutton.h" +#include "lldir.h" +#include "llfloaterchat.h" +#include "llviewerstats.h" +#include "lluictrlfactory.h" +#include "llselectmgr.h" + +#include "roles_constants.h" // for GP_OBJECT_MANIPULATE + + +LLFloaterBulkPermission::LLFloaterBulkPermission(const LLSD& seed) : mDone(FALSE) +{ + mID.generate(); + LLUICtrlFactory::getInstance()->buildFloater(this,"floater_bulk_perms.xml"); + childSetEnabled("next_owner_transfer", gSavedSettings.getBOOL("BulkChangeNextOwnerCopy")); + childSetAction("apply", onApplyBtn, this); + childSetAction("close", onCloseBtn, this); + childSetAction("check_all", onCheckAll, this); + childSetAction("check_none", onUncheckAll, this); + childSetCommitCallback("next_owner_copy", &onCommitCopy, this); +} + +void LLFloaterBulkPermission::doApply() +{ + // Inspects a stream of selected object contents and adds modifiable ones to the given array. + class ModifiableGatherer : public LLSelectedNodeFunctor + { + public: + ModifiableGatherer(LLDynamicArray<LLUUID>& q) : mQueue(q) {} + virtual bool apply(LLSelectNode* node) + { + if( node->allowOperationOnNode(PERM_MODIFY, GP_OBJECT_MANIPULATE) ) + { + mQueue.put(node->getObject()->getID()); + } + return true; + } + private: + LLDynamicArray<LLUUID>& mQueue; + }; + LLScrollListCtrl* list = getChild<LLScrollListCtrl>("queue output"); + list->deleteAllItems(); + ModifiableGatherer gatherer(mObjectIDs); + LLSelectMgr::getInstance()->getSelection()->applyToNodes(&gatherer); + if(mObjectIDs.empty()) + { + list->addCommentText(getString("nothing_to_modify_text")); + } + else + { + mDone = FALSE; + if (!start()) + { + llwarns << "Unexpected bulk permission change failure." << llendl; + } + } +} + + +// This is the callback method for the viewer object currently being +// worked on. +// NOT static, virtual! +void LLFloaterBulkPermission::inventoryChanged(LLViewerObject* viewer_object, + InventoryObjectList* inv, + S32, + void* q_id) +{ + //llinfos << "changed object: " << viewer_object->getID() << llendl; + + //Remove this listener from the object since its + //listener callback is now being executed. + + //We remove the listener here because the function + //removeVOInventoryListener removes the listener from a ViewerObject + //which it internally stores. + + //If we call this further down in the function, calls to handleInventory + //and nextObject may update the interally stored viewer object causing + //the removal of the incorrect listener from an incorrect object. + + //Fixes SL-6119:Recompile scripts fails to complete + removeVOInventoryListener(); + + if (viewer_object && inv && (viewer_object->getID() == mCurrentObjectID) ) + { + handleInventory(viewer_object, inv); + } + else + { + // something went wrong... + // note that we're not working on this one, and move onto the + // next object in the list. + llwarns << "No inventory for " << mCurrentObjectID << llendl; + nextObject(); + } +} + +void LLFloaterBulkPermission::onApplyBtn(void* user_data) +{ + LLFloaterBulkPermission* self = (LLFloaterBulkPermission*)user_data; + self->doApply(); +} + +void LLFloaterBulkPermission::onCloseBtn(void* user_data) +{ + LLFloaterBulkPermission* self = (LLFloaterBulkPermission*)user_data; + self->onClose(false); +} + +//static +void LLFloaterBulkPermission::onCommitCopy(LLUICtrl* ctrl, void* data) +{ + // Implements fair use + BOOL copyable = gSavedSettings.getBOOL("BulkChangeNextOwnerCopy"); + if(!copyable) + { + gSavedSettings.setBOOL("BulkChangeNextOwnerTransfer", TRUE); + } + LLCheckBoxCtrl* xfer = static_cast<LLFloaterPerms*>(data)->getChild<LLCheckBoxCtrl>("next_owner_transfer"); + xfer->setEnabled(copyable); +} + +BOOL LLFloaterBulkPermission::start() +{ + // note: number of top-level objects to modify is mObjectIDs.count(). + getChild<LLScrollListCtrl>("queue output")->addCommentText(getString("start_text")); + return nextObject(); +} + +// Go to the next object and start if found. Returns false if no objects left, true otherwise. +BOOL LLFloaterBulkPermission::nextObject() +{ + S32 count; + BOOL successful_start = FALSE; + do + { + count = mObjectIDs.count(); + //llinfos << "Objects left to process = " << count << llendl; + mCurrentObjectID.setNull(); + if(count > 0) + { + successful_start = popNext(); + //llinfos << (successful_start ? "successful" : "unsuccessful") << llendl; + } + } while((mObjectIDs.count() > 0) && !successful_start); + + if(isDone() && !mDone) + { + getChild<LLScrollListCtrl>("queue output")->addCommentText(getString("done_text")); + mDone = TRUE; + } + return successful_start; +} + +// Pop the top object off of the queue. +// Return TRUE if the queue has started, otherwise FALSE. +BOOL LLFloaterBulkPermission::popNext() +{ + // get the head element from the container, and attempt to get its inventory. + BOOL rv = FALSE; + S32 count = mObjectIDs.count(); + if(mCurrentObjectID.isNull() && (count > 0)) + { + mCurrentObjectID = mObjectIDs.get(0); + //llinfos << "mCurrentID: " << mCurrentObjectID << llendl; + mObjectIDs.remove(0); + LLViewerObject* obj = gObjectList.findObject(mCurrentObjectID); + if(obj) + { + //llinfos << "requesting inv for " << mCurrentObjectID << llendl; + LLUUID* id = new LLUUID(mID); + registerVOInventoryListener(obj,id); + requestVOInventory(); + rv = TRUE; + } + else + { + llinfos<<"NULL LLViewerObject" <<llendl; + } + } + + return rv; +} + + +void LLFloaterBulkPermission::doCheckUncheckAll(BOOL check) +{ + gSavedSettings.setBOOL("BulkChangeIncludeAnimations", check); + gSavedSettings.setBOOL("BulkChangeIncludeBodyParts" , check); + gSavedSettings.setBOOL("BulkChangeIncludeClothing" , check); + gSavedSettings.setBOOL("BulkChangeIncludeGestures" , check); + gSavedSettings.setBOOL("BulkChangeIncludeLandmarks" , check); + gSavedSettings.setBOOL("BulkChangeIncludeNotecards" , check); + gSavedSettings.setBOOL("BulkChangeIncludeObjects" , check); + gSavedSettings.setBOOL("BulkChangeIncludeScripts" , check); + gSavedSettings.setBOOL("BulkChangeIncludeSounds" , check); + gSavedSettings.setBOOL("BulkChangeIncludeTextures" , check); +} + + +void LLFloaterBulkPermission::handleInventory(LLViewerObject* viewer_obj, InventoryObjectList* inv) +{ + LLScrollListCtrl* list = getChild<LLScrollListCtrl>("queue output"); + + InventoryObjectList::const_iterator it = inv->begin(); + InventoryObjectList::const_iterator end = inv->end(); + for ( ; it != end; ++it) + { + LLAssetType::EType asstype = (*it)->getType(); + if( + ( asstype == LLAssetType::AT_ANIMATION && gSavedSettings.getBOOL("BulkChangeIncludeAnimations")) || + ( asstype == LLAssetType::AT_BODYPART && gSavedSettings.getBOOL("BulkChangeIncludeBodyParts" )) || + ( asstype == LLAssetType::AT_CLOTHING && gSavedSettings.getBOOL("BulkChangeIncludeClothing" )) || + ( asstype == LLAssetType::AT_GESTURE && gSavedSettings.getBOOL("BulkChangeIncludeGestures" )) || + ( asstype == LLAssetType::AT_LANDMARK && gSavedSettings.getBOOL("BulkChangeIncludeLandmarks" )) || + ( asstype == LLAssetType::AT_NOTECARD && gSavedSettings.getBOOL("BulkChangeIncludeNotecards" )) || + ( asstype == LLAssetType::AT_OBJECT && gSavedSettings.getBOOL("BulkChangeIncludeObjects" )) || + ( asstype == LLAssetType::AT_LSL_TEXT && gSavedSettings.getBOOL("BulkChangeIncludeScripts" )) || + ( asstype == LLAssetType::AT_SOUND && gSavedSettings.getBOOL("BulkChangeIncludeSounds" )) || + ( asstype == LLAssetType::AT_TEXTURE && gSavedSettings.getBOOL("BulkChangeIncludeTextures" ))) + { + LLViewerObject* object = gObjectList.findObject(viewer_obj->getID()); + + if (object) + { + LLInventoryItem* item = (LLInventoryItem*)((LLInventoryObject*)(*it)); + LLViewerInventoryItem* new_item = (LLViewerInventoryItem*)item; + LLPermissions perm(new_item->getPermissions()); + + // chomp the inventory name so it fits in the scroll window nicely + // and the user can see the [OK] + std::string invname; + invname=item->getName().substr(0,item->getName().size() < 30 ? item->getName().size() : 30 ); + + LLUIString status_text = getString("status_text"); + status_text.setArg("[NAME]", invname.c_str()); + // Check whether we appear to have the appropriate permissions to change permission on this item. + // Although the server will disallow any forbidden changes, it is a good idea to guess correctly + // so that we can warn the user. The risk of getting this check wrong is therefore the possibility + // of incorrectly choosing to not attempt to make a valid change. + // + // Trouble is this is extremely difficult to do and even when we know the results + // it is difficult to design the best messaging. Therefore in this initial implementation + // we'll always try to set the requested permissions and consider all cases successful + // and perhaps later try to implement a smarter, friendlier solution. -MG + if(true + //gAgent.allowOperation(PERM_MODIFY, perm, GP_OBJECT_MANIPULATE) // for group and everyone masks + //|| something else // for next owner perms + ) + { + perm.setMaskNext(LLFloaterPerms::getNextOwnerPerms("BulkChange")); + perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("BulkChange")); + perm.setMaskGroup(LLFloaterPerms::getGroupPerms("BulkChange")); + new_item->setPermissions(perm); // here's the beef + updateInventory(object,new_item,TASK_INVENTORY_ITEM_KEY,FALSE); + //status_text.setArg("[STATUS]", getString("status_ok_text")); + status_text.setArg("[STATUS]", ""); + } + else + { + //status_text.setArg("[STATUS]", getString("status_bad_text")); + status_text.setArg("[STATUS]", ""); + } + + list->addCommentText(status_text.getString()); + + //TODO if we are an object inside an object we should check a recuse flag and if set + //open the inventory of the object and recurse - Michelle2 Zenovka + + // if(recurse && ( (*it)->getType() == LLAssetType::AT_OBJECT && processObject)) + // { + // I think we need to get the UUID of the object inside the inventory + // call item->fetchFromServer(); + // we need a call back to say item has arrived *sigh* + // we then need to do something like + // LLUUID* id = new LLUUID(mID); + // registerVOInventoryListener(obj,id); + // requestVOInventory(); + // } + } + } + } + + nextObject(); +} + + +// Avoid inventory callbacks etc by just fire and forgetting the message with the permissions update +// we could do this via LLViewerObject::updateInventory but that uses inventory call backs and buggers +// us up and we would have a dodgy item iterator + +void LLFloaterBulkPermission::updateInventory(LLViewerObject* object, LLViewerInventoryItem* item, U8 key, bool is_new) +{ + LLMemType mt(LLMemType::MTYPE_OBJECT); + + // This slices the object into what we're concerned about on the viewer. + // The simulator will take the permissions and transfer ownership. + LLPointer<LLViewerInventoryItem> task_item = + new LLViewerInventoryItem(item->getUUID(), mID, item->getPermissions(), + item->getAssetUUID(), item->getType(), + item->getInventoryType(), + item->getName(), item->getDescription(), + item->getSaleInfo(), + item->getFlags(), + item->getCreationDate()); + task_item->setTransactionID(item->getTransactionID()); + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_UpdateTaskInventory); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->nextBlockFast(_PREHASH_UpdateData); + msg->addU32Fast(_PREHASH_LocalID, object->mLocalID); + msg->addU8Fast(_PREHASH_Key, key); + msg->nextBlockFast(_PREHASH_InventoryData); + task_item->packMessage(msg); + msg->sendReliable(object->getRegion()->getHost()); +} + diff --git a/indra/newview/llfloaterbulkpermission.h b/indra/newview/llfloaterbulkpermission.h new file mode 100644 index 0000000000..814c472fa3 --- /dev/null +++ b/indra/newview/llfloaterbulkpermission.h @@ -0,0 +1,107 @@ +/** + * @file llfloaterbulkpermissions.h + * @brief Allow multiple task inventory properties to be set in one go. + * @author Michelle2 Zenovka + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLBULKPERMISSION_H +#define LL_LLBULKPERMISSION_H + +#include "lldarray.h" +#include "llinventory.h" +#include "llviewerobject.h" +#include "llvoinventorylistener.h" +#include "llmap.h" +#include "lluuid.h" + +#include "llfloater.h" +#include "llscrolllistctrl.h" + +#include "llviewerinventory.h" + +class LLFloaterBulkPermission : public LLFloater, public LLVOInventoryListener, public LLFloaterSingleton<LLFloaterBulkPermission> +{ +public: + + LLFloaterBulkPermission(const LLSD& seed); + +private: + virtual ~LLFloaterBulkPermission() {} + + BOOL start(); // returns TRUE if the queue has started, otherwise FALSE. + BOOL nextObject(); + BOOL popNext(); + + // This is the callback method for the viewer object currently + // being worked on. + /*virtual*/ void inventoryChanged(LLViewerObject* obj, + InventoryObjectList* inv, + S32 serial_num, + void* queue); + + // This is called by inventoryChanged + void handleInventory(LLViewerObject* viewer_obj, + InventoryObjectList* inv); + + + void updateInventory(LLViewerObject* object, + LLViewerInventoryItem* item, + U8 key, + bool is_new); + + static void onCloseBtn(void* user_data); + static void onApplyBtn(void* user_data); + static void onCommitCopy(LLUICtrl* ctrl, void* data); + static void onCheckAll( void* user_data) { ((LLFloaterBulkPermission*)user_data)->doCheckUncheckAll(TRUE); } + static void onUncheckAll(void* user_data) { ((LLFloaterBulkPermission*)user_data)->doCheckUncheckAll(FALSE); } + + // returns true if this is done + BOOL isDone() const { return (mCurrentObjectID.isNull() || (mObjectIDs.count() == 0)); } + + //Read the settings and Apply the permissions + void doApply(); + void doCheckUncheckAll(BOOL check); + +private: + // UI + LLScrollListCtrl* mMessages; + LLButton* mCloseBtn; + + // Object Queue + LLDynamicArray<LLUUID> mObjectIDs; + LLUUID mCurrentObjectID; + BOOL mDone; + + LLUUID mID; + + const char* mStartString; +}; + +#endif + diff --git a/indra/newview/llfloaterbuyland.cpp b/indra/newview/llfloaterbuyland.cpp index b08dea248f..7aa6af2fea 100644 --- a/indra/newview/llfloaterbuyland.cpp +++ b/indra/newview/llfloaterbuyland.cpp @@ -1020,14 +1020,24 @@ void LLFloaterBuyLandUI::refreshUI() childSetText("info_size", getString("meters_supports_object", string_args)); + F32 cost_per_sqm = 0.0f; + if (mParcelActualArea > 0) + { + cost_per_sqm = (F32)mParcelPrice / (F32)mParcelActualArea; + } - childSetText("info_price", - llformat( - "L$ %d%s", - mParcelPrice, - mParcelSoldWithObjects - ? "\nsold with objects" - : "")); + LLStringUtil::format_map_t info_price_args; + info_price_args["[PRICE]"] = llformat("%d", mParcelPrice); + info_price_args["[PRICE_PER_SQM]"] = llformat("%.1f", cost_per_sqm); + if (mParcelSoldWithObjects) + { + info_price_args["[SOLD_WITH_OBJECTS]"] = getString("sold_with_objects"); + } + else + { + info_price_args["[SOLD_WITH_OBJECTS]"] = getString("sold_without_objects"); + } + childSetText("info_price", getString("info_price_string", info_price_args)); childSetVisible("info_price", mParcelIsForSale); } else diff --git a/indra/newview/llfloaterchat.cpp b/indra/newview/llfloaterchat.cpp index ba02ccc320..cf1dfa42e0 100644 --- a/indra/newview/llfloaterchat.cpp +++ b/indra/newview/llfloaterchat.cpp @@ -189,7 +189,7 @@ void LLFloaterChat::updateConsoleVisibility() || (getHost() && getHost()->isMinimized() )); // are we hosted in a minimized floater? } -void add_timestamped_line(LLViewerTextEditor* edit, const LLChat &chat, const LLColor4& color) +void add_timestamped_line(LLViewerTextEditor* edit, LLChat chat, const LLColor4& color) { std::string line = chat.mText; bool prepend_newline = true; @@ -199,16 +199,22 @@ void add_timestamped_line(LLViewerTextEditor* edit, const LLChat &chat, const LL prepend_newline = false; } - // If the msg is not from an agent (not yourself though), + // If the msg is from an agent (not yourself though), // extract out the sender name and replace it with the hotlinked name. if (chat.mSourceType == CHAT_SOURCE_AGENT && - chat.mFromID != LLUUID::null && - (line.length() > chat.mFromName.length() && line.find(chat.mFromName,0) == 0)) + chat.mFromID != LLUUID::null) + { + chat.mURL = llformat("secondlife:///app/agent/%s/about",chat.mFromID.asString().c_str()); + } + + // If the chat line has an associated url, link it up to the name. + if (!chat.mURL.empty() + && (line.length() > chat.mFromName.length() && line.find(chat.mFromName,0) == 0)) { std::string start_line = line.substr(0, chat.mFromName.length() + 1); line = line.substr(chat.mFromName.length() + 1); - const LLStyleSP &sourceStyle = LLStyleMap::instance().lookup(chat.mFromID); - edit->appendStyledText(start_line, false, prepend_newline, &sourceStyle); + const LLStyleSP &sourceStyle = LLStyleMap::instance().lookup(chat.mFromID,chat.mURL); + edit->appendStyledText(start_line, false, prepend_newline, sourceStyle); prepend_newline = false; } edit->appendColoredText(line, false, prepend_newline, color); diff --git a/indra/newview/llfloaterevent.cpp b/indra/newview/llfloaterevent.cpp index 3579b2a058..523ce6cb73 100644 --- a/indra/newview/llfloaterevent.cpp +++ b/indra/newview/llfloaterevent.cpp @@ -54,9 +54,10 @@ LLMap< U32, LLFloaterEventInfo* > gEventInfoInstances; class LLEventHandler : public LLCommandHandler { public: - // don't allow from external browsers - LLEventHandler() : LLCommandHandler("event", false) { } - bool handle(const LLSD& tokens, const LLSD& queryMap) + // requires trusted browser to trigger + LLEventHandler() : LLCommandHandler("event", true) { } + bool handle(const LLSD& tokens, const LLSD& query_map, + LLWebBrowserCtrl* web) { if (tokens.size() < 2) { diff --git a/indra/newview/llfloaterhandler.cpp b/indra/newview/llfloaterhandler.cpp new file mode 100644 index 0000000000..4c0461e910 --- /dev/null +++ b/indra/newview/llfloaterhandler.cpp @@ -0,0 +1,77 @@ +/** + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ +#include "llviewerprecompiledheaders.h" + +#include "llfloaterhandler.h" + +#include "llfloater.h" +#include "llwebbrowserctrl.h" + +// register with dispatch via global object +LLFloaterHandler gFloaterHandler; + + +LLFloater* get_parent_floater(LLView* view) +{ + LLFloater* floater = NULL; + LLView* parent = view->getParent(); + while (parent) + { + floater = dynamic_cast<LLFloater*>(parent); + if (floater) + { + break; + } + parent = parent->getParent(); + } + return floater; +} + + +bool LLFloaterHandler::handle(const LLSD ¶ms, const LLSD &query_map, LLWebBrowserCtrl *web) +{ + if (params.size() < 2) return false; + LLFloater* floater = NULL; + // *TODO: implement floater lookup by name + if (params[0].asString() == "self") + { + if (web) + { + floater = get_parent_floater(web); + } + } + if (params[1].asString() == "close") + { + if (floater) + { + floater->close(); + return true; + } + } + return false; +} diff --git a/indra/newview/llfloaterhandler.h b/indra/newview/llfloaterhandler.h new file mode 100644 index 0000000000..90e87c07e3 --- /dev/null +++ b/indra/newview/llfloaterhandler.h @@ -0,0 +1,44 @@ +/** + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ +#ifndef LLFLOATERHANDLER_H +#define LLFLOATERHANDLER_H + +// Support for SLURL control of floaters, such as +// secondlife:///app/floater/self/close + +#include "llcommandhandler.h" + +class LLFloaterHandler +: public LLCommandHandler +{ +public: + LLFloaterHandler() : LLCommandHandler("floater", true) { } + bool handle(const LLSD& params, const LLSD& query_map, LLWebBrowserCtrl* web); +}; + +#endif diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index f4a515e0a0..a92634bc31 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -604,6 +604,25 @@ void LLPanelLandGeneral::refresh() mBtnSellLand->setVisible(FALSE); mBtnStopSellLand->setVisible(FALSE); + // show pricing information + S32 area; + S32 claim_price; + S32 rent_price; + F32 dwell; + LLViewerParcelMgr::getInstance()->getDisplayInfo(&area, + &claim_price, + &rent_price, + &for_sale, + &dwell); + + // Area + LLUIString price = childGetText("area_size_text"); + price.setArg("[AREA]", llformat("%d",area)); + mTextPriceLabel->setText(childGetText("area_text")); + mTextPrice->setText(price.getString()); + + mTextDwell->setText(llformat("%.0f", dwell)); + if (for_sale) { mSaleInfoForSale1->setVisible(TRUE); @@ -619,7 +638,15 @@ void LLPanelLandGeneral::refresh() mSaleInfoForSaleNoObjects->setVisible(TRUE); } mSaleInfoNotForSale->setVisible(FALSE); + + F32 cost_per_sqm = 0.0f; + if (area > 0) + { + cost_per_sqm = (F32)parcel->getSalePrice() / (F32)area; + } + mSaleInfoForSale1->setTextArg("[PRICE]", llformat("%d", parcel->getSalePrice())); + mSaleInfoForSale1->setTextArg("[PRICE_PER_SQM]", llformat("%.1f", cost_per_sqm)); if (can_be_sold) { mBtnStopSellLand->setVisible(TRUE); @@ -645,25 +672,6 @@ void LLPanelLandGeneral::refresh() mBtnBuyGroupLand->setEnabled( LLViewerParcelMgr::getInstance()->canAgentBuyParcel(parcel, true)); - // show pricing information - S32 area; - S32 claim_price; - S32 rent_price; - F32 dwell; - LLViewerParcelMgr::getInstance()->getDisplayInfo(&area, - &claim_price, - &rent_price, - &for_sale, - &dwell); - - // Area - LLUIString price = getString("area_size_text"); - price.setArg("[AREA]", llformat("%d",area)); - mTextPriceLabel->setText(getString("area_text")); - mTextPrice->setText(price.getString()); - - mTextDwell->setText(llformat("%.0f", dwell)); - if(region_owner) { mBtnReclaimLand->setEnabled( @@ -1716,8 +1724,6 @@ LLPanelLandOptions::LLPanelLandOptions(LLParcelSelectionHandle& parcel) BOOL LLPanelLandOptions::postBuild() { - - mCheckEditObjects = getChild<LLCheckBoxCtrl>( "edit objects check"); childSetCommitCallback("edit objects check", onCommitAny, this); @@ -1829,6 +1835,8 @@ BOOL LLPanelLandOptions::postBuild() mLandingTypeCombo = getChild<LLComboBox>( "landing type"); childSetCommitCallback("landing type", onCommitAny, this); + getChild<LLTextureCtrl>("snapshot_ctrl")->setFallbackImageName("default_land_picture.j2c"); + return TRUE; } diff --git a/indra/newview/llfloaternamedesc.cpp b/indra/newview/llfloaternamedesc.cpp index f53482a476..b16351af17 100644 --- a/indra/newview/llfloaternamedesc.cpp +++ b/indra/newview/llfloaternamedesc.cpp @@ -43,6 +43,7 @@ #include "llradiogroup.h" #include "lldbstrings.h" #include "lldir.h" +#include "llfloaterperms.h" #include "llviewercontrol.h" #include "llviewermenufile.h" // upload_new_resource() #include "lluictrlfactory.h" @@ -180,7 +181,8 @@ void LLFloaterNameDesc::onBtnOK( void* userdata ) upload_new_resource(fp->mFilenameAndPath, // file fp->childGetValue("name_form").asString(), fp->childGetValue("description_form").asString(), - 0, LLAssetType::AT_NONE, LLInventoryType::IT_NONE); + 0, LLAssetType::AT_NONE, LLInventoryType::IT_NONE, + LLFloaterPerms::getNextOwnerPerms(), LLFloaterPerms::getGroupPerms(), LLFloaterPerms::getEveryonePerms()); fp->close(false); } diff --git a/indra/newview/llfloaterparcel.cpp b/indra/newview/llfloaterparcel.cpp index 59e95fb943..bbe278f885 100644 --- a/indra/newview/llfloaterparcel.cpp +++ b/indra/newview/llfloaterparcel.cpp @@ -51,9 +51,10 @@ LLMap< const LLUUID, LLFloaterParcelInfo* > gPlaceInfoInstances; class LLParcelHandler : public LLCommandHandler { public: - // don't allow from external browsers - LLParcelHandler() : LLCommandHandler("parcel", false) { } - bool handle(const LLSD& params, const LLSD& queryMap) + // requires trusted browser to trigger + LLParcelHandler() : LLCommandHandler("parcel", true) { } + bool handle(const LLSD& params, const LLSD& query_map, + LLWebBrowserCtrl* web) { if (params.size() < 2) { diff --git a/indra/newview/llfloaterperms.cpp b/indra/newview/llfloaterperms.cpp new file mode 100644 index 0000000000..9405bc61b2 --- /dev/null +++ b/indra/newview/llfloaterperms.cpp @@ -0,0 +1,157 @@ +/** + * @file llfloaterperms.cpp + * @brief Asset creation permission preferences. + * @author Coco + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2007, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llalertdialog.h" +#include "llcheckboxctrl.h" +#include "llfloaterperms.h" +#include "llviewercontrol.h" +#include "llviewerwindow.h" +#include "lluictrlfactory.h" +#include "llpermissions.h" + + +LLFloaterPerms::LLFloaterPerms(const LLSD& seed) +{ + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_perm_prefs.xml"); +} + +BOOL LLFloaterPerms::postBuild() +{ + childSetEnabled("next_owner_transfer", gSavedSettings.getBOOL("NextOwnerCopy")); + childSetAction("help", onClickHelp, this); + childSetAction("ok", onClickOK, this); + childSetAction("cancel", onClickCancel, this); + childSetCommitCallback("next_owner_copy", &onCommitCopy, this); + + refresh(); + + return TRUE; +} + +//static +void LLFloaterPerms::onClickOK(void* data) +{ + LLFloaterPerms* self = static_cast<LLFloaterPerms*>(data); + self->ok(); + self->close(); +} + +//static +void LLFloaterPerms::onClickCancel(void* data) +{ + LLFloaterPerms* self = static_cast<LLFloaterPerms*>(data); + self->cancel(); + self->close(); +} + +//static +void LLFloaterPerms::onCommitCopy(LLUICtrl* ctrl, void* data) +{ + // Implements fair use + BOOL copyable = gSavedSettings.getBOOL("NextOwnerCopy"); + if(!copyable) + { + gSavedSettings.setBOOL("NextOwnerTransfer", TRUE); + } + LLCheckBoxCtrl* xfer = static_cast<LLFloaterPerms*>(data)->getChild<LLCheckBoxCtrl>("next_owner_transfer"); + xfer->setEnabled(copyable); +} + +void LLFloaterPerms::ok() +{ + refresh(); // Changes were already applied to saved settings. Refreshing internal values makes it official. +} + +void LLFloaterPerms::cancel() +{ + gSavedSettings.setBOOL("ShareWithGroup", mShareWithGroup); + gSavedSettings.setBOOL("EveryoneCopy", mEveryoneCopy); + gSavedSettings.setBOOL("NextOwnerCopy", mNextOwnerCopy); + gSavedSettings.setBOOL("NextOwnerModify", mNextOwnerModify); + gSavedSettings.setBOOL("NextOwnerTransfer", mNextOwnerTransfer); +} + +void LLFloaterPerms::refresh() +{ + mShareWithGroup = gSavedSettings.getBOOL("ShareWithGroup"); + mEveryoneCopy = gSavedSettings.getBOOL("EveryoneCopy"); + mNextOwnerCopy = gSavedSettings.getBOOL("NextOwnerCopy"); + mNextOwnerModify = gSavedSettings.getBOOL("NextOwnerModify"); + mNextOwnerTransfer = gSavedSettings.getBOOL("NextOwnerTransfer"); +} + +void LLFloaterPerms::onClose(bool app_quitting) +{ + // Cancel any unsaved changes before closing. + // Note: when closed due to the OK button this amounts to a no-op. + cancel(); + LLFloater::onClose(app_quitting); +} + +//static +U32 LLFloaterPerms::getGroupPerms(std::string prefix) +{ + return gSavedSettings.getBOOL(prefix+"ShareWithGroup") ? PERM_COPY : PERM_NONE; +} + +//static +U32 LLFloaterPerms::getEveryonePerms(std::string prefix) +{ + return gSavedSettings.getBOOL(prefix+"EveryoneCopy") ? PERM_COPY : PERM_NONE; +} + +//static +U32 LLFloaterPerms::getNextOwnerPerms(std::string prefix) +{ + U32 flags = 0; + if ( gSavedSettings.getBOOL(prefix+"NextOwnerCopy") ) + { + flags |= PERM_COPY; + } + if ( gSavedSettings.getBOOL(prefix+"NextOwnerModify") ) + { + flags |= PERM_MODIFY; + } + if ( gSavedSettings.getBOOL(prefix+"NextOwnerTransfer") ) + { + flags |= PERM_TRANSFER; + } + return flags; +} + + +//static +void LLFloaterPerms::onClickHelp(void* data) +{ + gViewerWindow->alertXml("ClickUploadHelpPermissions"); +} diff --git a/indra/newview/llfloaterperms.h b/indra/newview/llfloaterperms.h new file mode 100644 index 0000000000..bd9dee1869 --- /dev/null +++ b/indra/newview/llfloaterperms.h @@ -0,0 +1,70 @@ +/** + * @file llfloaterperms.h + * @brief Asset creation permission preferences. + * @author Coco + * + * $LicenseInfo:firstyear=2002&license=viewergpl$ + * + * Copyright (c) 2002-2007, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLFLOATERPERMPREFS_H +#define LL_LLFLOATERPERMPREFS_H + +#include "llfloater.h" + +class LLFloaterPerms : public LLFloater, public LLFloaterSingleton<LLFloaterPerms> +{ + friend class LLUISingleton<LLFloaterPerms, VisibilityPolicy<LLFloater> >; + +public: + /*virtual*/ void onClose(bool app_quitting = false); + /*virtual*/ BOOL postBuild(); + void ok(); + void cancel(); + static void onClickOK(void*); + static void onClickCancel(void*); + static void onCommitCopy(LLUICtrl* ctrl, void* data); + // Convenience methods to get current permission preference bitfields from saved settings: + static U32 getEveryonePerms(std::string prefix=""); // prefix + "EveryoneCopy" + static U32 getGroupPerms(std::string prefix=""); // prefix + "ShareWithGroup" + static U32 getNextOwnerPerms(std::string prefix=""); // bitfield for prefix + "NextOwner" + "Copy", "Modify", and "Transfer" + +private: + LLFloaterPerms(const LLSD& seed); + void refresh(); + + /// callback for the menus help button + static void onClickHelp(void* data); + + BOOL // cached values only for implementing cancel. + mShareWithGroup, + mEveryoneCopy, + mNextOwnerCopy, + mNextOwnerModify, + mNextOwnerTransfer; +}; + +#endif diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 15d4d30221..2de00ec457 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -1,6 +1,6 @@ /** * @file llfloaterpreference.cpp - * @brief LLPreferenceCore class implementation + * @brief Global preferences with and without persistence. * * $LicenseInfo:firstyear=2002&license=viewergpl$ * @@ -89,9 +89,10 @@ LLFloaterPreference* LLFloaterPreference::sInstance = NULL; class LLPreferencesHandler : public LLCommandHandler { public: - // don't allow from external browsers - LLPreferencesHandler() : LLCommandHandler("preferences", false) { } - bool handle(const LLSD& tokens, const LLSD& queryMap) + // requires trusted browser + LLPreferencesHandler() : LLCommandHandler("preferences", true) { } + bool handle(const LLSD& tokens, const LLSD& query_map, + LLWebBrowserCtrl* web) { LLFloaterPreference::show(NULL); return true; @@ -259,6 +260,7 @@ void LLPreferenceCore::apply() mInputPanel->apply(); mNetworkPanel->apply(); mDisplayPanel->apply(); + mAudioPanel->apply(); mPrefsChat->apply(); mPrefsVoice->apply(); mPrefsIM->apply(); @@ -477,6 +479,7 @@ void LLFloaterPreference::onBtnApply( void* userdata ) void LLFloaterPreference::onClose(bool app_quitting) { LLPanelLogin::setAlwaysRefresh(false); + cancel(); // will be a no-op if OK or apply was performed just prior. LLFloater::onClose(app_quitting); } @@ -493,8 +496,7 @@ void LLFloaterPreference::onBtnCancel( void* userdata ) cur_focus->onCommit(); } } - fp->cancel(); - fp->close(); + fp->close(); // side effect will also cancel any unsaved changes. } diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp index f4843ea1a5..db2ea7f41a 100644 --- a/indra/newview/llfloatersnapshot.cpp +++ b/indra/newview/llfloatersnapshot.cpp @@ -369,7 +369,7 @@ void LLSnapshotLivePreview::drawPreviewRect(S32 offset_x, S32 offset_y) glLineWidth(2.0f * line_width) ; LLColor4 color(0.0f, 0.0f, 0.0f, 1.0f) ; gl_rect_2d( mPreviewRect.mLeft + offset_x, mPreviewRect.mTop + offset_y, - mPreviewRect.mRight + offset_x, mPreviewRect.mBottom + offset_y, color, FALSE ) ; + mPreviewRect.mRight + offset_x, mPreviewRect.mBottom + offset_y, color, FALSE ) ; glLineWidth(line_width) ; //draw four alpha rectangles to cover areas outside of the snapshot image @@ -383,20 +383,20 @@ void LLSnapshotLivePreview::drawPreviewRect(S32 offset_x, S32 offset_y) dwr = mThumbnailWidth - mPreviewRect.getWidth() - dwl ; gl_rect_2d(mPreviewRect.mLeft + offset_x - dwl, mPreviewRect.mTop + offset_y, - mPreviewRect.mLeft + offset_x, mPreviewRect.mBottom + offset_y, alpha_color, TRUE ) ; + mPreviewRect.mLeft + offset_x, mPreviewRect.mBottom + offset_y, alpha_color, TRUE ) ; gl_rect_2d( mPreviewRect.mRight + offset_x, mPreviewRect.mTop + offset_y, - mPreviewRect.mRight + offset_x + dwr, mPreviewRect.mBottom + offset_y, alpha_color, TRUE ) ; + mPreviewRect.mRight + offset_x + dwr, mPreviewRect.mBottom + offset_y, alpha_color, TRUE ) ; } if(mThumbnailHeight > mPreviewRect.getHeight()) { S32 dh = (mThumbnailHeight - mPreviewRect.getHeight()) >> 1 ; gl_rect_2d(mPreviewRect.mLeft + offset_x - dwl, mPreviewRect.mBottom + offset_y , - mPreviewRect.mRight + offset_x + dwr, mPreviewRect.mBottom + offset_y - dh, alpha_color, TRUE ) ; + mPreviewRect.mRight + offset_x + dwr, mPreviewRect.mBottom + offset_y - dh, alpha_color, TRUE ) ; dh = mThumbnailHeight - mPreviewRect.getHeight() - dh ; gl_rect_2d( mPreviewRect.mLeft + offset_x - dwl, mPreviewRect.mTop + offset_y + dh, - mPreviewRect.mRight + offset_x + dwr, mPreviewRect.mTop + offset_y, alpha_color, TRUE ) ; + mPreviewRect.mRight + offset_x + dwr, mPreviewRect.mTop + offset_y, alpha_color, TRUE ) ; } } } @@ -950,7 +950,9 @@ void LLSnapshotLivePreview::saveTexture() 0, LLAssetType::AT_SNAPSHOT_CATEGORY, LLInventoryType::IT_SNAPSHOT, - PERM_ALL, + PERM_ALL, // Note: Snapshots to inventory is a special case of content upload + PERM_NONE, // that ignores the user's premissions preferences and continues to + PERM_NONE, // always use these fairly permissive hard-coded initial perms. - MG "Snapshot : " + pos_string); gViewerWindow->playSnapshotAnimAndSound(); } @@ -1424,7 +1426,7 @@ void LLFloaterSnapshot::Impl::onClickMore(void* data) if(getPreviewView(view)) { getPreviewView(view)->setThumbnailImageSize() ; - } + } } } void LLFloaterSnapshot::Impl::onClickLess(void* data) @@ -1664,15 +1666,15 @@ void LLFloaterSnapshot::Impl::updateResolution(LLUICtrl* ctrl, void* data, BOOL if(view->childGetValue("snapshot_width").asInteger() != width || view->childGetValue("snapshot_height").asInteger() != height) { - view->childSetValue("snapshot_width", width); - view->childSetValue("snapshot_height", height); - // hide old preview as the aspect ratio could be wrong - checkAutoSnapshot(previewp, FALSE); + view->childSetValue("snapshot_width", width); + view->childSetValue("snapshot_height", height); + // hide old preview as the aspect ratio could be wrong + checkAutoSnapshot(previewp, FALSE); getPreviewView(view)->updateSnapshot(FALSE, TRUE); if(do_update) { updateControls(view); - } + } } } } diff --git a/indra/newview/llfloatertelehub.cpp b/indra/newview/llfloatertelehub.cpp index 0b4a05867f..49ece7a19e 100644 --- a/indra/newview/llfloatertelehub.cpp +++ b/indra/newview/llfloatertelehub.cpp @@ -68,7 +68,6 @@ void LLFloaterTelehub::show() // Find tools floater, glue to bottom if (gFloaterTools) { - gFloaterTools->showMore(FALSE); LLRect tools_rect = gFloaterTools->getRect(); S32 our_width = sInstance->getRect().getWidth(); S32 our_height = sInstance->getRect().getHeight(); diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp index 9e5eb2008b..1c28991261 100644 --- a/indra/newview/llfloatertools.cpp +++ b/indra/newview/llfloatertools.cpp @@ -53,6 +53,7 @@ #include "llpanelobject.h" #include "llpanelvolume.h" #include "llpanelpermissions.h" +#include "llresmgr.h" #include "llselectmgr.h" #include "llslider.h" #include "llstatusbar.h" @@ -106,9 +107,8 @@ void click_popup_rotate_left(void*); void click_popup_rotate_reset(void*); void click_popup_rotate_right(void*); void click_popup_dozer_mode(LLUICtrl *, void *user); -void click_popup_dozer_size(LLUICtrl *, void *user); +void commit_slider_dozer_size(LLUICtrl *, void*); void commit_slider_dozer_force(LLUICtrl *, void*); -void click_dozer_size(LLUICtrl *, void*); void click_apply_to_selection(void*); void commit_radio_zoom(LLUICtrl *, void*); void commit_radio_orbit(LLUICtrl *, void*); @@ -303,27 +303,22 @@ BOOL LLFloaterTools::postBuild() childSetCommitCallback("radio noise",click_popup_dozer_mode, (void*)4); mRadioDozerRevert = getChild<LLCheckBoxCtrl>("radio revert"); childSetCommitCallback("radio revert",click_popup_dozer_mode, (void*)5); - mComboDozerSize = getChild<LLComboBox>("combobox brush size"); - childSetCommitCallback("combobox brush size",click_dozer_size, (void*)0); - if(mComboDozerSize) mComboDozerSize->setCurrentByIndex(0); mBtnApplyToSelection = getChild<LLButton>("button apply to selection"); childSetAction("button apply to selection",click_apply_to_selection, (void*)0); - mCheckShowOwners = getChild<LLCheckBoxCtrl>("checkbox show owners"); - childSetValue("checkbox show owners",gSavedSettings.getBOOL("ShowParcelOwners")); + mSliderDozerSize = getChild<LLSlider>("slider brush size"); + childSetCommitCallback("slider brush size", commit_slider_dozer_size, (void*)0); + childSetValue( "slider brush size", gSavedSettings.getS32("RadioLandBrushSize")); + mSliderDozerForce = getChild<LLSlider>("slider force"); childSetCommitCallback("slider force",commit_slider_dozer_force, (void*)0); // the setting stores the actual force multiplier, but the slider is logarithmic, so we convert here childSetValue( "slider force", log10(gSavedSettings.getF32("LandBrushForce"))); - childSetAction("button more", click_show_more, this); - childSetAction("button less", click_show_more, this); mTab = getChild<LLTabContainer>("Object Info Tabs"); if(mTab) { - mTab->setVisible( gSavedSettings.getBOOL("ToolboxShowMore") ); mTab->setFollows(FOLLOWS_TOP | FOLLOWS_LEFT); - mTab->setVisible( gSavedSettings.getBOOL("ToolboxShowMore") ); mTab->setBorderVisible(FALSE); mTab->selectFirstTab(); } @@ -391,10 +386,9 @@ LLFloaterTools::LLFloaterTools() mRadioDozerSmooth(NULL), mRadioDozerNoise(NULL), mRadioDozerRevert(NULL), - mComboDozerSize(NULL), + mSliderDozerSize(NULL), + mSliderDozerForce(NULL), mBtnApplyToSelection(NULL), - mCheckShowOwners(NULL), - mTab(NULL), mPanelPermissions(NULL), @@ -418,19 +412,6 @@ LLFloaterTools::LLFloaterTools() factory_map["land info panel"] = LLCallbackMap(createPanelLandInfo, this);//LLPanelLandInfo LLUICtrlFactory::getInstance()->buildFloater(this,"floater_tools.xml",&factory_map,FALSE); - - mLargeHeight = getRect().getHeight(); - mSmallHeight = mLargeHeight; - if (mTab) mSmallHeight -= mTab->getRect().getHeight(); - - // force a toggle initially. seems to be needed to correctly initialize - // both "more" and "less" cases. it also seems to be important to begin - // with the user's preference first so that it's initial position will - // be correct (SL-51192) -MG - BOOL show_more = gSavedSettings.getBOOL("ToolboxShowMore"); // get user's preference - gSavedSettings.setBOOL("ToolboxShowMore", show_more); // sets up forced toggle below - showMore( !show_more ); // does the toggle - showMore( show_more ); // reset the real user's preference } LLFloaterTools::~LLFloaterTools() @@ -474,6 +455,16 @@ void LLFloaterTools::refresh() mTab->enableTabButton(idx_face, all_volume); mTab->enableTabButton(idx_contents, all_volume); + // Refresh object and prim count labels + LLLocale locale(LLLocale::USER_LOCALE); + std::string obj_count_string; + LLResMgr::getInstance()->getIntegerString(obj_count_string, LLSelectMgr::getInstance()->getSelection()->getRootObjectCount()); + childSetTextArg("obj_count", "[COUNT]", obj_count_string); + std::string prim_count_string; + LLResMgr::getInstance()->getIntegerString(prim_count_string, LLSelectMgr::getInstance()->getSelection()->getObjectCount()); + childSetTextArg("prim_count", "[COUNT]", prim_count_string); + + // Refresh child tabs mPanelPermissions->refresh(); mPanelObject->refresh(); mPanelVolume->refresh(); @@ -702,7 +693,6 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask) if (mRadioSelectLand) mRadioSelectLand->setVisible( land_visible ); S32 dozer_mode = gSavedSettings.getS32("RadioLandBrushAction"); - S32 dozer_size = gSavedSettings.getS32("RadioLandBrushSize"); if (mRadioDozerFlatten) { @@ -734,20 +724,16 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask) mRadioDozerRevert ->set( tool == LLToolBrushLand::getInstance() && dozer_mode == 5); mRadioDozerRevert ->setVisible( land_visible ); } - if (mComboDozerSize) - { - mComboDozerSize ->setCurrentByIndex(dozer_size); - mComboDozerSize ->setVisible( land_visible ); - mComboDozerSize ->setEnabled( tool == LLToolBrushLand::getInstance() ); - } if (mBtnApplyToSelection) { mBtnApplyToSelection->setVisible( land_visible ); mBtnApplyToSelection->setEnabled( land_visible && !LLViewerParcelMgr::getInstance()->selectionEmpty() && tool != LLToolSelectLand::getInstance()); } - if (mCheckShowOwners) + if (mSliderDozerSize) { - mCheckShowOwners ->setVisible( land_visible ); + mSliderDozerSize ->setVisible( land_visible ); + childSetVisible("Bulldozer:", land_visible); + childSetVisible("Dozer Size:", land_visible); } if (mSliderDozerForce) { @@ -755,13 +741,10 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask) childSetVisible("Strength:", land_visible); } - // - // More panel visibility - // - BOOL show_more = gSavedSettings.getBOOL("ToolboxShowMore"); - - mTab->setVisible(show_more && tool != LLToolBrushLand::getInstance() && tool != LLToolSelectLand::getInstance()); - mPanelLandInfo->setVisible(show_more && (tool == LLToolBrushLand::getInstance() || tool == LLToolSelectLand::getInstance())); + childSetVisible("obj_count", !land_visible); + childSetVisible("prim_count", !land_visible); + mTab->setVisible(!land_visible); + mPanelLandInfo->setVisible(land_visible); } @@ -816,46 +799,12 @@ void LLFloaterTools::onClose(bool app_quitting) // gMenuBarView->arrange(); } -void LLFloaterTools::showMore(BOOL show_more) -{ - BOOL showing_more = gSavedSettings.getBOOL("ToolboxShowMore"); - if (show_more == showing_more) - { - return; - } - - gSavedSettings.setBOOL("ToolboxShowMore", show_more); - - // Visibility updated next frame - JC - // mTab->setVisible(show_more); - - if (show_more) - { - reshape( getRect().getWidth(), mLargeHeight, TRUE); - translate( 0, mSmallHeight - mLargeHeight ); - } - else - { - reshape( getRect().getWidth(), mSmallHeight, TRUE); - translate( 0, mLargeHeight - mSmallHeight ); - } - childSetVisible("button less", show_more); - childSetVisible("button more", !show_more); -} - void LLFloaterTools::showPanel(EInfoPanel panel) { llassert(panel >= 0 && panel < PANEL_COUNT); mTab->selectTabByName(PANEL_NAMES[panel]); } -void click_show_more(void *userdata) -{ - LLFloaterTools *f = (LLFloaterTools *)userdata; - BOOL show_more = !gSavedSettings.getBOOL("ToolboxShowMore"); - f->showMore( show_more ); -} - void click_popup_info(void*) { // gBuildView->setPropertiesPanelOpen(TRUE); @@ -933,22 +882,14 @@ void click_popup_rotate_right(void*) void click_popup_dozer_mode(LLUICtrl *, void *user) { - S32 show_owners = gSavedSettings.getBOOL("ShowParcelOwners"); S32 mode = (S32)(intptr_t) user; gFloaterTools->setEditTool( LLToolBrushLand::getInstance() ); gSavedSettings.setS32("RadioLandBrushAction", mode); - gSavedSettings.setBOOL("ShowParcelOwners", show_owners); -} - -void click_popup_dozer_size(LLUICtrl *, void *user) -{ - S32 size = (S32)(intptr_t) user; - gSavedSettings.setS32("RadioLandBrushSize", size); } -void click_dozer_size(LLUICtrl *ctrl, void *user) +void commit_slider_dozer_size(LLUICtrl *ctrl, void*) { - S32 size = ((LLComboBox*) ctrl)->getCurrentIndex(); + S32 size = (S32)ctrl->getValue().asInteger(); gSavedSettings.setS32("RadioLandBrushSize", size); } diff --git a/indra/newview/llfloatertools.h b/indra/newview/llfloatertools.h index 81e40c0408..27e05ce237 100644 --- a/indra/newview/llfloatertools.h +++ b/indra/newview/llfloatertools.h @@ -95,7 +95,6 @@ public: /*virtual*/ void draw(); void dirty(); - void showMore(BOOL show_more); void showPanel(EInfoPanel panel); void setStatusText(const std::string& text); @@ -168,11 +167,10 @@ public: LLCheckBoxCtrl *mRadioDozerSmooth; LLCheckBoxCtrl *mRadioDozerNoise; LLCheckBoxCtrl *mRadioDozerRevert; + LLSlider *mSliderDozerSize; LLSlider *mSliderDozerForce; - LLComboBox *mComboDozerSize; LLButton *mBtnApplyToSelection; - LLCheckBoxCtrl *mCheckShowOwners; std::vector<LLButton*> mButtons;//[ 15 ]; @@ -191,8 +189,6 @@ public: private: BOOL mDirty; - S32 mSmallHeight; - S32 mLargeHeight; std::map<std::string, std::string> mStatusText; }; diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp index 89c91bbf2b..2281f1b598 100644 --- a/indra/newview/llfloaterworldmap.cpp +++ b/indra/newview/llfloaterworldmap.cpp @@ -49,10 +49,8 @@ #include "lldraghandle.h" #include "llfirstuse.h" #include "llfocusmgr.h" -#include "llinventorymodel.h" #include "lllandmarklist.h" #include "lllineeditor.h" -#include "llnetmap.h" #include "llpreviewlandmark.h" #include "llregionhandle.h" #include "llscrolllistctrl.h" diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp index 51b0470e07..770c117798 100644 --- a/indra/newview/llimpanel.cpp +++ b/indra/newview/llimpanel.cpp @@ -1500,8 +1500,8 @@ void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, const LLColor4 else { // Convert the name to a hotlink and add to message. - const LLStyleSP &source_style = LLStyleMap::instance().lookup(source); - mHistoryEditor->appendStyledText(name,false,prepend_newline,&source_style); + const LLStyleSP &source_style = LLStyleMap::instance().lookupAgent(source); + mHistoryEditor->appendStyledText(name,false,prepend_newline,source_style); } prepend_newline = false; } diff --git a/indra/newview/llloginhandler.cpp b/indra/newview/llloginhandler.cpp new file mode 100644 index 0000000000..c311b46779 --- /dev/null +++ b/indra/newview/llloginhandler.cpp @@ -0,0 +1,227 @@ +/** + * @file llloginhandler.cpp + * @brief Handles filling in the login panel information from a SLURL + * such as secondlife:///app/login?first=Bob&last=Dobbs + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ +#include "llviewerprecompiledheaders.h" + +#include "llloginhandler.h" + +// viewer includes +#include "llpanellogin.h" // save_password_to_disk() +#include "llstartup.h" // getStartupState() +#include "llurlsimstring.h" +#include "llviewercontrol.h" // gSavedSettings +#include "llviewernetwork.h" // EGridInfo + +// library includes +#include "llmd5.h" + + +// Must have instance to auto-register with LLCommandDispatcher +LLLoginHandler gLoginHandler; + + +//parses the input url and returns true if afterwards +//a web-login-key, firstname and lastname is set +bool LLLoginHandler::parseDirectLogin(std::string url) +{ + LLURI uri(url); + parse(uri.queryMap()); + + if (mWebLoginKey.isNull() || + mFirstName.empty() || + mLastName.empty()) + { + return false; + } + else + { + return true; + } +} + + +void LLLoginHandler::parse(const LLSD& queryMap) +{ + mWebLoginKey = queryMap["web_login_key"].asUUID(); + mFirstName = queryMap["first_name"].asString(); + mLastName = queryMap["last_name"].asString(); + + EGridInfo grid_choice = GRID_INFO_NONE; + if (queryMap["grid"].asString() == "aditi") + { + grid_choice = GRID_INFO_ADITI; + } + else if (queryMap["grid"].asString() == "agni") + { + grid_choice = GRID_INFO_AGNI; + } + else if (queryMap["grid"].asString() == "siva") + { + grid_choice = GRID_INFO_SIVA; + } + else if (queryMap["grid"].asString() == "damballah") + { + grid_choice = GRID_INFO_DAMBALLAH; + } + else if (queryMap["grid"].asString() == "durga") + { + grid_choice = GRID_INFO_DURGA; + } + else if (queryMap["grid"].asString() == "shakti") + { + grid_choice = GRID_INFO_SHAKTI; + } + else if (queryMap["grid"].asString() == "soma") + { + grid_choice = GRID_INFO_SOMA; + } + else if (queryMap["grid"].asString() == "ganga") + { + grid_choice = GRID_INFO_GANGA; + } + else if (queryMap["grid"].asString() == "vaak") + { + grid_choice = GRID_INFO_VAAK; + } + else if (queryMap["grid"].asString() == "uma") + { + grid_choice = GRID_INFO_UMA; + } + else if (queryMap["grid"].asString() == "mohini") + { + grid_choice = GRID_INFO_MOHINI; + } + else if (queryMap["grid"].asString() == "yami") + { + grid_choice = GRID_INFO_YAMI; + } + else if (queryMap["grid"].asString() == "nandi") + { + grid_choice = GRID_INFO_NANDI; + } + else if (queryMap["grid"].asString() == "mitra") + { + grid_choice = GRID_INFO_MITRA; + } + else if (queryMap["grid"].asString() == "radha") + { + grid_choice = GRID_INFO_RADHA; + } + else if (queryMap["grid"].asString() == "ravi") + { + grid_choice = GRID_INFO_RAVI; + } + else if (queryMap["grid"].asString() == "aruna") + { + grid_choice = GRID_INFO_ARUNA; + } + + if(grid_choice != GRID_INFO_NONE) + { + LLViewerLogin::getInstance()->setGridChoice(grid_choice); + } + + std::string startLocation = queryMap["location"].asString(); + + if (startLocation == "specify") + { + LLURLSimString::setString(queryMap["region"].asString()); + } + else if (startLocation == "home") + { + gSavedSettings.setBOOL("LoginLastLocation", FALSE); + LLURLSimString::setString(LLStringUtil::null); + } + else if (startLocation == "last") + { + gSavedSettings.setBOOL("LoginLastLocation", TRUE); + LLURLSimString::setString(LLStringUtil::null); + } +} + +bool LLLoginHandler::handle(const LLSD& tokens, + const LLSD& query_map, + LLWebBrowserCtrl* web) +{ + parse(query_map); + + //if we haven't initialized stuff yet, this is + //coming in from the GURL handler, just parse + if (STATE_FIRST == LLStartUp::getStartupState()) + { + return true; + } + + std::string password = query_map["password"].asString(); + + if (!password.empty()) + { + gSavedSettings.setBOOL("RememberPassword", TRUE); + + if (password.substr(0,3) != "$1$") + { + LLMD5 pass((unsigned char*)password.c_str()); + char md5pass[33]; /* Flawfinder: ignore */ + pass.hex_digest(md5pass); + password = ll_safe_string(md5pass, 32); + save_password_to_disk(password.c_str()); + } + } + else + { + save_password_to_disk(NULL); + gSavedSettings.setBOOL("RememberPassword", FALSE); + } + + + if (LLStartUp::getStartupState() < STATE_LOGIN_CLEANUP) //on splash page + { + if (!mFirstName.empty() || !mLastName.empty()) + { + // Fill in the name, and maybe the password, preserving the + // remember-password setting. JC + std::string ignore; + BOOL remember; + LLPanelLogin::getFields(ignore, ignore, ignore, remember); + LLPanelLogin::setFields(mFirstName, mLastName, password, remember); + } + + if (mWebLoginKey.isNull()) + { + LLPanelLogin::loadLoginPage(); + } + else + { + LLStartUp::setStartupState( STATE_LOGIN_CLEANUP ); + } + } + return true; +} diff --git a/indra/newview/llloginhandler.h b/indra/newview/llloginhandler.h new file mode 100644 index 0000000000..96149e3f06 --- /dev/null +++ b/indra/newview/llloginhandler.h @@ -0,0 +1,63 @@ +/** + * @file llloginhandler.h + * @brief Handles filling in the login panel information from a SLURL + * such as secondlife:///app/login?first=Bob&last=Dobbs + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ +#ifndef LLLOGINHANDLER_H +#define LLLOGINHANDLER_H + +#include "llcommandhandler.h" + +class LLLoginHandler : public LLCommandHandler +{ + public: + // allow from external browsers + LLLoginHandler() : LLCommandHandler("login", false) { } + /*virtual*/ bool handle(const LLSD& tokens, const LLSD& query_map, LLWebBrowserCtrl* web); + + // Fill in our internal fields from a SLURL like + // secondlife:///app/login?first=Bob&last=Dobbs + bool parseDirectLogin(std::string url); + + std::string getFirstName() const { return mFirstName; } + std::string getLastName() const { return mLastName; } + LLUUID getWebLoginKey() const { return mWebLoginKey; } + +private: + void parse(const LLSD& queryMap); + +private: + std::string mFirstName; + std::string mLastName; + LLUUID mWebLoginKey; +}; + +extern LLLoginHandler gLoginHandler; + +#endif diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index 21b1bee54f..d836876d66 100644 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -44,6 +44,7 @@ #include "llcallingcard.h" #include "llcolorscheme.h" #include "llviewercontrol.h" +#include "llfloateravatarinfo.h" #include "llfloaterworldmap.h" #include "llfloatermap.h" #include "llframetimer.h" @@ -73,6 +74,7 @@ const F32 MAP_SCALE_MIN = 64; const F32 MAP_SCALE_MID = 172; const F32 MAP_SCALE_MAX = 512; const F32 MAP_SCALE_INCREMENT = 16; +const F32 MAP_MIN_PICK_DIST = 4; const S32 TRACKING_RADIUS = 3; @@ -161,10 +163,11 @@ LLNetMap::LLNetMap( menu->appendSeparator(); menu->append(new LLMenuItemCallGL(std::string("Stop Tracking"), &LLTracker::stopTracking, &LLTracker::isTracking, NULL) ); + menu->append(new LLMenuItemCallGL(std::string("Profile..."), &showAgentProfile, + &isAgentUnderCursor, NULL) ); menu->setVisible(FALSE); addChild(menu); mPopupMenuHandle = menu->getHandle(); - sInstance = this; } @@ -370,6 +373,14 @@ void LLNetMap::draw() LLVector3d pos_global; LLVector3 pos_map; + // Mouse pointer in local coordinates + S32 local_mouse_x; + S32 local_mouse_y; + //localMouse(&local_mouse_x, &local_mouse_y); + LLUI::getCursorPositionLocal(this, &local_mouse_x, &local_mouse_y); + mClosestAgentToCursor.setNull(); + F32 closest_dist = F32_MAX; + // Draw avatars for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->mActiveRegionList.begin(); iter != LLWorld::getInstance()->mActiveRegionList.end(); ++iter) @@ -413,6 +424,13 @@ void LLNetMap::draw() pos_map.mV[VX], pos_map.mV[VY], show_as_friend ? gFriendMapColor : gAvatarMapColor, pos_map.mV[VZ]); + + F32 dist_to_cursor = dist_vec(LLVector2(pos_map.mV[VX], pos_map.mV[VY]), LLVector2(local_mouse_x,local_mouse_y)); + if(dist_to_cursor < MAP_MIN_PICK_DIST && dist_to_cursor < closest_dist) + { + closest_dist = dist_to_cursor; + mClosestAgentToCursor = regionp->mMapAvatarIDs.get(i); + } } } @@ -590,7 +608,14 @@ BOOL LLNetMap::handleToolTip( S32 x, S32 y, std::string& msg, LLRect* sticky_rec LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal( viewPosToGlobal( x, y ) ); if( region ) { - msg.assign( region->getName() ); + msg.assign(""); + std::string fullname; + if(mClosestAgentToCursor.notNull() && gCacheName->getFullName(mClosestAgentToCursor, fullname)) + { + msg.append(fullname); + msg.append("\n"); + } + msg.append( region->getName() ); #ifndef LL_RELEASE_FOR_DOWNLOAD std::string buffer; @@ -774,6 +799,7 @@ BOOL LLNetMap::handleDoubleClick( S32 x, S32 y, MASK mask ) BOOL LLNetMap::handleRightMouseDown(S32 x, S32 y, MASK mask) { + mClosestAgentAtLastRightClick = mClosestAgentToCursor; LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); if (menu) { @@ -805,3 +831,9 @@ void LLNetMap::handleZoomLevel(void* which) break; } } + +// static +void LLNetMap::showAgentProfile(void*) +{ + LLFloaterAvatarInfo::show(sInstance->mClosestAgentAtLastRightClick); +} diff --git a/indra/newview/llnetmap.h b/indra/newview/llnetmap.h index 3950a08166..214dc4df93 100644 --- a/indra/newview/llnetmap.h +++ b/indra/newview/llnetmap.h @@ -108,8 +108,14 @@ public: LLTextBox* mTextBoxNorthWest; LLTextBox* mTextBoxSouthWest; +private: + LLUUID mClosestAgentToCursor; + LLUUID mClosestAgentAtLastRightClick; + static BOOL sRotateMap; static LLNetMap* sInstance; + static BOOL isAgentUnderCursor(void*) { return sInstance && sInstance->mClosestAgentToCursor.notNull(); } + static void showAgentProfile(void*); }; diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index 7d66da30e5..9c8817da9a 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -389,7 +389,6 @@ LLPanelAvatarFirstLife::LLPanelAvatarFirstLife(const std::string& name, { } - void LLPanelAvatarFirstLife::enableControls(BOOL self) { childSetEnabled("img", self); @@ -438,6 +437,8 @@ BOOL LLPanelAvatarSecondLife::postBuild(void) childSetDoubleClickCallback("groups", onDoubleClickGroup, this ); + getChild<LLTextureCtrl>("img")->setFallbackImageName("default_profile_picture.j2c"); + return TRUE; } @@ -445,6 +446,9 @@ BOOL LLPanelAvatarFirstLife::postBuild(void) { BOOL own_avatar = (getPanelAvatar()->getAvatarID() == gAgent.getID() ); enableControls(own_avatar); + + getChild<LLTextureCtrl>("img")->setFallbackImageName("default_profile_picture.j2c"); + return TRUE; } @@ -1778,7 +1782,7 @@ void LLPanelAvatar::processAvatarPropertiesReply(LLMessageSystem *msg, void**) msg->getStringFast(_PREHASH_PropertiesData, _PREHASH_BornOn, born_on); msg->getString("PropertiesData","ProfileURL", profile_url); msg->getU32Fast(_PREHASH_PropertiesData, _PREHASH_Flags, flags); - + identified = (flags & AVATAR_IDENTIFIED); transacted = (flags & AVATAR_TRANSACTED); age_verified = (flags & AVATAR_AGEVERIFIED); // Not currently getting set in dataserver/lldataavatar.cpp for privacy considerations diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp index 34731f653f..64cc19e2fd 100644 --- a/indra/newview/llpanelclassified.cpp +++ b/indra/newview/llpanelclassified.cpp @@ -116,7 +116,7 @@ class LLClassifiedTeleportHandler : public LLCommandHandler { public: // don't allow from external browsers because it moves you immediately - LLClassifiedTeleportHandler() : LLCommandHandler("classifiedteleport", false) { } + LLClassifiedTeleportHandler() : LLCommandHandler("classifiedteleport", true) { } bool handle(const LLSD& tokens, const LLSD& queryMap) { @@ -139,8 +139,9 @@ public: const bool from_search = true; LLPanelClassified::sendClassifiedClickMessage(classified_id, "teleport", from_search); // Invoke teleport - const bool from_external_browser = false; - return LLURLDispatcher::dispatch(url, from_external_browser); + LLWebBrowserCtrl* web = NULL; + const bool trusted_browser = true; + return LLURLDispatcher::dispatch(url, web, trusted_browser); } }; // Creating the object registers with the dispatcher. diff --git a/indra/newview/llpanelcontents.cpp b/indra/newview/llpanelcontents.cpp index e9fb9d3a17..7fdd052af5 100644 --- a/indra/newview/llpanelcontents.cpp +++ b/indra/newview/llpanelcontents.cpp @@ -52,6 +52,7 @@ #include "lltextbox.h" #include "llbutton.h" #include "llcombobox.h" +#include "llfloaterbulkpermission.h" #include "llagent.h" #include "llviewerwindow.h" @@ -82,6 +83,7 @@ BOOL LLPanelContents::postBuild() setMouseOpaque(FALSE); childSetAction("button new script",&LLPanelContents::onClickNewScript, this); + childSetAction("button permissions",&LLPanelContents::onClickPermissions, this); return TRUE; } @@ -104,7 +106,6 @@ void LLPanelContents::getState(LLViewerObject *objectp ) if( !objectp ) { childSetEnabled("button new script",FALSE); - //mBtnNewScript->setEnabled( FALSE ); return; } @@ -117,21 +118,12 @@ void LLPanelContents::getState(LLViewerObject *objectp ) && ( objectp->permYouOwner() || ( !group_id.isNull() && gAgent.isInGroup(group_id) ))); // solves SL-23488 BOOL all_volume = LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME ); - // Edit script button - ok if object is editable and there's an - // unambiguous destination for the object. - if( editable && + // Edit script button - ok if object is editable and there's an unambiguous destination for the object. + childSetEnabled("button new script", + editable && all_volume && ((LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() == 1) - || (LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1))) - { - //mBtnNewScript->setEnabled(TRUE); - childSetEnabled("button new script",TRUE); - } - else - { - //mBtnNewScript->setEnabled(FALSE); - childSetEnabled("button new script",FALSE); - } + || (LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1))); } @@ -210,3 +202,11 @@ void LLPanelContents::onClickNewScript(void *userdata) #endif } } + + +// static +void LLPanelContents::onClickPermissions(void *userdata) +{ + LLPanelContents* self = (LLPanelContents*)userdata; + gFloaterView->getParentFloater(self)->addDependentFloater(LLFloaterBulkPermission::showInstance()); +} diff --git a/indra/newview/llpanelcontents.h b/indra/newview/llpanelcontents.h index 98e53d6de3..e8a00b9c6e 100644 --- a/indra/newview/llpanelcontents.h +++ b/indra/newview/llpanelcontents.h @@ -51,6 +51,7 @@ public: void refresh(); static void onClickNewScript( void* userdata); + static void onClickPermissions( void* userdata); protected: void getState(LLViewerObject *object); diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 8cc7844c0f..b3d03bba6f 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -424,7 +424,7 @@ void LLPanelFace::getState() } } func; identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, id ); - + if (identical) { // All selected have the same texture @@ -765,6 +765,7 @@ void LLPanelFace::getState() if(texture_ctrl) { texture_ctrl->setImageAssetID( LLUUID::null ); + texture_ctrl->setFallbackImageName( "locked_image.j2c" ); texture_ctrl->setEnabled( FALSE ); // this is a LLUICtrl, but we don't want it to have keyboard focus so we add it as a child, not a ctrl. // texture_ctrl->setValid(FALSE); } @@ -772,6 +773,7 @@ void LLPanelFace::getState() if(mColorSwatch) { mColorSwatch->setEnabled( FALSE ); + mColorSwatch->setFallbackImageName("locked_image.j2c" ); mColorSwatch->setValid(FALSE); } childSetEnabled("color trans",FALSE); diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp index ba4153b087..4b48fb3510 100644 --- a/indra/newview/llpanelgrouproles.cpp +++ b/indra/newview/llpanelgrouproles.cpp @@ -2085,8 +2085,19 @@ void LLPanelGroupRolesSubTab::handleRoleSelect() gAgent.hasPowerInGroup(mGroupID, GP_ROLE_PROPERTIES)); mRoleTitle->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_ROLE_PROPERTIES)); mRoleDescription->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_ROLE_PROPERTIES)); - mMemberVisibleCheck->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_ROLE_PROPERTIES)); - + + if ( is_owner_role ) + { + // you can't delete the owner role + can_delete = FALSE; + // ... or hide members with this role + mMemberVisibleCheck->setEnabled(FALSE); + } + else + { + mMemberVisibleCheck->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_ROLE_PROPERTIES)); + } + if (item->getUUID().isNull()) { // Everyone role, can't edit description or name or delete @@ -2094,8 +2105,6 @@ void LLPanelGroupRolesSubTab::handleRoleSelect() mRoleName->setEnabled(FALSE); can_delete = FALSE; } - //you can't delete the owner role - if ( is_owner_role ) can_delete = FALSE; } else { diff --git a/indra/newview/llpanelland.cpp b/indra/newview/llpanelland.cpp index f0afa3434e..11f88695c5 100644 --- a/indra/newview/llpanelland.cpp +++ b/indra/newview/llpanelland.cpp @@ -37,10 +37,13 @@ #include "llagent.h" #include "llbutton.h" +#include "llcheckboxctrl.h" #include "llfloaterland.h" #include "lltextbox.h" +#include "llviewercontrol.h" #include "llviewerparcelmgr.h" #include "llviewerregion.h" +#include "llviewerwindow.h" #include "roles_constants.h" #include "lluictrlfactory.h" @@ -65,6 +68,10 @@ BOOL LLPanelLandInfo::postBuild() childSetAction("button subdivide land",onClickDivide,this); childSetAction("button join land",onClickJoin,this); childSetAction("button about land",onClickAbout,this); + childSetAction("button show owners help", onShowOwnersHelp, this); + + mCheckShowOwners = getChild<LLCheckBoxCtrl>("checkbox show owners"); + childSetValue("checkbox show owners", gSavedSettings.getBOOL("ShowParcelOwners")); return TRUE; } @@ -72,7 +79,8 @@ BOOL LLPanelLandInfo::postBuild() // Methods // LLPanelLandInfo::LLPanelLandInfo(const std::string& name) -: LLPanel(name) +: LLPanel(name), + mCheckShowOwners(NULL) { if (!sInstance) { @@ -255,3 +263,8 @@ void LLPanelLandInfo::onClickAbout(void*) LLFloaterLand::showInstance(); } + +void LLPanelLandInfo::onShowOwnersHelp(void* user_data) +{ + gViewerWindow->alertXml("ShowOwnersHelp"); +} diff --git a/indra/newview/llpanelland.h b/indra/newview/llpanelland.h index 7db8e64801..477c5ed970 100644 --- a/indra/newview/llpanelland.h +++ b/indra/newview/llpanelland.h @@ -50,6 +50,8 @@ public: void refresh(); static void refreshAll(); + + LLCheckBoxCtrl *mCheckShowOwners; protected: static void onClickClaim(void*); @@ -57,6 +59,7 @@ protected: static void onClickDivide(void*); static void onClickJoin(void*); static void onClickAbout(void*); + static void onShowOwnersHelp(void*); protected: //LLTextBox* mTextPriceLabel; diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index 816a8b5765..20228ed306 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -32,6 +32,7 @@ #include "llviewerprecompiledheaders.h" #include "llpanellogin.h" + #include "llpanelgeneral.h" #include "indra_constants.h" // for key and mask constants @@ -43,7 +44,7 @@ #include "llbutton.h" #include "llcheckboxctrl.h" -#include "llcommandhandler.h" +#include "llcommandhandler.h" // for secondlife:///app/login/ #include "llcombobox.h" #include "llcurl.h" #include "llviewercontrol.h" @@ -78,9 +79,6 @@ #define USE_VIEWER_AUTH 0 -std::string load_password_from_disk(void); -void save_password_to_disk(const char* hashed_password); - const S32 BLACK_BORDER_HEIGHT = 160; const S32 MAX_PASSWORD = 16; @@ -92,8 +90,8 @@ class LLLoginRefreshHandler : public LLCommandHandler { public: // don't allow from external browsers - LLLoginRefreshHandler() : LLCommandHandler("login_refresh", false) { } - bool handle(const LLSD& tokens, const LLSD& queryMap) + LLLoginRefreshHandler() : LLCommandHandler("login_refresh", true) { } + bool handle(const LLSD& tokens, const LLSD& query_map, LLWebBrowserCtrl* web) { if (LLStartUp::getStartupState() < STATE_LOGIN_CLEANUP) { @@ -106,191 +104,6 @@ public: LLLoginRefreshHandler gLoginRefreshHandler; -//parses the input url and returns true if afterwards -//a web-login-key, firstname and lastname is set -bool LLLoginHandler::parseDirectLogin(std::string url) -{ - LLURI uri(url); - parse(uri.queryMap()); - - if (mWebLoginKey.isNull() || - mFirstName.empty() || - mLastName.empty()) - { - return false; - } - else - { - return true; - } -} - - -void LLLoginHandler::parse(const LLSD& queryMap) -{ - mWebLoginKey = queryMap["web_login_key"].asUUID(); - mFirstName = queryMap["first_name"].asString(); - mLastName = queryMap["last_name"].asString(); - - EGridInfo grid_choice = GRID_INFO_NONE; - if (queryMap["grid"].asString() == "aditi") - { - grid_choice = GRID_INFO_ADITI; - } - else if (queryMap["grid"].asString() == "agni") - { - grid_choice = GRID_INFO_AGNI; - } - else if (queryMap["grid"].asString() == "siva") - { - grid_choice = GRID_INFO_SIVA; - } - else if (queryMap["grid"].asString() == "damballah") - { - grid_choice = GRID_INFO_DAMBALLAH; - } - else if (queryMap["grid"].asString() == "durga") - { - grid_choice = GRID_INFO_DURGA; - } - else if (queryMap["grid"].asString() == "shakti") - { - grid_choice = GRID_INFO_SHAKTI; - } - else if (queryMap["grid"].asString() == "soma") - { - grid_choice = GRID_INFO_SOMA; - } - else if (queryMap["grid"].asString() == "ganga") - { - grid_choice = GRID_INFO_GANGA; - } - else if (queryMap["grid"].asString() == "vaak") - { - grid_choice = GRID_INFO_VAAK; - } - else if (queryMap["grid"].asString() == "uma") - { - grid_choice = GRID_INFO_UMA; - } - else if (queryMap["grid"].asString() == "mohini") - { - grid_choice = GRID_INFO_MOHINI; - } - else if (queryMap["grid"].asString() == "yami") - { - grid_choice = GRID_INFO_YAMI; - } - else if (queryMap["grid"].asString() == "nandi") - { - grid_choice = GRID_INFO_NANDI; - } - else if (queryMap["grid"].asString() == "mitra") - { - grid_choice = GRID_INFO_MITRA; - } - else if (queryMap["grid"].asString() == "radha") - { - grid_choice = GRID_INFO_RADHA; - } - else if (queryMap["grid"].asString() == "ravi") - { - grid_choice = GRID_INFO_RAVI; - } - else if (queryMap["grid"].asString() == "aruna") - { - grid_choice = GRID_INFO_ARUNA; - } - else if (queryMap["grid"].asString() == "bharati") - { - grid_choice = GRID_INFO_BHARATI; - } - else if (queryMap["grid"].asString() == "chandra") - { - grid_choice = GRID_INFO_CHANDRA; - } - else if (queryMap["grid"].asString() == "danu") - { - grid_choice = GRID_INFO_DANU; - } - else if (queryMap["grid"].asString() == "parvati") - { - grid_choice = GRID_INFO_PARVATI; - } - else if (queryMap["grid"].asString() == "skanda") - { - grid_choice = GRID_INFO_SKANDA; - } - - if(grid_choice != GRID_INFO_NONE) - { - LLViewerLogin::getInstance()->setGridChoice(grid_choice); - } - - std::string startLocation = queryMap["location"].asString(); - - if (startLocation == "specify") - { - LLURLSimString::setString(queryMap["region"].asString()); - } - else if (startLocation == "home") - { - gSavedSettings.setBOOL("LoginLastLocation", FALSE); - LLURLSimString::setString(LLStringUtil::null); - } - else if (startLocation == "last") - { - gSavedSettings.setBOOL("LoginLastLocation", TRUE); - LLURLSimString::setString(LLStringUtil::null); - } -} - -bool LLLoginHandler::handle(const LLSD& tokens, - const LLSD& queryMap) -{ - parse(queryMap); - - //if we haven't initialized stuff yet, this is - //coming in from the GURL handler, just parse - if (STATE_FIRST == LLStartUp::getStartupState()) - { - return true; - } - - std::string password = queryMap["password"].asString(); - - if (!password.empty()) - { - gSavedSettings.setBOOL("RememberPassword", TRUE); - - if (password.substr(0,3) != "$1$") - { - LLMD5 pass((unsigned char*)password.c_str()); - char md5pass[33]; /* Flawfinder: ignore */ - pass.hex_digest(md5pass); - password = ll_safe_string(md5pass, 32); - save_password_to_disk(password.c_str()); - } - } - else - { - save_password_to_disk(NULL); - gSavedSettings.setBOOL("RememberPassword", FALSE); - } - - - if (LLStartUp::getStartupState() < STATE_LOGIN_CLEANUP) //on splash page - { - if (mWebLoginKey.isNull()) { - LLPanelLogin::loadLoginPage(); - } else { - LLStartUp::setStartupState( STATE_LOGIN_CLEANUP ); - } - } - return true; -} - -LLLoginHandler gLoginHandler; // helper class that trys to download a URL from a web site and calls a method // on parent class indicating if the web server is working or not @@ -450,7 +263,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, LL_VERSION_PATCH, LL_VIEWER_BUILD ); LLTextBox* channel_text = getChild<LLTextBox>("channel_text"); - channel_text->setTextArg("[CHANNEL]", channel); + channel_text->setTextArg("[CHANNEL]", channel); // though not displayed channel_text->setTextArg("[VERSION]", version); channel_text->setClickedCallback(onClickVersion); channel_text->setCallbackUserData(this); @@ -465,7 +278,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, // get the web browser control LLWebBrowserCtrl* web_browser = getChild<LLWebBrowserCtrl>("login_html"); // Need to handle login secondlife:///app/ URLs - web_browser->setOpenAppSLURLs( true ); + web_browser->setTrusted( true ); // observe browser events web_browser->addObserver( this ); diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h index aa41ab70b8..9d7e386cda 100644 --- a/indra/newview/llpanellogin.h +++ b/indra/newview/llpanellogin.h @@ -33,36 +33,11 @@ #define LL_LLPANELLOGIN_H #include "llpanel.h" -#include "llcommandhandler.h" -#include "lldbstrings.h" -#include "llmemory.h" -#include "llviewerimage.h" -#include "llstring.h" -#include "llmd5.h" -#include "llwebbrowserctrl.h" - -class LLTextBox; -class LLLineEditor; -class LLCheckBoxCtrl; -class LLButton; -class LLComboBox; - - -class LLLoginHandler : public LLCommandHandler -{ - public: - // allow from external browsers - LLLoginHandler() : LLCommandHandler("login", true) { } - bool handle(const LLSD& tokens, const LLSD& queryMap); - bool parseDirectLogin(std::string url); - void parse(const LLSD& queryMap); - - LLUUID mWebLoginKey; - std::string mFirstName; - std::string mLastName; -}; +#include "llmemory.h" // LLPointer<> +#include "llwebbrowserctrl.h" // LLWebBrowserCtrlObserver + +class LLUIImage; -extern LLLoginHandler gLoginHandler; class LLPanelLogin: public LLPanel, @@ -130,4 +105,7 @@ private: BOOL mHtmlAvailable; }; +std::string load_password_from_disk(void); +void save_password_to_disk(const char* hashed_password); + #endif diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp index f7f33cb66b..38214d78d6 100644 --- a/indra/newview/llpanelobject.cpp +++ b/indra/newview/llpanelobject.cpp @@ -849,6 +849,7 @@ void LLPanelObject::getState( ) F32 twist_inc = OBJECT_TWIST_LINEAR_INC; BOOL advanced_is_dimple = FALSE; + BOOL advanced_is_slice = FALSE; BOOL size_is_hole = FALSE; // Tune based on overall volume type @@ -902,8 +903,20 @@ void LLPanelObject::getState( ) break; case MI_BOX: + advanced_cut_visible = TRUE; + advanced_is_slice = TRUE; + break; + case MI_CYLINDER: + advanced_cut_visible = TRUE; + advanced_is_slice = TRUE; + break; + case MI_PRISM: + advanced_cut_visible = TRUE; + advanced_is_slice = TRUE; + break; + default: break; } @@ -995,6 +1008,8 @@ void LLPanelObject::getState( ) childSetVisible("advanced_cut", FALSE); childSetVisible("advanced_dimple", FALSE); + childSetVisible("advanced_slice", FALSE); + if (advanced_cut_visible) { if (advanced_is_dimple) @@ -1002,6 +1017,12 @@ void LLPanelObject::getState( ) childSetVisible("advanced_dimple", TRUE); childSetEnabled("advanced_dimple", enabled); } + + else if (advanced_is_slice) + { + childSetVisible("advanced_slice", TRUE); + childSetEnabled("advanced_slice", enabled); + } else { childSetVisible("advanced_cut", TRUE); @@ -1895,8 +1916,9 @@ void LLPanelObject::clearCtrls() childSetEnabled("scale_hole", FALSE); childSetEnabled("scale_taper", FALSE); - childSetEnabled( "advanced_cut", FALSE ); - childSetEnabled( "advanced_dimple", FALSE ); + childSetEnabled("advanced_cut", FALSE); + childSetEnabled("advanced_dimple", FALSE); + childSetVisible("advanced_slice", FALSE); } // diff --git a/indra/newview/llpanelpermissions.cpp b/indra/newview/llpanelpermissions.cpp index fff5c1985b..8a75385984 100644 --- a/indra/newview/llpanelpermissions.cpp +++ b/indra/newview/llpanelpermissions.cpp @@ -190,9 +190,6 @@ void LLPanelPermissions::refresh() childSetEnabled("Description:",false); childSetText("Object Description",LLStringUtil::null); childSetEnabled("Object Description",false); - - childSetText("prim info",LLStringUtil::null); - childSetEnabled("prim info",false); childSetEnabled("Permissions:",false); @@ -395,33 +392,6 @@ void LLPanelPermissions::refresh() childSetEnabled("Object Description",false); } - - // Pre-compute object info string - S32 prim_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount(); - S32 obj_count = LLSelectMgr::getInstance()->getSelection()->getRootObjectCount(); - - std::string object_info_string; - if (1 == obj_count) - { - object_info_string.assign("1 Object, "); - } - else - { - object_info_string = llformat( "%d Objects, ", obj_count); - } - if (1 == prim_count) - { - object_info_string.append("1 Primitive"); - } - else - { - std::string buffer; - buffer = llformat( "%d Primitives", prim_count); - object_info_string.append(buffer); - } - childSetText("prim info",object_info_string); - childSetEnabled("prim info",true); - S32 total_sale_price = 0; S32 individual_sale_price = 0; BOOL is_for_sale_mixed = FALSE; diff --git a/indra/newview/llpanelplace.cpp b/indra/newview/llpanelplace.cpp index f40c101a4d..4ae253360a 100644 --- a/indra/newview/llpanelplace.cpp +++ b/indra/newview/llpanelplace.cpp @@ -360,6 +360,7 @@ void LLPanelPlace::displayParcelInfo(const LLVector3& pos_region, mDescEditor->setText(getString("server_update_text")); } mSnapshotCtrl->setImageAssetID(LLUUID::null); + mSnapshotCtrl->setFallbackImageName("default_land_picture.j2c"); } diff --git a/indra/newview/llprogressview.cpp b/indra/newview/llprogressview.cpp index c79022a98f..897596ea42 100644 --- a/indra/newview/llprogressview.cpp +++ b/indra/newview/llprogressview.cpp @@ -46,12 +46,14 @@ #include "llagent.h" #include "llbutton.h" #include "llfocusmgr.h" +#include "llprogressbar.h" #include "llstartup.h" #include "llviewercontrol.h" #include "llviewerimagelist.h" #include "llviewerwindow.h" #include "llappviewer.h" #include "llweb.h" +#include "lluictrlfactory.h" LLProgressView* LLProgressView::sInstance = NULL; @@ -69,28 +71,28 @@ const S32 ANIMATION_FRAMES = 1; //13; LLProgressView::LLProgressView(const std::string& name, const LLRect &rect) : LLPanel(name, rect, FALSE), mPercentDone( 0.f ), + mURLInMessage(false), mMouseDownInActiveArea( false ) { - const S32 CANCEL_BTN_WIDTH = 70; - const S32 CANCEL_BTN_OFFSET = 16; - LLRect r; - r.setOriginAndSize( - getRect().getWidth() - CANCEL_BTN_OFFSET - CANCEL_BTN_WIDTH, CANCEL_BTN_OFFSET, - CANCEL_BTN_WIDTH, BTN_HEIGHT ); - - mCancelBtn = new LLButton(std::string("Quit"), - r, - std::string(""), - LLProgressView::onCancelButtonClicked, - NULL ); - mCancelBtn->setFollows( FOLLOWS_RIGHT | FOLLOWS_BOTTOM ); - addChild( mCancelBtn ); + LLUICtrlFactory::getInstance()->buildPanel(this, "panel_progress.xml"); + reshape(rect.getWidth(), rect.getHeight()); +} + +BOOL LLProgressView::postBuild() +{ + mProgressBar = getChild<LLProgressBar>("login_progress_bar"); + + mCancelBtn = getChild<LLButton>("cancel_btn"); + mCancelBtn->setClickedCallback( LLProgressView::onCancelButtonClicked ); mFadeTimer.stop(); - setVisible(FALSE); - mOutlineRect.set( 0, 0, 0, 0 ); + getChild<LLTextBox>("title_text")->setText(LLStringExplicit(LLAppViewer::instance()->getSecondLifeTitle())); + + getChild<LLTextBox>("message_text")->setClickedCallback(onClickMessage); + getChild<LLTextBox>("message_text")->setCallbackUserData(this); sInstance = this; + return TRUE; } @@ -101,59 +103,11 @@ LLProgressView::~LLProgressView() sInstance = NULL; } -BOOL LLProgressView::handleMouseDown(S32 x, S32 y, MASK mask) -{ - if ( mOutlineRect.pointInRect( x, y ) ) - { - mMouseDownInActiveArea = TRUE; - return TRUE; - }; - - return LLPanel::handleMouseDown(x, y, mask); -} - -BOOL LLProgressView::handleMouseUp(S32 x, S32 y, MASK mask) -{ - if ( mOutlineRect.pointInRect( x, y ) ) - { - if ( mMouseDownInActiveArea ) - { - if ( ! mMessage.empty() ) - { - std::string url_to_open( "" ); - - size_t start_pos = mMessage.find( "http://" ); - if ( start_pos != std::string::npos ) - { - size_t end_pos = mMessage.find_first_of( " \n\r\t", start_pos ); - if ( end_pos != std::string::npos ) - url_to_open = mMessage.substr( start_pos, end_pos - start_pos ); - else - url_to_open = mMessage.substr( start_pos ); - - LLWeb::loadURLExternal( url_to_open ); - }; - }; - return TRUE; - }; - }; - - return LLPanel::handleMouseUp(x, y, mask); -} - BOOL LLProgressView::handleHover(S32 x, S32 y, MASK mask) { if( childrenHandleHover( x, y, mask ) == NULL ) { - lldebugst(LLERR_USER_INPUT) << "hover handled by LLProgressView" << llendl; - if ( mOutlineRect.pointInRect( x, y ) ) - { - gViewerWindow->setCursor(UI_CURSOR_ARROW); - } - else - { - gViewerWindow->setCursor(UI_CURSOR_WAIT); - } + gViewerWindow->setCursor(UI_CURSOR_WAIT); } return TRUE; } @@ -181,7 +135,7 @@ void LLProgressView::setVisible(BOOL visible) setFocus(TRUE); mFadeTimer.stop(); mProgressTimer.start(); - LLView::setVisible(visible); + LLPanel::setVisible(visible); } } @@ -190,19 +144,6 @@ void LLProgressView::draw() { static LLTimer timer; - if (gNoRender) - { - return; - } - - // Make sure the progress view always fills the entire window. - S32 width = gViewerWindow->getWindowWidth(); - S32 height = gViewerWindow->getWindowHeight(); - if( (width != getRect().getWidth()) || (height != getRect().getHeight()) ) - { - reshape( width, height ); - } - // Paint bitmap if we've got one glPushMatrix(); if (gStartImageGL) @@ -211,6 +152,8 @@ void LLProgressView::draw() gGL.getTexUnit(0)->bind(gStartImageGL); gGL.color4f(1.f, 1.f, 1.f, mFadeTimer.getStarted() ? clamp_rescale(mFadeTimer.getElapsedTimeF32(), 0.f, FADE_IN_TIME, 1.f, 0.f) : 1.f); F32 image_aspect = (F32)gStartImageWidth / (F32)gStartImageHeight; + S32 width = getRect().getWidth(); + S32 height = getRect().getHeight(); F32 view_aspect = (F32)width / (F32)height; // stretch image to maintain aspect ratio if (image_aspect > view_aspect) @@ -237,161 +180,37 @@ void LLProgressView::draw() // Handle fade-in animation if (mFadeTimer.getStarted()) { - LLView::draw(); + LLPanel::draw(); if (mFadeTimer.getElapsedTimeF32() > FADE_IN_TIME) { gFocusMgr.removeTopCtrlWithoutCallback(this); - LLView::setVisible(FALSE); + LLPanel::setVisible(FALSE); gStartImageGL = NULL; } return; } - S32 line_x = getRect().getWidth() / 2; - S32 line_one_y = getRect().getHeight() / 2 + 64; - const S32 LINE_SPACING = 25; - S32 line_two_y = line_one_y - LINE_SPACING; - const LLFontGL* font = LLFontGL::sSansSerif; - - LLUIImagePtr shadow_imagep = LLUI::getUIImage("rounded_square_soft.tga"); - LLUIImagePtr bar_fg_imagep = LLUI::getUIImage("progressbar_fill.tga"); - LLUIImagePtr bar_bg_imagep = LLUI::getUIImage("progressbar_track.tga"); - LLUIImagePtr bar_imagep = LLUI::getUIImage("rounded_square.tga"); - - LLColor4 background_color = gColors.getColor("LoginProgressBarBgColor"); - - F32 alpha = 0.5f + 0.5f*0.5f*(1.f + (F32)sin(3.f*timer.getElapsedTimeF32())); - // background_color.mV[3] = background_color.mV[3]*alpha; - - std::string top_line = LLAppViewer::instance()->getSecondLifeTitle(); - - S32 bar_bottom = line_two_y - 30; - S32 bar_height = 18; - S32 bar_width = getRect().getWidth() * 2 / 3; - S32 bar_left = (getRect().getWidth() / 2) - (bar_width / 2); - - // translucent outline box - S32 background_box_left = ( ( ( getRect().getWidth() / 2 ) - ( bar_width / 2 ) ) / 4 ) * 3; - S32 background_box_top = ( getRect().getHeight() / 2 ) + LINE_SPACING * 5; - S32 background_box_right = getRect().getWidth() - background_box_left; - S32 background_box_bottom = ( getRect().getHeight() / 2 ) - LINE_SPACING * 5; - S32 background_box_width = background_box_right - background_box_left + 1; - S32 background_box_height = background_box_top - background_box_bottom + 1; - -// shadow_imagep->draw( background_box_left + 2, -// background_box_bottom - 2, -// background_box_width, -// background_box_height, -// gColors.getColor( "LoginProgressBoxShadowColor" ) ); -// bar_outline_imagep->draw( background_box_left, -// background_box_bottom, -// background_box_width, -// background_box_height, -// gColors.getColor("LoginProgressBoxBorderColor") ); - - bar_imagep->draw( background_box_left + 1, - background_box_bottom + 1, - background_box_width - 2, - background_box_height - 2, - gColors.getColor("LoginProgressBoxCenterColor") ); - - // we'll need this later for catching a click if it looks like it contains a link - if ( mMessage.find( "http://" ) != std::string::npos ) - mOutlineRect.set( background_box_left, background_box_top, background_box_right, background_box_bottom ); - else - mOutlineRect.set( 0, 0, 0, 0 ); - - // draw loading bar - font->renderUTF8(top_line, 0, - line_x, line_one_y, - //LLColor4::white, - gColors.getColor("LoginProgressBoxTextColor"), - LLFontGL::HCENTER, LLFontGL::BASELINE, - LLFontGL::DROP_SHADOW); - font->renderUTF8(mText, 0, - line_x, line_two_y, - //LLColor4::white, - gColors.getColor("LoginProgressBoxTextColor"), - LLFontGL::HCENTER, LLFontGL::BASELINE, - LLFontGL::DROP_SHADOW); - -// shadow_imagep->draw( -// bar_left + 2, -// bar_bottom - 2, -// bar_width, -// bar_height, -// gColors.getColor("LoginProgressBoxShadowColor")); - -// bar_imagep->draw( -// bar_left, -// bar_bottom, -// bar_width, -// bar_height, -// LLColor4(0.7f, 0.7f, 0.8f, 1.0f)); - - bar_bg_imagep->draw( - bar_left + 2, - bar_bottom + 2, - bar_width - 4, - bar_height - 4, - background_color); - - LLColor4 bar_color = gColors.getColor("LoginProgressBarFgColor"); - bar_color.mV[3] = alpha; - bar_fg_imagep->draw( - bar_left + 2, - bar_bottom + 2, - llround((bar_width - 4) * (mPercentDone / 100.f)), - bar_height - 4, - bar_color); - - S32 line_three_y = line_two_y - LINE_SPACING * 3; - - // draw the message if there is one - if(!mMessage.empty()) - { - LLColor4 text_message_color = gColors.getColor("LoginProgressBoxTextColor"); - LLWString wmessage = utf8str_to_wstring(mMessage); - const F32 MAX_PIXELS = 640.0f; - S32 chars_left = wmessage.length(); - S32 chars_this_time = 0; - S32 msgidx = 0; - while(chars_left > 0) - { - chars_this_time = font->maxDrawableChars(wmessage.substr(msgidx).c_str(), - MAX_PIXELS, - MAX_STRING - 1, - TRUE); - LLWString wbuffer = wmessage.substr(msgidx, chars_this_time); - font->render(wbuffer, 0, - (F32)line_x, (F32)line_three_y, - //LLColor4::white, - gColors.getColor("LoginProgressBoxTextColor"), - LLFontGL::HCENTER, LLFontGL::BASELINE, - LLFontGL::DROP_SHADOW); - msgidx += chars_this_time; - chars_left -= chars_this_time; - line_three_y -= LINE_SPACING; - } - } - // draw children - LLView::draw(); + LLPanel::draw(); } void LLProgressView::setText(const std::string& text) { - mText = text; + getChild<LLTextBox>("progress_text")->setWrappedText(LLStringExplicit(text)); } void LLProgressView::setPercent(const F32 percent) { - mPercentDone = llclamp(percent, 0.f, 100.f); + mProgressBar->setPercent(percent); } void LLProgressView::setMessage(const std::string& msg) { mMessage = msg; + mURLInMessage = mMessage.find( "http://" ) != std::string::npos; + + getChild<LLTextBox>("message_text")->setWrappedText(LLStringExplicit(mMessage)); + getChild<LLTextBox>("message_text")->setHoverActive(mURLInMessage); } void LLProgressView::setCancelButtonVisible(BOOL b, const std::string& label) @@ -416,3 +235,25 @@ void LLProgressView::onCancelButtonClicked(void*) sInstance->setVisible(FALSE); } } + +// static +void LLProgressView::onClickMessage(void* data) +{ + LLProgressView* viewp = (LLProgressView*)data; + if ( ! viewp->mMessage.empty() ) + { + std::string url_to_open( "" ); + + size_t start_pos = viewp->mMessage.find( "http://" ); + if ( start_pos != std::string::npos ) + { + size_t end_pos = viewp->mMessage.find_first_of( " \n\r\t", start_pos ); + if ( end_pos != std::string::npos ) + url_to_open = viewp->mMessage.substr( start_pos, end_pos - start_pos ); + else + url_to_open = viewp->mMessage.substr( start_pos ); + + LLWeb::loadURLExternal( url_to_open ); + } + } +} diff --git a/indra/newview/llprogressview.h b/indra/newview/llprogressview.h index 84ae8f6e82..d29439635e 100644 --- a/indra/newview/llprogressview.h +++ b/indra/newview/llprogressview.h @@ -37,16 +37,17 @@ class LLImageRaw; class LLButton; +class LLProgressBar; class LLProgressView : public LLPanel { public: LLProgressView(const std::string& name, const LLRect& rect); virtual ~LLProgressView(); + + BOOL postBuild(); /*virtual*/ void draw(); - /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); - /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask); @@ -61,16 +62,18 @@ public: void setCancelButtonVisible(BOOL b, const std::string& label); static void onCancelButtonClicked( void* ); + static void onClickMessage(void*); protected: + LLProgressBar* mProgressBar; F32 mPercentDone; - std::string mText; std::string mMessage; LLButton* mCancelBtn; LLFrameTimer mFadeTimer; LLFrameTimer mProgressTimer; LLRect mOutlineRect; bool mMouseDownInActiveArea; + bool mURLInMessage; static LLProgressView* sInstance; }; diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index ca310cf8e4..3de0cf80ce 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -113,6 +113,7 @@ #include "llinventorymodel.h" #include "llinventoryview.h" #include "llkeyboard.h" +#include "llloginhandler.h" // gLoginHandler, SLURL support #include "llpanellogin.h" #include "llmutelist.h" #include "llnotify.h" @@ -654,16 +655,23 @@ bool idle_startup() // // Log on to system // - if ((!gLoginHandler.mFirstName.empty() && - !gLoginHandler.mLastName.empty() && - !gLoginHandler.mWebLoginKey.isNull()) - || gLoginHandler.parseDirectLogin(LLStartUp::sSLURLCommand) ) + if (!LLStartUp::sSLURLCommand.empty()) { - firstname = gLoginHandler.mFirstName; - lastname = gLoginHandler.mLastName; - web_login_key = gLoginHandler.mWebLoginKey; + // this might be a secondlife:///app/login URL + gLoginHandler.parseDirectLogin(LLStartUp::sSLURLCommand); + } + if (!gLoginHandler.getFirstName().empty() + || !gLoginHandler.getLastName().empty() + || !gLoginHandler.getWebLoginKey().isNull() ) + { + // We have at least some login information on a SLURL + firstname = gLoginHandler.getFirstName(); + lastname = gLoginHandler.getLastName(); + web_login_key = gLoginHandler.getWebLoginKey(); - show_connect_box = false; + // Show the login screen if we don't have everything + show_connect_box = + firstname.empty() || lastname.empty() || web_login_key.isNull(); } else if(gSavedSettings.getLLSD("UserLoginInfo").size() == 3) { @@ -814,11 +822,11 @@ bool idle_startup() if (STATE_LOGIN_CLEANUP == LLStartUp::getStartupState()) { //reset the values that could have come in from a slurl - if (!gLoginHandler.mWebLoginKey.isNull()) + if (!gLoginHandler.getWebLoginKey().isNull()) { - firstname = gLoginHandler.mFirstName; - lastname = gLoginHandler.mLastName; - web_login_key = gLoginHandler.mWebLoginKey; + firstname = gLoginHandler.getFirstName(); + lastname = gLoginHandler.getLastName(); + web_login_key = gLoginHandler.getWebLoginKey(); } if (show_connect_box) @@ -1779,6 +1787,8 @@ bool idle_startup() gFrameIntervalSeconds = 0.f; } + // Initialize FOV + LLViewerCamera::getInstance()->setView(gSavedSettings.getF32("CameraAngle")); // Make sure agent knows correct aspect ratio LLViewerCamera::getInstance()->setViewHeightInPixels(gViewerWindow->getWindowDisplayHeight()); if (gViewerWindow->mWindow->getFullscreen()) @@ -3947,8 +3957,9 @@ bool LLStartUp::dispatchURL() // ok, if we've gotten this far and have a startup URL if (!sSLURLCommand.empty()) { - const bool from_external_browser = true; - LLURLDispatcher::dispatch(sSLURLCommand, from_external_browser); + LLWebBrowserCtrl* web = NULL; + const bool trusted_browser = false; + LLURLDispatcher::dispatch(sSLURLCommand, web, trusted_browser); } else if (LLURLSimString::parse()) { @@ -3964,8 +3975,9 @@ bool LLStartUp::dispatchURL() || (dy*dy > SLOP*SLOP) ) { std::string url = LLURLSimString::getURL(); - const bool from_external_browser = true; - LLURLDispatcher::dispatch(url, from_external_browser); + LLWebBrowserCtrl* web = NULL; + const bool trusted_browser = false; + LLURLDispatcher::dispatch(url, web, trusted_browser); } return true; } diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp index ac80f1b669..278f7ea9d1 100644 --- a/indra/newview/llstatusbar.cpp +++ b/indra/newview/llstatusbar.cpp @@ -757,7 +757,7 @@ static void onClickParcelInfo(void* data) static void onClickBalance(void* data) { - LLFloaterBuyCurrency::buyCurrency(); + onClickBuyCurrency(data); } static void onClickBuyCurrency(void* data) diff --git a/indra/newview/llstylemap.cpp b/indra/newview/llstylemap.cpp index 2d3fb566e0..bc8c353de0 100644 --- a/indra/newview/llstylemap.cpp +++ b/indra/newview/llstylemap.cpp @@ -47,13 +47,13 @@ LLStyleMap::~LLStyleMap() LLStyleMap &LLStyleMap::instance() { - static LLStyleMap mStyleMap; - return mStyleMap; + static LLStyleMap style_map; + return style_map; } // This is similar to the [] accessor except that if the entry doesn't already exist, // then this will create the entry. -const LLStyleSP &LLStyleMap::lookup(const LLUUID &source) +const LLStyleSP &LLStyleMap::lookupAgent(const LLUUID &source) { // Find this style in the map or add it if not. This map holds links to residents' profiles. if (find(source) == end()) @@ -77,6 +77,37 @@ const LLStyleSP &LLStyleMap::lookup(const LLUUID &source) return (*this)[source]; } +// This is similar to lookupAgent for any generic URL encoded style. +const LLStyleSP &LLStyleMap::lookup(const LLUUID& id, const std::string& link) +{ + // Find this style in the map or add it if not. + iterator iter = find(id); + if (iter == end()) + { + LLStyleSP style(new LLStyle); + style->setVisible(true); + style->setFontName(LLStringUtil::null); + if (id != LLUUID::null && !link.empty()) + { + style->setColor(gSavedSettings.getColor4("HTMLLinkColor")); + style->setLinkHREF(link); + } + else + style->setColor(LLColor4::white); + (*this)[id] = style; + } + else + { + LLStyleSP style = (*iter).second; + if ( style->getLinkHREF() != link ) + { + style->setLinkHREF(link); + } + } + + return (*this)[id]; +} + void LLStyleMap::update() { for (style_map_t::iterator iter = begin(); iter != end(); ++iter) diff --git a/indra/newview/llstylemap.h b/indra/newview/llstylemap.h index fbf12a04a3..8d9da8e3b2 100644 --- a/indra/newview/llstylemap.h +++ b/indra/newview/llstylemap.h @@ -47,7 +47,8 @@ public: LLStyleMap(); ~LLStyleMap(); // Just like the [] accessor but it will add the entry in if it doesn't exist. - const LLStyleSP &lookup(const LLUUID &source); + const LLStyleSP &lookupAgent(const LLUUID &source); + const LLStyleSP &lookup(const LLUUID &source, const std::string& link); static LLStyleMap &instance(); // Forces refresh of the entries, call when something changes (e.g. link color). diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 7bdea15ac4..29dbc08fae 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -111,7 +111,9 @@ public: const std::string& label, PermissionMask immediate_filter_perm_mask, PermissionMask non_immediate_filter_perm_mask, - BOOL can_apply_immediately); + BOOL can_apply_immediately, + const std::string& fallback_image_name); + virtual ~LLFloaterTexturePicker(); // LLView overrides @@ -164,12 +166,13 @@ protected: LLTextureCtrl* mOwner; LLUUID mImageAssetID; // Currently selected texture + std::string mFallbackImageName; // What to show if currently selected texture is null. LLUUID mWhiteImageAssetID; LLUUID mSpecialCurrentImageAssetID; // Used when the asset id has no corresponding texture in the user's inventory. LLUUID mOriginalImageAssetID; - std::string mLabel; + std::string mLabel; LLTextBox* mTentativeLabel; LLTextBox* mResolutionLabel; @@ -194,7 +197,8 @@ LLFloaterTexturePicker::LLFloaterTexturePicker( const std::string& label, PermissionMask immediate_filter_perm_mask, PermissionMask non_immediate_filter_perm_mask, - BOOL can_apply_immediately) + BOOL can_apply_immediately, + const std::string& fallback_image_name) : LLFloater( std::string("texture picker"), rect, @@ -203,6 +207,7 @@ LLFloaterTexturePicker::LLFloaterTexturePicker( TEX_PICKER_MIN_WIDTH, TEX_PICKER_MIN_HEIGHT ), mOwner( owner ), mImageAssetID( owner->getImageAssetID() ), + mFallbackImageName( fallback_image_name ), mWhiteImageAssetID( gSavedSettings.getString( "UIImgWhiteUUID" ) ), mOriginalImageAssetID(owner->getImageAssetID()), mLabel(label), @@ -549,6 +554,11 @@ void LLFloaterTexturePicker::draw() mTexturep = gImageList.getImage(mImageAssetID, MIPMAP_YES, IMMEDIATE_NO); mTexturep->setBoostLevel(LLViewerImage::BOOST_PREVIEW); } + else if (!mFallbackImageName.empty()) + { + mTexturep = gImageList.getImageFromFile(mFallbackImageName); + mTexturep->setBoostLevel(LLViewerImage::BOOST_PREVIEW); + } if (mTentativeLabel) { @@ -1130,7 +1140,9 @@ void LLTextureCtrl::showPicker(BOOL take_focus) mLabel, mImmediateFilterPermMask, mNonImmediateFilterPermMask, - mCanApplyImmediately); + mCanApplyImmediately, + mFallbackImageName); + mFloaterHandle = floaterp->getHandle(); gFloaterView->getParentFloater(this)->addDependentFloater(floaterp); @@ -1289,15 +1301,21 @@ void LLTextureCtrl::draw() { mBorder->setKeyboardFocusHighlight(hasFocus()); - if (mImageAssetID.isNull() || !mValid) + if (!mValid) { mTexturep = NULL; } - else + else if (!mImageAssetID.isNull()) { mTexturep = gImageList.getImage(mImageAssetID, MIPMAP_YES, IMMEDIATE_NO); mTexturep->setBoostLevel(LLViewerImage::BOOST_PREVIEW); } + else if (!mFallbackImageName.empty()) + { + // Show fallback image. + mTexturep = gImageList.getImageFromFile(mFallbackImageName); + mTexturep->setBoostLevel(LLViewerImage::BOOST_PREVIEW); + } // Border LLRect border( 0, getRect().getHeight(), getRect().getWidth(), BTN_HEIGHT_SMALL ); diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h index cf83c628b8..5e369ec29e 100644 --- a/indra/newview/lltexturectrl.h +++ b/indra/newview/lltexturectrl.h @@ -115,9 +115,12 @@ public: const LLUUID& getImageAssetID() const { return mImageAssetID; } void setDefaultImageAssetID( const LLUUID& id ) { mDefaultImageAssetID = id; } + const LLUUID& getDefaultImageAssetID() const { return mDefaultImageAssetID; } const std::string& getDefaultImageName() const { return mDefaultImageName; } - const LLUUID& getDefaultImageAssetID() const { return mDefaultImageAssetID; } + + void setFallbackImageName( const std::string& name ) { mFallbackImageName = name; } + const std::string& getFallbackImageName() const { return mFallbackImageName; } void setCaption(const std::string& caption); void setCanApplyImmediately(BOOL b); @@ -163,6 +166,7 @@ private: LLUUID mImageItemID; LLUUID mImageAssetID; LLUUID mDefaultImageAssetID; + std::string mFallbackImageName; std::string mDefaultImageName; LLHandle<LLFloater> mFloaterHandle; LLTextBox* mTentativeLabel; diff --git a/indra/newview/llurldispatcher.cpp b/indra/newview/llurldispatcher.cpp index 5f26155bc0..477146a473 100644 --- a/indra/newview/llurldispatcher.cpp +++ b/indra/newview/llurldispatcher.cpp @@ -64,26 +64,33 @@ public: static bool isSLURLCommand(const std::string& url); - static bool dispatch(const std::string& url, bool from_external_browser); + static bool dispatch(const std::string& url, + LLWebBrowserCtrl* web, + bool trusted_browser); // returns true if handled or explicitly blocked. static bool dispatchRightClick(const std::string& url); private: static bool dispatchCore(const std::string& url, - bool from_external_browser, bool right_mouse); + bool right_mouse, + LLWebBrowserCtrl* web, + bool trusted_browser); // handles both left and right click - static bool dispatchHelp(const std::string& url, BOOL right_mouse); + static bool dispatchHelp(const std::string& url, bool right_mouse); // Handles sl://app.floater.html.help by showing Help floater. // Returns true if handled. - static bool dispatchApp(const std::string& url, bool from_external_browser, BOOL right_mouse); + static bool dispatchApp(const std::string& url, + bool right_mouse, + LLWebBrowserCtrl* web, + bool trusted_browser); // Handles secondlife:///app/agent/<agent_id>/about and similar // by showing panel in Search floater. // Returns true if handled or explicitly blocked. - static bool dispatchRegion(const std::string& url, BOOL right_mouse); + static bool dispatchRegion(const std::string& url, bool right_mouse); // handles secondlife://Ahern/123/45/67/ // Returns true if handled. @@ -127,11 +134,14 @@ bool LLURLDispatcherImpl::isSLURLCommand(const std::string& url) } // static -bool LLURLDispatcherImpl::dispatchCore(const std::string& url, bool from_external_browser, bool right_mouse) +bool LLURLDispatcherImpl::dispatchCore(const std::string& url, + bool right_mouse, + LLWebBrowserCtrl* web, + bool trusted_browser) { if (url.empty()) return false; if (dispatchHelp(url, right_mouse)) return true; - if (dispatchApp(url, from_external_browser, right_mouse)) return true; + if (dispatchApp(url, right_mouse, web, trusted_browser)) return true; if (dispatchRegion(url, right_mouse)) return true; /* @@ -145,23 +155,27 @@ bool LLURLDispatcherImpl::dispatchCore(const std::string& url, bool from_externa } // static -bool LLURLDispatcherImpl::dispatch(const std::string& url, bool from_external_browser) +bool LLURLDispatcherImpl::dispatch(const std::string& url, + LLWebBrowserCtrl* web, + bool trusted_browser) { llinfos << "url: " << url << llendl; const bool right_click = false; - return dispatchCore(url, from_external_browser, right_click); + return dispatchCore(url, right_click, web, trusted_browser); } // static bool LLURLDispatcherImpl::dispatchRightClick(const std::string& url) { llinfos << "url: " << url << llendl; - const bool from_external_browser = false; const bool right_click = true; - return dispatchCore(url, from_external_browser, right_click); + LLWebBrowserCtrl* web = NULL; + const bool trusted_browser = false; + return dispatchCore(url, right_click, web, trusted_browser); } + // static -bool LLURLDispatcherImpl::dispatchHelp(const std::string& url, BOOL right_mouse) +bool LLURLDispatcherImpl::dispatchHelp(const std::string& url, bool right_mouse) { #if LL_LIBXUL_ENABLED if (matchPrefix(url, SLURL_SL_HELP_PREFIX)) @@ -175,8 +189,9 @@ bool LLURLDispatcherImpl::dispatchHelp(const std::string& url, BOOL right_mouse) // static bool LLURLDispatcherImpl::dispatchApp(const std::string& url, - bool from_external_browser, - BOOL right_mouse) + bool right_mouse, + LLWebBrowserCtrl* web, + bool trusted_browser) { if (!isSLURL(url)) { @@ -189,12 +204,12 @@ bool LLURLDispatcherImpl::dispatchApp(const std::string& url, std::string cmd = pathArray.get(0); pathArray.erase(0); // erase "cmd" bool handled = LLCommandDispatcher::dispatch( - cmd, from_external_browser, pathArray, uri.queryMap()); + cmd, pathArray, uri.queryMap(), web, trusted_browser); return handled; } // static -bool LLURLDispatcherImpl::dispatchRegion(const std::string& url, BOOL right_mouse) +bool LLURLDispatcherImpl::dispatchRegion(const std::string& url, bool right_mouse) { if (!isSLURL(url)) { @@ -359,10 +374,13 @@ std::string LLURLDispatcherImpl::stripProtocol(const std::string& url) class LLTeleportHandler : public LLCommandHandler { public: - // not allowed from outside the app - LLTeleportHandler() : LLCommandHandler("teleport", false) { } + // Teleport requests *must* come from a trusted browser + // inside the app, otherwise a malicious web page could + // cause a constant teleport loop. JC + LLTeleportHandler() : LLCommandHandler("teleport", true) { } - bool handle(const LLSD& tokens, const LLSD& queryMap) + bool handle(const LLSD& tokens, const LLSD& query_map, + LLWebBrowserCtrl* web) { // construct a "normal" SLURL, resolve the region to // a global position, and teleport to it @@ -401,10 +419,13 @@ bool LLURLDispatcher::isSLURLCommand(const std::string& url) } // static -bool LLURLDispatcher::dispatch(const std::string& url, bool from_external_browser) +bool LLURLDispatcher::dispatch(const std::string& url, + LLWebBrowserCtrl* web, + bool trusted_browser) { - return LLURLDispatcherImpl::dispatch(url, from_external_browser); + return LLURLDispatcherImpl::dispatch(url, web, trusted_browser); } + // static bool LLURLDispatcher::dispatchRightClick(const std::string& url) { @@ -414,13 +435,20 @@ bool LLURLDispatcher::dispatchRightClick(const std::string& url) // static bool LLURLDispatcher::dispatchFromTextEditor(const std::string& url) { - // text editors are by definition internal to our code - const bool from_external_browser = false; - return LLURLDispatcherImpl::dispatch(url, from_external_browser); + // *NOTE: Text editors are considered sources of trusted URLs + // in order to make objectim and avatar profile links in chat + // history work. While a malicious resident could chat an app + // SLURL, the receiving resident will see it and must affirmatively + // click on it. + // *TODO: Make this trust model more refined. JC + const bool trusted_browser = true; + LLWebBrowserCtrl* web = NULL; + return LLURLDispatcherImpl::dispatch(url, web, trusted_browser); } // static -std::string LLURLDispatcher::buildSLURL(const std::string& regionname, S32 x, S32 y, S32 z) +std::string LLURLDispatcher::buildSLURL(const std::string& regionname, + S32 x, S32 y, S32 z) { std::string slurl = SLURL_SLURL_PREFIX + regionname + llformat("/%d/%d/%d",x,y,z); slurl = LLWeb::escapeURL( slurl ); diff --git a/indra/newview/llurldispatcher.h b/indra/newview/llurldispatcher.h index a8629626b1..6640ca11b3 100644 --- a/indra/newview/llurldispatcher.h +++ b/indra/newview/llurldispatcher.h @@ -31,6 +31,9 @@ #ifndef LLURLDISPATCHER_H #define LLURLDISPATCHER_H +class LLWebBrowserCtrl; + + class LLURLDispatcher { public: @@ -40,13 +43,20 @@ public: static bool isSLURLCommand(const std::string& url); // Is this a special secondlife://app/ URL? - static bool dispatch(const std::string& url, bool from_external_browser); + static bool dispatch(const std::string& url, + LLWebBrowserCtrl* web, + bool trusted_browser); // At startup time and on clicks in internal web browsers, // teleport, open map, or run requested command. - // Handles: + // @param url // secondlife://RegionName/123/45/67/ // secondlife:///app/agent/3d6181b0-6a4b-97ef-18d8-722652995cf1/show // sl://app/foo/bar + // @param web + // Pointer to LLWebBrowserCtrl sending URL, can be NULL + // @param trusted_browser + // True if coming inside the app AND from a brower instance + // that navigates to trusted (Linden Lab) pages. // Returns true if someone handled the URL. static bool dispatchRightClick(const std::string& url); diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp index 5f6fcb70e3..f9ced0f53f 100644 --- a/indra/newview/llviewercamera.cpp +++ b/indra/newview/llviewercamera.cpp @@ -138,9 +138,9 @@ void LLViewerCamera::updateCameraLocation(const LLVector3 ¢er, mVelocityStat.addValue(dpos); mAngularVelocityStat.addValue(drot); // update pixel meter ratio using default fov, not modified one - mPixelMeterRatio = mViewHeightInPixels / (2.f*tanf(mCameraFOVDefault*0.5)); + mPixelMeterRatio = getViewHeightInPixels()/ (2.f*tanf(mCameraFOVDefault*0.5)); // update screen pixel area - mScreenPixelArea =(S32)((F32)mViewHeightInPixels * ((F32)mViewHeightInPixels * mAspect)); + mScreenPixelArea =(S32)((F32)getViewHeightInPixels() * ((F32)getViewHeightInPixels() * getAspect())); } const LLMatrix4 &LLViewerCamera::getProjection() const @@ -732,3 +732,38 @@ BOOL LLViewerCamera::areVertsVisible(LLViewerObject* volumep, BOOL all_verts) } return all_verts; } + +// changes local camera and broadcasts change +/* virtual */ void LLViewerCamera::setView(F32 vertical_fov_rads) +{ + F32 old_fov = LLViewerCamera::getInstance()->getDefaultFOV(); + + // cap the FoV + vertical_fov_rads = llclamp(vertical_fov_rads, getMinView(), getMaxView()); + + if (vertical_fov_rads == old_fov) return; + + // send the new value to the simulator + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_AgentFOV); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addU32Fast(_PREHASH_CircuitCode, gMessageSystem->mOurCircuitCode); + + msg->nextBlockFast(_PREHASH_FOVBlock); + msg->addU32Fast(_PREHASH_GenCounter, 0); + msg->addF32Fast(_PREHASH_VerticalAngle, vertical_fov_rads); + + gAgent.sendReliableMessage(); + + // sync the camera with the new value + LLCamera::setView(vertical_fov_rads); // call base implementation +} + +void LLViewerCamera::setDefaultFOV(F32 vertical_fov_rads) { + vertical_fov_rads = llclamp(vertical_fov_rads, getMinView(), getMaxView()); + setView(vertical_fov_rads); + mCameraFOVDefault = vertical_fov_rads; +} + diff --git a/indra/newview/llviewercamera.h b/indra/newview/llviewercamera.h index cc37851d05..8aec405bf0 100644 --- a/indra/newview/llviewercamera.h +++ b/indra/newview/llviewercamera.h @@ -55,9 +55,6 @@ class LLViewerCamera : public LLCamera, public LLSingleton<LLViewerCamera> public: LLViewerCamera(); -// const LLVector3 &getPositionAgent() const; -// const LLVector3d &getPositionGlobal() const; - void updateCameraLocation(const LLVector3 ¢er, const LLVector3 &up_direction, const LLVector3 &point_of_interest); @@ -80,7 +77,10 @@ public: void getPixelVectors(const LLVector3 &pos_agent, LLVector3 &up, LLVector3 &right); LLVector3 roundToPixel(const LLVector3 &pos_agent); - void setDefaultFOV(F32 fov) { mCameraFOVDefault = fov; } + // Sets the current matrix + /* virtual */ void setView(F32 vertical_fov_rads); + // Sets the current matrix AND remembers result as default view + void setDefaultFOV(F32 vertical_fov_rads); F32 getDefaultFOV() { return mCameraFOVDefault; } BOOL cameraUnderWater() const; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index e8ce3e02ea..6e37e6253f 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -107,6 +107,7 @@ #include "llfloatergroups.h" #include "llfloaterhtml.h" #include "llfloaterhtmlhelp.h" +#include "llfloaterhtmlsimple.h" #include "llfloaterhud.h" #include "llfloaterinspect.h" #include "llfloaterlagmeter.h" @@ -116,6 +117,7 @@ #include "llfloatermute.h" #include "llfloateropenobject.h" #include "llfloaterpermissionsmgr.h" +#include "llfloaterperms.h" #include "llfloaterpostprocess.h" #include "llfloaterpreference.h" #include "llfloaterregioninfo.h" @@ -329,7 +331,6 @@ void handle_agent_stop_moving(void*); void print_packets_lost(void*); void drop_packet(void*); void velocity_interpolate( void* data ); -void update_fov(S32 increments); void toggle_wind_audio(void); void toggle_water_audio(void); void handle_rebake_textures(void*); @@ -358,7 +359,8 @@ void run_vectorize_perf_test(void *) // Debug UI void handle_web_search_demo(void*); -void handle_slurl_test(void*); +void handle_web_browser_test(void*); +void handle_buy_currency_test(void*); void handle_save_to_xml(void*); void handle_load_from_xml(void*); @@ -1018,7 +1020,8 @@ extern BOOL gDebugSelectMgr; void init_debug_ui_menu(LLMenuGL* menu) { - menu->append(new LLMenuItemCallGL("SLURL Test", &handle_slurl_test)); + menu->append(new LLMenuItemCallGL("Web Browser Test", &handle_web_browser_test)); + menu->append(new LLMenuItemCallGL("Buy Currency Test", &handle_buy_currency_test)); menu->append(new LLMenuItemCallGL("Editable UI", &edit_ui)); menu->append(new LLMenuItemToggleGL("Async Keystrokes", &gHandleKeysAsync)); menu->append(new LLMenuItemCallGL( "Dump SelectMgr", &dump_select_mgr)); @@ -3048,86 +3051,6 @@ void velocity_interpolate( void* data ) } -void update_fov(S32 increments) -{ - F32 old_fov = LLViewerCamera::getInstance()->getDefaultFOV(); - // for each increment, FoV is 20% bigger - F32 new_fov = old_fov * pow(1.2f, increments); - - // cap the FoV - new_fov = llclamp(new_fov, MIN_FIELD_OF_VIEW, MAX_FIELD_OF_VIEW); - - if (new_fov != old_fov) - { - LLMessageSystem* msg = gMessageSystem; - msg->newMessageFast(_PREHASH_AgentFOV); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->addU32Fast(_PREHASH_CircuitCode, gMessageSystem->mOurCircuitCode); - - msg->nextBlockFast(_PREHASH_FOVBlock); - msg->addU32Fast(_PREHASH_GenCounter, 0); - msg->addF32Fast(_PREHASH_VerticalAngle, new_fov); - - gAgent.sendReliableMessage(); - - // force agent to update dirty patches - LLViewerCamera::getInstance()->setDefaultFOV(new_fov); - LLViewerCamera::getInstance()->setView(new_fov); - } -} - -class LLViewZoomOut : public view_listener_t -{ - bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) - { - update_fov(1); - return true; - } -}; - -class LLViewZoomIn : public view_listener_t -{ - bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) - { - update_fov(-1); - return true; - } -}; - -class LLViewZoomDefault : public view_listener_t -{ - bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) - { - F32 old_fov = LLViewerCamera::getInstance()->getView(); - // for each increment, FoV is 20% bigger - F32 new_fov = DEFAULT_FIELD_OF_VIEW; - - if (new_fov != old_fov) - { - LLMessageSystem* msg = gMessageSystem; - msg->newMessageFast(_PREHASH_AgentFOV); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->addU32Fast(_PREHASH_CircuitCode, gMessageSystem->mOurCircuitCode); - msg->nextBlockFast(_PREHASH_FOVBlock); - msg->addU32Fast(_PREHASH_GenCounter, 0); - msg->addF32Fast(_PREHASH_VerticalAngle, new_fov); - - gAgent.sendReliableMessage(); - - // force agent to update dirty patches - LLViewerCamera::getInstance()->setDefaultFOV(new_fov); - LLViewerCamera::getInstance()->setView(new_fov); - } - return true; - } -}; - - - void toggle_wind_audio(void) { if (gAudiop) @@ -4291,12 +4214,7 @@ class LLToolsStopAllAnimations : public view_listener_t { bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) { - LLVOAvatar* avatarp = gAgent.getAvatarObject(); - if (avatarp) - { - avatarp->deactivateAllMotions(); - avatarp->startDefaultMotions(); - } + gAgent.stopCurrentAnimations(); return true; } }; @@ -5291,6 +5209,10 @@ class LLShowFloater : public view_listener_t { LLFloaterBeacons::toggleInstance(LLSD()); } + else if (floater_name == "perm prefs") + { + LLFloaterPerms::toggleInstance(LLSD()); + } return true; } }; @@ -5474,7 +5396,6 @@ class LLLandEdit : public view_listener_t LLViewerParcelMgr::getInstance()->selectParcelAt( LLToolPie::getInstance()->getPick().mPosGlobal ); - gFloaterTools->showMore(TRUE); gFloaterView->bringToFront( gFloaterTools ); // Switch to land edit toolset @@ -7003,7 +6924,7 @@ void handle_save_to_xml(void*) LLFloater* frontmost = gFloaterView->getFrontmost(); if (!frontmost) { - gViewerWindow->alertXml("NoFrontmostFloater"); + gViewerWindow->alertXml("NoFrontmostFloater"); return; } @@ -7036,17 +6957,54 @@ void handle_load_from_xml(void*) } } -void handle_slurl_test(void*) +void handle_web_browser_test(void*) { const bool open_links_externally = false; const bool open_app_slurls = true; LLFloaterHtml::getInstance()->show( "http://secondlife.com/app/search/slurls.html", - "SLURL Test", + "Web Browser Test", open_links_externally, open_app_slurls); } +void handle_buy_currency_test(void*) +{ + std::string url = + "http://sarahd-sl-13041.webdev.lindenlab.com/app/lindex/index.php?agent_id=[AGENT_ID]&secure_session_id=[SESSION_ID]&lang=[LANGUAGE]"; + + LLStringUtil::format_map_t replace; + replace["[AGENT_ID]"] = gAgent.getID().asString(); + replace["[SESSION_ID]"] = gAgent.getSecureSessionID().asString(); + + // *TODO: Replace with call to LLUI::getLanguage() after windows-setup + // branch merges in. JC + std::string language = "en-us"; + language = gSavedSettings.getString("Language"); + if (language.empty() || language == "default") + { + language = gSavedSettings.getString("InstallLanguage"); + } + if (language.empty() || language == "default") + { + language = gSavedSettings.getString("SystemLanguage"); + } + if (language.empty() || language == "default") + { + language = "en-us"; + } + + replace["[LANGUAGE]"] = language; + LLStringUtil::format(url, replace); + + llinfos << "buy currency url " << url << llendl; + + LLFloaterHtmlSimple* floater = LLFloaterHtmlSimple::showInstance(url); + // Needed so we can use secondlife:///app/floater/self/close SLURLs + floater->setTrusted(true); + floater->center(); +} + void handle_rebake_textures(void*) { LLVOAvatar* avatar = gAgent.getAvatarObject(); @@ -7418,6 +7376,24 @@ static void addMenu(view_listener_t *menu, const std::string& name) void initialize_menus() { + // A parameterized event handler used as ctrl-8/9/0 zoom controls below. + class LLZoomer : public view_listener_t + { + public: + // The "mult" parameter says whether "val" is a multiplier or used to set the value. + LLZoomer(F32 val, bool mult=true) : mVal(val), mMult(mult) {} + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + F32 new_fov_rad = mMult ? LLViewerCamera::getInstance()->getDefaultFOV() * mVal : mVal; + LLViewerCamera::getInstance()->setDefaultFOV(new_fov_rad); + gSavedSettings.setF32("CameraAngle", LLViewerCamera::getInstance()->getView()); // setView may have clamped it. + return true; + } + private: + F32 mVal; + bool mMult; + }; + // File menu init_menu_file(); @@ -7457,9 +7433,9 @@ void initialize_menus() addMenu(new LLViewHighlightTransparent(), "View.HighlightTransparent"); addMenu(new LLViewToggleRenderType(), "View.ToggleRenderType"); addMenu(new LLViewShowHUDAttachments(), "View.ShowHUDAttachments"); - addMenu(new LLViewZoomOut(), "View.ZoomOut"); - addMenu(new LLViewZoomIn(), "View.ZoomIn"); - addMenu(new LLViewZoomDefault(), "View.ZoomDefault"); + addMenu(new LLZoomer(1.2f), "View.ZoomOut"); + addMenu(new LLZoomer(1/1.2f), "View.ZoomIn"); + addMenu(new LLZoomer(DEFAULT_FIELD_OF_VIEW, false), "View.ZoomDefault"); addMenu(new LLViewFullscreen(), "View.Fullscreen"); addMenu(new LLViewDefaultUISize(), "View.DefaultUISize"); diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index 27badfb1dd..9448a00e68 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -43,6 +43,7 @@ #include "llfloatersnapshot.h" #include "llinventorymodel.h" // gInventory #include "llresourcedata.h" +#include "llfloaterperms.h" #include "llstatusbar.h" #include "llviewercontrol.h" // gSavedSettings #include "llviewerimagelist.h" @@ -322,7 +323,9 @@ class LLFileUploadBulk : public view_listener_t LLStringUtil::stripNonprintable(asset_name); LLStringUtil::trim(asset_name); - upload_new_resource(filename, asset_name, asset_name, 0, LLAssetType::AT_NONE, LLInventoryType::IT_NONE); // file + upload_new_resource(filename, asset_name, asset_name, 0, LLAssetType::AT_NONE, LLInventoryType::IT_NONE, + LLFloaterPerms::getNextOwnerPerms(), LLFloaterPerms::getGroupPerms(), LLFloaterPerms::getEveryonePerms()); + // *NOTE: Ew, we don't iterate over the file list here, // we handle the next files in upload_done_callback() } @@ -515,7 +518,9 @@ void upload_new_resource(const std::string& src_filename, std::string name, std::string desc, S32 compression_info, LLAssetType::EType destination_folder_type, LLInventoryType::EType inv_type, - U32 next_owner_perm, + U32 next_owner_perms, + U32 group_perms, + U32 everyone_perms, const std::string& display_name, LLAssetStorage::LLStoreAssetCallback callback, void *userdata) @@ -803,7 +808,7 @@ void upload_new_resource(const std::string& src_filename, std::string name, t_disp_name = src_filename; } upload_new_resource(tid, asset_type, name, desc, compression_info, // tid - destination_folder_type, inv_type, next_owner_perm, + destination_folder_type, inv_type, next_owner_perms, group_perms, everyone_perms, display_name, callback, userdata); } else @@ -875,15 +880,15 @@ void upload_done_callback(const LLUUID& uuid, void* user_data, S32 result, LLExt LLUUID folder_id(gInventory.findCategoryUUIDForType(dest_loc)); if(folder_id.notNull()) { - U32 next_owner_perm = data->mNextOwnerPerm; - if(PERM_NONE == next_owner_perm) + U32 next_owner_perms = data->mNextOwnerPerm; + if(PERM_NONE == next_owner_perms) { - next_owner_perm = PERM_MOVE | PERM_TRANSFER; + next_owner_perms = PERM_MOVE | PERM_TRANSFER; } create_inventory_item(gAgent.getID(), gAgent.getSessionID(), folder_id, data->mAssetInfo.mTransactionID, data->mAssetInfo.getName(), data->mAssetInfo.getDescription(), data->mAssetInfo.mType, - data->mInventoryType, NOT_WEARABLE, next_owner_perm, + data->mInventoryType, NOT_WEARABLE, next_owner_perms, LLPointer<LLInventoryCallback>(NULL)); } else @@ -925,7 +930,9 @@ void upload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_ty std::string desc, S32 compression_info, LLAssetType::EType destination_folder_type, LLInventoryType::EType inv_type, - U32 next_owner_perm, + U32 next_owner_perms, + U32 group_perms, + U32 everyone_perms, const std::string& display_name, LLAssetStorage::LLStoreAssetCallback callback, void *userdata) @@ -984,10 +991,14 @@ void upload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_ty body["inventory_type"] = LLInventoryType::lookup(inv_type); body["name"] = name; body["description"] = desc; + body["next_owner_mask"] = LLSD::Integer(next_owner_perms); + body["group_mask"] = LLSD::Integer(group_perms); + body["everyone_mask"] = LLSD::Integer(everyone_perms); - std::ostringstream llsdxml; - LLSDSerialize::toXML(body, llsdxml); - lldebugs << "posting body to capability: " << llsdxml.str() << llendl; + //std::ostringstream llsdxml; + //LLSDSerialize::toPrettyXML(body, llsdxml); + //llinfos << "posting body to capability: " << llsdxml.str() << llendl; + LLHTTPClient::post(url, body, new LLNewAgentInventoryResponder(body, uuid, asset_type)); } else @@ -1015,7 +1026,7 @@ void upload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_ty data->mAssetInfo.mType = asset_type; data->mAssetInfo.mCreatorID = gAgentID; data->mInventoryType = inv_type; - data->mNextOwnerPerm = next_owner_perm; + data->mNextOwnerPerm = next_owner_perms; data->mUserData = userdata; data->mAssetInfo.setName(name); data->mAssetInfo.setDescription(desc); diff --git a/indra/newview/llviewermenufile.h b/indra/newview/llviewermenufile.h index f43e5bfc92..36dd1d78b7 100644 --- a/indra/newview/llviewermenufile.h +++ b/indra/newview/llviewermenufile.h @@ -40,21 +40,29 @@ class LLTransactionID; void init_menu_file(); -void upload_new_resource(const std::string& src_filename, std::string name, - std::string desc, S32 compression_info, +void upload_new_resource(const std::string& src_filename, + std::string name, + std::string desc, + S32 compression_info, LLAssetType::EType destination_folder_type, LLInventoryType::EType inv_type, - U32 next_owner_perm = 0x0, // PERM_NONE + U32 next_owner_perms = 0x0, // PERM_NONE + U32 group_perms = 0x0, // PERM_NONE + U32 everyone_perms = 0x0, // PERM_NONE const std::string& display_name = LLStringUtil::null, LLAssetStorage::LLStoreAssetCallback callback = NULL, void *userdata = NULL); -void upload_new_resource(const LLTransactionID &tid, LLAssetType::EType type, +void upload_new_resource(const LLTransactionID &tid, + LLAssetType::EType type, std::string name, - std::string desc, S32 compression_info, + std::string desc, + S32 compression_info, LLAssetType::EType destination_folder_type, LLInventoryType::EType inv_type, - U32 next_owner_perm = 0x0, // PERM_NONE + U32 next_owner_perms = 0x0, // PERM_NONE + U32 group_perms = 0x0, // PERM_NONE + U32 everyone_perms = 0x0, // PERM_NONE const std::string& display_name = LLStringUtil::null, LLAssetStorage::LLStoreAssetCallback callback = NULL, void *userdata = NULL); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 426edb37ca..eeedb98250 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -1803,15 +1803,51 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) break; case IM_FROM_TASK: - if (is_busy && !is_owned_by_me) { - return; + if (is_busy && !is_owned_by_me) + { + return; + } + chat.mText = name + separator_string + message.substr(message_offset); + chat.mFromName = name; + + // Build a link to open the object IM info window. + std::string location = ll_safe_string((char*)binary_bucket,binary_bucket_size); + + LLSD query_string; + query_string["owner"] = from_id; + query_string["slurl"] = location.c_str(); + query_string["name"] = name; + if (from_group) + { + query_string["groupowned"] = "true"; + } + + if (session_id.notNull()) + { + chat.mFromID = session_id; + } + else + { + // This message originated on a region without the updated code for task id and slurl information. + // We just need a unique ID for this object that isn't the owner ID. + // If it is the owner ID it will overwrite the style that contains the link to that owner's profile. + // This isn't ideal - it will make 1 style for all objects owned by the the same person/group. + // This works because the only thing we can really do in this case is show the owner name and link to their profile. + chat.mFromID = from_id ^ gAgent.getSessionID(); + } + + std::ostringstream link; + link << "secondlife:///app/objectim/" << session_id + << LLURI::mapToQueryString(query_string); + + chat.mURL = link.str(); + + // Note: lie to LLFloaterChat::addChat(), pretending that this is NOT an IM, because + // IMs from objcts don't open IM sessions. + chat.mSourceType = CHAT_SOURCE_OBJECT; + LLFloaterChat::addChat(chat, FALSE, FALSE); } - chat.mText = name + separator_string + message.substr(message_offset); - // Note: lie to LLFloaterChat::addChat(), pretending that this is NOT an IM, because - // IMs from objcts don't open IM sessions. - chat.mSourceType = CHAT_SOURCE_OBJECT; - LLFloaterChat::addChat(chat, FALSE, FALSE); break; case IM_FROM_TASK_AS_ALERT: if (is_busy && !is_owned_by_me) diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 38e376b511..edb339eab4 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1342,8 +1342,9 @@ void LLViewerWindow::handleDataCopy(LLWindow *window, S32 data_type, void *data) case SLURL_MESSAGE_TYPE: // received URL std::string url = (const char*)data; - const bool from_external_browser = true; - if (LLURLDispatcher::dispatch(url, from_external_browser)) + LLWebBrowserCtrl* web = NULL; + const bool trusted_browser = false; + if (LLURLDispatcher::dispatch(url, web, trusted_browser)) { // bring window to foreground, as it has just been "launched" from a URL mWindow->bringToFront(); diff --git a/indra/newview/skins/default/textures/default_land_picture.j2c b/indra/newview/skins/default/textures/default_land_picture.j2c Binary files differnew file mode 100644 index 0000000000..34df0291ae --- /dev/null +++ b/indra/newview/skins/default/textures/default_land_picture.j2c diff --git a/indra/newview/skins/default/textures/default_profile_picture.j2c b/indra/newview/skins/default/textures/default_profile_picture.j2c Binary files differnew file mode 100644 index 0000000000..c53a22e816 --- /dev/null +++ b/indra/newview/skins/default/textures/default_profile_picture.j2c diff --git a/indra/newview/skins/default/textures/locked_image.j2c b/indra/newview/skins/default/textures/locked_image.j2c Binary files differnew file mode 100644 index 0000000000..9e8998d675 --- /dev/null +++ b/indra/newview/skins/default/textures/locked_image.j2c diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index 9e1d9b5196..34c9dea7e6 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -369,4 +369,8 @@ <texture name="skin_thumbnail_default.png" preload="true" /> <texture name="skin_thumbnail_silver.png" preload="true" /> + + <texture name="default_land_picture.j2c"/> + <texture name="default_profile_picture.j2c"/> + <texture name="locked_image.j2c"/> </textures> |