diff options
Diffstat (limited to 'indra/newview')
108 files changed, 4006 insertions, 2013 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 4286b91654..a25ea01d11 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -161,7 +161,6 @@ set(viewer_SOURCE_FILES llfloaterfonttest.cpp llfloatergesture.cpp llfloatergodtools.cpp - llfloatergroupinfo.cpp llfloatergroupinvite.cpp llfloatergroups.cpp llfloaterhandler.cpp @@ -248,6 +247,7 @@ set(viewer_SOURCE_FILES lllocaltextureobject.cpp lllocationhistory.cpp lllocationinputctrl.cpp + llurllineeditorctrl.cpp lllogchat.cpp llloginhandler.cpp llmanip.cpp @@ -328,7 +328,6 @@ set(viewer_SOURCE_FILES llpreviewanim.cpp llpreview.cpp llpreviewgesture.cpp - llpreviewlandmark.cpp llpreviewnotecard.cpp llpreviewscript.cpp llpreviewsound.cpp @@ -354,6 +353,8 @@ set(viewer_SOURCE_FILES llstylemap.cpp llsurface.cpp llsurfacepatch.cpp + llsyswellitem.cpp + llsyswellwindow.cpp llteleporthistory.cpp lltexglobalcolor.cpp lltexlayer.cpp @@ -602,7 +603,6 @@ set(viewer_HEADER_FILES llfloaterfriends.h llfloatergesture.h llfloatergodtools.h - llfloatergroupinfo.h llfloatergroupinvite.h llfloatergroups.h llfloaterhandler.h @@ -690,6 +690,7 @@ set(viewer_HEADER_FILES lllocaltextureobject.h lllocationhistory.h lllocationinputctrl.h + llurllineeditorctrl.h lllogchat.h llloginhandler.h llmanip.h @@ -768,7 +769,6 @@ set(viewer_HEADER_FILES llpreview.h llpreviewanim.h llpreviewgesture.h - llpreviewlandmark.h llpreviewnotecard.h llpreviewscript.h llpreviewsound.h @@ -796,6 +796,8 @@ set(viewer_HEADER_FILES llstylemap.h llsurface.h llsurfacepatch.h + llsyswellitem.h + llsyswellwindow.h lltable.h llteleporthistory.h lltexglobalcolor.h diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index fa6ce4f1d8..f42ce2136f 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -1193,10 +1193,10 @@ <real>6.0</real> </array> </map> - <key>CameraOffsetDefault</key> + <key>CameraOffsetRearView</key> <map> <key>Comment</key> - <string>Default camera offset from avatar</string> + <string>Initial camera offset from avatar in Rear View</string> <key>Persist</key> <integer>1</integer> <key>Type</key> @@ -1208,6 +1208,36 @@ <real>0.75</real> </array> </map> + <key>CameraOffsetFrontView</key> + <map> + <key>Comment</key> + <string>Initial camera offset from avatar in Front View</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Vector3</string> + <key>Value</key> + <array> + <real>2.2</real> + <real>0.0</real> + <real>0.0</real> + </array> + </map> + <key>CameraOffsetGroupView</key> + <map> + <key>Comment</key> + <string>Initial camera offset from avatar in Group View</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Vector3</string> + <key>Value</key> + <array> + <real>-1.0</real> + <real>0.7</real> + <real>0.5</real> + </array> + </map> <key>CameraOffsetScale</key> <map> <key>Comment</key> @@ -1245,6 +1275,17 @@ <key>Value</key> <real>1.0</real> </map> + <key>CameraPreset</key> + <map> + <key>Comment</key> + <string>Preset camera position - view (0 - rear, 1 - front, 2 - group)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <integer>0</integer> + </map> <key>ChatBarStealsFocus</key> <map> <key>Comment</key> @@ -3134,14 +3175,14 @@ <key>Value</key> <integer>0</integer> </map> - <key>FocusOffsetDefault</key> + <key>FocusOffsetRearView</key> <map> <key>Comment</key> - <string>Default focus point offset relative to avatar (x-axis is forward)</string> + <string>Initial focus point offset relative to avatar for the camera preset Rear View (x-axis is forward)</string> <key>Persist</key> <integer>1</integer> <key>Type</key> - <string>Vector3</string> + <string>Vector3D</string> <key>Value</key> <array> <real>1.0</real> @@ -3149,6 +3190,36 @@ <real>1.0</real> </array> </map> + <key>FocusOffsetFrontView</key> + <map> + <key>Comment</key> + <string>Initial focus point offset relative to avatar for the camera preset Front View</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Vector3D</string> + <key>Value</key> + <array> + <real>0.0</real> + <real>0.0</real> + <real>0.0</real> + </array> + </map> + <key>FocusOffsetGroupView</key> + <map> + <key>Comment</key> + <string>Initial focus point offset relative to avatar for the camera preset Group View</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Vector3D</string> + <key>Value</key> + <array> + <real>1.5</real> + <real>0.5</real> + <real>1.0</real> + </array> + </map> <key>FocusPosOnLogout</key> <map> <key>Comment</key> @@ -4593,7 +4664,7 @@ <key>Type</key> <string>F32</string> <key>Value</key> - <integer>20</integer> + <integer>130</integer> </map> <key>NextOwnerCopy</key> <map> @@ -6827,8 +6898,30 @@ <string>Boolean</string> <key>Value</key> <integer>0</integer> + </map> + <key>ShowPGSearchAll</key> + <map> + <key>Comment</key> + <string>Show/Hide Navigation Bar Favorites Panel</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>ShowNavbarFavoritesPanel</key> + <map> + <key>Comment</key> + <string>Show/Hide Navigation Bar Navigation Panel</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> </map> - <key>ShowPGSearchAll</key> + <key>ShowNavbarNavigationPanel</key> <map> <key>Comment</key> <string>Display results of search All that are flagged as PG</string> diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index ce8b05d97a..513988789b 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -45,13 +45,15 @@ #include "llfloatercamera.h" #include "llfloatercustomize.h" #include "llfloaterdirectory.h" -#include "llfloatergroupinfo.h" + #include "llfloaterland.h" #include "llfloatermute.h" #include "llfloatersnapshot.h" #include "llfloatertools.h" #include "llfloaterworldmap.h" +#include "llgroupactions.h" + #include "llfocusmgr.h" #include "llgroupmgr.h" #include "llhomelocationresponder.h" @@ -280,6 +282,8 @@ LLAgent::LLAgent() : mLastCameraMode( CAMERA_MODE_THIRD_PERSON ), mViewsPushed(FALSE), + mCameraPreset(CAMERA_PRESET_REAR_VIEW), + mCustomAnim(FALSE), mShowAvatar(TRUE), mCameraAnimating( FALSE ), @@ -293,7 +297,6 @@ LLAgent::LLAgent() : mCameraFocusOffset(), mCameraFOVDefault(DEFAULT_FIELD_OF_VIEW), - mCameraOffsetDefault(), mCameraCollidePlane(), mCurrentCameraDistance(2.f), // meters, set in init() @@ -405,9 +408,19 @@ void LLAgent::init() setFlying( gSavedSettings.getBOOL("FlyingAtExit") ); mCameraFocusOffsetTarget = LLVector4(gSavedSettings.getVector3("CameraOffsetBuild")); - mCameraOffsetDefault = gSavedSettings.getVector3("CameraOffsetDefault"); + + mCameraPreset = (ECameraPreset) gSavedSettings.getU32("CameraPreset"); + + mCameraOffsetInitial[CAMERA_PRESET_REAR_VIEW] = gSavedSettings.getVector3("CameraOffsetRearView"); + mCameraOffsetInitial[CAMERA_PRESET_FRONT_VIEW] = gSavedSettings.getVector3("CameraOffsetFrontView"); + mCameraOffsetInitial[CAMERA_PRESET_GROUP_VIEW] = gSavedSettings.getVector3("CameraOffsetGroupView"); + + mFocusOffsetInitial[CAMERA_PRESET_REAR_VIEW] = gSavedSettings.getVector3d("FocusOffsetRearView"); + mFocusOffsetInitial[CAMERA_PRESET_FRONT_VIEW] = gSavedSettings.getVector3d("FocusOffsetFrontView"); + mFocusOffsetInitial[CAMERA_PRESET_GROUP_VIEW] = gSavedSettings.getVector3d("FocusOffsetGroupView"); + mCameraCollidePlane.clearVec(); - mCurrentCameraDistance = mCameraOffsetDefault.magVec() * gSavedSettings.getF32("CameraOffsetScale"); + mCurrentCameraDistance = getCameraOffsetInitial().magVec() * gSavedSettings.getF32("CameraOffsetScale"); mTargetCameraDistance = mCurrentCameraDistance; mCameraZoomFraction = 1.f; mTrackFocusObject = gSavedSettings.getBOOL("TrackFocusObject"); @@ -929,6 +942,20 @@ LLHost LLAgent::getRegionHost() const //----------------------------------------------------------------------------- std::string LLAgent::getSLURL() const { + return buildSLURL(true); +} + +//----------------------------------------------------------------------------- +// getUnescapedSLURL() +// returns empty() if getRegion() == NULL +//----------------------------------------------------------------------------- +std::string LLAgent::getUnescapedSLURL() const +{ + return buildSLURL(false); +} + +std::string LLAgent::buildSLURL(const bool escape) const +{ std::string slurl; LLViewerRegion *regionp = getRegion(); if (regionp) @@ -937,7 +964,10 @@ std::string LLAgent::getSLURL() const S32 x = llround( (F32)fmod( agentPos.mdV[VX], (F64)REGION_WIDTH_METERS ) ); S32 y = llround( (F32)fmod( agentPos.mdV[VY], (F64)REGION_WIDTH_METERS ) ); S32 z = llround( (F32)agentPos.mdV[VZ] ); - slurl = LLSLURL::buildSLURL(regionp->getName(), x, y, z); + if (escape) + slurl = LLSLURL::buildSLURL(regionp->getName(), x, y, z); + else + slurl = LLSLURL::buildUnescapedSLURL(regionp->getName(), x, y, z); } return slurl; } @@ -1885,7 +1915,7 @@ void LLAgent::cameraOrbitIn(const F32 meters) { if (mFocusOnAvatar && mCameraMode == CAMERA_MODE_THIRD_PERSON) { - F32 camera_offset_dist = llmax(0.001f, mCameraOffsetDefault.magVec() * gSavedSettings.getF32("CameraOffsetScale")); + F32 camera_offset_dist = llmax(0.001f, getCameraOffsetInitial().magVec() * gSavedSettings.getF32("CameraOffsetScale")); mCameraZoomFraction = (mTargetCameraDistance - meters) / camera_offset_dist; @@ -3540,7 +3570,6 @@ LLVector3d LLAgent::calcThirdPersonFocusOffset() { // ...offset from avatar LLVector3d focus_offset; - focus_offset.setVec(gSavedSettings.getVector3("FocusOffsetDefault")); LLQuaternion agent_rot = mFrameAgent.getQuaternion(); if (!mAvatarObject.isNull() && mAvatarObject->getParent()) @@ -3548,7 +3577,7 @@ LLVector3d LLAgent::calcThirdPersonFocusOffset() agent_rot *= ((LLViewerObject*)(mAvatarObject->getParent()))->getRenderRotation(); } - focus_offset = focus_offset * agent_rot; + focus_offset = mFocusOffsetInitial[mCameraPreset] * agent_rot; return focus_offset; } @@ -3625,7 +3654,6 @@ LLVector3d LLAgent::calcCameraPositionTargetGlobal(BOOL *hit_limit) LLVector3d frame_center_global = mAvatarObject.isNull() ? getPositionGlobal() : getPosGlobalFromAgent(mAvatarObject->mRoot.getWorldPosition()); - LLVector3 upAxis = getUpAxis(); BOOL isConstrained = FALSE; LLVector3d head_offset; head_offset.setVec(mThirdPersonHeadOffset); @@ -3688,7 +3716,7 @@ LLVector3d LLAgent::calcCameraPositionTargetGlobal(BOOL *hit_limit) } else { - local_camera_offset = mCameraZoomFraction * mCameraOffsetDefault * gSavedSettings.getF32("CameraOffsetScale"); + local_camera_offset = mCameraZoomFraction * getCameraOffsetInitial() * gSavedSettings.getF32("CameraOffsetScale"); // are we sitting down? if (mAvatarObject.notNull() && mAvatarObject->getParent()) @@ -3885,6 +3913,12 @@ LLVector3d LLAgent::calcCameraPositionTargetGlobal(BOOL *hit_limit) } +LLVector3 LLAgent::getCameraOffsetInitial() +{ + return mCameraOffsetInitial[mCameraPreset]; +} + + //----------------------------------------------------------------------------- // handleScrollWheel() //----------------------------------------------------------------------------- @@ -3919,10 +3953,12 @@ void LLAgent::handleScrollWheel(S32 clicks) } else if (mFocusOnAvatar && mCameraMode == CAMERA_MODE_THIRD_PERSON) { - F32 current_zoom_fraction = mTargetCameraDistance / (mCameraOffsetDefault.magVec() * gSavedSettings.getF32("CameraOffsetScale")); + F32 camera_offset_initial_mag = getCameraOffsetInitial().magVec(); + + F32 current_zoom_fraction = mTargetCameraDistance / (camera_offset_initial_mag * gSavedSettings.getF32("CameraOffsetScale")); current_zoom_fraction *= 1.f - pow(ROOT_ROOT_TWO, clicks); - cameraOrbitIn(current_zoom_fraction * mCameraOffsetDefault.magVec() * gSavedSettings.getF32("CameraOffsetScale")); + cameraOrbitIn(current_zoom_fraction * camera_offset_initial_mag * gSavedSettings.getF32("CameraOffsetScale")); } else { @@ -4295,6 +4331,20 @@ void LLAgent::changeCameraToCustomizeAvatar(BOOL avatar_animate, BOOL camera_ani } +void LLAgent::switchCameraPreset(ECameraPreset preset) +{ + //zoom is supposed to be reset for the front and group views + mCameraZoomFraction = 1.f; + + //focusing on avatar in that case means following him on movements + mFocusOnAvatar = TRUE; + + mCameraPreset = preset; + + gSavedSettings.setU32("CameraPreset", mCameraPreset); +} + + // // Focus point management // @@ -5493,8 +5543,8 @@ BOOL LLAgent::downGrabbed() const void update_group_floaters(const LLUUID& group_id) { - LLFloaterGroupInfo::refreshGroup(group_id); - + + LLGroupActions::refresh(group_id); //*TODO Implement group update for Profile View // still actual as of July 31, 2009 (DZ) @@ -5542,7 +5592,7 @@ void LLAgent::processAgentDropGroup(LLMessageSystem *msg, void **) LLGroupMgr::getInstance()->clearGroupData(group_id); // close the floater for this group, if any. - LLFloaterGroupInfo::closeGroup(group_id); + LLGroupActions::closeGroup(group_id); // refresh the group panel of the search window, if necessary. LLFloaterDirectory::refreshGroup(group_id); } @@ -5621,7 +5671,7 @@ class LLAgentDropGroupViewerNode : public LLHTTPNode LLGroupMgr::getInstance()->clearGroupData(group_id); // close the floater for this group, if any. - LLFloaterGroupInfo::closeGroup(group_id); + LLGroupActions::closeGroup(group_id); // refresh the group panel of the search window, //if necessary. LLFloaterDirectory::refreshGroup(group_id); diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index 0b1ff2e76b..ff9e7f574f 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -75,6 +75,19 @@ enum ECameraMode CAMERA_MODE_FOLLOW }; +/** Camera Presets for CAMERA_MODE_THIRD_PERSON */ +enum ECameraPreset +{ + /** Default preset, what the Third Person Mode actually was */ + CAMERA_PRESET_REAR_VIEW, + + /** "Looking at the Avatar from the front" */ + CAMERA_PRESET_FRONT_VIEW, + + /** "Above and to the left, over the shoulder, pulled back a little on the zoom" */ + CAMERA_PRESET_GROUP_VIEW +}; + enum EAnimRequest { ANIM_REQUEST_START, @@ -261,10 +274,12 @@ public: LLViewerRegion *getRegion() const; LLHost getRegionHost() const; std::string getSLURL() const; + std::string getUnescapedSLURL() const; BOOL inPrelude(); BOOL buildLocationString(std::string& str, ELocationFormat fmt = LOCATION_FORMAT_LANDMARK); // Utility to build a location string private: LLViewerRegion *mRegionp; + std::string buildSLURL(const bool escape) const; //-------------------------------------------------------------------- // History @@ -657,6 +672,27 @@ private: ECameraMode mLastCameraMode; //-------------------------------------------------------------------- + // Preset + //-------------------------------------------------------------------- +public: + void switchCameraPreset(ECameraPreset preset); + +private: + + /** Determines default camera offset depending on the current camera preset */ + LLVector3 getCameraOffsetInitial(); + + /** Camera preset in Third Person Mode */ + ECameraPreset mCameraPreset; + + /** Initial camera offsets */ + std::map<ECameraPreset, LLVector3> mCameraOffsetInitial; + + /** Initial focus offsets */ + std::map<ECameraPreset, LLVector3d> mFocusOffsetInitial; + + + //-------------------------------------------------------------------- // Position //-------------------------------------------------------------------- public: @@ -674,7 +710,6 @@ private: F32 mCameraFOVZoomFactor; // Amount of fov zoom applied to camera when zeroing in on an object F32 mCameraCurrentFOVZoomFactor; // Interpolated fov zoom F32 mCameraFOVDefault; // Default field of view that is basis for FOV zoom effect - LLVector3 mCameraOffsetDefault; // Default third-person camera offset LLVector4 mCameraCollidePlane; // Colliding plane for camera F32 mCameraZoomFraction; // Mousewheel driven fraction of zoom LLVector3 mCameraPositionAgent; // Camera position in agent coordinates diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index 281d73b18b..4e289efd1b 100644 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -48,6 +48,7 @@ #include "llviewermessage.h" // for handle_lure #include "llviewerregion.h" + // static void LLAvatarActions::requestFriendshipDialog(const LLUUID& id, const std::string& name) { @@ -79,6 +80,19 @@ void LLAvatarActions::requestFriendshipDialog(const LLUUID& id, const std::strin } // static +void LLAvatarActions::requestFriendshipDialog(const LLUUID& id) +{ + if(id.isNull()) + { + return; + } + + std::string full_name; + gCacheName->getFullName(id, full_name); + requestFriendshipDialog(id, full_name); +} + +// static void LLAvatarActions::removeFriendDialog(const LLUUID& id) { if (id.isNull()) diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h index 73325d21f1..f3c411e033 100644 --- a/indra/newview/llavataractions.h +++ b/indra/newview/llavataractions.h @@ -45,6 +45,11 @@ public: static void requestFriendshipDialog(const LLUUID& id, const std::string& name); /** + * Show a dialog explaining what friendship entails, then request friendship. + */ + static void requestFriendshipDialog(const LLUUID& id); + + /** * Show a friend removal dialog. */ static void removeFriendDialog(const LLUUID& id); diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp index 40dd20dfa4..a85f8710c7 100644 --- a/indra/newview/llavatarlist.cpp +++ b/indra/newview/llavatarlist.cpp @@ -117,24 +117,6 @@ void LLAvatarList::draw() } } -//virtual -BOOL LLAvatarList::handleMouseDown(S32 x, S32 y, MASK mask) -{ - LLScrollListItem* hit_item = hitItem(x, y); - if (NULL == hit_item) - { - std::vector<LLScrollListItem*> selectedItems = getAllSelected(); - std::vector<LLScrollListItem*>::const_iterator it = selectedItems.begin(); - - for (; it != selectedItems.end(); ++it) - { - (*it)->setSelected(FALSE); - } - return TRUE; - } - return LLScrollListCtrl::handleMouseDown(x, y, mask); -} - std::vector<LLUUID> LLAvatarList::getSelectedIDs() { LLUUID selected_id; diff --git a/indra/newview/llavatarlist.h b/indra/newview/llavatarlist.h index 991e9fa145..8b419dbb57 100644 --- a/indra/newview/llavatarlist.h +++ b/indra/newview/llavatarlist.h @@ -59,14 +59,6 @@ public: virtual ~LLAvatarList() {} /*virtual*/ void draw(); - /** - * Overrides base-class behavior of Mouse Down Event. - * - * LLScrollListCtrl::handleMouseDown version calls setFocus which select the first item if nothing selected. - * We need to deselect all items if perform click not over the any item. Otherwise calls base method. - * See EXT-246 - */ - /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); BOOL update(const std::vector<LLUUID>& all_buddies, const std::string& name_filter = LLStringUtil::null); diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp index 9eb8369c4c..bfb2d26870 100644 --- a/indra/newview/llbottomtray.cpp +++ b/indra/newview/llbottomtray.cpp @@ -1,34 +1,34 @@ /** -* @file llbottomtray.cpp -* @brief LLBottomTray class implementation -* -* $LicenseInfo:firstyear=2009&license=viewergpl$ -* -* Copyright (c) 2009, Linden Research, Inc. -* -* Second Life Viewer Source Code -* The source code in this file ("Source Code") is provided by Linden Lab -* to you under the terms of the GNU General Public License, version 2.0 -* ("GPL"), unless you have obtained a separate licensing agreement -* ("Other License"), formally executed by you and Linden Lab. Terms of -* the GPL can be found in doc/GPL-license.txt in this distribution, or -* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 -* -* There are special exceptions to the terms and conditions of the GPL as -* it is applied to this Source Code. View the full text of the exception -* in the file doc/FLOSS-exception.txt in this software distribution, or -* online at -* http://secondlifegrid.net/programs/open_source/licensing/flossexception -* -* By copying, modifying or distributing this software, you acknowledge -* that you have read and understood your obligations described above, -* and agree to abide by those obligations. -* -* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO -* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, -* COMPLETENESS OR PERFORMANCE. -* $/LicenseInfo$ -*/ + * @file llbottomtray.cpp + * @brief LLBottomTray class implementation + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ #include "llviewerprecompiledheaders.h" // must be first include #include "llbottomtray.h" @@ -37,6 +37,7 @@ #include "llchiclet.h" #include "llfloaterreg.h" #include "llflyoutbutton.h" +#include "lllayoutstack.h" #include "llnearbychatbar.h" #include "llsplitbutton.h" #include "llfloatercamera.h" @@ -47,20 +48,23 @@ LLBottomTray::LLBottomTray(const LLSD&) mIMWell(NULL), mSysWell(NULL), mTalkBtn(NULL), - mNearbyChatBar(NULL) + mNearbyChatBar(NULL), + mToolbarStack(NULL) + { mFactoryMap["chat_bar"] = LLCallbackMap(LLBottomTray::createNearbyChatBar, NULL); LLUICtrlFactory::getInstance()->buildPanel(this,"panel_bottomtray.xml"); - mChicletPanel = getChild<LLChicletPanel>("chiclet_list",TRUE,FALSE); - mIMWell = getChild<LLNotificationChiclet>("im_well",TRUE,FALSE); - mSysWell = getChild<LLNotificationChiclet>("sys_well",TRUE,FALSE); + mChicletPanel = getChild<LLChicletPanel>("chiclet_list"); + mIMWell = getChild<LLNotificationChiclet>("im_well"); + mSysWell = getChild<LLNotificationChiclet>("sys_well"); + mSysWell->setNotificationChicletWindow(LLFloaterReg::getInstance("syswell_window")); mChicletPanel->setChicletClickedCallback(boost::bind(&LLBottomTray::onChicletClick,this,_1)); - LLSplitButton* presets = getChild<LLSplitButton>("presets", TRUE, FALSE); - if (presets) presets->setSelectionCallback(LLFloaterCamera::onClickCameraPresets); + LLSplitButton* presets = getChild<LLSplitButton>("presets"); + presets->setSelectionCallback(LLFloaterCamera::onClickCameraPresets); LLIMMgr::getInstance()->addSessionObserver(this); @@ -75,9 +79,10 @@ LLBottomTray::LLBottomTray(const LLSD&) BOOL LLBottomTray::postBuild() { - mNearbyChatBar = getChild<LLNearbyChatBar>("chat_bar"); + mNearbyChatBar = getChild<LLNearbyChatBar>("chat_bar"); + mToolbarStack = getChild<LLLayoutStack>("toolbar_stack"); - return TRUE; + return TRUE; } LLBottomTray::~LLBottomTray() @@ -152,13 +157,14 @@ void LLBottomTray::setVisible(BOOL visible) { LLPanel::setVisible(visible); - LLView* stack = getChild<LLView>("toolbar_stack",TRUE,FALSE); - - if (stack) + // *NOTE: we must check mToolbarStack against NULL because sewtVisible is called from the + // LLPanel::initFromParams BEFORE postBuild is called and child controls are not exist yet + if (NULL != mToolbarStack) { BOOL visibility = gAgent.cameraMouselook() ? false : true; - for ( child_list_const_iter_t child_it = stack->getChildList()->begin(); child_it != stack->getChildList()->end(); child_it++) + for ( child_list_const_iter_t child_it = mToolbarStack->getChildList()->begin(); + child_it != mToolbarStack->getChildList()->end(); child_it++) { LLView* viewp = *child_it; diff --git a/indra/newview/llbottomtray.h b/indra/newview/llbottomtray.h index ffb0f9ae4f..fec533f9f3 100644 --- a/indra/newview/llbottomtray.h +++ b/indra/newview/llbottomtray.h @@ -38,6 +38,7 @@ class LLChicletPanel; class LLLineEditor; +class LLLayoutStack; class LLNotificationChiclet; class LLTalkButton; class LLNearbyChatBar; @@ -80,6 +81,8 @@ protected: LLNotificationChiclet* mSysWell; LLTalkButton* mTalkBtn; LLNearbyChatBar* mNearbyChatBar; + LLLayoutStack* mToolbarStack; + }; #endif // LL_LLBOTTOMPANEL_H diff --git a/indra/newview/llchannelmanager.cpp b/indra/newview/llchannelmanager.cpp index 118385ab58..91945038aa 100644 --- a/indra/newview/llchannelmanager.cpp +++ b/indra/newview/llchannelmanager.cpp @@ -58,15 +58,14 @@ LLChannelManager::~LLChannelManager() //-------------------------------------------------------------------------- void LLChannelManager::onLoginCompleted() { - S32 hidden_notifications = 0; + S32 away_notifications = 0; for(std::vector<ChannelElem>::iterator it = mChannelList.begin(); it != mChannelList.end(); ++it) { - //(*it).channel->showToasts(); - hidden_notifications +=(*it).channel->getNumberOfHiddenToasts(); + away_notifications +=(*it).channel->getNumberOfHiddenToasts(); } - if(!hidden_notifications) + if(!away_notifications) { LLScreenChannel::setStartUpToastShown(); return; @@ -81,15 +80,19 @@ void LLChannelManager::onLoginCompleted() if(!mStartUpChannel) return; - static_cast<LLUICtrl*>(mStartUpChannel)->setCommitCallback(boost::bind(&LLChannelManager::enableShowToasts, this)); - mStartUpChannel->setNumberOfHiddenToasts(hidden_notifications); - mStartUpChannel->createOverflowToast(gSavedSettings.getS32("ChannelBottomPanelMargin"), gSavedSettings.getS32("StartUpToastTime")); + static_cast<LLUICtrl*>(mStartUpChannel)->setCommitCallback(boost::bind(&LLChannelManager::removeStartUpChannel, this)); + mStartUpChannel->createStartUpToast(away_notifications, gSavedSettings.getS32("ChannelBottomPanelMargin"), gSavedSettings.getS32("StartUpToastTime")); } //-------------------------------------------------------------------------- -void LLChannelManager::enableShowToasts() +void LLChannelManager::removeStartUpChannel() { - LLScreenChannel::setStartUpToastShown(); + if(!mStartUpChannel) + return; + + mStartUpChannel->setVisible(FALSE); + mStartUpChannel->closeStartUpToast(); + getRootView()->removeChild(mStartUpChannel); delete mStartUpChannel; mStartUpChannel = NULL; } diff --git a/indra/newview/llchannelmanager.h b/indra/newview/llchannelmanager.h index ac8e81d7ef..6adc79713a 100644 --- a/indra/newview/llchannelmanager.h +++ b/indra/newview/llchannelmanager.h @@ -102,7 +102,7 @@ public: // On LoginCompleted - show StartUp toast void onLoginCompleted(); - void enableShowToasts(); + void removeStartUpChannel(); //TODO: make protected? in order to be shure that channels are created only by notification handlers LLScreenChannel* createChannel(LLChannelManager::Params& p); diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp index 46a2179e8d..7a118deb8a 100644 --- a/indra/newview/llchatbar.cpp +++ b/indra/newview/llchatbar.cpp @@ -122,6 +122,8 @@ BOOL LLChatBar::postBuild() { getChild<LLUICtrl>("Say")->setCommitCallback(boost::bind(&LLChatBar::onClickSay, this, _1)); + // * NOTE: mantipov: getChild with default parameters returns dummy widget. + // Seems this class will be completle removed // attempt to bind to an existing combo box named gesture setGestureCombo(getChild<LLComboBox>( "Gesture", TRUE, FALSE)); diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp index 2b455485ca..a63477a442 100644 --- a/indra/newview/llchatitemscontainerctrl.cpp +++ b/indra/newview/llchatitemscontainerctrl.cpp @@ -82,8 +82,10 @@ void LLChatItemCtrl::reshape (S32 width, S32 height, BOOL called_from_parent ) { LLPanel::reshape(width, height,called_from_parent); - LLPanel* caption = getChild<LLPanel>("msg_caption",false,false); - LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text",false,false); + // *NOTE: we must check if child items exist because reshape is called from the + // LLView::initFromParams BEFORE postBuild is called and child controls are not exist yet + LLPanel* caption = findChild<LLPanel>("msg_caption", false); + LLChatMsgBox* msg_text = findChild<LLChatMsgBox>("msg_text" ,false); if(caption && msg_text) { LLRect caption_rect = caption->getRect(); @@ -125,17 +127,14 @@ std::string LLChatItemCtrl::appendTime() void LLChatItemCtrl::addText (const std::string& message) { - LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text",false,false); - if(msg_text) - msg_text->addText(message); + LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text", false); + msg_text->addText(message); mMessages.push_back(message); } void LLChatItemCtrl::setMessage (const LLChat& msg) { - LLPanel* caption = getChild<LLPanel>("msg_caption",false,false); - if(!caption) - return; + LLPanel* caption = getChild<LLPanel>("msg_caption", false); std::string str_sender; @@ -145,20 +144,19 @@ void LLChatItemCtrl::setMessage (const LLChat& msg) else str_sender = LLTrans::getString("You");; - caption->getChild<LLTextBox>("sender_name",false,false)->setText(str_sender); + caption->getChild<LLTextBox>("sender_name", false)->setText(str_sender); std::string tt = appendTime(); - caption->getChild<LLTextBox>("msg_time",false,false)->setText(tt); + caption->getChild<LLTextBox>("msg_time", false)->setText(tt); - caption->getChild<LLAvatarIconCtrl>("avatar_icon",false,false)->setValue(msg.mFromID); + caption->getChild<LLAvatarIconCtrl>("avatar_icon", false)->setValue(msg.mFromID); mOriginalMessage = msg; - LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text",false,false); - if(msg_text) - msg_text->setText(msg.mText); + LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text", false); + msg_text->setText(msg.mText); LLUICtrl* msg_inspector = caption->getChild<LLUICtrl>("msg_inspector"); if(mOriginalMessage.mSourceType != CHAT_SOURCE_AGENT) @@ -170,17 +168,13 @@ void LLChatItemCtrl::setMessage (const LLChat& msg) void LLChatItemCtrl::snapToMessageHeight () { - LLChatMsgBox* text_box = getChild<LLChatMsgBox>("msg_text",false,false); - if(!text_box) - return;///actually assert fits better + LLChatMsgBox* text_box = getChild<LLChatMsgBox>("msg_text", false); S32 new_height = text_box->getTextPixelHeight(); LLRect panel_rect = getRect(); S32 caption_height = 0; - LLPanel* caption = getChild<LLPanel>("msg_caption",false,false); - if(caption) - caption_height = caption->getRect().getHeight(); - + LLPanel* caption = getChild<LLPanel>("msg_caption", false); + caption_height = caption->getRect().getHeight(); panel_rect.setLeftTopAndSize( panel_rect.mLeft, panel_rect.mTop, panel_rect.getWidth() , caption_height + new_height); @@ -193,14 +187,11 @@ void LLChatItemCtrl::snapToMessageHeight () void LLChatItemCtrl::setWidth(S32 width) { - LLChatMsgBox* text_box = getChild<LLChatMsgBox>("msg_text",false,false); - if(!text_box) - return;///actually assert fits better - + LLChatMsgBox* text_box = getChild<LLChatMsgBox>("msg_text", false); text_box->reshape(width - msg_left_offset - msg_right_offset,100/*its not magic number, we just need any number*/); - LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text",false,false); - if(msg_text && mOriginalMessage.mText.length()) + LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text", false); + if(mOriginalMessage.mText.length()) msg_text->setText(mOriginalMessage.mText); for(size_t i=0;i<mMessages.size();++i) @@ -212,58 +203,41 @@ void LLChatItemCtrl::setWidth(S32 width) void LLChatItemCtrl::onMouseLeave (S32 x, S32 y, MASK mask) { - LLPanel* caption = getChild<LLPanel>("msg_caption",false,false); - if(!caption) - return; + LLPanel* caption = getChild<LLPanel>("msg_caption", false); LLUICtrl* msg_inspector = caption->getChild<LLUICtrl>("msg_inspector"); - if(msg_inspector) - msg_inspector->setVisible(false); + msg_inspector->setVisible(false); } void LLChatItemCtrl::onMouseEnter (S32 x, S32 y, MASK mask) { if(mOriginalMessage.mSourceType != CHAT_SOURCE_AGENT) return; - LLPanel* caption = getChild<LLPanel>("msg_caption",false,false); - if(!caption) - return; + LLPanel* caption = getChild<LLPanel>("msg_caption", false); LLUICtrl* msg_inspector = caption->getChild<LLUICtrl>("msg_inspector"); - if(msg_inspector) - msg_inspector->setVisible(true); + msg_inspector->setVisible(true); } BOOL LLChatItemCtrl::handleMouseDown (S32 x, S32 y, MASK mask) { if(mOriginalMessage.mSourceType != CHAT_SOURCE_AGENT) return LLPanel::handleMouseDown(x,y,mask); - LLPanel* caption = getChild<LLPanel>("msg_caption",false,false); - if(caption) + LLPanel* caption = getChild<LLPanel>("msg_caption", false); + LLUICtrl* msg_inspector = caption->getChild<LLUICtrl>("msg_inspector"); + S32 local_x = x - msg_inspector->getRect().mLeft - caption->getRect().mLeft; + S32 local_y = y - msg_inspector->getRect().mBottom - caption->getRect().mBottom; + if(msg_inspector->pointInView(local_x, local_y)) { - LLUICtrl* msg_inspector = caption->getChild<LLUICtrl>("msg_inspector"); - if(msg_inspector) - { - S32 local_x = x - msg_inspector->getRect().mLeft - caption->getRect().mLeft; - S32 local_y = y - msg_inspector->getRect().mBottom - caption->getRect().mBottom; - if(msg_inspector->pointInView(local_x, local_y)) - { - LLFloaterReg::showInstance("mini_inspector", mOriginalMessage.mFromID); - } - } + LLFloaterReg::showInstance("mini_inspector", mOriginalMessage.mFromID); } return LLPanel::handleMouseDown(x,y,mask); } void LLChatItemCtrl::setHeaderVisibility(EShowItemHeader e) { - LLPanel* caption = getChild<LLPanel>("msg_caption",false,false); - if(!caption) - return; + LLPanel* caption = getChild<LLPanel>("msg_caption", false); - LLUICtrl* icon = caption->getChild<LLUICtrl>("avatar_icon",false,false); - LLUICtrl* name = caption->getChild<LLUICtrl>("sender_name",false,false); - - if(icon == 0 || name == 0) - return; + LLUICtrl* icon = caption->getChild<LLUICtrl>("avatar_icon", false); + LLUICtrl* name = caption->getChild<LLUICtrl>("sender_name", false); icon->setVisible(e == CHATITEMHEADER_SHOW_ONLY_ICON || e==CHATITEMHEADER_SHOW_BOTH); name->setVisible(e == CHATITEMHEADER_SHOW_ONLY_NAME || e==CHATITEMHEADER_SHOW_BOTH); @@ -272,20 +246,15 @@ void LLChatItemCtrl::setHeaderVisibility(EShowItemHeader e) bool LLChatItemCtrl::canAddText () { - LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text",false,false); - if(!msg_text ) - return false; + LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text", false); return msg_text->getTextLinesNum()<10; } BOOL LLChatItemCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask) { - LLPanel* caption = getChild<LLPanel>("msg_caption",false,false); - if(!caption) - return LLPanel::handleRightMouseDown(x,y,mask); - LLUICtrl* avatar_icon = caption->getChild<LLUICtrl>("avatar_icon",false,false); - if(!avatar_icon) - return LLPanel::handleRightMouseDown(x,y,mask); + LLPanel* caption = getChild<LLPanel>("msg_caption", false); + LLUICtrl* avatar_icon = caption->getChild<LLUICtrl>("avatar_icon", false); + S32 local_x = x - avatar_icon->getRect().mLeft - caption->getRect().mLeft; S32 local_y = y - avatar_icon->getRect().mBottom - caption->getRect().mBottom; diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp index 3b88bcfe20..80e27bd366 100644 --- a/indra/newview/llchiclet.cpp +++ b/indra/newview/llchiclet.cpp @@ -39,7 +39,6 @@ #include "lliconctrl.h" #include "llimpanel.h" // LLFloaterIMPanel #include "llimview.h" -#include "llfloatergroupinfo.h" #include "llfloaterreg.h" #include "llmenugl.h" #include "lloutputmonitorctrl.h" @@ -78,6 +77,7 @@ LLNotificationChiclet::LLNotificationChiclet(const Params& p) : LLChiclet(p) , mButton(NULL) , mCounterCtrl(NULL) +, mNotificationChicletWindow(NULL) { LLButton::Params button_params = p.button; button_params.rect(p.rect()); @@ -403,9 +403,7 @@ void LLIMChiclet::onMenuItemClicked(const LLSD& user_data) } else if("add" == level) { - std::string name; - gCacheName->getFullName(other_participant_id,name); - LLAvatarActions::requestFriendshipDialog(other_participant_id,name); + LLAvatarActions::requestFriendshipDialog(other_participant_id); } else if("remove" == level) { @@ -417,7 +415,7 @@ void LLIMChiclet::onMenuItemClicked(const LLSD& user_data) } else if("info" == level) { - LLFloaterGroupInfo::showFromUUID(other_participant_id); + LLGroupActions::show(other_participant_id); } } diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h index a748141a14..103443ccd8 100644 --- a/indra/newview/llchiclet.h +++ b/indra/newview/llchiclet.h @@ -363,10 +363,15 @@ public: /*virtual*/ ~ LLNotificationChiclet(); + // Notification Chiclet Window + void setNotificationChicletWindow(LLFloater* wnd) { mNotificationChicletWindow = wnd; } + protected: LLNotificationChiclet(const Params& p); friend class LLUICtrlFactory; + LLFloater* mNotificationChicletWindow; + protected: LLButton* mButton; LLChicletNotificationCounterCtrl* mCounterCtrl; diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp index 3964fbfa74..9cb3ea127f 100644 --- a/indra/newview/llfavoritesbar.cpp +++ b/indra/newview/llfavoritesbar.cpp @@ -168,6 +168,18 @@ void LLFavoritesBarCtrl::reshape(S32 width, S32 height, BOOL called_from_parent) LLUICtrl::reshape(width, height, called_from_parent); } +LLXMLNodePtr LLFavoritesBarCtrl::getButtonXMLNode() +{ + LLXMLNodePtr buttonXMLNode = NULL; + bool success = LLUICtrlFactory::getLayeredXMLNode("favorites_bar_button.xml", buttonXMLNode); + if (!success) + { + llwarns << "Unable to read xml file with button for Favorites Bar: favorites_bar_button.xml" << llendl; + buttonXMLNode = NULL; + } + return buttonXMLNode; +} + void LLFavoritesBarCtrl::updateButtons(U32 bar_width) { LLInventoryModel::item_array_t items; @@ -177,21 +189,25 @@ void LLFavoritesBarCtrl::updateButtons(U32 bar_width) return; } - const S32 buttonHPad = LLUI::sSettingGroups["config"]->getS32("ButtonHPad"); - const S32 buttonHGap = 2; + static LLXMLNodePtr buttonXMLNode = getButtonXMLNode(); + if (buttonXMLNode.isNull()) + { + return; + } + + S32 buttonWidth = 120; //default value + buttonXMLNode->getAttributeS32("width", buttonWidth); + S32 buttonHGap = 2; // default value + buttonXMLNode->getAttributeS32("left", buttonHGap); + const S32 buttonVGap = 2; - static LLButton::Params default_button_params(LLUICtrlFactory::getDefaultParams<LLButton>()); - std::string flat_icon = "transparent.j2c"; - std::string hover_icon = default_button_params.image_unselected.name; - std::string hover_icon_selected = default_button_params.image_selected.name; - S32 curr_x = buttonHGap; - S32 count = items.count(); + const S32 buttonHPad = LLUI::sSettingGroups["config"]->getS32("ButtonHPad"); const S32 chevron_button_width = mFont->getWidth(">>") + buttonHPad * 2; - S32 buttons_space = bar_width - curr_x; + S32 buttons_space = bar_width - buttonHGap; S32 first_drop_down_item = count; @@ -199,7 +215,7 @@ void LLFavoritesBarCtrl::updateButtons(U32 bar_width) S32 buttons_width = 0; for (S32 i = 0; i < count; ++i) { - buttons_width += mFont->getWidth(items.get(i)->getName()) + buttonHPad * 2 + buttonHGap; + buttons_width += buttonWidth + buttonHGap; if (buttons_width > buttons_space) { // There is no space for all buttons. @@ -207,7 +223,7 @@ void LLFavoritesBarCtrl::updateButtons(U32 bar_width) buttons_space -= chevron_button_width + buttonHGap; while (i >= 0 && buttons_width > buttons_space) { - buttons_width -= mFont->getWidth(items.get(i)->getName()) + buttonHPad * 2 + buttonHGap; + buttons_width -= buttonWidth + buttonHGap; i--; } first_drop_down_item = i + 1; // First item behind visible items @@ -259,37 +275,7 @@ void LLFavoritesBarCtrl::updateButtons(U32 bar_width) } } - // Adding buttons - for(S32 i = mFirstDropDownItem -1; i >= 0; i--) - { - - LLInventoryItem* item = items.get(i); - - S32 buttonWidth = mFont->getWidth(item->getName()) + buttonHPad * 2; - - LLRect rect; - rect.setOriginAndSize(curr_x, buttonVGap, buttonWidth, getRect().getHeight()-buttonVGap); - - LLButton::Params bparams; - bparams.image_unselected.name(flat_icon); - bparams.image_disabled.name(flat_icon); - bparams.image_selected.name(hover_icon_selected); - bparams.image_hover_selected.name(hover_icon_selected); - bparams.image_disabled_selected.name(hover_icon_selected); - bparams.image_hover_unselected.name(hover_icon); - bparams.follows.flags (FOLLOWS_LEFT | FOLLOWS_BOTTOM); - bparams.rect (rect); - bparams.tab_stop(false); - bparams.font(mFont); - bparams.name(item->getName()); - bparams.tool_tip(item->getName()); - bparams.click_callback.function(boost::bind(&LLFavoritesBarCtrl::onButtonClick, this, item->getUUID())); - bparams.rightclick_callback.function(boost::bind(&LLFavoritesBarCtrl::onButtonRightClick, this, item->getUUID())); - - addChildInBack(LLUICtrlFactory::create<LLButton> (bparams)); - - curr_x += buttonWidth + buttonHGap; - } + createButtons(items, buttonXMLNode, buttonWidth, buttonHGap); } // Chevron button @@ -307,6 +293,11 @@ void LLFavoritesBarCtrl::updateButtons(U32 bar_width) } else { + static LLButton::Params default_button_params(LLUICtrlFactory::getDefaultParams<LLButton>()); + std::string flat_icon = "transparent.j2c"; + std::string hover_icon = default_button_params.image_unselected.name; + std::string hover_icon_selected = default_button_params.image_selected.name; + LLButton::Params bparams; LLRect rect; @@ -341,6 +332,37 @@ void LLFavoritesBarCtrl::updateButtons(U32 bar_width) } } + +void LLFavoritesBarCtrl::createButtons(const LLInventoryModel::item_array_t &items, const LLXMLNodePtr &buttonXMLNode, S32 buttonWidth, S32 buttonHGap) +{ + S32 curr_x = buttonHGap; + // Adding buttons + for(S32 i = mFirstDropDownItem -1; i >= 0; i--) + { + LLInventoryItem* item = items.get(i); + + LLButton* fav_btn = LLUICtrlFactory::defaultBuilder<LLButton>(buttonXMLNode, this, NULL); + if (NULL == fav_btn) + { + llwarns << "Unable to create button for landmark: " << item->getName() << llendl; + continue; + } + + // change only left and save bottom + fav_btn->setOrigin(curr_x, fav_btn->getRect().mBottom); + fav_btn->setFont(mFont); + fav_btn->setName(item->getName()); + fav_btn->setLabel(item->getName()); + fav_btn->setToolTip(item->getName()); + fav_btn->setCommitCallback(boost::bind(&LLFavoritesBarCtrl::onButtonClick, this, item->getUUID())); + fav_btn->setRightClickedCallback(boost::bind(&LLFavoritesBarCtrl::onButtonRightClick, this, item->getUUID(), _1, _2, _3,_4 )); + sendChildToBack(fav_btn); + + curr_x += buttonWidth + buttonHGap; + } +} + + BOOL LLFavoritesBarCtrl::postBuild() { // make the popup menu available @@ -462,10 +484,8 @@ void LLFavoritesBarCtrl::showDropDownMenu() item_params.label(item_name); item_params.on_click.function(boost::bind(&LLFavoritesBarCtrl::onButtonClick, this, item->getUUID())); - item_params.rightclick_callback.function(boost::bind(&LLFavoritesBarCtrl::onButtonRightClick, this, item->getUUID())); - LLMenuItemCallGL *menu_item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params); - + menu_item->setRightClickedCallback(boost::bind(&LLFavoritesBarCtrl::onButtonRightClick, this,item->getUUID(),_1,_2,_3,_4)); // Check whether item name wider than menu if ((S32) menu_item->getNominalWidth() > bar_width) { @@ -514,7 +534,7 @@ void LLFavoritesBarCtrl::onButtonClick(LLUUID item_id) LLInvFVBridgeAction::doAction(item_id,&gInventory); } -void LLFavoritesBarCtrl::onButtonRightClick(LLUUID item_id) +void LLFavoritesBarCtrl::onButtonRightClick( LLUUID item_id,LLView* fav_button,S32 x,S32 y,MASK mask) { mSelectedItemID = item_id; @@ -525,10 +545,7 @@ void LLFavoritesBarCtrl::onButtonRightClick(LLUUID item_id) } menu->updateParent(LLMenuGL::sMenuContainer); - - S32 x,y; - LLUI::getCursorPositionLocal(this, &x, &y); - LLMenuGL::showPopup(this, menu, x, y); + LLMenuGL::showPopup(fav_button, menu, x, y); } void LLFavoritesBarCtrl::doToSelected(const LLSD& userdata) diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h index a559692331..7da33e2f6e 100644 --- a/indra/newview/llfavoritesbar.h +++ b/indra/newview/llfavoritesbar.h @@ -61,10 +61,12 @@ public: protected: void updateButtons(U32 bar_width); + void createButtons(const LLInventoryModel::item_array_t &items, const LLXMLNodePtr &root, S32 buttonWidth, S32 buttonHGap); + LLXMLNodePtr getButtonXMLNode(); BOOL collectFavoriteItems(LLInventoryModel::item_array_t &items); void onButtonClick(LLUUID id); - void onButtonRightClick(LLUUID id); + void onButtonRightClick(LLUUID id,LLView* button,S32 x,S32 y,MASK mask); void doToSelected(const LLSD& userdata); diff --git a/indra/newview/llfloatercamera.cpp b/indra/newview/llfloatercamera.cpp index 8cba42dea5..94ea20893a 100644 --- a/indra/newview/llfloatercamera.cpp +++ b/indra/newview/llfloatercamera.cpp @@ -140,17 +140,17 @@ void LLFloaterCamera::onClickCameraPresets(LLUICtrl* ctrl, const LLSD& param) if ("rear_view" == name) { LLFirstTimeTipsManager::showTipsFor(LLFirstTimeTipsManager::FTT_CAMERA_PRESET_REAR, ctrl); - gAgent.resetView(TRUE, TRUE); + gAgent.switchCameraPreset(CAMERA_PRESET_REAR_VIEW); } - else if ("3/4_view" == name) + else if ("group_view" == name) { LLFirstTimeTipsManager::showTipsFor(LLFirstTimeTipsManager::FTT_CAMERA_PRESET_GROUP); - //*TODO implement 3/4 view + gAgent.switchCameraPreset(CAMERA_PRESET_GROUP_VIEW); } else if ("front_view" == name) { LLFirstTimeTipsManager::showTipsFor(LLFirstTimeTipsManager::FTT_CAMERA_PRESET_FRONT); - //*TODO implement front view + gAgent.switchCameraPreset(CAMERA_PRESET_FRONT_VIEW); } } @@ -165,8 +165,7 @@ void LLFloaterCamera::updatePosition() LLBottomTray* tray = LLBottomTray::getInstance(); if (!tray) return; - LLButton* camera_button = tray->getChild<LLButton>("camera_btn", TRUE, FALSE); - if (!camera_button) return; + LLButton* camera_button = tray->getChild<LLButton>("camera_btn"); //align centers of a button and a floater S32 x = camera_button->calcScreenRect().getCenterX() - getRect().getWidth()/2; @@ -281,14 +280,10 @@ void LLFloaterCamera::onClickBtn(ECameraControlMode mode) void LLFloaterCamera::assignButton2Mode(ECameraControlMode mode, const std::string& button_name) { - LLButton* button = getChild<LLButton>(button_name, TRUE, FALSE); - llassert_always(button); + LLButton* button = getChild<LLButton>(button_name); - if (button) - { - button->setClickedCallback(boost::bind(&LLFloaterCamera::onClickBtn, this, mode)); - mMode2Button[mode] = button; - } + button->setClickedCallback(boost::bind(&LLFloaterCamera::onClickBtn, this, mode)); + mMode2Button[mode] = button; } void LLFloaterCamera::initMode2TipTypeMap() diff --git a/indra/newview/llfloatergroups.cpp b/indra/newview/llfloatergroups.cpp index 7f03d63b3e..f49f854620 100644 --- a/indra/newview/llfloatergroups.cpp +++ b/indra/newview/llfloatergroups.cpp @@ -273,7 +273,7 @@ void LLPanelGroups::onBtnSearch(void* userdata) void LLPanelGroups::create() { - LLGroupActions::create(); + LLGroupActions::createGroup(); } void LLPanelGroups::activate() @@ -293,7 +293,7 @@ void LLPanelGroups::info() LLUUID group_id; if (group_list && (group_id = group_list->getCurrentID()).notNull()) { - LLGroupActions::info(group_id); + LLGroupActions::show(group_id); } } diff --git a/indra/newview/llfloaterinventory.cpp b/indra/newview/llfloaterinventory.cpp index a486ef565a..33a99facad 100644 --- a/indra/newview/llfloaterinventory.cpp +++ b/indra/newview/llfloaterinventory.cpp @@ -64,7 +64,6 @@ #include "llmenugl.h" #include "llpreviewanim.h" #include "llpreviewgesture.h" -#include "llpreviewlandmark.h" #include "llpreviewnotecard.h" #include "llpreviewscript.h" #include "llpreviewsound.h" diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index 63ac44da4f..c5e07c6596 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -51,7 +51,6 @@ #include "llfloateravatarpicker.h" #include "llfloaterauction.h" #include "llfloatergroups.h" -#include "llfloatergroupinfo.h" #include "llavataractions.h" #include "lllineeditor.h" #include "llnamelistctrl.h" @@ -79,6 +78,8 @@ #include "roles_constants.h" #include "lltrans.h" +#include "llgroupactions.h" + static std::string OWNER_ONLINE = "0"; static std::string OWNER_OFFLINE = "1"; static std::string OWNER_GROUP = "2"; @@ -806,7 +807,7 @@ void LLPanelLandGeneral::onClickProfile(void* data) if (parcel->getIsGroupOwned()) { const LLUUID& group_id = parcel->getGroupID(); - LLFloaterGroupInfo::showFromUUID(group_id); + LLGroupActions::show(group_id); } else { @@ -1080,7 +1081,7 @@ void LLPanelLandObjects::onDoubleClickOwner(void *userdata) BOOL is_group = cell->getValue().asString() == OWNER_GROUP; if (is_group) { - LLFloaterGroupInfo::showFromUUID(owner_id); + LLGroupActions::show(owner_id); } else { diff --git a/indra/newview/llfloaterlandholdings.cpp b/indra/newview/llfloaterlandholdings.cpp index de3cd5d4e3..19552ca9c9 100644 --- a/indra/newview/llfloaterlandholdings.cpp +++ b/indra/newview/llfloaterlandholdings.cpp @@ -42,7 +42,6 @@ #include "llagent.h" #include "llfloaterreg.h" -#include "llfloatergroupinfo.h" #include "llfloaterworldmap.h" #include "llproductinforequest.h" #include "llscrolllistctrl.h" @@ -56,6 +55,8 @@ #include "llviewermessage.h" #include "lluictrlfactory.h" +#include "llgroupactions.h" + // protected LLFloaterLandHoldings::LLFloaterLandHoldings(const LLSD& key) : LLFloater(key), @@ -323,7 +324,7 @@ void LLFloaterLandHoldings::onGrantList(void* data) LLUUID group_id = list->getCurrentID(); if (group_id.notNull()) { - LLFloaterGroupInfo::showFromUUID(group_id); + LLGroupActions::show(group_id); } } diff --git a/indra/newview/llfloaternotificationsconsole.cpp b/indra/newview/llfloaternotificationsconsole.cpp index 7042882084..0a3d97245b 100644 --- a/indra/newview/llfloaternotificationsconsole.cpp +++ b/indra/newview/llfloaternotificationsconsole.cpp @@ -212,12 +212,9 @@ void LLFloaterNotificationConsole::addChannel(const std::string& name, bool open void LLFloaterNotificationConsole::removeChannel(const std::string& name) { - LLPanel* panelp = getChild<LLPanel>(name, TRUE, FALSE); - if (panelp) - { - getChildRef<LLLayoutStack>("notification_channels").removePanel(panelp); - delete panelp; - } + LLPanel* panelp = getChild<LLPanel>(name); + getChildRef<LLLayoutStack>("notification_channels").removePanel(panelp); + delete panelp; updateResizeLimits(); } diff --git a/indra/newview/llfloaterproperties.cpp b/indra/newview/llfloaterproperties.cpp index 7312808bd6..cafaa6dd79 100644 --- a/indra/newview/llfloaterproperties.cpp +++ b/indra/newview/llfloaterproperties.cpp @@ -43,7 +43,6 @@ #include "llagent.h" #include "llbutton.h" #include "llcheckboxctrl.h" -#include "llfloatergroupinfo.h" #include "llavataractions.h" #include "llinventorymodel.h" #include "lllineeditor.h" @@ -59,6 +58,7 @@ #include "llviewerregion.h" #include "llviewercontrol.h" #include "llviewerwindow.h" +#include "llgroupactions.h" #include "lluictrlfactory.h" @@ -554,7 +554,7 @@ void LLFloaterProperties::onClickOwner() if(!item) return; if(item->getPermissions().isGroupOwned()) { - LLFloaterGroupInfo::showFromUUID(item->getPermissions().getGroup()); + LLGroupActions::show(item->getPermissions().getGroup()); } else { diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp index 57acbb147d..098a5197df 100644 --- a/indra/newview/llfloaterworldmap.cpp +++ b/indra/newview/llfloaterworldmap.cpp @@ -51,12 +51,13 @@ #include "llfocusmgr.h" #include "lllandmarklist.h" #include "lllineeditor.h" -#include "llpreviewlandmark.h" #include "llregionhandle.h" #include "llscrolllistctrl.h" #include "llslurl.h" +#include "lltabcontainer.h" #include "lltextbox.h" #include "lltracker.h" +#include "llinventorymodel.h" #include "llviewerinventory.h" // LLViewerInventoryItem #include "llviewermenu.h" #include "llviewerregion.h" diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp index 30f4447283..b14f23f9cf 100644 --- a/indra/newview/llgroupactions.cpp +++ b/indra/newview/llgroupactions.cpp @@ -36,12 +36,74 @@ #include "llgroupactions.h" #include "llagent.h" -#include "llfloatergroupinfo.h" #include "llfloaterreg.h" #include "llimview.h" // for gIMMgr #include "llgroupmgr.h" #include "llavataractions.h" #include "llviewercontrol.h" +#include "llsidetray.h" + +#include "llcommandhandler.h" + +// +// Globals +// + +class LLGroupHandler : public LLCommandHandler +{ +public: + // requires trusted browser to trigger + LLGroupHandler() : LLCommandHandler("group", true) { } + bool handle(const LLSD& tokens, const LLSD& query_map, + LLWebBrowserCtrl* web) + { + if (tokens.size() < 1) + { + return false; + } + + if (tokens[0].asString() == "create") + { + LLGroupActions::createGroup(); + return true; + } + + if (tokens.size() < 2) + { + return false; + } + + if (tokens[0].asString() == "list") + { + if (tokens[1].asString() == "show") + { + LLFloaterReg::showInstance("contacts", "groups"); + return true; + } + return false; + } + + LLUUID group_id; + if (!group_id.set(tokens[0], FALSE)) + { + return false; + } + + if (tokens[1].asString() == "about") + { + if (group_id.isNull()) + return true; + + LLGroupActions::show(group_id); + + return true; + } + return false; + } +}; +LLGroupHandler gGroupHandler; + + // LLGroupActions::teleport helper // @@ -168,12 +230,6 @@ void LLGroupActions::search() } // static -void LLGroupActions::create() -{ - LLFloaterGroupInfo::showCreateGroup(NULL); -} - -// static void LLGroupActions::leave(const LLUUID& group_id) { if (group_id.isNull()) @@ -208,14 +264,66 @@ void LLGroupActions::activate(const LLUUID& group_id) gAgent.sendReliableMessage(); } +bool isGroupUIVisible() +{ + LLPanel* panel = LLSideTray::getInstance()->findChild<LLPanel>("panel_group_info_sidetray"); + if(!panel) + return false; + return panel->getVisible(); +} + // static -void LLGroupActions::info(const LLUUID& group_id) +void LLGroupActions::show(const LLUUID& group_id) { if (group_id.isNull()) return; - LLFloaterGroupInfo::showFromUUID(group_id); + LLSD params; + params["group_id"] = group_id; + params["open_tab_name"] = "panel_group_info_sidetray"; + + LLSideTray::getInstance()->showPanel("panel_group_info_sidetray", params); +} + +//static +void LLGroupActions::refresh(const LLUUID& group_id) +{ + if(!isGroupUIVisible()) + return; + + LLSD params; + params["group_id"] = group_id; + params["open_tab_name"] = "panel_group_info_sidetray"; + params["action"] = "refresh"; + + LLSideTray::getInstance()->showPanel("panel_group_info_sidetray", params); +} + +//static +void LLGroupActions::createGroup() +{ + LLSD params; + params["group_id"] = LLUUID::null; + params["open_tab_name"] = "panel_group_info_sidetray"; + params["action"] = "create"; + + LLSideTray::getInstance()->showPanel("panel_group_info_sidetray", params); + } +//static +void LLGroupActions::closeGroup(const LLUUID& group_id) +{ + if(!isGroupUIVisible()) + return; + + LLSD params; + params["group_id"] = group_id; + params["open_tab_name"] = "panel_group_info_sidetray"; + params["action"] = "close"; + + LLSideTray::getInstance()->showPanel("panel_group_info_sidetray", params); +} + // static void LLGroupActions::startChat(const LLUUID& group_id) diff --git a/indra/newview/llgroupactions.h b/indra/newview/llgroupactions.h index b6ddb4511a..70170d3cfe 100644 --- a/indra/newview/llgroupactions.h +++ b/indra/newview/llgroupactions.h @@ -48,11 +48,6 @@ public: static void search(); /** - * Invokes group creation floater. - */ - static void create(); - - /** * Invokes "Leave Group" floater. */ static void leave(const LLUUID& group_id); @@ -63,9 +58,24 @@ public: static void activate(const LLUUID& group_id); /** - * Show group information dialog. + * Show group information panel. + */ + static void show(const LLUUID& group_id); + + /** + * Refresh group information panel. + */ + static void refresh(const LLUUID& group_id); + + /** + * Refresh group information panel. + */ + static void createGroup(); + + /** + * Close group information panel. */ - static void info(const LLUUID& group_id); + static void closeGroup (const LLUUID& group_id); /** * Start group instant messaging session. diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp index a8d97c6afb..0ba1019765 100644 --- a/indra/newview/llgroupmgr.cpp +++ b/indra/newview/llgroupmgr.cpp @@ -51,7 +51,8 @@ #include "lleconomy.h" #include "llviewerwindow.h" #include "llfloaterdirectory.h" -#include "llfloatergroupinfo.h" +#include "llpanelgroup.h" +#include "llgroupactions.h" #include "lluictrlfactory.h" #include <boost/regex.hpp> @@ -1210,7 +1211,7 @@ void LLGroupMgr::processEjectGroupMemberReply(LLMessageSystem* msg, void ** data // If we had a failure, the group panel needs to be updated. if (!success) { - LLFloaterGroupInfo::refreshGroup(group_id); + LLGroupActions::refresh(group_id); } } @@ -1230,7 +1231,7 @@ void LLGroupMgr::processJoinGroupReply(LLMessageSystem* msg, void ** data) LLGroupMgr::getInstance()->clearGroupData(group_id); // refresh the floater for this group, if any. - LLFloaterGroupInfo::refreshGroup(group_id); + LLGroupActions::refresh(group_id); // refresh the group panel of the search window, if necessary. LLFloaterDirectory::refreshGroup(group_id); } @@ -1252,7 +1253,7 @@ void LLGroupMgr::processLeaveGroupReply(LLMessageSystem* msg, void ** data) LLGroupMgr::getInstance()->clearGroupData(group_id); // close the floater for this group, if any. - LLFloaterGroupInfo::closeGroup(group_id); + LLGroupActions::closeGroup(group_id); // refresh the group panel of the search window, if necessary. LLFloaterDirectory::refreshGroup(group_id); } @@ -1288,8 +1289,10 @@ void LLGroupMgr::processCreateGroupReply(LLMessageSystem* msg, void ** data) gAgent.mGroups.push_back(gd); - LLFloaterGroupInfo::closeCreateGroup(); - LLFloaterGroupInfo::showFromUUID(group_id,"roles_tab"); + LLPanelGroup::refreshCreatedGroup(group_id); + //FIXME + //LLFloaterGroupInfo::closeCreateGroup(); + //LLFloaterGroupInfo::showFromUUID(group_id,"roles_tab"); } else { diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp index 879f106b1f..eeb127c878 100644 --- a/indra/newview/llimpanel.cpp +++ b/indra/newview/llimpanel.cpp @@ -51,9 +51,9 @@ #include "llchat.h" #include "llchiclet.h" #include "llconsole.h" +#include "llgroupactions.h" #include "llfloater.h" #include "llfloatercall.h" -#include "llfloatergroupinfo.h" #include "llavataractions.h" #include "llimview.h" #include "llinventory.h" @@ -1581,7 +1581,8 @@ void LLFloaterIMPanel::onClickGroupInfo( void* userdata ) // Bring up the Profile window LLFloaterIMPanel* self = (LLFloaterIMPanel*) userdata; - LLFloaterGroupInfo::showFromUUID(self->mSessionUUID); + LLGroupActions::show(self->mSessionUUID); + } // static @@ -2120,7 +2121,7 @@ BOOL LLIMFloater::postBuild() childSetCommitCallback("chat_editor", onSendMsg, this); - mHistoryEditor = getChild<LLViewerTextEditor>("im_text", true, false); + mHistoryEditor = getChild<LLViewerTextEditor>("im_text"); setTitle(LLIMModel::instance().getName(mSessionID)); setDocked(true); diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index bf09774203..2ef643e3f7 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -67,7 +67,6 @@ #include "llmenugl.h" #include "llpreviewanim.h" #include "llpreviewgesture.h" -#include "llpreviewlandmark.h" #include "llpreviewnotecard.h" #include "llpreviewscript.h" #include "llpreviewsound.h" @@ -2899,10 +2898,6 @@ void LLLandmarkBridge::performAction(LLFolderView* folder, LLInventoryModel* mod key["id"] = item->getUUID(); LLSideTray::getInstance()->showPanel("panel_places", key); - - // Floater preview_landmark disabled, - // its functionality moved to Side Tray Places Panel - //LLFloaterReg::showInstance("preview_landmark", LLSD(item->getUUID()), TAKE_FOCUS_YES); } } else diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp index 7986d7c861..e2dc7d69a1 100644 --- a/indra/newview/lllocationinputctrl.cpp +++ b/indra/newview/lllocationinputctrl.cpp @@ -55,7 +55,7 @@ #include "llviewerinventory.h" #include "llviewerparcelmgr.h" #include "llviewercontrol.h" - +#include "llurllineeditorctrl.h" //============================================================================ /* * "ADD LANDMARK" BUTTON UPDATING LOGIC @@ -163,12 +163,38 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p) mInfoBtn(NULL), mAddLandmarkBtn(NULL) { + // Lets replace default LLLineEditor with LLLocationLineEditor + // to make needed escaping while copying and cutting url + this->removeChild(mTextEntry); + delete mTextEntry; + + // Can't access old mTextEntry fields as they are protected, so lets build new params + // That is C&P from LLComboBox::createLineEditor function + static LLUICachedControl<S32> drop_shadow_button ("DropShadowButton", 0); + S32 arrow_width = mArrowImage ? mArrowImage->getWidth() : 0; + LLRect text_entry_rect(0, getRect().getHeight(), getRect().getWidth(), 0); + text_entry_rect.mRight -= llmax(8,arrow_width) + 2 * drop_shadow_button; + + LLLineEditor::Params params = p.combo_editor; + params.rect(text_entry_rect); + params.default_text(LLStringUtil::null); + params.max_length_bytes(p.max_chars); + params.commit_callback.function(boost::bind(&LLComboBox::onTextCommit, this, _2)); + params.keystroke_callback(boost::bind(&LLComboBox::onTextEntry, this, _1)); + params.focus_lost_callback(NULL); + params.handle_edit_keys_directly(true); + params.commit_on_focus_lost(false); + params.follows.flags(FOLLOWS_ALL); + mTextEntry = LLUICtrlFactory::create<LLURLLineEditor>(params); + this->addChild(mTextEntry); + // LLLineEditor is replaced with LLLocationLineEditor + // "Place information" button. LLButton::Params info_params = p.info_button; mInfoBtn = LLUICtrlFactory::create<LLButton>(info_params); mInfoBtn->setClickedCallback(boost::bind(&LLLocationInputCtrl::onInfoButtonClicked, this)); addChild(mInfoBtn); - + // "Add landmark" button. LLButton::Params al_params = p.add_landmark_button; if (p.add_landmark_image_enabled()) @@ -187,6 +213,7 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p) addChild(mAddLandmarkBtn); setPrearrangeCallback(boost::bind(&LLLocationInputCtrl::onLocationPrearrange, this, _2)); + getTextEntry()->setMouseUpCallback(boost::bind(&LLLocationInputCtrl::onTextEditorMouseUp, this, _2,_3,_4)); updateWidgetlayout(); @@ -234,24 +261,20 @@ BOOL LLLocationInputCtrl::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* // Let the buttons show their tooltips. if (LLUICtrl::handleToolTip(x, y, msg, sticky_rect_screen) && !msg.empty()) { - LLLocationHistory* lh = LLLocationHistory::getInstance(); - const std::string tooltip = lh->getToolTip(msg); + if (mList->getRect().pointInRect(x, y)) { + LLLocationHistory* lh = LLLocationHistory::getInstance(); + const std::string tooltip = lh->getToolTip(msg); - if (!tooltip.empty()) { - msg = tooltip; + if (!tooltip.empty()) { + msg = tooltip; + } } return TRUE; } - // Cursor is above the text entry. msg = LLUI::sShowXUINames ? getShowNamesToolTip() : ""; - if (mTextEntry && sticky_rect_screen) - { - *sticky_rect_screen = mTextEntry->calcScreenRect(); - } - - return TRUE; + return mTextEntry->getRect().pointInRect(x, y); } BOOL LLLocationInputCtrl::handleKeyHere(KEY key, MASK mask) @@ -328,19 +351,19 @@ void LLLocationInputCtrl::handleLoginComplete() void LLLocationInputCtrl::onFocusReceived() { prearrangeList(); - setText(gAgent.getSLURL()); - if (mTextEntry) - mTextEntry->endSelection(); // we don't want handleMouseUp() to "finish" the selection } void LLLocationInputCtrl::onFocusLost() { LLUICtrl::onFocusLost(); refreshLocation(); + if(mTextEntry->hasSelection()){ + mTextEntry->deselect(); + } } void LLLocationInputCtrl::draw(){ - if(!hasFocus()){ + if(!hasFocus() && gSavedSettings.getBOOL("ShowCoordinatesOption")){ refreshLocation(); } LLComboBox::draw(); @@ -378,6 +401,13 @@ void LLLocationInputCtrl::onLocationPrearrange(const LLSD& data) rebuildLocationHistory(filter); mList->mouseOverHighlightNthItem(-1); // Clear highlight on the last selected item. } +void LLLocationInputCtrl::onTextEditorMouseUp(S32 x, S32 y, MASK mask) +{ + if (!mTextEntry->hasSelection()) { + setText(gAgent.getUnescapedSLURL()); + mTextEntry->selectAll(); + } +} void LLLocationInputCtrl::refresh() { diff --git a/indra/newview/lllocationinputctrl.h b/indra/newview/lllocationinputctrl.h index bda67fd313..0196aae4e7 100644 --- a/indra/newview/lllocationinputctrl.h +++ b/indra/newview/lllocationinputctrl.h @@ -103,6 +103,7 @@ private: void onInfoButtonClicked(); void onLocationHistoryLoaded(); void onLocationPrearrange(const LLSD& data); + void onTextEditorMouseUp(S32 x, S32 y, MASK mask); void onLandmarkLoaded(LLLandmark* lm); void onAddLandmarkButtonClicked(); void onAgentParcelChange(); diff --git a/indra/newview/llmoveview.cpp b/indra/newview/llmoveview.cpp index 96c8f3e2e9..fc425d1b33 100644 --- a/indra/newview/llmoveview.cpp +++ b/indra/newview/llmoveview.cpp @@ -373,8 +373,7 @@ void LLFloaterMove::updatePosition() LLBottomTray* tray = LLBottomTray::getInstance(); if (!tray) return; - LLButton* movement_btn = tray->getChild<LLButton>(BOTTOM_TRAY_BUTTON_NAME, TRUE, FALSE); - if (!movement_btn) return; + LLButton* movement_btn = tray->getChild<LLButton>(BOTTOM_TRAY_BUTTON_NAME); //align centers of a button and a floater S32 x = movement_btn->calcScreenRect().getCenterX() - getRect().getWidth()/2; @@ -569,8 +568,7 @@ void LLPanelStandStopFlying::updatePosition() LLBottomTray* tray = LLBottomTray::getInstance(); if (!tray) return; - LLButton* movement_btn = tray->getChild<LLButton>(BOTTOM_TRAY_BUTTON_NAME, TRUE, FALSE); - if (!movement_btn) return; + LLButton* movement_btn = tray->getChild<LLButton>(BOTTOM_TRAY_BUTTON_NAME); //align centers of a button and a floater S32 x = movement_btn->calcScreenRect().getCenterX() - getRect().getWidth()/2; diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp index b980490434..0f719f29e9 100644 --- a/indra/newview/llnavigationbar.cpp +++ b/indra/newview/llnavigationbar.cpp @@ -56,6 +56,7 @@ #include "llworldmap.h" #include "llappviewer.h" #include "llviewercontrol.h" +#include "llfavoritesbar.h" //-- LLTeleportHistoryMenuItem ----------------------------------------------- @@ -200,6 +201,9 @@ LLNavigationBar::LLNavigationBar() // set a listener function for LoginComplete event LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLNavigationBar::handleLoginComplete, this)); + + // Necessary for focus movement among child controls + setFocusRoot(TRUE); } LLNavigationBar::~LLNavigationBar() @@ -246,6 +250,9 @@ BOOL LLNavigationBar::postBuild() return FALSE; } + mDefaultNbRect = getRect(); + mDefaultFpRect = getChild<LLFavoritesBarCtrl>("favorite")->getRect(); + // we'll be notified on teleport history changes LLTeleportHistory::getInstance()->setHistoryChangedCallback( boost::bind(&LLNavigationBar::onTeleportHistoryChanged, this)); @@ -278,6 +285,11 @@ BOOL LLNavigationBar::handleRightMouseUp(S32 x, S32 y, MASK mask) { mLocationContextMenu->buildDrawLabels(); mLocationContextMenu->updateParent(LLMenuGL::sMenuContainer); + LLLineEditor* textEntry =mCmbLocation->getTextEntry(); + if(textEntry && !textEntry->hasSelection() ){ + textEntry->setText(gAgent.getUnescapedSLURL()); + textEntry->selectAll(); + } LLMenuGL::showPopup(this, mLocationContextMenu, x, y); } return TRUE; @@ -605,3 +617,131 @@ void LLNavigationBar::clearHistoryCache() lh->save(); mPurgeTPHistoryItems= true; } + +void LLNavigationBar::showNavigationPanel(BOOL visible) +{ + bool fpVisible = gSavedSettings.getBOOL("ShowNavbarFavoritesPanel"); + + LLFavoritesBarCtrl* fb = getChild<LLFavoritesBarCtrl>("favorite"); + LLPanel* navPanel = getChild<LLPanel>("navigation_panel"); + + LLRect nbRect(getRect()); + LLRect fbRect(fb->getRect()); + + navPanel->setVisible(visible); + + if (visible) + { + if (fpVisible) + { + // Navigation Panel must be shown. Favorites Panel is visible. + + nbRect.setLeftTopAndSize(nbRect.mLeft, nbRect.mTop, nbRect.getWidth(), mDefaultNbRect.getHeight()); + fbRect.setLeftTopAndSize(fbRect.mLeft, mDefaultFpRect.mTop, fbRect.getWidth(), fbRect.getHeight()); + + // this is duplicated in 'else' section because it should be called BEFORE fb->reshape + reshape(nbRect.getWidth(), nbRect.getHeight()); + setRect(nbRect); + + fb->reshape(fbRect.getWidth(), fbRect.getHeight()); + fb->setRect(fbRect); + } + else + { + // Navigation Panel must be shown. Favorites Panel is hidden. + + S32 height = mDefaultNbRect.getHeight() - mDefaultFpRect.getHeight(); + nbRect.setLeftTopAndSize(nbRect.mLeft, nbRect.mTop, nbRect.getWidth(), height); + + reshape(nbRect.getWidth(), nbRect.getHeight()); + setRect(nbRect); + } + } + else + { + if (fpVisible) + { + // Navigation Panel must be hidden. Favorites Panel is visible. + + nbRect.setLeftTopAndSize(nbRect.mLeft, nbRect.mTop, nbRect.getWidth(), fbRect.getHeight()); + fbRect.setLeftTopAndSize(fbRect.mLeft, fbRect.getHeight(), fbRect.getWidth(), fbRect.getHeight()); + + // this is duplicated in 'else' section because it should be called BEFORE fb->reshape + reshape(nbRect.getWidth(), nbRect.getHeight()); + setRect(nbRect); + + fb->reshape(fbRect.getWidth(), fbRect.getHeight()); + fb->setRect(fbRect); + } + else + { + // Navigation Panel must be hidden. Favorites Panel is hidden. + + nbRect.setLeftTopAndSize(nbRect.mLeft, nbRect.mTop, nbRect.getWidth(), 0); + + reshape(nbRect.getWidth(), nbRect.getHeight()); + setRect(nbRect); + } + } +} + +void LLNavigationBar::showFavoritesPanel(BOOL visible) +{ + bool npVisible = gSavedSettings.getBOOL("ShowNavbarNavigationPanel"); + + LLFavoritesBarCtrl* fb = getChild<LLFavoritesBarCtrl>("favorite"); + + LLRect nbRect(getRect()); + LLRect fbRect(fb->getRect()); + + if (visible) + { + if (npVisible) + { + // Favorites Panel must be shown. Navigation Panel is visible. + + S32 fbHeight = fbRect.getHeight(); + S32 newHeight = nbRect.getHeight() + fbHeight; + + nbRect.setLeftTopAndSize(nbRect.mLeft, nbRect.mTop, nbRect.getWidth(), newHeight); + fbRect.setLeftTopAndSize(mDefaultFpRect.mLeft, mDefaultFpRect.mTop, fbRect.getWidth(), fbRect.getHeight()); + } + else + { + // Favorites Panel must be shown. Navigation Panel is hidden. + + S32 fpHeight = mDefaultFpRect.getHeight(); + nbRect.setLeftTopAndSize(nbRect.mLeft, nbRect.mTop, nbRect.getWidth(), fpHeight); + fbRect.setLeftTopAndSize(fbRect.mLeft, fpHeight, fbRect.getWidth(), fpHeight); + } + + reshape(nbRect.getWidth(), nbRect.getHeight()); + setRect(nbRect); + + fb->reshape(fbRect.getWidth(), fbRect.getHeight()); + fb->setRect(fbRect); + } + else + { + if (npVisible) + { + // Favorites Panel must be hidden. Navigation Panel is visible. + + S32 fbHeight = fbRect.getHeight(); + S32 newHeight = nbRect.getHeight() - fbHeight; + + nbRect.setLeftTopAndSize(nbRect.mLeft, nbRect.mTop, nbRect.getWidth(), newHeight); + } + else + { + // Favorites Panel must be hidden. Navigation Panel is hidden. + + nbRect.setLeftTopAndSize(nbRect.mLeft, nbRect.mTop, nbRect.getWidth(), 0); + } + + reshape(nbRect.getWidth(), nbRect.getHeight()); + setRect(nbRect); + } + + fb->setVisible(visible); +} diff --git a/indra/newview/llnavigationbar.h b/indra/newview/llnavigationbar.h index 1c93a05348..c533953a02 100644 --- a/indra/newview/llnavigationbar.h +++ b/indra/newview/llnavigationbar.h @@ -60,6 +60,9 @@ public: void handleLoginComplete(); void clearHistoryCache(); + + void showNavigationPanel(BOOL visible); + void showFavoritesPanel(BOOL visible); private: LLNavigationBar(); @@ -101,6 +104,8 @@ private: LLButton* mBtnHome; LLSearchEditor* mLeSearch; LLLocationInputCtrl* mCmbLocation; + LLRect mDefaultNbRect; + LLRect mDefaultFpRect; boost::signals2::connection mParcelMgrConnection; bool mPurgeTPHistoryItems; bool mUpdateTypedLocationHistory; diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp index 1fa1e2a09d..c89715e815 100644 --- a/indra/newview/llnearbychat.cpp +++ b/indra/newview/llnearbychat.cpp @@ -48,11 +48,20 @@ #include "llnearbychathandler.h" #include "llchannelmanager.h" +//for LLViewerTextEditor support +#include "llagent.h" // gAgent +#include "llfloaterscriptdebug.h" +#include "llviewertexteditor.h" +#include "llstylemap.h" + + static const S32 RESIZE_BAR_THICKNESS = 3; LLNearbyChat::LLNearbyChat(const LLSD& key) : LLFloater(key), - mEChatTearofState(CHAT_PINNED) + mEChatTearofState(CHAT_PINNED), + mChatCaptionPanel(NULL), + mChatHistoryEditor(NULL) { } @@ -94,23 +103,14 @@ BOOL LLNearbyChat::postBuild() gSavedSettings.declareS32("nearbychat_showicons_and_names",2,"NearByChat header settings",true); - /* - LLChatItemsContainerCtrl* panel = getChild<LLChatItemsContainerCtrl>("chat_history",false,false); - if(panel) - { - panel->setHeaderVisibility((EShowItemHeader)gSavedSettings.getS32("nearbychat_showicons_and_names")); - } - */ - + mChatCaptionPanel = getChild<LLPanel>("chat_caption", false); + mChatHistoryEditor = getChild<LLViewerTextEditor>("Chat History Editor"); + reshape(getRect().getWidth(), getRect().getHeight(), FALSE); return LLFloater::postBuild(); } -#include "llagent.h" // gAgent -#include "llfloaterscriptdebug.h" -#include "llviewertexteditor.h" -#include "llstylemap.h" LLColor4 nearbychat_get_text_color(const LLChat& chat) { @@ -215,15 +215,6 @@ void nearbychat_add_timestamped_line(LLViewerTextEditor* edit, LLChat chat, cons void LLNearbyChat::addMessage(const LLChat& chat) { - /* - LLChatItemsContainerCtrl* panel = getChild<LLChatItemsContainerCtrl>("chat_history",false,false); - if(!panel) - return; - panel->addMessage(message); - */ - - //"Chat History Editor" !!!!! - LLColor4 color = nearbychat_get_text_color(chat); @@ -241,13 +232,12 @@ void LLNearbyChat::addMessage(const LLChat& chat) // could flash the chat button in the status bar here. JC - LLViewerTextEditor* history_editor = getChild<LLViewerTextEditor>("Chat History Editor"); - history_editor->setParseHTML(TRUE); - history_editor->setParseHighlights(TRUE); + mChatHistoryEditor->setParseHTML(TRUE); + mChatHistoryEditor->setParseHighlights(TRUE); if (!chat.mMuted) - nearbychat_add_timestamped_line(history_editor, chat, color); + nearbychat_add_timestamped_line(mChatHistoryEditor, chat, color); } void LLNearbyChat::onNearbySpeakers() @@ -270,8 +260,6 @@ void LLNearbyChat::reshape(S32 width, S32 height, BOOL called_from_parent) LLFloater::reshape(width, height, called_from_parent); - LLPanel* caption = getChild<LLPanel>("chat_caption",false,false); - LLRect resize_rect; resize_rect.setLeftTopAndSize( 0, height, width, RESIZE_BAR_THICKNESS); if (mResizeBar[LLResizeBar::TOP]) @@ -301,25 +289,23 @@ void LLNearbyChat::reshape(S32 width, S32 height, BOOL called_from_parent) mResizeBar[LLResizeBar::RIGHT]->setRect(resize_rect); } - + // *NOTE: we must check mChatCaptionPanel and mChatHistoryEditor against NULL because reshape is called from the + // LLView::initFromParams BEFORE postBuild is called and child controls are not exist yet LLRect caption_rect; - if (caption) + if (NULL != mChatCaptionPanel) { - caption_rect = caption->getRect(); + caption_rect = mChatCaptionPanel->getRect(); caption_rect.setLeftTopAndSize( 2, height - RESIZE_BAR_THICKNESS, width - 4, caption_rect.getHeight()); - caption->reshape( width - 4, caption_rect.getHeight(), 1); - caption->setRect(caption_rect); + mChatCaptionPanel->reshape( width - 4, caption_rect.getHeight(), 1); + mChatCaptionPanel->setRect(caption_rect); } - //LLPanel* scroll_panel = getChild<LLPanel>("chat_history",false,false); - LLViewerTextEditor* scroll_panel = getChild<LLViewerTextEditor>("Chat History Editor"); - - if (scroll_panel) + if (NULL != mChatHistoryEditor) { - LLRect scroll_rect = scroll_panel->getRect(); + LLRect scroll_rect = mChatHistoryEditor->getRect(); scroll_rect.setLeftTopAndSize( 2, height - caption_rect.getHeight() - RESIZE_BAR_THICKNESS, width - 4, height - caption_rect.getHeight() - RESIZE_BAR_THICKNESS*2); - scroll_panel->reshape( width - 4, height - caption_rect.getHeight() - RESIZE_BAR_THICKNESS*2, 1); - scroll_panel->setRect(scroll_rect); + mChatHistoryEditor->reshape( width - 4, height - caption_rect.getHeight() - RESIZE_BAR_THICKNESS*2, 1); + mChatHistoryEditor->setRect(scroll_rect); } // @@ -342,57 +328,47 @@ void LLNearbyChat::reshape(S32 width, S32 height, BOOL called_from_parent) BOOL LLNearbyChat::handleMouseDown (S32 x, S32 y, MASK mask) { - LLPanel* caption = getChild<LLPanel>("chat_caption",false,false); - if(caption) + LLUICtrl* nearby_speakers_btn = mChatCaptionPanel->getChild<LLUICtrl>("nearby_speakers_btn"); + LLUICtrl* tearoff_btn = mChatCaptionPanel->getChild<LLUICtrl>("tearoff_btn"); + LLUICtrl* close_btn = mChatCaptionPanel->getChild<LLUICtrl>("close_btn"); + + S32 caption_local_x = x - mChatCaptionPanel->getRect().mLeft; + S32 caption_local_y = y - mChatCaptionPanel->getRect().mBottom; + + S32 local_x = caption_local_x - nearby_speakers_btn->getRect().mLeft; + S32 local_y = caption_local_y - nearby_speakers_btn->getRect().mBottom; + if(nearby_speakers_btn->pointInView(local_x, local_y)) { - LLUICtrl* nearby_speakers_btn = caption->getChild<LLUICtrl>("nearby_speakers_btn"); - LLUICtrl* tearoff_btn = caption->getChild<LLUICtrl>("tearoff_btn"); - LLUICtrl* close_btn = caption->getChild<LLUICtrl>("close_btn"); - - S32 caption_local_x = x - caption->getRect().mLeft; - S32 caption_local_y = y - caption->getRect().mBottom; - - if(nearby_speakers_btn && tearoff_btn) - { - S32 local_x = caption_local_x - nearby_speakers_btn->getRect().mLeft; - S32 local_y = caption_local_y - nearby_speakers_btn->getRect().mBottom; - if(nearby_speakers_btn->pointInView(local_x, local_y)) - { - onNearbySpeakers(); - bringToFront( x, y ); - return true; - } - local_x = caption_local_x - tearoff_btn->getRect().mLeft; - local_y = caption_local_y- tearoff_btn->getRect().mBottom; - if(tearoff_btn->pointInView(local_x, local_y)) - { - onTearOff(); - bringToFront( x, y ); - return true; - } + onNearbySpeakers(); + bringToFront( x, y ); + return true; + } + local_x = caption_local_x - tearoff_btn->getRect().mLeft; + local_y = caption_local_y- tearoff_btn->getRect().mBottom; + if(tearoff_btn->pointInView(local_x, local_y)) + { + onTearOff(); + bringToFront( x, y ); + return true; + } - if(close_btn) - { - local_x = caption_local_x - close_btn->getRect().mLeft; - local_y = caption_local_y - close_btn->getRect().mBottom; - if(close_btn->pointInView(local_x, local_y)) - { - setVisible(false); - bringToFront( x, y ); - return true; - } - } - } + local_x = caption_local_x - close_btn->getRect().mLeft; + local_y = caption_local_y - close_btn->getRect().mBottom; + if(close_btn->pointInView(local_x, local_y)) + { + setVisible(false); + bringToFront( x, y ); + return true; + } - if(mEChatTearofState == CHAT_UNPINNED && caption->pointInView(caption_local_x, caption_local_y) ) - { - //start draggind - gFocusMgr.setMouseCapture(this); - mStart_Y = y; - mStart_X = x; - bringToFront( x, y ); - return true; - } + if(mEChatTearofState == CHAT_UNPINNED && mChatCaptionPanel->pointInView(caption_local_x, caption_local_y) ) + { + //start draggind + gFocusMgr.setMouseCapture(this); + mStart_Y = y; + mStart_X = x; + bringToFront( x, y ); + return true; } return LLFloater::handleMouseDown(x,y,mask); @@ -425,8 +401,7 @@ BOOL LLNearbyChat::handleHover(S32 x, S32 y, MASK mask) void LLNearbyChat::pinn_panel() { mEChatTearofState = CHAT_PINNED; - LLPanel* caption = getChild<LLPanel>("chat_caption",false,false); - LLIconCtrl* tearoff_btn = caption->getChild<LLIconCtrl>("tearoff_btn",false,false); + LLIconCtrl* tearoff_btn = mChatCaptionPanel->getChild<LLIconCtrl>("tearoff_btn",false); tearoff_btn->setValue("inv_item_landmark_visited.tga"); @@ -445,8 +420,7 @@ void LLNearbyChat::pinn_panel() void LLNearbyChat::float_panel() { mEChatTearofState = CHAT_UNPINNED; - LLPanel* caption = getChild<LLPanel>("chat_caption",false,false); - LLIconCtrl* tearoff_btn = caption->getChild<LLIconCtrl>("tearoff_btn",false,false); + LLIconCtrl* tearoff_btn = mChatCaptionPanel->getChild<LLIconCtrl>("tearoff_btn", false); tearoff_btn->setValue("inv_item_landmark.tga"); mResizeBar[LLResizeBar::BOTTOM]->setVisible(true); @@ -456,50 +430,20 @@ void LLNearbyChat::float_panel() translate(4,4); } -void LLNearbyChat::onNearbyChatContextMenuItemClicked(const LLSD& userdata) +void LLNearbyChat::onNearbyChatContextMenuItemClicked(const LLSD& userdata) { - /* - LLChatItemsContainerCtrl* panel = getChild<LLChatItemsContainerCtrl>("chat_history",false,false); - if(!panel) - return; - - std::string str = userdata.asString(); - if(str == "show_buddy_icons") - panel->setHeaderVisibility(CHATITEMHEADER_SHOW_ONLY_ICON); - else if(str == "show_names") - panel->setHeaderVisibility(CHATITEMHEADER_SHOW_ONLY_NAME); - else if(str == "show_icons_and_names") - panel->setHeaderVisibility(CHATITEMHEADER_SHOW_BOTH); - - gSavedSettings.setS32("nearbychat_showicons_and_names", (S32)panel->getHeaderVisibility()); - */ } bool LLNearbyChat::onNearbyChatCheckContextMenuItem(const LLSD& userdata) { std::string str = userdata.asString(); if(str == "nearby_people") onNearbySpeakers(); - /* - LLChatItemsContainerCtrl* panel = getChild<LLChatItemsContainerCtrl>("chat_history",false,false); - if(!panel) - return false; - - if(str == "show_buddy_icons") - return panel->getHeaderVisibility() == CHATITEMHEADER_SHOW_ONLY_ICON; - else if(str == "show_names") - return panel->getHeaderVisibility() == CHATITEMHEADER_SHOW_ONLY_NAME; - else if(str == "show_icons_and_names") - return panel->getHeaderVisibility() == CHATITEMHEADER_SHOW_BOTH; - else if(str == "nearby_people") - onNearbySpeakers(); - */ return false; } BOOL LLNearbyChat::handleRightMouseDown(S32 x, S32 y, MASK mask) { - LLPanel* caption = getChild<LLPanel>("chat_caption",false,false); - if(caption && caption->pointInView(x - caption->getRect().mLeft, y - caption->getRect().mBottom) ) + if(mChatCaptionPanel->pointInView(x - mChatCaptionPanel->getRect().mLeft, y - mChatCaptionPanel->getRect().mBottom) ) { LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h index 670a394c95..efa2e479e6 100644 --- a/indra/newview/llnearbychat.h +++ b/indra/newview/llnearbychat.h @@ -38,6 +38,7 @@ #include "llchat.h" class LLResizeBar; +class LLViewerTextEditor; class LLNearbyChat: public LLFloater { @@ -87,6 +88,8 @@ private: //LLResizeBar* mResizeBar[RESIZE_BAR_COUNT]; LLHandle<LLView> mPopupMenuHandle; + LLPanel* mChatCaptionPanel; + LLViewerTextEditor* mChatHistoryEditor; }; #endif diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp index 83f8d14b5f..50e31e85e4 100644 --- a/indra/newview/llnearbychatbar.cpp +++ b/indra/newview/llnearbychatbar.cpp @@ -179,25 +179,29 @@ LLNearbyChatBar::LLNearbyChatBar() //virtual BOOL LLNearbyChatBar::postBuild() { - mChatBox = getChild<LLLineEditor>("chat_box",TRUE,FALSE); + mChatBox = getChild<LLLineEditor>("chat_box"); - if (mChatBox) - { - mChatBox->setCommitCallback(boost::bind(&LLNearbyChatBar::onChatBoxCommit, this)); - mChatBox->setKeystrokeCallback(&onChatBoxKeystroke, this); - mChatBox->setFocusLostCallback(&onChatBoxFocusLost, this); - - mChatBox->setIgnoreArrowKeys(TRUE); - mChatBox->setCommitOnFocusLost( FALSE ); - mChatBox->setRevertOnEsc( FALSE ); - mChatBox->setIgnoreTab(TRUE); - mChatBox->setPassDelete(TRUE); - mChatBox->setReplaceNewlinesWithSpaces(FALSE); - mChatBox->setMaxTextLength(1023); - mChatBox->setEnableLineHistory(TRUE); - } + mChatBox->setCommitCallback(boost::bind(&LLNearbyChatBar::onChatBoxCommit, this)); + mChatBox->setKeystrokeCallback(&onChatBoxKeystroke, this); + mChatBox->setFocusLostCallback(&onChatBoxFocusLost, this); + + mChatBox->setIgnoreArrowKeys(TRUE); + mChatBox->setCommitOnFocusLost( FALSE ); + mChatBox->setRevertOnEsc( FALSE ); + mChatBox->setIgnoreTab(TRUE); + mChatBox->setPassDelete(TRUE); + mChatBox->setReplaceNewlinesWithSpaces(FALSE); + mChatBox->setMaxTextLength(1023); + mChatBox->setEnableLineHistory(TRUE); + + mTalkBtn = getChild<LLTalkButton>("talk"); - mTalkBtn = getChild<LLTalkButton>("talk",TRUE,FALSE); + // Speak button should be initially disabled because + // it takes some time between logging in to world and connecting to voice channel. + mTalkBtn->setEnabled(FALSE); + + // Registering Chat Bar to receive Voice client status change notifications. + gVoiceClient->addObserver(this); return TRUE; } @@ -208,6 +212,12 @@ LLNearbyChatBar* LLNearbyChatBar::getInstance() return LLBottomTray::getInstance() ? LLBottomTray::getInstance()->getNearbyChatBar() : NULL; } +//static +bool LLNearbyChatBar::instanceExists() +{ + return LLBottomTray::instanceExists() && LLBottomTray::getInstance()->getNearbyChatBar() != NULL; +} + std::string LLNearbyChatBar::getCurrentChat() { return mChatBox ? mChatBox->getText() : LLStringUtil::null; @@ -616,6 +626,27 @@ public: } }; +void LLNearbyChatBar::onChange(EStatusType status, const std::string &channelURI, bool proximal) +{ + // Time it takes to connect to voice channel might be pretty long, + // so don't expect user login or STATUS_VOICE_ENABLED to be followed by STATUS_JOINED. + BOOL enable = FALSE; + + switch (status) + { + // Do not add STATUS_VOICE_ENABLED because voice chat is + // inactive until STATUS_JOINED + case STATUS_JOINED: + enable = TRUE; + break; + default: + enable = FALSE; + break; + } + + mTalkBtn->setEnabled(enable); +} + // Creating the object registers with the dispatcher. LLChatHandler gChatHandler; diff --git a/indra/newview/llnearbychatbar.h b/indra/newview/llnearbychatbar.h index b640aedf7a..4b0c42c3c0 100644 --- a/indra/newview/llnearbychatbar.h +++ b/indra/newview/llnearbychatbar.h @@ -38,6 +38,7 @@ #include "llgesturemgr.h" #include "llchat.h" #include "llchiclet.h" +#include "llvoiceclient.h" class LLGestureComboBox : public LLComboBox @@ -65,6 +66,7 @@ protected: class LLNearbyChatBar : public LLPanel +, public LLVoiceClientStatusObserver { public: // constructor for inline chat-bars (e.g. hosted in chat history window) @@ -75,6 +77,8 @@ public: static LLNearbyChatBar* getInstance(); + static bool instanceExists(); + LLLineEditor* getChatBox() { return mChatBox; } std::string getCurrentChat(); @@ -87,6 +91,11 @@ public: static void sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate); static void sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate); + /** + * Implements LLVoiceClientStatusObserver::onChange() + */ + /*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal); + protected: static BOOL matchChatTypeTrigger(const std::string& in_str, std::string* out_str); static void onChatBoxKeystroke(LLLineEditor* caller, void* userdata); diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp index cb1b65a604..837f924c44 100644 --- a/indra/newview/llnearbychathandler.cpp +++ b/indra/newview/llnearbychathandler.cpp @@ -62,7 +62,7 @@ LLNearbyChatHandler::LLNearbyChatHandler(e_notification_type type, const LLSD& i mChannel = LLChannelManager::getInstance()->createChannel(p); mChannel->setFollows(FOLLOWS_LEFT | FOLLOWS_BOTTOM | FOLLOWS_TOP); mChannel->setOverflowFormatString("You have %d unread nearby chat messages"); - mChannel->setStoreToasts(false); + mChannel->setCanStoreToasts(false); } LLNearbyChatHandler::~LLNearbyChatHandler() { @@ -93,11 +93,11 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg) item->setVisible(true); - - LLToast* toast = mChannel->addToast(id, item); - - toast->setOnMouseEnterCallback(boost::bind(&LLNearbyChatHandler::onToastDestroy, this, toast)); - toast->setAndStartTimer(gSavedSettings.getS32("NotificationToastTime")); + LLToast::Params p; + p.id = id; + p.panel = item; + p.on_mouse_enter = boost::bind(&LLNearbyChatHandler::onToastDestroy, this, _1); + mChannel->addToast(p); } void LLNearbyChatHandler::onToastDestroy(LLToast* toast) diff --git a/indra/newview/llnotificationalerthandler.cpp b/indra/newview/llnotificationalerthandler.cpp index 06826998bf..7003879dbf 100644 --- a/indra/newview/llnotificationalerthandler.cpp +++ b/indra/newview/llnotificationalerthandler.cpp @@ -67,21 +67,20 @@ LLAlertHandler::~LLAlertHandler() //-------------------------------------------------------------------------- void LLAlertHandler::processNotification(const LLSD& notify) { - LLToast* toast = NULL; - LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID()); if (notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "load") { LLToastAlertPanel* alert_dialog = new LLToastAlertPanel(notification, mIsModal); - - toast = mChannel->addToast(notification->getID(), (LLToastPanel*)alert_dialog); - if(!toast) - return; - toast->setHideButtonEnabled(false); - toast->setOnToastDestroyCallback((boost::bind(&LLAlertHandler::onToastDestroy, this, toast))); - toast->setCanFade(false); - toast->setModal(mIsModal); + LLToast::Params p; + p.id = notification->getID(); + p.notification = notification; + p.panel = dynamic_cast<LLToastPanel*>(alert_dialog); + p.enable_hide_btn = false; + p.can_fade = false; + p.is_modal = mIsModal; + p.on_toast_destroy = boost::bind(&LLAlertHandler::onToastDestroy, this, _1); + mChannel->addToast(p); } else if (notify["sigtype"].asString() == "change") { diff --git a/indra/newview/llnotificationgrouphandler.cpp b/indra/newview/llnotificationgrouphandler.cpp index ad09f43c10..9a6a041c35 100644 --- a/indra/newview/llnotificationgrouphandler.cpp +++ b/indra/newview/llnotificationgrouphandler.cpp @@ -37,6 +37,8 @@ #include "llagent.h" #include "llbottomtray.h" #include "llviewercontrol.h" +#include "llfloaterreg.h" +#include "llsyswellwindow.h" using namespace LLNotificationsUI; @@ -65,18 +67,17 @@ LLGroupHandler::~LLGroupHandler() //-------------------------------------------------------------------------- void LLGroupHandler::processNotification(const LLSD& notify) { - LLToast* toast = NULL; - LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID()); if(notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "change") { - LLPanel* notify_box = new LLToastGroupNotifyPanel(notification); - toast = mChannel->addToast(notification->getID(), notify_box); - if(!toast) - return; - toast->setAndStartTimer(gSavedSettings.getS32("NotificationToastTime")); - toast->setOnToastDestroyCallback((boost::bind(&LLGroupHandler::onToastDestroy, this, toast))); - mChiclet->setCounter(mChiclet->getCounter() + 1); + LLPanel* notify_box = new LLToastGroupNotifyPanel(notification); + LLToast::Params p; + p.id = notification->getID(); + p.notification = notification; + p.panel = notify_box; + p.on_toast_destroy = boost::bind(&LLGroupHandler::onToastDestroy, this, _1); + mChannel->addToast(p); + mChiclet->setCounter(mChiclet->getCounter() + 1); } else if (notify["sigtype"].asString() == "delete") { @@ -88,6 +89,14 @@ void LLGroupHandler::processNotification(const LLSD& notify) void LLGroupHandler::onToastDestroy(LLToast* toast) { mChiclet->setCounter(mChiclet->getCounter() - 1); + + LLToastPanel* panel = dynamic_cast<LLToastPanel*>(toast->getPanel()); + LLFloaterReg::getTypedInstance<LLSysWellWindow>("syswell_window")->removeItemByID(panel->getID()); + + // turning hovering off mannualy because onMouseLeave won't happen if a toast was closed using a keyboard + if(toast->hasFocus()) + mChannel->setHovering(false); + toast->close(); } diff --git a/indra/newview/llnotificationhandler.h b/indra/newview/llnotificationhandler.h index 9037fc82ab..2e5fdd9ed5 100644 --- a/indra/newview/llnotificationhandler.h +++ b/indra/newview/llnotificationhandler.h @@ -127,12 +127,14 @@ public: LLInfoHandler(e_notification_type type, const LLSD& id); virtual ~LLInfoHandler(); - + // base interface functions virtual void processNotification(const LLSD& notify); virtual void onToastDestroy(LLToast* toast); virtual void onChicletClick(void); virtual void onChicletClose(void); + // own handlers + void onStoreToast(LLPanel* info_panel, LLUUID id); protected: }; diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index 91156ae542..6c7fb8a0be 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -31,14 +31,13 @@ */ #include "llviewerprecompiledheaders.h" - #include "llpanelavatar.h" #include "llagent.h" +#include "llavataractions.h" #include "llavatarconstants.h" #include "llcallingcard.h" #include "llcombobox.h" -#include "llavataractions.h" #include "llimview.h" #include "lltexteditor.h" #include "lltexturectrl.h" @@ -117,136 +116,240 @@ BOOL LLDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, static LLDefaultChildRegistry::Register<LLDropTarget> r("drop_target"); -////////////////////////////////////////////////////////////////////////// +static LLRegisterPanelClassWrapper<LLPanelAvatarProfile> t_panel_profile("panel_profile"); +static LLRegisterPanelClassWrapper<LLPanelAvatarMeProfile> t_panel_me_profile("panel_me_profile"); +static LLRegisterPanelClassWrapper<LLPanelAvatarNotes> t_panel_notes("panel_notes"); + //----------------------------------------------------------------------------- -// LLPanelProfileTab() +// LLPanelAvatarNotes() //----------------------------------------------------------------------------- -////////////////////////////////////////////////////////////////////////// -LLPanelProfileTab::LLPanelProfileTab(const LLUUID& avatar_id) - : LLPanel() - , mAvatarId(LLUUID::null) - , mProfileType(PT_UNKNOWN) +LLPanelAvatarNotes::LLPanelAvatarNotes() +: LLPanelProfileTab() +{ + +} + +void LLPanelAvatarNotes::updateData() { - setAvatarId(avatar_id); + LLAvatarPropertiesProcessor::getInstance()->sendDataRequest(getAvatarId(),APT_NOTES); } -LLPanelProfileTab::LLPanelProfileTab(const Params& params ) - : LLPanel() - , mAvatarId(LLUUID::null) - , mProfileType(PT_UNKNOWN) +BOOL LLPanelAvatarNotes::postBuild() { + childSetCommitCallback("status_check", boost::bind(&LLPanelAvatarNotes::onCommitRights, this), NULL); + childSetCommitCallback("map_check", boost::bind(&LLPanelAvatarNotes::onCommitRights, this), NULL); + childSetCommitCallback("objects_check", boost::bind(&LLPanelAvatarNotes::onCommitRights, this), NULL); + + childSetCommitCallback("add_friend", boost::bind(&LLPanelAvatarNotes::onAddFriendButtonClick, this),NULL); + childSetCommitCallback("im", boost::bind(&LLPanelAvatarNotes::onIMButtonClick, this), NULL); + childSetCommitCallback("call", boost::bind(&LLPanelAvatarNotes::onCallButtonClick, this), NULL); + childSetCommitCallback("teleport", boost::bind(&LLPanelAvatarNotes::onTeleportButtonClick, this), NULL); + childSetCommitCallback("share", boost::bind(&LLPanelAvatarNotes::onShareButtonClick, this), NULL); + LLTextEditor* te = getChild<LLTextEditor>("notes_edit"); + te->setCommitCallback(boost::bind(&LLPanelAvatarNotes::onCommitNotes,this)); + te->setCommitOnFocusLost(TRUE); + + resetControls(); + resetData(); + + return TRUE; } -LLPanelProfileTab::~LLPanelProfileTab() +void LLPanelAvatarNotes::onOpen(const LLSD& key) +{ + LLPanelProfileTab::onOpen(key); + + fillRightsData(); + + //Disable "Add Friend" button for friends. + childSetEnabled("add_friend", !LLAvatarActions::isFriend(getAvatarId())); +} + +void LLPanelAvatarNotes::fillRightsData() { - if(mAvatarId.notNull()) + const LLRelationship* relation = LLAvatarTracker::instance().getBuddyInfo(getAvatarId()); + // If true - we are viewing friend's profile, enable check boxes and set values. + if(relation) { - LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this); + S32 rights = relation->getRightsGrantedTo(); + + childSetValue("status_check",LLRelationship::GRANT_ONLINE_STATUS & rights ? TRUE : FALSE); + childSetValue("map_check",LLRelationship::GRANT_MAP_LOCATION & rights ? TRUE : FALSE); + childSetValue("objects_check",LLRelationship::GRANT_MODIFY_OBJECTS & rights ? TRUE : FALSE); + + childSetEnabled("status_check",TRUE); + childSetEnabled("map_check",TRUE); + childSetEnabled("objects_check",TRUE); } } -void LLPanelProfileTab::setAvatarId(const LLUUID& avatar_id) +void LLPanelAvatarNotes::onCommitNotes() +{ + std::string notes = childGetValue("notes_edit").asString(); + LLAvatarPropertiesProcessor::getInstance()-> sendNotes(getAvatarId(),notes); +} + +void LLPanelAvatarNotes::onCommitRights() +{ + S32 rights = 0; + + if(childGetValue("status_check").asBoolean()) + rights |= LLRelationship::GRANT_ONLINE_STATUS; + if(childGetValue("map_check").asBoolean()) + rights |= LLRelationship::GRANT_MAP_LOCATION; + if(childGetValue("objects_check").asBoolean()) + rights |= LLRelationship::GRANT_MODIFY_OBJECTS; + + LLAvatarPropertiesProcessor::getInstance()->sendFriendRights(getAvatarId(),rights); +} + +void LLPanelAvatarNotes::processProperties(void* data, EAvatarProcessorType type) { - if(avatar_id.notNull()) + if(APT_NOTES == type) { - if(mAvatarId.notNull()) + LLAvatarNotes* avatar_notes = static_cast<LLAvatarNotes*>(data); + if(avatar_notes && getAvatarId() == avatar_notes->target_id) { - LLAvatarPropertiesProcessor::getInstance()->removeObserver(mAvatarId,this); + childSetValue("notes_edit",avatar_notes->notes); + childSetEnabled("notes edit", true); + + LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this); } - mAvatarId = avatar_id; - LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(),this); - setProfileType(); } } -void LLPanelProfileTab::setProfileType() +void LLPanelAvatarNotes::resetData() { - mProfileType = (gAgentID == mAvatarId) ? PT_OWN : PT_OTHER; + childSetValue("notes_edit",LLStringUtil::null); + // Default value is TRUE + childSetValue("status_check", TRUE); } -void LLPanelProfileTab::onOpen(const LLSD& key) +void LLPanelAvatarNotes::resetControls() +{ + //Disable "Add Friend" button for friends. + childSetEnabled("add_friend", TRUE); + + childSetEnabled("status_check",FALSE); + childSetEnabled("map_check",FALSE); + childSetEnabled("objects_check",FALSE); +} + +void LLPanelAvatarNotes::onAddFriendButtonClick() { - onActivate(key); + LLAvatarActions::requestFriendshipDialog(getAvatarId()); } -void LLPanelProfileTab::onActivate(const LLUUID& id) +void LLPanelAvatarNotes::onIMButtonClick() { - setAvatarId(id); - scrollToTop(); - updateData(); + LLAvatarActions::startIM(getAvatarId()); } -void LLPanelProfileTab::onAddFriend() +void LLPanelAvatarNotes::onTeleportButtonClick() { - if (getAvatarId().notNull()) + LLAvatarActions::offerTeleport(getAvatarId()); +} + +void LLPanelAvatarNotes::onCallButtonClick() +{ + //*TODO not implemented. +} + +void LLPanelAvatarNotes::onShareButtonClick() +{ + //*TODO not implemented. +} + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +LLPanelProfileTab::LLPanelProfileTab() +: LLPanel() +, mAvatarId(LLUUID::null) +{ +} + +LLPanelProfileTab::~LLPanelProfileTab() +{ + if(getAvatarId().notNull()) { - std::string name; - gCacheName->getFullName(getAvatarId(),name); - LLAvatarActions::requestFriendshipDialog(getAvatarId(), name); + LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this); } } -void LLPanelProfileTab::onIM() +void LLPanelProfileTab::setAvatarId(const LLUUID& id) { - if (getAvatarId().notNull()) + if(id.notNull()) { - std::string name; - gCacheName->getFullName(getAvatarId(), name); - gIMMgr->addSession(name, IM_NOTHING_SPECIAL, getAvatarId()); + if(getAvatarId().notNull()) + { + LLAvatarPropertiesProcessor::getInstance()->removeObserver(mAvatarId,this); + } + mAvatarId = id; + LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(),this); } } -void LLPanelProfileTab::onTeleport() +void LLPanelProfileTab::onOpen(const LLSD& key) { - if(getAvatarId().notNull()) + // Don't reset panel if we are opening it for same avatar. + if(getAvatarId() != key.asUUID()) { - LLAvatarActions::offerTeleport(getAvatarId()); + resetControls(); + resetData(); + + scrollToTop(); } + + // Update data even if we are viewing same avatar profile as some data might been changed. + setAvatarId(key.asUUID()); + updateData(); } void LLPanelProfileTab::scrollToTop() { - LLScrollContainer* scrollContainer = getChild<LLScrollContainer>("profile_scroll", FALSE, FALSE); - if (NULL != scrollContainer) - { - scrollContainer->goToTop(); - } + LLScrollContainer* scrollContainer = getChild<LLScrollContainer>("profile_scroll"); + scrollContainer->goToTop(); } ////////////////////////////////////////////////////////////////////////// -//----------------------------------------------------------------------------- -// LLPanelAvatarProfile() -//----------------------------------------------------------------------------- ////////////////////////////////////////////////////////////////////////// -LLPanelAvatarProfile::LLPanelAvatarProfile(const LLUUID& avatar_id /* = LLUUID::null */) - : LLPanelProfileTab(avatar_id), mUpdated(false), mEditMode(false), mStatusCombobox(NULL), mStatusMessage(NULL) -{ - updateData(); -} +////////////////////////////////////////////////////////////////////////// -LLPanelAvatarProfile::LLPanelAvatarProfile(const Params& params ) - : LLPanelProfileTab(params), mUpdated(false), mEditMode(false), mStatusCombobox(NULL), mStatusMessage(NULL) +LLPanelAvatarProfile::LLPanelAvatarProfile() +: LLPanelProfileTab() { } -LLPanelAvatarProfile::~LLPanelAvatarProfile() +BOOL LLPanelAvatarProfile::postBuild() { - if(getAvatarId().notNull()) - { - LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this); - } + childSetActionTextbox("homepage_edit", boost::bind(&LLPanelAvatarProfile::onHomepageTextboxClicked, this)); + childSetCommitCallback("add_friend",(boost::bind(&LLPanelAvatarProfile::onAddFriendButtonClick,this)),NULL); + childSetCommitCallback("im",(boost::bind(&LLPanelAvatarProfile::onIMButtonClick,this)),NULL); + childSetCommitCallback("call",(boost::bind(&LLPanelAvatarProfile::onCallButtonClick,this)),NULL); + childSetCommitCallback("teleport",(boost::bind(&LLPanelAvatarProfile::onTeleportButtonClick,this)),NULL); + childSetCommitCallback("share",(boost::bind(&LLPanelAvatarProfile::onShareButtonClick,this)),NULL); + + LLTextureCtrl* pic = getChild<LLTextureCtrl>("2nd_life_pic"); + pic->setFallbackImageName("default_land_picture.j2c"); + + pic = getChild<LLTextureCtrl>("real_world_pic"); + pic->setFallbackImageName("default_land_picture.j2c"); + + resetControls(); + resetData(); + + return TRUE; } -void* LLPanelAvatarProfile::create(void* data /* = NULL */) +void LLPanelAvatarProfile::onOpen(const LLSD& key) { - LLSD* id = NULL; - if(data) - { - id = static_cast<LLSD*>(data); - return new LLPanelAvatarProfile(LLUUID(id->asUUID())); - } - return new LLPanelAvatarProfile(); + LLPanelProfileTab::onOpen(key); + + //Disable "Add Friend" button for friends. + childSetEnabled("add_friend", !LLAvatarActions::isFriend(getAvatarId())); } void LLPanelAvatarProfile::updateData() @@ -258,6 +361,37 @@ void LLPanelAvatarProfile::updateData() } } +void LLPanelAvatarProfile::resetControls() +{ + childSetVisible("status_panel", true); + childSetVisible("profile_buttons_panel", true); + childSetVisible("title_groups_text", true); + childSetVisible("sl_groups", true); + childSetEnabled("add_friend", true); + + childSetVisible("user_name", false); + childSetVisible("status_me_panel", false); + childSetVisible("profile_me_buttons_panel", false); + childSetVisible("account_actions_panel", false); + childSetVisible("partner_edit_link", false); +} + +void LLPanelAvatarProfile::resetData() +{ + childSetValue("2nd_life_pic",LLUUID::null); + childSetValue("real_world_pic",LLUUID::null); + childSetValue("online_status",LLStringUtil::null); + childSetValue("status_message",LLStringUtil::null); + childSetValue("sl_description_edit",LLStringUtil::null); + childSetValue("fl_description_edit",LLStringUtil::null); + childSetValue("sl_groups",LLStringUtil::null); + childSetValue("homepage_edit",LLStringUtil::null); + childSetValue("register_date",LLStringUtil::null); + childSetValue("acc_status_text",LLStringUtil::null); + childSetTextArg("partner_text", "[FIRST]", LLStringUtil::null); + childSetTextArg("partner_text", "[LAST]", LLStringUtil::null); +} + void LLPanelAvatarProfile::processProperties(void* data, EAvatarProcessorType type) { if(APT_PROPERTIES == type) @@ -265,120 +399,94 @@ void LLPanelAvatarProfile::processProperties(void* data, EAvatarProcessorType ty const LLAvatarData* avatar_data = static_cast<const LLAvatarData*>(data); if(avatar_data && getAvatarId() == avatar_data->avatar_id) { - childSetValue("register_date", avatar_data->born_on); - childSetValue("sl_description_edit", avatar_data->about_text); - childSetValue("fl_description_edit",avatar_data->fl_about_text); - childSetValue("2nd_life_pic", avatar_data->image_id); - childSetValue("real_world_pic", avatar_data->fl_image_id); - childSetValue("homepage_edit", avatar_data->profile_url); - - if (!isEditMode()) - { - setCaptionText(avatar_data); - if (avatar_data->partner_id.notNull()) - { - std::string first, last; - BOOL found = gCacheName->getName(avatar_data->partner_id, first, last); - if (found) - { - childSetTextArg("partner_text", "[FIRST]", first); - childSetTextArg("partner_text", "[LAST]", last); - } - } - else - { - childSetTextArg("partner_text", "[FIRST]", getString("no_partner_text")); - } - } - else - { - childSetValue("show_in_search_checkbox", (BOOL)(avatar_data->flags & AVATAR_ALLOW_PUBLISH)); - } - - - bool online = avatar_data->flags & AVATAR_ONLINE; - if(LLAvatarActions::isFriend(avatar_data->avatar_id)) - { - // Online status NO could be because they are hidden - // If they are a friend, we may know the truth! - online = LLAvatarTracker::instance().isBuddyOnline(avatar_data->avatar_id); - } - childSetValue("online_status", online ? - "Online" : "Offline"); - childSetColor("online_status", online ? - LLColor4::green : LLColor4::red); - - LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this); - } - if (isOwnProfile() && NULL != mStatusCombobox) - { - std::string status; - if (gAgent.getAFK()) - { - status = "away"; - } - else if (gAgent.getBusy()) - { - status = "busy"; - } - else - { - status = "online"; - } - mStatusCombobox->setValue(status); - } - if (isOwnProfile()) - { - std::string full_name; - gCacheName->getFullName(mAvatarId, full_name); - childSetValue("user_name", full_name); + processProfileProperties(avatar_data); } } else if(APT_GROUPS == type) { LLAvatarGroups* avatar_groups = static_cast<LLAvatarGroups*>(data); - if(avatar_groups) + if(avatar_groups && getAvatarId() == avatar_groups->avatar_id) { - std::string groups; - if (!avatar_groups->group_list.empty()) { - LLAvatarGroups::group_list_t::const_iterator it = avatar_groups->group_list.begin(); - LLAvatarGroups::LLGroupData group_data = *it; - groups+= group_data.group_name; - while (++it != avatar_groups->group_list.end()) - { - group_data = *it; - groups += ", "; - groups += group_data.group_name; - - } - } - childSetValue("sl_groups",groups); + processGroupProperties(avatar_groups); } } } -void LLPanelAvatarProfile::clear() +void LLPanelAvatarProfile::processProfileProperties(const LLAvatarData* avatar_data) { - clearControls(); + fillCommonData(avatar_data); + + fillPartnerData(avatar_data); + + fillOnlineStatus(avatar_data); + + fillAccountStatus(avatar_data); } -void LLPanelAvatarProfile::clearControls() +void LLPanelAvatarProfile::processGroupProperties(const LLAvatarGroups* avatar_groups) { - childSetValue("2nd_life_pic",LLUUID::null); - childSetValue("real_world_pic",LLUUID::null); - childSetValue("online_status",LLStringUtil::null); - childSetValue("status_message",LLStringUtil::null); - childSetValue("sl_description_edit",LLStringUtil::null); - childSetValue("fl_description_edit",LLStringUtil::null); - childSetValue("sl_groups",LLStringUtil::null); - childSetValue("homepage_edit",LLStringUtil::null); - childSetValue("register_date",LLStringUtil::null); - childSetValue("acc_status_text",LLStringUtil::null); - childSetTextArg("partner_text", "[FIRST]", LLStringUtil::null); - childSetTextArg("partner_text", "[LAST]", LLStringUtil::null); + std::string groups; + LLAvatarGroups::group_list_t::const_iterator it = avatar_groups->group_list.begin(); + const LLAvatarGroups::group_list_t::const_iterator it_end = avatar_groups->group_list.end(); + + if(it_end != it) + { + groups = (*it).group_name; + ++it; + } + for(; it_end != it; ++it) + { + LLAvatarGroups::LLGroupData group_data = *it; + groups += ", "; + groups += group_data.group_name; + } + childSetValue("sl_groups",groups); +} + +void LLPanelAvatarProfile::fillCommonData(const LLAvatarData* avatar_data) +{ + childSetValue("register_date", avatar_data->born_on); + childSetValue("sl_description_edit", avatar_data->about_text); + childSetValue("fl_description_edit",avatar_data->fl_about_text); + childSetValue("2nd_life_pic", avatar_data->image_id); + childSetValue("real_world_pic", avatar_data->fl_image_id); + childSetValue("homepage_edit", avatar_data->profile_url); +} + +void LLPanelAvatarProfile::fillPartnerData(const LLAvatarData* avatar_data) +{ + if (avatar_data->partner_id.notNull()) + { + std::string first, last; + BOOL found = gCacheName->getName(avatar_data->partner_id, first, last); + if (found) + { + childSetTextArg("partner_text", "[FIRST]", first); + childSetTextArg("partner_text", "[LAST]", last); + } + } + else + { + childSetTextArg("partner_text", "[FIRST]", getString("no_partner_text")); + } +} + +void LLPanelAvatarProfile::fillOnlineStatus(const LLAvatarData* avatar_data) +{ + bool online = avatar_data->flags & AVATAR_ONLINE; + if(LLAvatarActions::isFriend(avatar_data->avatar_id)) + { + // Online status NO could be because they are hidden + // If they are a friend, we may know the truth! + online = LLAvatarTracker::instance().isBuddyOnline(avatar_data->avatar_id); + } + childSetValue("online_status", online ? + "Online" : "Offline"); + childSetColor("online_status", online ? + LLColor4::green : LLColor4::red); } -void LLPanelAvatarProfile::setCaptionText(const LLAvatarData* avatar_data) +void LLPanelAvatarProfile::fillAccountStatus(const LLAvatarData* avatar_data) { std::string caption_text = avatar_data->caption_text; if(caption_text.empty()) @@ -432,130 +540,126 @@ void LLPanelAvatarProfile::setCaptionText(const LLAvatarData* avatar_data) childSetValue("acc_status_text", caption_text); } +void LLPanelAvatarProfile::onUrlTextboxClicked(std::string url) +{ + LLWeb::loadURL(url); +} + +void LLPanelAvatarProfile::onHomepageTextboxClicked() +{ + std::string url = childGetValue("homepage_edit").asString(); + if(!url.empty()) + { + onUrlTextboxClicked(url); + } +} + void LLPanelAvatarProfile::onAddFriendButtonClick() { - onAddFriend(); + LLAvatarActions::requestFriendshipDialog(getAvatarId()); } void LLPanelAvatarProfile::onIMButtonClick() { - onIM(); + LLAvatarActions::startIM(getAvatarId()); } void LLPanelAvatarProfile::onTeleportButtonClick() { - onTeleport(); + LLAvatarActions::offerTeleport(getAvatarId()); } void LLPanelAvatarProfile::onCallButtonClick() { - + //*TODO not implemented } void LLPanelAvatarProfile::onShareButtonClick() { - + //*TODO not implemented } -/*virtual*/ BOOL LLPanelAvatarProfile::postBuild(void) +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +LLPanelAvatarMeProfile::LLPanelAvatarMeProfile() +: LLPanelAvatarProfile() { - mStatusCombobox = getChild<LLComboBox>("status_combo", TRUE, FALSE); - if (NULL != mStatusCombobox) - { - mStatusCombobox->setCommitCallback(boost::bind(&LLPanelAvatarProfile::onStatusChanged, this)); - } - mStatusMessage = getChild<LLLineEditor>("status_me_message_edit", TRUE, FALSE); - if (NULL != mStatusMessage) - { - mStatusMessage->setCommitCallback(boost::bind(&LLPanelAvatarProfile::onStatusMessageChanged, this)); - } +} - if (!isEditMode()) - { - childSetActionTextbox("homepage_edit", boost::bind(&LLPanelAvatarProfile::onHomepageTextboxClicked, this)); - childSetActionTextbox("payment_update_link", boost::bind(&LLPanelAvatarProfile::onUpdateAccountTextboxClicked, this)); - childSetActionTextbox("my_account_link", boost::bind(&LLPanelAvatarProfile::onMyAccountTextboxClicked, this)); - childSetActionTextbox("partner_edit_link", boost::bind(&LLPanelAvatarProfile::onPartnerEditTextboxClicked, this)); - } +BOOL LLPanelAvatarMeProfile::postBuild() +{ + LLPanelAvatarProfile::postBuild(); - childSetCommitCallback("add_friend",(boost::bind(&LLPanelAvatarProfile::onAddFriendButtonClick,this)),NULL); - childSetCommitCallback("im",(boost::bind(&LLPanelAvatarProfile::onIMButtonClick,this)),NULL); - childSetCommitCallback("call",(boost::bind(&LLPanelAvatarProfile::onCallButtonClick,this)),NULL); - childSetCommitCallback("teleport",(boost::bind(&LLPanelAvatarProfile::onTeleportButtonClick,this)),NULL); - childSetCommitCallback("share",(boost::bind(&LLPanelAvatarProfile::onShareButtonClick,this)),NULL); + mStatusCombobox = getChild<LLComboBox>("status_combo"); - LLTextureCtrl* pic = getChild<LLTextureCtrl>("2nd_life_pic",TRUE,FALSE); - if(pic) - { - pic->setFallbackImageName("default_land_picture.j2c"); - } - pic = getChild<LLTextureCtrl>("real_world_pic",TRUE,FALSE); - if(pic) - { - pic->setFallbackImageName("default_land_picture.j2c"); - } + childSetCommitCallback("status_combo", boost::bind(&LLPanelAvatarMeProfile::onStatusChanged, this), NULL); + childSetCommitCallback("status_me_message_text", boost::bind(&LLPanelAvatarMeProfile::onStatusMessageChanged, this), NULL); + childSetActionTextbox("payment_update_link", boost::bind(&LLPanelAvatarMeProfile::onUpdateAccountTextboxClicked, this)); + childSetActionTextbox("my_account_link", boost::bind(&LLPanelAvatarMeProfile::onMyAccountTextboxClicked, this)); + childSetActionTextbox("partner_edit_link", boost::bind(&LLPanelAvatarMeProfile::onPartnerEditTextboxClicked, this)); - clearControls(); - updateChildrenList(); + resetControls(); + resetData(); return TRUE; } -void LLPanelAvatarProfile::onOpen(const LLSD& key) +void LLPanelAvatarMeProfile::onOpen(const LLSD& key) { - onActivate(key); - updateChildrenList(); + LLPanelProfileTab::onOpen(key); + + std::string full_name; + gCacheName->getFullName(getAvatarId(), full_name); + childSetValue("user_name", full_name); } +void LLPanelAvatarMeProfile::processProfileProperties(const LLAvatarData* avatar_data) +{ + fillCommonData(avatar_data); + + fillPartnerData(avatar_data); -void LLPanelAvatarProfile::updateChildrenList() + fillStatusData(avatar_data); + + fillAccountStatus(avatar_data); +} + +void LLPanelAvatarMeProfile::fillStatusData(const LLAvatarData* avatar_data) { - switch (mProfileType) + std::string status; + if (gAgent.getAFK()) { - case PT_OWN: - if (mUpdated || isEditMode()) - { - return; - } - childSetVisible("user_name", true); - childSetVisible("status_panel", false); - childSetVisible("profile_buttons_panel", false); - childSetVisible("title_groups_text", false); - childSetVisible("sl_groups", false); - mUpdated = true; - childSetVisible("status_me_panel", true); - childSetVisible("profile_me_buttons_panel", true); - - break; - case PT_OTHER: - childSetVisible("user_name", false); - childSetVisible("status_me_panel", false); - childSetVisible("profile_me_buttons_panel", false); - - childSetVisible("status_panel", true); - childSetVisible("profile_buttons_panel", true); - childSetVisible("title_groups_text", true); - childSetVisible("sl_groups", true); - - // account actions - childSetVisible("account_actions_panel", false); - childSetVisible("partner_edit_link", false); - - //hide for friends - childSetEnabled("add_friend", !LLAvatarActions::isFriend(getAvatarId())); - - //need to update profile view on every activate - mUpdated = false; - break; - case PT_UNKNOWN: break;//do nothing - default: - llassert(false); + status = "away"; + } + else if (gAgent.getBusy()) + { + status = "busy"; + } + else + { + status = "online"; } + + mStatusCombobox->setValue(status); +} + +void LLPanelAvatarMeProfile::resetControls() +{ + childSetVisible("user_name", true); + childSetVisible("status_panel", false); + childSetVisible("profile_buttons_panel", false); + childSetVisible("title_groups_text", false); + childSetVisible("sl_groups", false); + childSetVisible("status_me_panel", true); + childSetVisible("profile_me_buttons_panel", true); } -void LLPanelAvatarProfile::onStatusChanged() + +void LLPanelAvatarMeProfile::onStatusChanged() { LLSD::String status = mStatusCombobox->getValue().asString(); - + if ("online" == status) { gAgent.clearAFK(); @@ -572,169 +676,24 @@ void LLPanelAvatarProfile::onStatusChanged() gAgent.setBusy(); LLNotifications::instance().add("BusyModeSet"); } - else - { - } - } -void LLPanelAvatarProfile::onStatusMessageChanged() +void LLPanelAvatarMeProfile::onStatusMessageChanged() { updateData(); } -//static -void LLPanelAvatarProfile::onUrlTextboxClicked(std::string url) -{ - LLWeb::loadURL(url); -} - -void LLPanelAvatarProfile::onHomepageTextboxClicked() -{ - onUrlTextboxClicked(childGetValue("homepage_edit").asString()); -} - -void LLPanelAvatarProfile::onUpdateAccountTextboxClicked() +void LLPanelAvatarMeProfile::onUpdateAccountTextboxClicked() { onUrlTextboxClicked(getString("payment_update_link_url")); } -void LLPanelAvatarProfile::onMyAccountTextboxClicked() +void LLPanelAvatarMeProfile::onMyAccountTextboxClicked() { onUrlTextboxClicked(getString("my_account_link_url")); } -void LLPanelAvatarProfile::onPartnerEditTextboxClicked() +void LLPanelAvatarMeProfile::onPartnerEditTextboxClicked() { onUrlTextboxClicked(getString("partner_edit_link_url")); } - -//----------------------------------------------------------------------------- -// LLPanelAvatarNotes() -//----------------------------------------------------------------------------- -LLPanelAvatarNotes::LLPanelAvatarNotes(const LLUUID& id /* = LLUUID::null */) -:LLPanelProfileTab(id) -{ - updateData(); -} - -LLPanelAvatarNotes::LLPanelAvatarNotes(const Params& params) -: LLPanelProfileTab(params) -{ - -} - -LLPanelAvatarNotes::~LLPanelAvatarNotes() -{ - if(getAvatarId().notNull()) - { - LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this); - } -} - -void* LLPanelAvatarNotes::create(void* data) -{ - if(data) - { - LLSD* id = static_cast<LLSD*>(data); - return new LLPanelAvatarNotes(LLUUID(id->asUUID())); - } - return new LLPanelAvatarNotes(); -} - -void LLPanelAvatarNotes::updateData() -{ - LLAvatarPropertiesProcessor::getInstance()->sendDataRequest(getAvatarId(),APT_NOTES); - - const LLRelationship* relation = LLAvatarTracker::instance().getBuddyInfo(getAvatarId()); - if(relation) - { - childSetEnabled("status_check",TRUE); - childSetEnabled("map_check",TRUE); - childSetEnabled("objects_check",TRUE); - - S32 rights = relation->getRightsGrantedTo(); - - childSetValue("status_check",LLRelationship::GRANT_ONLINE_STATUS & rights ? TRUE : FALSE); - childSetValue("map_check",LLRelationship::GRANT_MAP_LOCATION & rights ? TRUE : FALSE); - childSetValue("objects_check",LLRelationship::GRANT_MODIFY_OBJECTS & rights ? TRUE : FALSE); - } -} - -BOOL LLPanelAvatarNotes::postBuild() -{ - childSetCommitCallback("status_check",boost::bind(&LLPanelAvatarNotes::onCommitRights,this),NULL); - childSetCommitCallback("map_check",boost::bind(&LLPanelAvatarNotes::onCommitRights,this),NULL); - childSetCommitCallback("objects_check",boost::bind(&LLPanelAvatarNotes::onCommitRights,this),NULL); - - childSetCommitCallback("add_friend",(boost::bind(&LLPanelAvatarProfile::onAddFriend,this)),NULL); - childSetCommitCallback("im",(boost::bind(&LLPanelAvatarProfile::onIM,this)),NULL); -// childSetCommitCallback("call",(boost::bind(&LLPanelAvatarProfile::onCallButtonClick,this))); - childSetCommitCallback("teleport",(boost::bind(&LLPanelAvatarProfile::onTeleport,this)),NULL); -// childSetCommitCallback("share",(boost::bind(&LLPanelAvatarProfile::onShareButtonClick,this))); - - LLTextEditor* te = getChild<LLTextEditor>("notes_edit",TRUE,FALSE); - if(te) - { - te->setCommitCallback(boost::bind(&LLPanelAvatarNotes::onCommitNotes,this)); - te->setCommitOnFocusLost(TRUE); - } - - return TRUE; -} - -void LLPanelAvatarNotes::onCommitNotes() -{ - std::string notes = childGetValue("notes_edit").asString(); - LLAvatarPropertiesProcessor::getInstance()-> sendNotes(getAvatarId(),notes); -} - -void LLPanelAvatarNotes::onCommitRights() -{ - S32 rights = 0; - - if(childGetValue("status_check").asBoolean()) - rights |= LLRelationship::GRANT_ONLINE_STATUS; - if(childGetValue("map_check").asBoolean()) - rights |= LLRelationship::GRANT_MAP_LOCATION; - if(childGetValue("objects_check").asBoolean()) - rights |= LLRelationship::GRANT_MODIFY_OBJECTS; - - LLAvatarPropertiesProcessor::getInstance()->sendFriendRights(getAvatarId(),rights); -} - -void LLPanelAvatarNotes::clear() -{ - childSetValue("notes_edit",LLStringUtil::null); - - childSetEnabled("status_check",FALSE); - childSetEnabled("map_check",FALSE); - childSetEnabled("objects_check",FALSE); -} - -void LLPanelAvatarNotes::processProperties(void* data, EAvatarProcessorType type) -{ - if(APT_NOTES == type) - { - LLAvatarNotes* avatar_notes = static_cast<LLAvatarNotes*>(data); - if(avatar_notes && getAvatarId() == avatar_notes->target_id) - { - childSetValue("notes_edit",avatar_notes->notes); - childSetEnabled("notes edit", true); - - LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this); - } - } -} - -void LLPanelAvatarNotes::onActivate(const LLUUID& id) -{ - LLPanelProfileTab::onActivate(id); - updateChildrenList(); -} - -void LLPanelAvatarNotes::updateChildrenList() -{ - //hide for friends - childSetEnabled("add_friend", !LLAvatarActions::isFriend(getAvatarId())); -} diff --git a/indra/newview/llpanelavatar.h b/indra/newview/llpanelavatar.h index 2b0fbaf193..a6cf2a2d27 100644 --- a/indra/newview/llpanelavatar.h +++ b/indra/newview/llpanelavatar.h @@ -45,137 +45,199 @@ enum EOnlineStatus ONLINE_STATUS_YES = 1 }; - -class LLPanelProfileTab +/** +* Base class for any Profile View or Me Profile Panel. +*/ +class LLPanelProfileTab : public LLPanel , public LLAvatarPropertiesObserver { public: - - LLPanelProfileTab(const LLUUID& avatar_id); - LLPanelProfileTab(const Params& params ); - void setAvatarId(const LLUUID& avatar_id); + /** + * Sets avatar ID, sets panel as observer of avatar related info replies from server. + */ + virtual void setAvatarId(const LLUUID& id); - const LLUUID& getAvatarId(){return mAvatarId;} + /** + * Returns avatar ID. + */ + virtual const LLUUID& getAvatarId() { return mAvatarId; } + /** + * Sends update data request to server. + */ virtual void updateData() = 0; + /** + * Clears panel data if viewing avatar info for first time and sends update data request. + */ virtual void onOpen(const LLSD& key); - virtual void onActivate(const LLUUID& id); + /** + * Resets controls visibility, state, etc. + */ + virtual void resetControls(){}; - typedef enum e_profile_type - { - PT_UNKNOWN, - PT_OWN, - PT_OTHER - } EProfileType; + /** + * Clears all data received from server. + */ + virtual void resetData(){}; - virtual void onAddFriend(); + /*virtual*/ ~LLPanelProfileTab(); - virtual void onIM(); - - virtual void onTeleport(); +protected: - virtual void clear(){}; + LLPanelProfileTab(); -protected: - virtual ~LLPanelProfileTab(); - void setProfileType(); + /** + * Scrolls panel to top when viewing avatar info for first time. + */ + void scrollToTop(); private: - void scrollToTop(); -protected: - e_profile_type mProfileType; LLUUID mAvatarId; }; -class LLPanelAvatarProfile +/** +* Panel for displaying Avatar's first and second life related info. +*/ +class LLPanelAvatarProfile : public LLPanelProfileTab { public: - LLPanelAvatarProfile(const LLUUID& avatar_id = LLUUID::null); - LLPanelAvatarProfile(const Params& params ); - ~LLPanelAvatarProfile(); - - static void* create(void* data); + LLPanelAvatarProfile(); + + /*virtual*/ void onOpen(const LLSD& key); + /** + * Processes data received from server. + */ /*virtual*/ void processProperties(void* data, EAvatarProcessorType type); - void updateData(); + /*virtual*/ BOOL postBuild(); - void clear(); + /*virtual*/ void updateData(); - virtual void clearControls(); + /*virtual*/ void resetControls(); - /*virtual*/ BOOL postBuild(void); - /*virtual*/ void onOpen(const LLSD& key); + /*virtual*/ void resetData(); -private: - bool isOwnProfile(){return PT_OWN == mProfileType;} - bool isEditMode(){return mEditMode;} - void updateChildrenList(); - void onStatusChanged(); - void onStatusMessageChanged(); - void setCaptionText(const LLAvatarData* avatar_data); +protected: - static void onUrlTextboxClicked(std::string url); - void onHomepageTextboxClicked(); - void onUpdateAccountTextboxClicked(); - void onMyAccountTextboxClicked(); - void onPartnerEditTextboxClicked(); + /** + * Process profile related data received from server. + */ + virtual void processProfileProperties(const LLAvatarData* avatar_data); + + /** + * Processes group related data received from server. + */ + virtual void processGroupProperties(const LLAvatarGroups* avatar_groups); + + /** + * Fills common for Avatar profile and Me Profile fields. + */ + virtual void fillCommonData(const LLAvatarData* avatar_data); + + /** + * Fills partner data. + */ + virtual void fillPartnerData(const LLAvatarData* avatar_data); + + /** + * Fills Avatar's online status. + */ + virtual void fillOnlineStatus(const LLAvatarData* avatar_data); + + /** + * Fills account status. + */ + virtual void fillAccountStatus(const LLAvatarData* avatar_data); + void onUrlTextboxClicked(std::string url); + void onHomepageTextboxClicked(); void onAddFriendButtonClick(); void onIMButtonClick(); void onCallButtonClick(); void onTeleportButtonClick(); void onShareButtonClick(); +}; + +/** + * Panel for displaying own first and second life related info. + */ +class LLPanelAvatarMeProfile + : public LLPanelAvatarProfile +{ +public: + LLPanelAvatarMeProfile(); + + /*virtual*/ BOOL postBuild(); + +protected: + + /*virtual*/ void onOpen(const LLSD& key); + + /*virtual*/ void processProfileProperties(const LLAvatarData* avatar_data); + /** + * Fills Avatar status data. + */ + virtual void fillStatusData(const LLAvatarData* avatar_data); + + /*virtual*/ void resetControls(); protected: - bool mEditMode; + + void onStatusChanged(); + void onStatusMessageChanged(); + void onUpdateAccountTextboxClicked(); + void onMyAccountTextboxClicked(); + void onPartnerEditTextboxClicked(); private: - bool mUpdated; - LLComboBox * mStatusCombobox; - LLLineEditor * mStatusMessage; -}; + LLComboBox* mStatusCombobox; +}; +/** +* Panel for displaying Avatar's notes and modifying friend's rights. +*/ class LLPanelAvatarNotes : public LLPanelProfileTab { public: - LLPanelAvatarNotes(const LLUUID& id = LLUUID::null); - LLPanelAvatarNotes(const Params& params ); - ~LLPanelAvatarNotes(); + LLPanelAvatarNotes(); - static void* create(void* data); + /*virtual*/ void onOpen(const LLSD& key); - void onActivate(const LLUUID& id); + /*virtual*/ BOOL postBuild(); - BOOL postBuild(void); + /*virtual*/ void processProperties(void* data, EAvatarProcessorType type); - void onCommitRights(); + /*virtual*/ void updateData(); - void onCommitNotes(); +protected: - void clear(); + /*virtual*/ void resetControls(); - void processProperties(void* data, EAvatarProcessorType type); + /*virtual*/ void resetData(); - void updateData(); + /** + * Fills rights data for friends. + */ + void fillRightsData(); -protected: + void onCommitRights(); + void onCommitNotes(); - void updateChildrenList(); + void onAddFriendButtonClick(); + void onIMButtonClick(); + void onCallButtonClick(); + void onTeleportButtonClick(); + void onShareButtonClick(); }; - - -// helper funcs -void add_left_label(LLPanel *panel, const std::string& name, S32 y); - #endif // LL_LLPANELAVATAR_H diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp index 3acaa6b68e..086b06c1a3 100644 --- a/indra/newview/llpanelgroup.cpp +++ b/indra/newview/llpanelgroup.cpp @@ -35,10 +35,6 @@ #include "llagent.h" #include "llbutton.h" -#include "llpanelgroupgeneral.h" -#include "llpanelgrouproles.h" -#include "llpanelgrouplandmoney.h" -#include "llpanelgroupnotices.h" #include "lltabcontainer.h" #include "lltextbox.h" #include "llviewermessage.h" @@ -46,26 +42,31 @@ #include "llviewerwindow.h" #include "llappviewer.h" #include "llnotifications.h" +#include "llfloaterreg.h" #include "llfloater.h" -// static -void* LLPanelGroupTab::createTab(void* data) -{ - LLUUID* group_id = static_cast<LLUUID*>(data); - return new LLPanelGroupTab(*group_id); -} +#include "llsidetraypanelcontainer.h" + +#include "llpanelgroupnotices.h" +#include "llpanelgroupgeneral.h" + +#include "llsidetray.h" +#include "llaccordionctrltab.h" + +static LLRegisterPanelClassWrapper<LLPanelGroup> t_panel_group("panel_group_info_sidetray"); -LLPanelGroupTab::LLPanelGroupTab(const LLUUID& group_id) + + +LLPanelGroupTab::LLPanelGroupTab() : LLPanel(), - mGroupID(group_id), mAllowEdit(TRUE), mHasModal(FALSE) { + mGroupID = LLUUID::null; } LLPanelGroupTab::~LLPanelGroupTab() { - mObservers.clear(); } BOOL LLPanelGroupTab::isVisibleByAgent(LLAgent* agentp) @@ -76,39 +77,10 @@ BOOL LLPanelGroupTab::isVisibleByAgent(LLAgent* agentp) BOOL LLPanelGroupTab::postBuild() { - // Hook up the help button callback. - LLButton* button = findChild<LLButton>("help_button"); - if (button) - { - button->setCommitCallback(boost::bind(&LLPanelGroupTab::handleClickHelp, this)); - } - mHelpText = getString("help_text"); return TRUE; } -void LLPanelGroupTab::addObserver(LLPanelGroupTabObserver *obs) -{ - mObservers.insert(obs); -} - -void LLPanelGroupTab::removeObserver(LLPanelGroupTabObserver *obs) -{ - mObservers.erase(obs); -} - -void LLPanelGroupTab::notifyObservers() -{ - - for (observer_list_t::iterator iter = mObservers.begin(); - iter != mObservers.end(); ) - { - LLPanelGroupTabObserver* observer = *iter; - observer->tabChanged(); - // safe way to incrament since changed may delete entries! (@!##%@!@&*!) - iter = mObservers.upper_bound(observer); - } -} void LLPanelGroupTab::handleClickHelp() { @@ -125,384 +97,240 @@ void LLPanelGroupTab::handleClickHelp() } } -LLPanelGroup::LLPanelGroup(const LLUUID& group_id) -: LLPanel(), - LLGroupMgrObserver( group_id ), - mCurrentTab( NULL ), - mRequestedTab( NULL ), - mTabContainer( NULL ), - mIgnoreTransition( FALSE ), - mApplyBtn( NULL ), - mForceClose( FALSE ), - mAllowEdit( TRUE ), - mShowingNotifyDialog( FALSE ) +LLPanelGroup::LLPanelGroup() +: LLPanel() + ,LLGroupMgrObserver( LLUUID() ) + ,mAllowEdit(TRUE) { // Set up the factory callbacks. - mFactoryMap["general_tab"] = LLCallbackMap(LLPanelGroupGeneral::createTab, &mID); - mFactoryMap["roles_tab"] = LLCallbackMap(LLPanelGroupRoles::createTab, &mID); - mFactoryMap["notices_tab"] = LLCallbackMap(LLPanelGroupNotices::createTab, &mID); - mFactoryMap["land_money_tab"]= LLCallbackMap(LLPanelGroupLandMoney::createTab, &mID); // Roles sub tabs - mFactoryMap["members_sub_tab"] = LLCallbackMap(LLPanelGroupMembersSubTab::createTab, &mID); - mFactoryMap["roles_sub_tab"] = LLCallbackMap(LLPanelGroupRolesSubTab::createTab, &mID); - mFactoryMap["actions_sub_tab"] = LLCallbackMap(LLPanelGroupActionsSubTab::createTab, &mID); - LLGroupMgr::getInstance()->addObserver(this); + } + LLPanelGroup::~LLPanelGroup() { LLGroupMgr::getInstance()->removeObserver(this); - - for (S32 i=mTabContainer->getTabCount() - 1; i >=0; --i) - { - LLPanelGroupTab* panelp = (LLPanelGroupTab*) mTabContainer->getPanelByIndex(i); - if ( panelp ) - panelp->removeObserver(this); - } } -void LLPanelGroup::updateTabVisibility() +void LLPanelGroup::onOpen(const LLSD& key) { - for (S32 i = mTabContainer->getTabCount() - 1; i >=0; --i) + LLUUID group_id = key["group_id"]; + if(!key.has("action")) { - LLPanelGroupTab* panelp = (LLPanelGroupTab*) mTabContainer->getPanelByIndex(i); + setGroupID(group_id); + return; + } - BOOL visible = panelp->isVisibleByAgent(&gAgent) || gAgent.isGodlike(); - mTabContainer->enableTabButton(i, visible); + std::string str_action = key["action"]; - if ( !visible && mCurrentTab == panelp ) - { - //we are disabling the currently selected tab - //select the previous one - mTabContainer->selectPrevTab(); - mCurrentTab = (LLPanelGroupTab*) mTabContainer->getCurrentPanel(); - } + if(str_action == "refresh") + { + if(mID == group_id) + refreshData(); + } + else if(str_action == "close") + { + onBackBtnClick(); + } + else if(str_action == "create") + { + setGroupID(LLUUID::null); } -} - +} BOOL LLPanelGroup::postBuild() { - mTabContainer = getChild<LLTabContainer>("group_tab_container"); - - if (mTabContainer) - { - mCurrentTab = dynamic_cast<LLPanelGroupTab*>(mTabContainer->getCurrentPanel()); - llassert_always(mCurrentTab); - - // Add click callback. - mTabContainer->setCommitCallback(boost::bind(&LLPanelGroup::handleClickTab, this)); - - // Setup pabels - for (S32 i = mTabContainer->getTabCount() - 1; i >=0; --i) - { - LLPanel* tab_panel = mTabContainer->getPanelByIndex(i); - LLPanelGroupTab* panelp = dynamic_cast<LLPanelGroupTab*>(tab_panel); - if (panelp) - { - // Pass on whether or not to allow edit to tabs. - panelp->setAllowEdit(mAllowEdit); - panelp->addObserver(this); - } - } - updateTabVisibility(); - - // Act as though this tab was just activated. - mCurrentTab->activate(); - } - mDefaultNeedsApplyMesg = getString("default_needs_apply_text"); mWantApplyMesg = getString("want_apply_text"); - LLButton* button = getChild<LLButton>("btn_ok"); - button->setClickedCallback(onBtnOK, this); - button->setVisible(mAllowEdit); - - button = getChild<LLButton>("btn_cancel"); - button->setClickedCallback(onBtnCancel, this); - button->setVisible(mAllowEdit); + LLButton* button; button = getChild<LLButton>("btn_apply"); button->setClickedCallback(onBtnApply, this); - button->setVisible(mAllowEdit); - button->setEnabled(FALSE); - mApplyBtn = button; + button->setVisible(true); + button->setEnabled(false); + button = getChild<LLButton>("btn_refresh"); button->setClickedCallback(onBtnRefresh, this); button->setVisible(mAllowEdit); + getChild<LLButton>("btn_create")->setVisible(false); + + childSetCommitCallback("btn_create",boost::bind(&LLPanelGroup::onBtnCreate,this),NULL); + childSetCommitCallback("back",boost::bind(&LLPanelGroup::onBackBtnClick,this),NULL); + + LLPanelGroupTab* panel_general = findChild<LLPanelGroupTab>("group_general_tab_panel"); + LLPanelGroupTab* panel_roles = findChild<LLPanelGroupTab>("group_roles_tab_panel"); + LLPanelGroupTab* panel_notices = findChild<LLPanelGroupTab>("group_notices_tab_panel"); + LLPanelGroupTab* panel_land = findChild<LLPanelGroupTab>("group_land_tab_panel"); + + if(panel_general) mTabs.push_back(panel_general); + if(panel_roles) mTabs.push_back(panel_roles); + if(panel_notices) mTabs.push_back(panel_notices); + if(panel_land) mTabs.push_back(panel_land); + return TRUE; } -void LLPanelGroup::changed(LLGroupChange gc) +void LLPanelGroup::reshape(S32 width, S32 height, BOOL called_from_parent ) { - updateTabVisibility(); - // Notify the currently active panel that group manager information has changed. - LLPanelGroupTab* panelp = (LLPanelGroupTab*) mTabContainer->getCurrentPanel(); + LLPanel::reshape(width, height, called_from_parent ); - if (panelp) - { - panelp->update(gc); - } + LLButton* button = getChild<LLButton>("btn_apply"); + LLRect btn_rect = button->getRect(); + btn_rect.setLeftTopAndSize( btn_rect.mLeft, 28, btn_rect.getWidth(), btn_rect.getHeight()); + button->setRect(btn_rect); + + button = getChild<LLButton>("btn_create"); + btn_rect = button->getRect(); + btn_rect.setLeftTopAndSize( btn_rect.mLeft, 28, btn_rect.getWidth(), btn_rect.getHeight()); + button->setRect(btn_rect); + + + button = getChild<LLButton>("btn_refresh"); + btn_rect = button->getRect(); + btn_rect.setLeftTopAndSize( btn_rect.mLeft, 28, btn_rect.getWidth(), btn_rect.getHeight()); + button->setRect(btn_rect); } -// PanelGroupTab observer trigger -void LLPanelGroup::tabChanged() +void LLPanelGroup::onBackBtnClick() { - //some tab information has changed,....enable/disable the apply button - //based on if they need an apply - if ( mApplyBtn ) + LLSideTrayPanelContainer* parent = dynamic_cast<LLSideTrayPanelContainer*>(getParent()); + if(parent) { - std::string mesg; - mApplyBtn->setEnabled(mCurrentTab->needsApply(mesg)); + parent->openPreviousPanel(); } } -void LLPanelGroup::handleClickTab() +void LLPanelGroup::onBtnCreate() { - // If we are already handling a transition, - // ignore this. - if (mIgnoreTransition) - { + LLPanelGroupGeneral* panel_general = findChild<LLPanelGroupGeneral>("group_general_tab_panel"); + if(!panel_general) return; - } - - mRequestedTab = (LLPanelGroupTab*) mTabContainer->getCurrentPanel(); - - // Make sure they aren't just clicking the same tab... - if (mRequestedTab == mCurrentTab) - { - return; - } + std::string apply_mesg; + panel_general->apply(apply_mesg);//yes yes you need to call apply to create... +} - // Try to switch from the current panel to the panel the user selected. - attemptTransition(); +void LLPanelGroup::onBtnRefresh(void* user_data) +{ + LLPanelGroup* self = static_cast<LLPanelGroup*>(user_data); + self->refreshData(); } -void LLPanelGroup::setGroupID(const LLUUID& group_id) +void LLPanelGroup::onBtnApply(void* user_data) { - LLRect rect(getRect()); + LLPanelGroup* self = static_cast<LLPanelGroup*>(user_data); + self->apply(); +} - LLGroupMgr::getInstance()->removeObserver(this); - mID = group_id; - LLGroupMgr::getInstance()->addObserver(this); - //*TODO: this is really bad, we should add a method - // where the panels can just update themselves - // on a group id change. Similar to update() but with a group - // id change. +void LLPanelGroup::changed(LLGroupChange gc) +{ + for(std::vector<LLPanelGroupTab* >::iterator it = mTabs.begin();it!=mTabs.end();++it) + (*it)->update(gc); - // For now, rebuild panel - //delete children and rebuild panel - deleteAllChildren(); - LLUICtrlFactory::getInstance()->buildPanel(this, "panel_group.xml"); + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mID); + if(gdatap) + childSetValue("group_name", gdatap->mName); } -void LLPanelGroup::selectTab(std::string tab_name) +void LLPanelGroup::notifyObservers() { - const BOOL recurse = TRUE; + for(std::vector<LLPanelGroupTab* >::iterator it = mTabs.begin();it!=mTabs.end();++it) + (*it)->update(GC_ALL); - LLPanelGroupTab* tabp = findChild<LLPanelGroupTab>(tab_name, recurse); - - if ( tabp && mTabContainer ) - { - mTabContainer->selectTabPanel(tabp); - handleClickTab(); - } + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mID); + if(gdatap) + childSetValue("group_name", gdatap->mName); } -BOOL LLPanelGroup::canClose() -{ - if (mShowingNotifyDialog) return FALSE; - if (mCurrentTab && mCurrentTab->hasModal()) return FALSE; - if (mForceClose || !mAllowEdit) return TRUE; - // Try to switch from the current panel to nothing, indicating a close action. - mRequestedTab = NULL; - return attemptTransition(); -} -BOOL LLPanelGroup::attemptTransition() +void LLPanelGroup::setGroupID(const LLUUID& group_id) { - // Check if the current tab needs to be applied. - std::string mesg; - if (mCurrentTab && mCurrentTab->needsApply(mesg)) - { - // If no message was provided, give a generic one. - if (mesg.empty()) - { - mesg = mDefaultNeedsApplyMesg; - } - // Create a notify box, telling the user about the unapplied tab. - LLSD args; - args["NEEDS_APPLY_MESSAGE"] = mesg; - args["WANT_APPLY_MESSAGE"] = mWantApplyMesg; - LLNotifications::instance().add("PanelGroupApply", args, LLSD(), - boost::bind(&LLPanelGroup::handleNotifyCallback, this, _1, _2)); - mShowingNotifyDialog = TRUE; - - // We need to reselect the current tab, since it isn't finished. - if (mTabContainer) - { - // selectTabPanel is going to trigger another - // click event. We want to ignore it so that - // mRequestedTab is not updated. - mIgnoreTransition = TRUE; - mTabContainer->selectTabPanel( mCurrentTab ); - mIgnoreTransition = FALSE; - } - // Returning FALSE will block a close action from finishing until - // we get a response back from the user. - return FALSE; - } - else - { - // The current panel didn't have anything it needed to apply. - if ( mRequestedTab ) - { - transitionToTab(); - } - // Returning TRUE will allow any close action to proceed. - return TRUE; - } -} + LLGroupMgr::getInstance()->removeObserver(this); + mID = group_id; + LLGroupMgr::getInstance()->addObserver(this); -void LLPanelGroup::transitionToTab() -{ - // Tell the current panel that it is being deactivated. - if (mCurrentTab) - { - mCurrentTab->deactivate(); - } + for(std::vector<LLPanelGroupTab* >::iterator it = mTabs.begin();it!=mTabs.end();++it) + (*it)->setGroupID(group_id); + + LLButton* button_apply = getChild<LLButton>("btn_apply"); + LLButton* button_refresh = getChild<LLButton>("btn_refresh"); + LLButton* button_create = getChild<LLButton>("btn_create"); + + + bool is_null_group_id = group_id == LLUUID::null; - // If the requested panel exists, activate it. - if (mRequestedTab) - { - // This is now the current tab; - mCurrentTab = mRequestedTab; - mCurrentTab->activate(); - } - else // NULL requested indicates a close action. - { - closePanel(); - } -} + button_apply->setVisible(!is_null_group_id); + button_refresh->setVisible(!is_null_group_id); + button_create->setVisible(is_null_group_id); -bool LLPanelGroup::handleNotifyCallback(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotification::getSelectedOption(notification, response); - mShowingNotifyDialog = FALSE; - switch (option) - { - case 0: // "Apply Changes" - // Try to apply changes, and switch to the requested tab. - if ( !apply() ) - { - // There was a problem doing the apply. - // Skip switching tabs. - break; - } + LLAccordionCtrlTab* tab_general = findChild<LLAccordionCtrlTab>("group_general_tab"); + LLAccordionCtrlTab* tab_roles = findChild<LLAccordionCtrlTab>("group_roles_tab"); + LLAccordionCtrlTab* tab_notices = findChild<LLAccordionCtrlTab>("group_notices_tab"); + LLAccordionCtrlTab* tab_land = findChild<LLAccordionCtrlTab>("group_land_tab"); - // This panel's info successfully applied. - // Switch to the next panel. - mIgnoreTransition = TRUE; - mTabContainer->selectTabPanel( mRequestedTab ); - mIgnoreTransition = FALSE; - transitionToTab(); - break; - case 1: // "Ignore Changes" - // Switch to the requested panel without applying changes - // (Changes may already have been applied in the previous block) - mCurrentTab->cancel(); - mIgnoreTransition = TRUE; - mTabContainer->selectTabPanel( mRequestedTab ); - mIgnoreTransition = FALSE; - transitionToTab(); - break; - case 2: // "Cancel" - default: - // Do nothing. The user is canceling the action. - // If we were quitting, we didn't really mean it. - LLAppViewer::instance()->abortQuit(); - break; + if(is_null_group_id)//creating new group + { + if(!tab_general->getDisplayChildren()) + tab_general->changeOpenClose(tab_general->getDisplayChildren()); + + if(tab_roles->getDisplayChildren()) + tab_roles->changeOpenClose(tab_roles->getDisplayChildren()); + if(tab_notices->getDisplayChildren()) + tab_notices->changeOpenClose(tab_notices->getDisplayChildren()); + if(tab_land->getDisplayChildren()) + tab_land->changeOpenClose(tab_land->getDisplayChildren()); + + tab_roles->canOpenClose(false); + tab_notices->canOpenClose(false); + tab_land->canOpenClose(false); } - return false; -} - -// static -void LLPanelGroup::onBtnOK(void* user_data) -{ - LLPanelGroup* self = static_cast<LLPanelGroup*>(user_data); - // If we are able to apply changes, then close. - if(self->apply()) + else { - self->closePanel(); + tab_roles->canOpenClose(true); + tab_notices->canOpenClose(true); + tab_land->canOpenClose(true); } } -// static -void LLPanelGroup::onBtnCancel(void* user_data) -{ - LLPanelGroup* self = static_cast<LLPanelGroup*>(user_data); - self->closePanel(); -} - -// static -void LLPanelGroup::onBtnApply(void* user_data) -{ - LLPanelGroup* self = static_cast<LLPanelGroup*>(user_data); - self->apply(); -} - -bool LLPanelGroup::apply() +bool LLPanelGroup::apply(LLPanelGroupTab* tab) { - // Pass this along to the currently visible tab. - if (!mTabContainer) + if(!tab) return false; - LLPanelGroupTab* panelp = dynamic_cast<LLPanelGroupTab*>(mTabContainer->getCurrentPanel()); - if (!panelp) - return false; - std::string mesg; - if ( !panelp->needsApply(mesg) ) - { - // We don't need to apply anything. - // We're done. + if ( !tab->needsApply(mesg) ) return true; - } - - // Ignore the needs apply message. - // Try to do the actual apply. + std::string apply_mesg; - if ( panelp->apply( apply_mesg ) ) - { - // Everything worked. We're done. + if(tab->apply( apply_mesg ) ) return true; - } - - // There was a problem doing the actual apply. - // Inform the user. + if ( !apply_mesg.empty() ) { LLSD args; args["MESSAGE"] = apply_mesg; LLNotifications::instance().add("GenericAlert", args); } - return false; } -// static -void LLPanelGroup::onBtnRefresh(void* user_data) +bool LLPanelGroup::apply() { - LLPanelGroup* self = static_cast<LLPanelGroup*>(user_data); - self->refreshData(); + return apply(findChild<LLPanelGroupTab>("group_general_tab_panel")) + && apply(findChild<LLPanelGroupTab>("group_roles_tab_panel")) + && apply(findChild<LLPanelGroupTab>("group_notices_tab_panel")) + && apply(findChild<LLPanelGroupTab>("group_land_tab_panel")) + ; } + // virtual void LLPanelGroup::draw() { @@ -513,18 +341,22 @@ void LLPanelGroup::draw() mRefreshTimer.stop(); childEnable("btn_refresh"); } - if (mCurrentTab) - { - std::string mesg; - childSetEnabled("btn_apply", mCurrentTab->needsApply(mesg)); - } + bool enable = false; + std::string mesg; + for(std::vector<LLPanelGroupTab* >::iterator it = mTabs.begin();it!=mTabs.end();++it) + enable = enable || (*it)->needsApply(mesg); + + childSetEnabled("btn_apply", enable); } void LLPanelGroup::refreshData() { LLGroupMgr::getInstance()->clearGroupData(getID()); - mCurrentTab->activate(); + + for(std::vector<LLPanelGroupTab* >::iterator it = mTabs.begin();it!=mTabs.end();++it) + (*it)->activate(); + // 5 second timeout childDisable("btn_refresh"); @@ -532,20 +364,6 @@ void LLPanelGroup::refreshData() mRefreshTimer.setTimerExpirySec(5); } -void LLPanelGroup::closePanel() -{ - // Pass this to the parent, if it is a floater. - LLView* viewp = getParent(); - LLFloater* floaterp = dynamic_cast<LLFloater*>(viewp); - if (floaterp) - { - // First, set the force close flag, since the floater - // will be asking us whether it can close. - mForceClose = TRUE; - // Tell the parent floater to close. - floaterp->closeFloater(); - } -} void LLPanelGroup::showNotice(const std::string& subject, const std::string& message, @@ -553,7 +371,8 @@ void LLPanelGroup::showNotice(const std::string& subject, const std::string& inventory_name, LLOfferInfo* inventory_offer) { - if (mCurrentTab->getName() != "notices_tab") + LLPanelGroupNotices* panel_notices = findChild<LLPanelGroupNotices>("group_notices_tab_panel"); + if(!panel_notices) { // We need to clean up that inventory offer. if (inventory_offer) @@ -562,8 +381,37 @@ void LLPanelGroup::showNotice(const std::string& subject, } return; } + panel_notices->showNotice(subject,message,has_inventory,inventory_name,inventory_offer); +} - LLPanelGroupNotices* notices = static_cast<LLPanelGroupNotices*>(mCurrentTab); - notices->showNotice(subject,message,has_inventory,inventory_name,inventory_offer); + + +//static +void LLPanelGroup::refreshCreatedGroup(const LLUUID& group_id) +{ + LLPanelGroup* panel = LLSideTray::getInstance()->findChild<LLPanelGroup>("panel_group_info_sidetray"); + if(!panel) + return; + panel->setGroupID(group_id); } + +//static + +void LLPanelGroup::showNotice(const std::string& subject, + const std::string& message, + const LLUUID& group_id, + const bool& has_inventory, + const std::string& inventory_name, + LLOfferInfo* inventory_offer) +{ + LLPanelGroup* panel = LLSideTray::getInstance()->findChild<LLPanelGroup>("panel_group_info_sidetray"); + if(!panel) + return; + + if(panel->getID() != group_id)//???? only for current group_id or switch panels? FIXME + return; + panel->showNotice(subject,message,has_inventory,inventory_name,inventory_offer); + +} + diff --git a/indra/newview/llpanelgroup.h b/indra/newview/llpanelgroup.h index 55c7494a44..e5e1d1b6ad 100644 --- a/indra/newview/llpanelgroup.h +++ b/indra/newview/llpanelgroup.h @@ -45,93 +45,79 @@ class LLPanelGroupTab; class LLTabContainer; class LLAgent; -class LLPanelGroupTabObserver -{ -public: - LLPanelGroupTabObserver() {}; - virtual ~LLPanelGroupTabObserver(){}; - virtual void tabChanged() = 0; -}; class LLPanelGroup : public LLPanel, - public LLGroupMgrObserver, - public LLPanelGroupTabObserver + public LLGroupMgrObserver { public: - LLPanelGroup(const LLUUID& group_id); + LLPanelGroup(); virtual ~LLPanelGroup(); virtual BOOL postBuild(); - static void onBtnOK(void*); - static void onBtnCancel(void*); - static void onBtnApply(void*); - static void onBtnRefresh(void*); - void handleClickTab(); - void setGroupID(const LLUUID& group_id); - void selectTab(std::string tab_name); - - // Called when embedded in a floater during a close attempt. - BOOL canClose(); - - // Checks if the current tab needs to be applied, and tries to switch to the requested tab. - BOOL attemptTransition(); - - // Switches to the requested tab (will close() if requested is NULL) - void transitionToTab(); - - void updateTabVisibility(); - - // Used by attemptTransition to query the user's response to a tab that needs to apply. - bool handleNotifyCallback(const LLSD& notification, const LLSD& response); - bool apply(); - void refreshData(); - void closePanel(); void draw(); + void onOpen(const LLSD& key); + // Group manager observer trigger. virtual void changed(LLGroupChange gc); - // PanelGroupTab observer trigger - virtual void tabChanged(); - - void setAllowEdit(BOOL v) { mAllowEdit = v; } - void showNotice(const std::string& subject, const std::string& message, const bool& has_inventory, const std::string& inventory_name, LLOfferInfo* inventory_offer); + + void notifyObservers(); + + bool apply(); + void refreshData(); + + virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); + + void setAllowEdit(BOOL v) { mAllowEdit = v; } + + + static void refreshCreatedGroup(const LLUUID& group_id); + + static void showNotice(const std::string& subject, + const std::string& message, + const LLUUID& group_id, + const bool& has_inventory, + const std::string& inventory_name, + LLOfferInfo* inventory_offer); + + protected: - LLPanelGroupTab* mCurrentTab; - LLPanelGroupTab* mRequestedTab; - LLTabContainer* mTabContainer; - BOOL mIgnoreTransition; + void onBtnCreate(); + void onBackBtnClick(); - LLButton* mApplyBtn; + static void onBtnApply(void*); + static void onBtnRefresh(void*); + + +protected: + bool apply(LLPanelGroupTab* tab); LLTimer mRefreshTimer; - BOOL mForceClose; + BOOL mAllowEdit; std::string mDefaultNeedsApplyMesg; std::string mWantApplyMesg; - BOOL mAllowEdit; - BOOL mShowingNotifyDialog; + std::vector<LLPanelGroupTab* > mTabs; + }; class LLPanelGroupTab : public LLPanel { public: - LLPanelGroupTab(const LLUUID& group_id); + LLPanelGroupTab(); virtual ~LLPanelGroupTab(); - // Factory that returns a new LLPanelGroupFoo tab. - static void* createTab(void* data); - // Triggered when the tab becomes active. virtual void activate() { } @@ -168,20 +154,19 @@ public: void setAllowEdit(BOOL v) { mAllowEdit = v; } - void addObserver(LLPanelGroupTabObserver *obs); - void removeObserver(LLPanelGroupTabObserver *obs); - void notifyObservers(); + virtual void setGroupID(const LLUUID& id) {mGroupID = id;}; + + void notifyObservers() {}; + + const LLUUID& getGroupID() const { return mGroupID;} protected: LLUUID mGroupID; - LLTabContainer* mTabContainer; std::string mHelpText; BOOL mAllowEdit; BOOL mHasModal; - typedef std::set<LLPanelGroupTabObserver*> observer_list_t; - observer_list_t mObservers; }; #endif // LL_LLPANELGROUP_H diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp index b1b464b4e4..d63e112357 100644 --- a/indra/newview/llpanelgroupgeneral.cpp +++ b/indra/newview/llpanelgroupgeneral.cpp @@ -37,7 +37,6 @@ #include "lluictrlfactory.h" #include "llagent.h" #include "roles_constants.h" -#include "llfloatergroupinfo.h" // UI elements #include "llbutton.h" @@ -45,6 +44,7 @@ #include "llcombobox.h" #include "lldbstrings.h" #include "llavataractions.h" +#include "llgroupactions.h" #include "lllineeditor.h" #include "llnamebox.h" #include "llnamelistctrl.h" @@ -57,21 +57,16 @@ #include "lltrans.h" #include "llviewerwindow.h" +static LLRegisterPanelClassWrapper<LLPanelGroupGeneral> t_panel_group_general("panel_group_general"); + // consts const S32 MATURE_CONTENT = 1; const S32 NON_MATURE_CONTENT = 2; const S32 DECLINE_TO_STATE = 0; -// static -void* LLPanelGroupGeneral::createTab(void* data) -{ - LLUUID* group_id = static_cast<LLUUID*>(data); - return new LLPanelGroupGeneral(*group_id); -} - -LLPanelGroupGeneral::LLPanelGroupGeneral(const LLUUID& group_id) -: LLPanelGroupTab(group_id), +LLPanelGroupGeneral::LLPanelGroupGeneral() +: LLPanelGroupTab(), mPendingMemberUpdate(FALSE), mChanged(FALSE), mFirstUse(TRUE), @@ -311,7 +306,8 @@ void LLPanelGroupGeneral::onClickInfo(void *userdata) lldebugs << "open group info: " << self->mGroupID << llendl; - LLFloaterGroupInfo::showFromUUID(self->mGroupID); + LLGroupActions::show(self->mGroupID); + } // static @@ -888,3 +884,150 @@ void LLPanelGroupGeneral::updateChanged() } } } + +void LLPanelGroupGeneral::reset() +{ + mCtrlReceiveNotices->set(false); + + + mCtrlListGroup->set(true); + + mCtrlReceiveNotices->setEnabled(true); + mCtrlReceiveNotices->setVisible(true); + + mCtrlListGroup->setEnabled(true); + + mGroupNameEditor->setEnabled(TRUE); + mEditCharter->setEnabled(TRUE); + + mCtrlShowInGroupList->setEnabled(TRUE); + mComboMature->setEnabled(TRUE); + + mCtrlOpenEnrollment->setEnabled(TRUE); + + mCtrlEnrollmentFee->setEnabled(TRUE); + + mSpinEnrollmentFee->setEnabled(TRUE); + mSpinEnrollmentFee->set((F32)0); + + mBtnJoinGroup->setVisible(FALSE); + mBtnInfo->setVisible(FALSE); + mGroupName->setVisible(FALSE); + + mGroupNameEditor->setVisible(true); + + mComboActiveTitle->setVisible(false); + mInsignia->setImageAssetID(mDefaultIconID); + + { + std::string empty_str = ""; + mEditCharter->setText(empty_str); + } + + { + LLSD row; + row["columns"][0]["value"] = "no members yet"; + + mListVisibleMembers->deleteAllItems(); + mListVisibleMembers->setEnabled(FALSE); + mListVisibleMembers->addElement(row); + } + + mBtnJoinGroup->setVisible(false); + + { + mComboMature->setEnabled(true); + mComboMature->setVisible( !gAgent.isTeen() ); + } + + + resetDirty(); +} + +void LLPanelGroupGeneral::resetDirty() +{ + // List all the controls we want to check for changes... + LLUICtrl *check_list[] = + { + mGroupNameEditor, + mGroupName, + mFounderName, + mInsignia, + mEditCharter, + mCtrlShowInGroupList, + mComboMature, + mCtrlOpenEnrollment, + mCtrlEnrollmentFee, + mSpinEnrollmentFee, + mCtrlReceiveNotices, + mCtrlListGroup, + mActiveTitleLabel, + mComboActiveTitle + }; + + for( size_t i=0; i<LL_ARRAY_SIZE(check_list); i++ ) + { + if( check_list[i] ) + check_list[i]->resetDirty() ; + } + + +} + +void LLPanelGroupGeneral::setGroupID(const LLUUID& id) +{ + LLPanelGroupTab::setGroupID(id); + + if(id == LLUUID::null) + { + reset(); + return; + } + + BOOL accept_notices = FALSE; + BOOL list_in_profile = FALSE; + LLGroupData data; + if(gAgent.getGroupData(mGroupID,data)) + { + accept_notices = data.mAcceptNotices; + list_in_profile = data.mListInProfile; + } + mCtrlReceiveNotices = getChild<LLCheckBoxCtrl>("receive_notices"); + if (mCtrlReceiveNotices) + { + mCtrlReceiveNotices->set(accept_notices); + mCtrlReceiveNotices->setEnabled(data.mID.notNull()); + } + + mCtrlListGroup = getChild<LLCheckBoxCtrl>("list_groups_in_profile"); + if (mCtrlListGroup) + { + mCtrlListGroup->set(list_in_profile); + mCtrlListGroup->setEnabled(data.mID.notNull()); + } + + mActiveTitleLabel = getChild<LLTextBox>("active_title_label"); + + mComboActiveTitle = getChild<LLComboBox>("active_title"); + + if (mGroupID.isNull()) + { + mGroupNameEditor->setEnabled(TRUE); + mEditCharter->setEnabled(TRUE); + + mCtrlShowInGroupList->setEnabled(TRUE); + mComboMature->setEnabled(TRUE); + mCtrlOpenEnrollment->setEnabled(TRUE); + mCtrlEnrollmentFee->setEnabled(TRUE); + mSpinEnrollmentFee->setEnabled(TRUE); + + mBtnJoinGroup->setVisible(FALSE); + mBtnInfo->setVisible(FALSE); + mGroupName->setVisible(FALSE); + } + + resetDirty(); + + activate(); +} + diff --git a/indra/newview/llpanelgroupgeneral.h b/indra/newview/llpanelgroupgeneral.h index c04b40819d..e7028228b0 100644 --- a/indra/newview/llpanelgroupgeneral.h +++ b/indra/newview/llpanelgroupgeneral.h @@ -49,11 +49,10 @@ class LLSpinCtrl; class LLPanelGroupGeneral : public LLPanelGroupTab { public: - LLPanelGroupGeneral(const LLUUID& group_id); + LLPanelGroupGeneral(); virtual ~LLPanelGroupGeneral(); // LLPanelGroupTab - static void* createTab(void* data); virtual void activate(); virtual bool needsApply(std::string& mesg); virtual bool apply(std::string& mesg); @@ -66,7 +65,13 @@ public: virtual void draw(); + virtual void setGroupID(const LLUUID& id); + private: + void reset(); + + void resetDirty(); + static void onFocusEdit(LLFocusableElement* ctrl, void* data); static void onCommitAny(LLUICtrl* ctrl, void* data); static void onCommitUserOnly(LLUICtrl* ctrl, void* data); diff --git a/indra/newview/llpanelgrouplandmoney.cpp b/indra/newview/llpanelgrouplandmoney.cpp index 39a9f231b2..d95240e30c 100644 --- a/indra/newview/llpanelgrouplandmoney.cpp +++ b/indra/newview/llpanelgrouplandmoney.cpp @@ -59,7 +59,54 @@ #include "llfloaterworldmap.h" #include "llviewermessage.h" +static LLRegisterPanelClassWrapper<LLPanelGroupLandMoney> t_panel_group_money("panel_group_land_money"); + + + //////////////////////////////////////////////////////////////////////////// +//************************************************* +//** LLGroupMoneyTabEventHandler::impl Functions ** +//************************************************* + +class LLGroupMoneyTabEventHandlerImpl +{ +public: + LLGroupMoneyTabEventHandlerImpl(LLButton* earlier_buttonp, + LLButton* later_buttonp, + LLTextEditor* text_editorp, + LLPanel* tabpanelp, + const std::string& loading_text, + S32 interval_length_days, + S32 max_interval_days); + ~LLGroupMoneyTabEventHandlerImpl(); + + bool getCanClickLater(); + bool getCanClickEarlier(); + + void updateButtons(); + + void setGroupID(const LLUUID& group_id) { mGroupID = group_id; } ; + const LLUUID& getGroupID() const { return mGroupID;} + + +//member variables +public: + LLUUID mPanelID; + LLUUID mGroupID; + + LLPanel* mTabPanelp; + + int mIntervalLength; + int mMaxInterval; + int mCurrentInterval; + + LLTextEditor* mTextEditorp; + LLButton* mEarlierButtonp; + LLButton* mLaterButtonp; + + std::string mLoadingText; +}; + class LLGroupMoneyTabEventHandler { @@ -70,7 +117,6 @@ public: LLTabContainer* tab_containerp, LLPanel* panelp, const std::string& loading_text, - const LLUUID& group_id, S32 interval_length_days, S32 max_interval_days); virtual ~LLGroupMoneyTabEventHandler(); @@ -82,14 +128,17 @@ public: virtual void onClickLater(); virtual void onClickTab(); + void setGroupID(const LLUUID& group_id) { if(mImplementationp) mImplementationp->setGroupID(group_id); } ; + static void clickEarlierCallback(void* data); static void clickLaterCallback(void* data); + + static LLMap<LLUUID, LLGroupMoneyTabEventHandler*> sInstanceIDs; static std::map<LLPanel*, LLGroupMoneyTabEventHandler*> sTabsToHandlers; protected: - class impl; - impl* mImplementationp; + LLGroupMoneyTabEventHandlerImpl* mImplementationp; }; class LLGroupMoneyDetailsTabEventHandler : public LLGroupMoneyTabEventHandler @@ -100,8 +149,8 @@ public: LLTextEditor* text_editorp, LLTabContainer* tab_containerp, LLPanel* panelp, - const std::string& loading_text, - const LLUUID& group_id); + const std::string& loading_text + ); virtual ~LLGroupMoneyDetailsTabEventHandler(); virtual void requestData(LLMessageSystem* msg); @@ -117,8 +166,8 @@ public: LLTextEditor* text_editorp, LLTabContainer* tab_containerp, LLPanel* panelp, - const std::string& loading_text, - const LLUUID& group_id); + const std::string& loading_text + ); virtual ~LLGroupMoneySalesTabEventHandler(); virtual void requestData(LLMessageSystem* msg); @@ -131,8 +180,8 @@ public: LLGroupMoneyPlanningTabEventHandler(LLTextEditor* text_editor, LLTabContainer* tab_containerp, LLPanel* panelp, - const std::string& loading_text, - const LLUUID& group_id); + const std::string& loading_text + ); virtual ~LLGroupMoneyPlanningTabEventHandler(); virtual void requestData(LLMessageSystem* msg); @@ -144,7 +193,7 @@ public: class LLPanelGroupLandMoney::impl { public: - impl(LLPanelGroupLandMoney& panel, const LLUUID& group_id); //constructor + impl(LLPanelGroupLandMoney& panel); //constructor virtual ~impl(); void requestGroupLandInfo(); @@ -178,7 +227,6 @@ public: LLScrollListCtrl* mGroupParcelsp; - LLUUID mGroupID; LLUUID mTransID; bool mBeenActivated; @@ -192,9 +240,8 @@ public: //******************************************* //** LLPanelGroupLandMoney::impl Functions ** //******************************************* -LLPanelGroupLandMoney::impl::impl(LLPanelGroupLandMoney& panel, const LLUUID& group_id) - : mPanel(panel), - mGroupID(group_id) +LLPanelGroupLandMoney::impl::impl(LLPanelGroupLandMoney& panel) + : mPanel(panel) { mTransID = LLUUID::null; @@ -227,7 +274,7 @@ void LLPanelGroupLandMoney::impl::requestGroupLandInfo() mTransID.generate(); mGroupParcelsp->deleteAllItems(); - send_places_query(mGroupID, mTransID, "", query_flags, LLParcel::C_ANY, ""); + send_places_query(mPanel.mGroupID, mTransID, "", query_flags, LLParcel::C_ANY, ""); } void LLPanelGroupLandMoney::impl::onMapButton() @@ -277,7 +324,7 @@ bool LLPanelGroupLandMoney::impl::applyContribution() new_contribution <= sqm_avail ) { // update group info and server - if(!gAgent.setGroupContribution(mGroupID, new_contribution)) + if(!gAgent.setGroupContribution(mPanel.mGroupID, new_contribution)) { // should never happen... llwarns << "Unable to set contribution." << llendl; @@ -304,7 +351,7 @@ int LLPanelGroupLandMoney::impl::getStoredContribution() LLGroupData group_data; group_data.mContribution = 0; - gAgent.getGroupData(mGroupID, group_data); + gAgent.getGroupData(mPanel.mGroupID, group_data); return group_data.mContribution; } @@ -403,7 +450,7 @@ void LLPanelGroupLandMoney::impl::processGroupLand(LLMessageSystem* msg) if ( trans_id != mTransID ) return; // This power was removed to make group roles simpler //if ( !gAgent.hasPowerInGroup(mGroupID, GP_LAND_VIEW_OWNED) ) return; - if (!gAgent.isInGroup(mGroupID)) return; + if (!gAgent.isInGroup(mPanel.mGroupID)) return; std::string name; std::string desc; @@ -487,25 +534,22 @@ void LLPanelGroupLandMoney::impl::processGroupLand(LLMessageSystem* msg) //** LLPanelGroupLandMoney Functions ** //************************************* -//static -void* LLPanelGroupLandMoney::createTab(void* data) -{ - LLUUID* group_id = static_cast<LLUUID*>(data); - return new LLPanelGroupLandMoney(*group_id); -} //static LLMap<LLUUID, LLPanelGroupLandMoney*> LLPanelGroupLandMoney::sGroupIDs; -LLPanelGroupLandMoney::LLPanelGroupLandMoney(const LLUUID& group_id) : - LLPanelGroupTab(group_id) +LLPanelGroupLandMoney::LLPanelGroupLandMoney() : + LLPanelGroupTab() { - mImplementationp = new impl(*this, group_id); + //FIXME - add setGroupID(); + mImplementationp = new impl(*this); //problem what if someone has both the group floater open and the finder //open to the same group? Some maps that map group ids to panels //will then only be working for the last panel for a given group id :( - LLPanelGroupLandMoney::sGroupIDs.addData(group_id, this); + + //FIXME - add to setGroupID() + //LLPanelGroupLandMoney::sGroupIDs.addData(group_id, this); } LLPanelGroupLandMoney::~LLPanelGroupLandMoney() @@ -719,8 +763,7 @@ BOOL LLPanelGroupLandMoney::postBuild() textp, tabcp, panelp, - loading_text, - mGroupID); + loading_text); } textp = getChild<LLTextEditor>("group_money_planning_text", true); @@ -737,8 +780,7 @@ BOOL LLPanelGroupLandMoney::postBuild() new LLGroupMoneyPlanningTabEventHandler(textp, tabcp, panelp, - loading_text, - mGroupID); + loading_text); } //pull out the widgets for the L$ sales tab @@ -759,8 +801,7 @@ BOOL LLPanelGroupLandMoney::postBuild() textp, tabcp, panelp, - loading_text, - mGroupID); + loading_text); } return LLPanelGroupTab::postBuild(); @@ -787,56 +828,15 @@ void LLPanelGroupLandMoney::processPlacesReply(LLMessageSystem* msg, void**) selfp->mImplementationp->processGroupLand(msg); } -//************************************************* -//** LLGroupMoneyTabEventHandler::impl Functions ** -//************************************************* - -class LLGroupMoneyTabEventHandler::impl -{ -public: - impl(LLButton* earlier_buttonp, - LLButton* later_buttonp, - LLTextEditor* text_editorp, - LLPanel* tabpanelp, - const std::string& loading_text, - const LLUUID& group_id, - S32 interval_length_days, - S32 max_interval_days); - ~impl(); - - bool getCanClickLater(); - bool getCanClickEarlier(); - - void updateButtons(); - -//member variables -public: - LLUUID mGroupID; - LLUUID mPanelID; - - LLPanel* mTabPanelp; - - int mIntervalLength; - int mMaxInterval; - int mCurrentInterval; - - LLTextEditor* mTextEditorp; - LLButton* mEarlierButtonp; - LLButton* mLaterButtonp; - std::string mLoadingText; -}; - -LLGroupMoneyTabEventHandler::impl::impl(LLButton* earlier_buttonp, +LLGroupMoneyTabEventHandlerImpl::LLGroupMoneyTabEventHandlerImpl(LLButton* earlier_buttonp, LLButton* later_buttonp, LLTextEditor* text_editorp, LLPanel* tabpanelp, const std::string& loading_text, - const LLUUID& group_id, S32 interval_length_days, S32 max_interval_days) { - mGroupID = group_id; mPanelID.generate(); mIntervalLength = interval_length_days; @@ -851,21 +851,21 @@ LLGroupMoneyTabEventHandler::impl::impl(LLButton* earlier_buttonp, mLoadingText = loading_text; } -LLGroupMoneyTabEventHandler::impl::~impl() +LLGroupMoneyTabEventHandlerImpl::~LLGroupMoneyTabEventHandlerImpl() { } -bool LLGroupMoneyTabEventHandler::impl::getCanClickEarlier() +bool LLGroupMoneyTabEventHandlerImpl::getCanClickEarlier() { return (mCurrentInterval < mMaxInterval); } -bool LLGroupMoneyTabEventHandler::impl::getCanClickLater() +bool LLGroupMoneyTabEventHandlerImpl::getCanClickLater() { return ( mCurrentInterval > 0 ); } -void LLGroupMoneyTabEventHandler::impl::updateButtons() +void LLGroupMoneyTabEventHandlerImpl::updateButtons() { if ( mEarlierButtonp ) { @@ -890,16 +890,14 @@ LLGroupMoneyTabEventHandler::LLGroupMoneyTabEventHandler(LLButton* earlier_butto LLTabContainer* tab_containerp, LLPanel* panelp, const std::string& loading_text, - const LLUUID& group_id, S32 interval_length_days, S32 max_interval_days) { - mImplementationp = new impl(earlier_buttonp, + mImplementationp = new LLGroupMoneyTabEventHandlerImpl(earlier_buttonp, later_buttonp, text_editorp, panelp, loading_text, - group_id, interval_length_days, max_interval_days); @@ -998,15 +996,13 @@ LLGroupMoneyDetailsTabEventHandler::LLGroupMoneyDetailsTabEventHandler(LLButton* LLTextEditor* text_editorp, LLTabContainer* tab_containerp, LLPanel* panelp, - const std::string& loading_text, - const LLUUID& group_id) + const std::string& loading_text) : LLGroupMoneyTabEventHandler(earlier_buttonp, later_buttonp, text_editorp, tab_containerp, panelp, loading_text, - group_id, SUMMARY_INTERVAL, SUMMARY_MAX) { @@ -1022,7 +1018,7 @@ void LLGroupMoneyDetailsTabEventHandler::requestData(LLMessageSystem* msg) msg->nextBlockFast(_PREHASH_AgentData); msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() ); - msg->addUUIDFast(_PREHASH_GroupID, mImplementationp->mGroupID ); + msg->addUUIDFast(_PREHASH_GroupID, mImplementationp->getGroupID() ); msg->nextBlockFast(_PREHASH_MoneyData); msg->addUUIDFast(_PREHASH_RequestID, mImplementationp->mPanelID ); msg->addS32Fast(_PREHASH_IntervalDays, mImplementationp->mIntervalLength ); @@ -1043,7 +1039,7 @@ void LLGroupMoneyDetailsTabEventHandler::processReply(LLMessageSystem* msg, { LLUUID group_id; msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_GroupID, group_id ); - if (mImplementationp->mGroupID != group_id) + if (mImplementationp->getGroupID() != group_id) { llwarns << "Group Account details not for this group!" << llendl; return; @@ -1133,15 +1129,13 @@ LLGroupMoneySalesTabEventHandler::LLGroupMoneySalesTabEventHandler(LLButton* ear LLTextEditor* text_editorp, LLTabContainer* tab_containerp, LLPanel* panelp, - const std::string& loading_text, - const LLUUID& group_id) + const std::string& loading_text) : LLGroupMoneyTabEventHandler(earlier_buttonp, later_buttonp, text_editorp, tab_containerp, panelp, loading_text, - group_id, SUMMARY_INTERVAL, SUMMARY_MAX) { @@ -1157,7 +1151,7 @@ void LLGroupMoneySalesTabEventHandler::requestData(LLMessageSystem* msg) msg->nextBlockFast(_PREHASH_AgentData); msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() ); - msg->addUUIDFast(_PREHASH_GroupID, mImplementationp->mGroupID ); + msg->addUUIDFast(_PREHASH_GroupID, mImplementationp->getGroupID() ); msg->nextBlockFast(_PREHASH_MoneyData); msg->addUUIDFast(_PREHASH_RequestID, mImplementationp->mPanelID ); msg->addS32Fast(_PREHASH_IntervalDays, mImplementationp->mIntervalLength ); @@ -1178,7 +1172,7 @@ void LLGroupMoneySalesTabEventHandler::processReply(LLMessageSystem* msg, { LLUUID group_id; msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_GroupID, group_id ); - if (mImplementationp->mGroupID != group_id) + if (mImplementationp->getGroupID() != group_id) { llwarns << "Group Account Transactions not for this group!" << llendl; return; @@ -1305,15 +1299,13 @@ void LLPanelGroupLandMoney::processGroupAccountTransactionsReply(LLMessageSystem LLGroupMoneyPlanningTabEventHandler::LLGroupMoneyPlanningTabEventHandler(LLTextEditor* text_editorp, LLTabContainer* tab_containerp, LLPanel* panelp, - const std::string& loading_text, - const LLUUID& group_id) + const std::string& loading_text) : LLGroupMoneyTabEventHandler(NULL, NULL, text_editorp, tab_containerp, panelp, loading_text, - group_id, SUMMARY_INTERVAL, SUMMARY_MAX) { @@ -1329,7 +1321,7 @@ void LLGroupMoneyPlanningTabEventHandler::requestData(LLMessageSystem* msg) msg->nextBlockFast(_PREHASH_AgentData); msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() ); - msg->addUUIDFast(_PREHASH_GroupID, mImplementationp->mGroupID ); + msg->addUUIDFast(_PREHASH_GroupID, mImplementationp->getGroupID() ); msg->nextBlockFast(_PREHASH_MoneyData); msg->addUUIDFast(_PREHASH_RequestID, mImplementationp->mPanelID ); msg->addS32Fast(_PREHASH_IntervalDays, mImplementationp->mIntervalLength); @@ -1350,7 +1342,7 @@ void LLGroupMoneyPlanningTabEventHandler::processReply(LLMessageSystem* msg, { LLUUID group_id; msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_GroupID, group_id ); - if (mImplementationp->mGroupID != group_id) + if (mImplementationp->getGroupID() != group_id) { llwarns << "Group Account Summary received not for this group!" << llendl; return; @@ -1468,3 +1460,141 @@ void LLPanelGroupLandMoney::processGroupAccountSummaryReply(LLMessageSystem* msg self->processReply(msg, data); } + +void LLPanelGroupLandMoney::setGroupID(const LLUUID& id) +{ + LLPanelGroupLandMoney::sGroupIDs.removeData(mGroupID); + LLPanelGroupTab::setGroupID(id); + LLPanelGroupLandMoney::sGroupIDs.addData(mGroupID, this); + + + bool can_view = gAgent.isInGroup(mGroupID); + + mImplementationp->mGroupOverLimitIconp = + getChild<LLIconCtrl>("group_over_limit_icon"); + mImplementationp->mGroupOverLimitTextp = + getChild<LLTextBox>("group_over_limit_text"); + + mImplementationp->mYourContributionEditorp + = getChild<LLLineEditor>("your_contribution_line_editor"); + if ( mImplementationp->mYourContributionEditorp ) + { + LLLineEditor* editor = mImplementationp->mYourContributionEditorp; + + editor->setCommitCallback(mImplementationp->contributionCommitCallback, this); + editor->setKeystrokeCallback(mImplementationp->contributionKeystrokeCallback, this); + } + + mImplementationp->mMapButtonp = getChild<LLButton>("map_button"); + + mImplementationp->mGroupParcelsp = + getChild<LLScrollListCtrl>("group_parcel_list"); + + if ( mImplementationp->mGroupParcelsp ) + { + mImplementationp->mGroupParcelsp->setCommitCallback(boost::bind(&LLButton::setEnabled, mImplementationp->mMapButtonp, true)); + mImplementationp->mGroupParcelsp->setCommitOnSelectionChange(true); + } + + mImplementationp->mCantViewParcelsText = getString("cant_view_group_land_text"); + mImplementationp->mCantViewAccountsText = getString("cant_view_group_accounting_text"); + + if ( mImplementationp->mMapButtonp ) + { + mImplementationp->mMapButtonp->setClickedCallback(LLPanelGroupLandMoney::impl::mapCallback, mImplementationp); + } + + if ( mImplementationp->mGroupOverLimitTextp ) + { + mImplementationp->mGroupOverLimitTextp->setVisible(FALSE); + } + + if ( mImplementationp->mGroupOverLimitIconp ) + { + mImplementationp->mGroupOverLimitIconp->setVisible(FALSE); + } + + if ( !can_view ) + { + if ( mImplementationp->mGroupParcelsp ) + { + mImplementationp->mGroupParcelsp->setCommentText( + mImplementationp->mCantViewParcelsText); + mImplementationp->mGroupParcelsp->setEnabled(FALSE); + } + } + + + + LLButton* earlierp, *laterp; + LLTextEditor* textp; + LLPanel* panelp; + + LLTabContainer* tabcp = getChild<LLTabContainer>("group_money_tab_container"); + + if ( tabcp ) + { + S32 i; + S32 tab_count = tabcp->getTabCount(); + + for (i = tab_count - 1; i >=0; --i) + { + tabcp->enableTabButton(i, can_view ); + } + } + + std::string loading_text = getString("loading_txt"); + + //pull out the widgets for the L$ details tab + earlierp = getChild<LLButton>("earlier_details_button", true); + laterp = getChild<LLButton>("later_details_button", true); + textp = getChild<LLTextEditor>("group_money_details_text", true); + panelp = getChild<LLPanel>("group_money_details_tab", true); + + if ( !can_view ) + { + textp->setText(mImplementationp->mCantViewAccountsText); + } + else + { + if(mImplementationp->mMoneyDetailsTabEHp == 0) + mImplementationp->mMoneyDetailsTabEHp = new LLGroupMoneyDetailsTabEventHandler(earlierp,laterp,textp,tabcp,panelp,loading_text); + mImplementationp->mMoneyDetailsTabEHp->setGroupID(mGroupID); + } + + textp = getChild<LLTextEditor>("group_money_planning_text", true); + + + if ( !can_view ) + { + textp->setText(mImplementationp->mCantViewAccountsText); + } + else + { + panelp = getChild<LLPanel>("group_money_planning_tab", true); + if(mImplementationp->mMoneyPlanningTabEHp == 0) + mImplementationp->mMoneyPlanningTabEHp = new LLGroupMoneyPlanningTabEventHandler(textp,tabcp,panelp,loading_text); + mImplementationp->mMoneyPlanningTabEHp->setGroupID(mGroupID); + } + + //pull out the widgets for the L$ sales tab + textp = getChild<LLTextEditor>("group_money_sales_text", true); + + + if ( !can_view ) + { + textp->setText(mImplementationp->mCantViewAccountsText); + } + else + { + earlierp = getChild<LLButton>("earlier_sales_button", true); + laterp = getChild<LLButton>("later_sales_button", true); + panelp = getChild<LLPanel>("group_money_sales_tab", true); + if(mImplementationp->mMoneySalesTabEHp == NULL) + mImplementationp->mMoneySalesTabEHp = new LLGroupMoneySalesTabEventHandler(earlierp,laterp,textp,tabcp,panelp,loading_text); + mImplementationp->mMoneySalesTabEHp->setGroupID(mGroupID); + } + + activate(); +} + diff --git a/indra/newview/llpanelgrouplandmoney.h b/indra/newview/llpanelgrouplandmoney.h index 748485745b..73c52cdf2e 100644 --- a/indra/newview/llpanelgrouplandmoney.h +++ b/indra/newview/llpanelgrouplandmoney.h @@ -44,13 +44,11 @@ class LLPanelGroupLandMoney : public LLPanelGroupTab { public: - LLPanelGroupLandMoney(const LLUUID& group_id); + LLPanelGroupLandMoney(); virtual ~LLPanelGroupLandMoney(); virtual BOOL postBuild(); virtual BOOL isVisibleByAgent(LLAgent* agentp); - static void* createTab(void* data); - virtual void activate(); virtual bool needsApply(std::string& mesg); virtual bool apply(std::string& mesg); @@ -64,6 +62,8 @@ public: static void processGroupAccountDetailsReply(LLMessageSystem* msg, void** data); static void processGroupAccountTransactionsReply(LLMessageSystem* msg, void** data); static void processGroupAccountSummaryReply(LLMessageSystem* msg, void** data); + + virtual void setGroupID(const LLUUID& id); protected: class impl; diff --git a/indra/newview/llpanelgroupnotices.cpp b/indra/newview/llpanelgroupnotices.cpp index 15ae374447..f06342ebfc 100644 --- a/indra/newview/llpanelgroupnotices.cpp +++ b/indra/newview/llpanelgroupnotices.cpp @@ -58,6 +58,9 @@ #include "llviewermessage.h" #include "llnotifications.h" +static LLRegisterPanelClassWrapper<LLPanelGroupNotices> t_panel_group_notices("panel_group_notices"); + + ///////////////////////// // LLPanelGroupNotices // ///////////////////////// @@ -207,12 +210,13 @@ std::string build_notice_date(const U32& the_time) return dateStr; } -LLPanelGroupNotices::LLPanelGroupNotices(const LLUUID& group_id) : - LLPanelGroupTab(group_id), +LLPanelGroupNotices::LLPanelGroupNotices() : + LLPanelGroupTab(), mInventoryItem(NULL), mInventoryOffer(NULL) { - sInstances[group_id] = this; + + } LLPanelGroupNotices::~LLPanelGroupNotices() @@ -228,12 +232,6 @@ LLPanelGroupNotices::~LLPanelGroupNotices() } } -// static -void* LLPanelGroupNotices::createTab(void* data) -{ - LLUUID* group_id = static_cast<LLUUID*>(data); - return new LLPanelGroupNotices(*group_id); -} BOOL LLPanelGroupNotices::isVisibleByAgent(LLAgent* agentp) { @@ -590,3 +588,17 @@ void LLPanelGroupNotices::arrangeNoticeView(ENoticeView view_type) mBtnOpenAttachment->setEnabled(FALSE); } } +void LLPanelGroupNotices::setGroupID(const LLUUID& id) +{ + sInstances.erase(mGroupID); + LLPanelGroupTab::setGroupID(id); + sInstances[mGroupID] = this; + + mBtnNewMessage->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_NOTICES_SEND)); + + LLGroupDropTarget* target = getChild<LLGroupDropTarget> ("drop_target"); + target->setPanel (this); + target->setGroup (mGroupID); + + activate(); +} diff --git a/indra/newview/llpanelgroupnotices.h b/indra/newview/llpanelgroupnotices.h index a0712f1770..c41a5f501b 100644 --- a/indra/newview/llpanelgroupnotices.h +++ b/indra/newview/llpanelgroupnotices.h @@ -47,11 +47,10 @@ class LLScrollListCtrl; class LLPanelGroupNotices : public LLPanelGroupTab { public: - LLPanelGroupNotices(const LLUUID& group_id); + LLPanelGroupNotices(); virtual ~LLPanelGroupNotices(); // LLPanelGroupTab - static void* createTab(void* data); virtual void activate(); //virtual bool needsApply(std::string& mesg); //virtual bool apply(std::string& mesg); @@ -70,6 +69,8 @@ public: const std::string& inventory_name, LLOfferInfo* inventory_offer); + virtual void setGroupID(const LLUUID& id); + private: static void onClickRemoveAttachment(void* data); static void onClickOpenAttachment(void* data); diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp index 50e1f84cad..ab614fea53 100644 --- a/indra/newview/llpanelgrouproles.cpp +++ b/indra/newview/llpanelgrouproles.cpp @@ -55,6 +55,8 @@ #include "roles_constants.h" +static LLRegisterPanelClassWrapper<LLPanelGroupRoles> t_panel_group_roles("panel_group_roles"); + bool agentCanRemoveFromRole(const LLUUID& group_id, const LLUUID& role_id) { @@ -108,14 +110,9 @@ bool agentCanAddToRole(const LLUUID& group_id, } // static -void* LLPanelGroupRoles::createTab(void* data) -{ - LLUUID* group_id = static_cast<LLUUID*>(data); - return new LLPanelGroupRoles(*group_id); -} -LLPanelGroupRoles::LLPanelGroupRoles(const LLUUID& group_id) -: LLPanelGroupTab(group_id), +LLPanelGroupRoles::LLPanelGroupRoles() +: LLPanelGroupTab(), mCurrentTab(NULL), mRequestedTab( NULL ), mSubTabContainer( NULL ), @@ -126,13 +123,6 @@ LLPanelGroupRoles::LLPanelGroupRoles(const LLUUID& group_id) LLPanelGroupRoles::~LLPanelGroupRoles() { - int i; - for (i = 0; i < mSubTabContainer->getTabCount(); ++i) - { - LLPanelGroupSubTab* subtabp = (LLPanelGroupSubTab*) mSubTabContainer->getPanelByIndex(i); - - subtabp->removeObserver(this); - } } BOOL LLPanelGroupRoles::postBuild() @@ -161,7 +151,7 @@ BOOL LLPanelGroupRoles::postBuild() if (!subtabp->postBuildSubTab(this)) return FALSE; - subtabp->addObserver(this); + //subtabp->addObserver(this); } // Set the current tab to whatever is currently being shown. @@ -387,7 +377,8 @@ std::string LLPanelGroupRoles::getHelpText() const void LLPanelGroupRoles::update(LLGroupChange gc) { if (mGroupID.isNull()) return; - + + LLPanelGroupTab* panelp = (LLPanelGroupTab*) mSubTabContainer->getCurrentPanel(); if (panelp) { @@ -397,6 +388,7 @@ void LLPanelGroupRoles::update(LLGroupChange gc) { llwarns << "LLPanelGroupRoles::update() -- No subtab to update!" << llendl; } + } void LLPanelGroupRoles::activate() @@ -464,17 +456,12 @@ BOOL LLPanelGroupRoles::hasModal() return panelp->hasModal(); } -// PanelGroupTab observer trigger -void LLPanelGroupRoles::tabChanged() -{ - notifyObservers(); -} //////////////////////////// // LLPanelGroupSubTab //////////////////////////// -LLPanelGroupSubTab::LLPanelGroupSubTab(const LLUUID& group_id) -: LLPanelGroupTab(group_id), +LLPanelGroupSubTab::LLPanelGroupSubTab() +: LLPanelGroupTab(), mHeader(NULL), mFooter(NULL), mSearchLineEditor(NULL), @@ -847,15 +834,11 @@ void LLPanelGroupSubTab::setFooterEnabled(BOOL enable) // LLPanelGroupMembersSubTab //////////////////////////// -// static -void* LLPanelGroupMembersSubTab::createTab(void* data) -{ - LLUUID* group_id = static_cast<LLUUID*>(data); - return new LLPanelGroupMembersSubTab(*group_id); -} -LLPanelGroupMembersSubTab::LLPanelGroupMembersSubTab(const LLUUID& group_id) -: LLPanelGroupSubTab(group_id), +static LLRegisterPanelClassWrapper<LLPanelGroupMembersSubTab> t_panel_group_members_subtab("panel_group_members_subtab"); + +LLPanelGroupMembersSubTab::LLPanelGroupMembersSubTab() +: LLPanelGroupSubTab(), mMembersList(NULL), mAssignedRolesList(NULL), mAllowedActionsList(NULL), @@ -1708,15 +1691,10 @@ void LLPanelGroupMembersSubTab::updateMembers() // LLPanelGroupRolesSubTab //////////////////////////// -// static -void* LLPanelGroupRolesSubTab::createTab(void* data) -{ - LLUUID* group_id = static_cast<LLUUID*>(data); - return new LLPanelGroupRolesSubTab(*group_id); -} +static LLRegisterPanelClassWrapper<LLPanelGroupRolesSubTab> t_panel_group_roles_subtab("panel_group_roles_subtab"); -LLPanelGroupRolesSubTab::LLPanelGroupRolesSubTab(const LLUUID& group_id) - : LLPanelGroupSubTab(group_id), +LLPanelGroupRolesSubTab::LLPanelGroupRolesSubTab() + : LLPanelGroupSubTab(), mRolesList(NULL), mAssignedMembersList(NULL), mAllowedActionsList(NULL), @@ -2418,15 +2396,11 @@ void LLPanelGroupRolesSubTab::saveRoleChanges() // LLPanelGroupActionsSubTab //////////////////////////// -// static -void* LLPanelGroupActionsSubTab::createTab(void* data) -{ - LLUUID* group_id = static_cast<LLUUID*>(data); - return new LLPanelGroupActionsSubTab(*group_id); -} +static LLRegisterPanelClassWrapper<LLPanelGroupActionsSubTab> t_panel_group_actions_subtab("panel_group_actions_subtab"); -LLPanelGroupActionsSubTab::LLPanelGroupActionsSubTab(const LLUUID& group_id) -: LLPanelGroupSubTab(group_id) + +LLPanelGroupActionsSubTab::LLPanelGroupActionsSubTab() +: LLPanelGroupSubTab() { } @@ -2598,3 +2572,30 @@ void LLPanelGroupActionsSubTab::handleActionSelect() LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mGroupID); } } +void LLPanelGroupRoles::setGroupID(const LLUUID& id) +{ + LLPanelGroupTab::setGroupID(id); + + LLPanelGroupMembersSubTab* group_members_tab = findChild<LLPanelGroupMembersSubTab>("members_sub_tab"); + LLPanelGroupRolesSubTab* group_roles_tab = findChild<LLPanelGroupRolesSubTab>("roles_sub_tab"); + LLPanelGroupActionsSubTab* group_actions_tab = findChild<LLPanelGroupActionsSubTab>("actions_sub_tab"); + + if(group_members_tab) group_members_tab->setGroupID(id); + if(group_roles_tab) group_roles_tab->setGroupID(id); + if(group_actions_tab) group_actions_tab->setGroupID(id); + + activate(); + + if (!mSubTabContainer) return ; + + // Hook up each sub-tabs callback and widgets. + for (S32 i = 0; i < mSubTabContainer->getTabCount(); ++i) + { + LLPanel* panel = mSubTabContainer->getPanelByIndex(i); + LLPanelGroupSubTab* subtabp = dynamic_cast<LLPanelGroupSubTab*>(panel); + if (subtabp) + subtabp->postBuildSubTab(this); + } +} + + diff --git a/indra/newview/llpanelgrouproles.h b/indra/newview/llpanelgrouproles.h index 3ceaae1313..9519263bba 100644 --- a/indra/newview/llpanelgrouproles.h +++ b/indra/newview/llpanelgrouproles.h @@ -49,11 +49,10 @@ class LLTextEditor; typedef std::map<std::string,std::string> icon_map_t; -class LLPanelGroupRoles : public LLPanelGroupTab, - public LLPanelGroupTabObserver +class LLPanelGroupRoles : public LLPanelGroupTab { public: - LLPanelGroupRoles(const LLUUID& group_id); + LLPanelGroupRoles(); virtual ~LLPanelGroupRoles(); // Allow sub tabs to ask for sibling controls. @@ -64,7 +63,7 @@ public: virtual BOOL postBuild(); virtual BOOL isVisibleByAgent(LLAgent* agentp); - static void* createTab(void* data); + void handleClickSubTab(); // Checks if the current tab needs to be applied, and tries to switch to the requested tab. @@ -87,8 +86,7 @@ public: virtual void cancel(); virtual void update(LLGroupChange gc); - // PanelGroupTab observer trigger - virtual void tabChanged(); + virtual void setGroupID(const LLUUID& id); protected: LLPanelGroupTab* mCurrentTab; @@ -104,7 +102,7 @@ protected: class LLPanelGroupSubTab : public LLPanelGroupTab { public: - LLPanelGroupSubTab(const LLUUID& group_id); + LLPanelGroupSubTab(); virtual ~LLPanelGroupSubTab(); virtual BOOL postBuild(); @@ -164,13 +162,11 @@ protected: class LLPanelGroupMembersSubTab : public LLPanelGroupSubTab { public: - LLPanelGroupMembersSubTab(const LLUUID& group_id); + LLPanelGroupMembersSubTab(); virtual ~LLPanelGroupMembersSubTab(); virtual BOOL postBuildSubTab(LLView* root); - static void* createTab(void* data); - static void onMemberSelect(LLUICtrl*, void*); void handleMemberSelect(); @@ -229,13 +225,11 @@ protected: class LLPanelGroupRolesSubTab : public LLPanelGroupSubTab { public: - LLPanelGroupRolesSubTab(const LLUUID& group_id); + LLPanelGroupRolesSubTab(); virtual ~LLPanelGroupRolesSubTab(); virtual BOOL postBuildSubTab(LLView* root); - static void* createTab(void* data); - virtual void activate(); virtual void deactivate(); virtual bool needsApply(std::string& mesg); @@ -290,12 +284,11 @@ protected: class LLPanelGroupActionsSubTab : public LLPanelGroupSubTab { public: - LLPanelGroupActionsSubTab(const LLUUID& group_id); + LLPanelGroupActionsSubTab(); virtual ~LLPanelGroupActionsSubTab(); virtual BOOL postBuildSubTab(LLView* root); - static void* createTab(void* data); virtual void activate(); virtual void deactivate(); diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index 0d50d7c781..a8e3fd3195 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -638,6 +638,11 @@ void LLPanelPeople::onTabSelected(const LLSD& param) std::string tab_name = getChild<LLPanel>(param.asString())->getName(); mNearbyListUpdater->setActive(tab_name == NEARBY_TAB_NAME); updateButtons(); + + if (GROUP_TAB_NAME == tab_name) + mFilterEditor->setLabel(getString("groups_filter_label")); + else + mFilterEditor->setLabel(getString("people_filter_label")); } void LLPanelPeople::onAvatarListDoubleClicked(LLAvatarList* list) @@ -669,9 +674,7 @@ void LLPanelPeople::onAddFriendButtonClicked() LLUUID id = getCurrentItemID(); if (id.notNull()) { - std::string name; - gCacheName->getFullName(id, name); - LLAvatarActions::requestFriendshipDialog(id, name); + LLAvatarActions::requestFriendshipDialog(id); } } @@ -693,9 +696,7 @@ void LLPanelPeople::onDeleteFriendButtonClicked() void LLPanelPeople::onGroupInfoButtonClicked() { - LLUUID group_id = getCurrentItemID(); - if (group_id.notNull()) - LLGroupActions::info(group_id); + LLGroupActions::show(getCurrentItemID()); } void LLPanelPeople::onChatButtonClicked() @@ -763,7 +764,7 @@ void LLPanelPeople::onGroupPlusMenuItemClicked(const LLSD& userdata) if (chosen_item == "join_group") LLGroupActions::search(); else if (chosen_item == "new_group") - LLGroupActions::create(); + LLGroupActions::createGroup(); } void LLPanelPeople::onCallButtonClicked() diff --git a/indra/newview/llpanelpermissions.cpp b/indra/newview/llpanelpermissions.cpp index 19aef93d7e..d515b03ea9 100644 --- a/indra/newview/llpanelpermissions.cpp +++ b/indra/newview/llpanelpermissions.cpp @@ -56,7 +56,6 @@ #include "llcombobox.h" #include "lluiconstants.h" #include "lldbstrings.h" -#include "llfloatergroupinfo.h" #include "llfloatergroups.h" #include "llfloaterreg.h" #include "llavataractions.h" @@ -65,6 +64,7 @@ #include "lluictrlfactory.h" #include "llspinctrl.h" #include "roles_constants.h" +#include "llgroupactions.h" ///---------------------------------------------------------------------------- /// Class llpanelpermissions @@ -820,7 +820,7 @@ void LLPanelPermissions::onClickOwner(void *data) { LLUUID group_id; LLSelectMgr::getInstance()->selectGetGroup(group_id); - LLFloaterGroupInfo::showFromUUID(group_id); + LLGroupActions::show(group_id); } else { diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp index e8d6ff9ec9..afcd8c735c 100644 --- a/indra/newview/llpanelpicks.cpp +++ b/indra/newview/llpanelpicks.cpp @@ -57,12 +57,13 @@ static const std::string XML_PICKS_LIST = "back_panel"; #define PICK_ITEMS_BETWEEN 5 +static LLRegisterPanelClassWrapper<LLPanelPicks> t_panel_picks("panel_picks"); //----------------------------------------------------------------------------- // LLPanelPicks //----------------------------------------------------------------------------- LLPanelPicks::LLPanelPicks() -: LLPanelProfileTab(LLUUID::null), +: LLPanelProfileTab(), mPopupMenu(NULL), mSelectedPickItem(NULL), mProfilePanel(NULL), @@ -100,7 +101,6 @@ void LLPanelPicks::processProperties(void* data, EAvatarProcessorType type) childSetTextArg("pick_title", "[NAME]",name); LLView* picks_list = getPicksList(); - if(!picks_list) return; // to restore selection of the same item later LLUUID pick_id_selected(LLUUID::null); @@ -131,7 +131,7 @@ void LLPanelPicks::processProperties(void* data, EAvatarProcessorType type) picture->setPickId(pick_id); picture->setCreatorId(getAvatarId()); - LLAvatarPropertiesProcessor::instance().addObserver(mAvatarId, picture); + LLAvatarPropertiesProcessor::instance().addObserver(getAvatarId(), picture); picture->update(); mPickItemList.push_back(picture); if (pick_id_selected != LLUUID::null && @@ -152,14 +152,11 @@ void LLPanelPicks::processProperties(void* data, EAvatarProcessorType type) void LLPanelPicks::clear() { LLView* scroll = getPicksList(); - if(scroll) + picture_list_t::const_iterator it = mPickItemList.begin(); + for(; mPickItemList.end() != it; ++it) { - picture_list_t::const_iterator it = mPickItemList.begin(); - for(; mPickItemList.end() != it; ++it) - { - scroll->removeChild(*it); - delete *it; - } + scroll->removeChild(*it); + delete *it; } mPickItemList.clear(); mSelectedPickItem = NULL; @@ -225,7 +222,7 @@ void LLPanelPicks::reshapePickItem(LLView* const pick_item, const S32 last_botto LLView* LLPanelPicks::getPicksList() const { - return getChild<LLView>(XML_PICKS_LIST, TRUE, FALSE); + return getChild<LLView>(XML_PICKS_LIST); } BOOL LLPanelPicks::postBuild() @@ -261,6 +258,8 @@ void LLPanelPicks::onOpen(const LLSD& key) // Disable buttons when viewing profile for first time if(getAvatarId() != id) { + clear(); + childSetEnabled(XML_BTN_INFO,FALSE); childSetEnabled(XML_BTN_TELEPORT,FALSE); childSetEnabled(XML_BTN_SHOW_ON_MAP,FALSE); @@ -373,7 +372,7 @@ void LLPanelPicks::updateButtons() int picks_num = mPickItemList.size(); childSetEnabled(XML_BTN_INFO, picks_num > 0); - if (mAvatarId == gAgentID) + if (getAvatarId() == gAgentID) { childSetEnabled(XML_BTN_NEW, picks_num < MAX_AVATAR_PICKS); childSetEnabled(XML_BTN_DELETE, picks_num > 0); @@ -403,12 +402,14 @@ void LLPanelPicks::setSelectedPickItem(LLPickItem* item) BOOL LLPanelPicks::isMouseInPick( S32 x, S32 y ) { - LLScrollContainer* scroll = getChild<LLScrollContainer>("profile_scroll"); - if (!scroll->parentPointInView(x, y)) return FALSE; - S32 x_l = x; S32 y_l = y; + if(!getChild<LLUICtrl>("profile_scroll")->getRect().pointInRect(x, y)) + { + return FALSE; + } + picture_list_t::const_iterator it = mPickItemList.begin(); for(; mPickItemList.end() != it; ++it) { @@ -516,11 +517,8 @@ void LLPickItem::init(LLPickData* pick_data) mPosGlobal = pick_data->pos_global; mLocation = pick_data->location_text; - LLTextureCtrl* picture = getChild<LLTextureCtrl>("picture", TRUE, FALSE); - if (picture) - { - picture->setImageAssetID(pick_data->snapshot_id); - } + LLTextureCtrl* picture = getChild<LLTextureCtrl>("picture"); + picture->setImageAssetID(pick_data->snapshot_id); } void LLPickItem::setPickName(const std::string& name) diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp index a2d491c2cf..0931333ed9 100644 --- a/indra/newview/llpanelplaceinfo.cpp +++ b/indra/newview/llpanelplaceinfo.cpp @@ -115,7 +115,7 @@ BOOL LLPanelPlaceInfo::postBuild() mScrollingPanel = getChild<LLPanel>("scrolling_panel"); mInfoPanel = getChild<LLPanel>("info_panel"); mMediaPanel = getChild<LLMediaPanel>("media_panel"); - if (!(mMediaPanel && mInfoPanel && mScrollingPanel)) + if (!mMediaPanel) return FALSE; return TRUE; @@ -241,9 +241,6 @@ void LLPanelPlaceInfo::setParcelID(const LLUUID& parcel_id) void LLPanelPlaceInfo::setInfoType(INFO_TYPE type) { - if (!mInfoPanel) - return; - if (type != PLACE) toggleMediaPanel(FALSE); @@ -291,7 +288,7 @@ BOOL LLPanelPlaceInfo::isMediaPanelVisible() void LLPanelPlaceInfo::toggleMediaPanel(BOOL visible) { - if (!(mMediaPanel && mInfoPanel)) + if (!mMediaPanel) return; if (visible) @@ -439,7 +436,7 @@ void LLPanelPlaceInfo::displayAgentParcelInfo() LLParcelData parcel_data; parcel_data.desc = parcel->getDesc(); - parcel_data.flags = parcel->getParcelFlags(); + parcel_data.flags = region->getSimAccess(); parcel_data.name = parcel->getName(); parcel_data.sim_name = gAgent.getRegion()->getName(); parcel_data.snapshot_id = parcel->getSnapshotID(); diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp index 191c43791d..7461d150c8 100644 --- a/indra/newview/llpanelplaces.cpp +++ b/indra/newview/llpanelplaces.cpp @@ -293,7 +293,7 @@ void LLPanelPlaces::onTeleportButtonClicked() payload["asset_id"] = mItem->getAssetUUID(); LLNotifications::instance().add("TeleportFromLandmark", LLSD(), payload); } - else if (mPlaceInfoType == "remote_place") + else if (mPlaceInfoType == "remote_place" || mPlaceInfoType == "agent") { LLFloaterWorldMap* worldmap_instance = LLFloaterWorldMap::getInstance(); if (!mPosGlobal.isExactlyZero() && worldmap_instance) @@ -380,6 +380,11 @@ void LLPanelPlaces::toggleMediaPanel() return; mPlaceInfo->toggleMediaPanel(!mPlaceInfo->isMediaPanelVisible()); + + // Refresh the current place info because + // the media panel controls can't refer to + // the remote parcel media. + onOpen(LLSD().insert("type", "agent")); } void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible) @@ -445,10 +450,14 @@ void LLPanelPlaces::onAgentParcelChange() if (!mPlaceInfo) return; - if (mPlaceInfo->getVisible() && (mPlaceInfoType == "agent" || mPlaceInfoType == "create_landmark")) + if (mPlaceInfo->getVisible() && mPlaceInfoType == "create_landmark") { onOpen(LLSD().insert("type", mPlaceInfoType)); } + else if (mPlaceInfo->isMediaPanelVisible()) + { + onOpen(LLSD().insert("type", "agent")); + } else { updateVerbs(); @@ -463,6 +472,7 @@ void LLPanelPlaces::updateVerbs() bool is_place_info_visible = mPlaceInfo->getVisible(); bool is_agent_place_info_visible = mPlaceInfoType == "agent"; bool is_create_landmark_visible = mPlaceInfoType == "create_landmark"; + bool is_media_panel_visible = mPlaceInfo->isMediaPanelVisible(); mTeleportBtn->setVisible(!is_create_landmark_visible); mShareBtn->setVisible(!is_create_landmark_visible); @@ -477,15 +487,18 @@ void LLPanelPlaces::updateVerbs() { if (is_agent_place_info_visible) { - // We don't need to teleport to the current location so disable the button - mTeleportBtn->setEnabled(FALSE); + // We don't need to teleport to the current location + // so check if the location is not within the current parcel. + mTeleportBtn->setEnabled(!is_media_panel_visible && + !mPosGlobal.isExactlyZero() && + !LLViewerParcelMgr::getInstance()->inAgentParcel(mPosGlobal)); } else if (mPlaceInfoType == "landmark" || mPlaceInfoType == "remote_place") { mTeleportBtn->setEnabled(TRUE); } - mShowOnMapBtn->setEnabled(TRUE); + mShowOnMapBtn->setEnabled(!is_media_panel_visible); } else { diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index f97105caa8..017a7312a1 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -32,20 +32,16 @@ #include "llviewerprecompiledheaders.h" #include "llpanelprofile.h" -#include "lltabcontainer.h" -#include "llpanelpicks.h" + #include "llagent.h" -#include "llcommandhandler.h" #include "llavataractions.h" +#include "llcommandhandler.h" +#include "llpanelpicks.h" +#include "lltabcontainer.h" static const std::string PANEL_PICKS = "panel_picks"; -static const std::string PANEL_NOTES = "panel_notes"; static const std::string PANEL_PROFILE = "panel_profile"; -static LLRegisterPanelClassWrapper<LLPanelAvatarProfile> t_panel_profile(PANEL_PROFILE); -static LLRegisterPanelClassWrapper<LLPanelPicks> t_panel_picks(PANEL_PICKS); - - class LLAgentHandler : public LLCommandHandler { public: @@ -74,34 +70,45 @@ LLAgentHandler gAgentHandler; LLPanelProfile::LLPanelProfile() -: LLPanel(), - mTabContainer(NULL) -{ -} - -LLPanelProfile::~LLPanelProfile() + : LLPanel() + , mTabCtrl(NULL) + , mAvatarId(LLUUID::null) { } BOOL LLPanelProfile::postBuild() { - mTabContainer = getChild<LLTabContainer>("tabs"); - mTabContainer->setCommitCallback(boost::bind(&LLPanelProfile::onTabSelected, this, _2)); + mTabCtrl = getChild<LLTabContainer>("tabs"); + + getTabCtrl()->setCommitCallback(boost::bind(&LLPanelProfile::onTabSelected, this, _2)); LLPanelPicks* panel_picks = getChild<LLPanelPicks>(PANEL_PICKS); panel_picks->setProfilePanel(this); - mTabs[PANEL_PICKS] = panel_picks; - mTabs[PANEL_PROFILE] = getChild<LLPanelAvatarProfile>(PANEL_PROFILE); + getTabContainer()[PANEL_PICKS] = panel_picks; + getTabContainer()[PANEL_PROFILE] = getChild<LLPanelAvatarProfile>(PANEL_PROFILE); return TRUE; } +void LLPanelProfile::onOpen(const LLSD& key) +{ + if (key.has("open_tab_name")) + { + // onOpen from selected panel will be called from onTabSelected callback + getTabCtrl()->selectTabByName(key["open_tab_name"]); + } + else + { + getTabCtrl()->getCurrentPanel()->onOpen(getAvatarId()); + } +} + //*TODO redo panel toggling void LLPanelProfile::togglePanel(LLPanel* panel) { // TRUE - we need to open/expand "panel" - BOOL expand = this->getChildList()->back() != panel; // mTabContainer->getVisible(); + bool expand = getChildList()->back() != panel; // mTabCtrl->getVisible(); if (expand) { @@ -128,29 +135,31 @@ void LLPanelProfile::togglePanel(LLPanel* panel) else { this->setAllChildrenVisible(TRUE); - if (panel->getParent() == this) removeChild(panel); - sendChildToBack(mTabContainer); - mTabContainer->getCurrentPanel()->onOpen(mAvatarId); + if (panel->getParent() == this) + { + removeChild(panel); + } + sendChildToBack(getTabCtrl()); + getTabCtrl()->getCurrentPanel()->onOpen(getAvatarId()); } } - void LLPanelProfile::onTabSelected(const LLSD& param) { std::string tab_name = param.asString(); - if (NULL != mTabs[tab_name]) + if (NULL != getTabContainer()[tab_name]) { - mTabs[tab_name]->onOpen(mAvatarId); + getTabContainer()[tab_name]->onOpen(getAvatarId()); } } void LLPanelProfile::setAllChildrenVisible(BOOL visible) { const child_list_t* child_list = getChildList(); - for (child_list_const_iter_t child_it = child_list->begin(); child_it != child_list->end(); ++child_it) + child_list_const_iter_t child_it = child_list->begin(); + for (; child_it != child_list->end(); ++child_it) { LLView* viewp = *child_it; viewp->setVisible(visible); } } - diff --git a/indra/newview/llpanelprofile.h b/indra/newview/llpanelprofile.h index 2f6d53a859..b55963ec4a 100644 --- a/indra/newview/llpanelprofile.h +++ b/indra/newview/llpanelprofile.h @@ -39,34 +39,42 @@ class LLTabContainer; +/** +* Base class for Profile View and Me Profile. +*/ class LLPanelProfile : public LLPanel { LOG_CLASS(LLPanelProfile); public: - virtual BOOL postBuild(); + /*virtual*/ BOOL postBuild(); - virtual void onOpen(const LLSD& key) {}; + /*virtual*/ void onOpen(const LLSD& key); virtual void togglePanel(LLPanel*); protected: + LLPanelProfile(); - ~LLPanelProfile(); - void onTabSelected(const LLSD& param); + virtual void onTabSelected(const LLSD& param); + + virtual void setAllChildrenVisible(BOOL visible); + + LLTabContainer* getTabCtrl() { return mTabCtrl; } - void setAllChildrenVisible(BOOL visible); + const LLUUID& getAvatarId() { return mAvatarId; } + void setAvatarId(const LLUUID& avatar_id) { mAvatarId = avatar_id; } - LLTabContainer* mTabContainer; - typedef std::map<std::string, LLPanelProfileTab*> profile_tabs_t; - profile_tabs_t mTabs; + profile_tabs_t& getTabContainer() { return mTabContainer; } + +private: + LLTabContainer* mTabCtrl; + profile_tabs_t mTabContainer; LLUUID mAvatarId; }; - - #endif //LL_LLPANELPROFILE_H diff --git a/indra/newview/llpanelprofileview.cpp b/indra/newview/llpanelprofileview.cpp index 00254ee8ee..cd18dc4462 100644 --- a/indra/newview/llpanelprofileview.cpp +++ b/indra/newview/llpanelprofileview.cpp @@ -39,14 +39,12 @@ #include "llpanelprofile.h" static LLRegisterPanelClassWrapper<LLPanelProfileView> t_panel_target_profile("panel_profile_view"); -static LLRegisterPanelClassWrapper<LLPanelAvatarNotes> t_panel_notes("panel_notes"); -static std::string PANEL_PROFILE = "panel_profile"; -static std::string PANEL_PICKS = "panel_picks"; static std::string PANEL_NOTES = "panel_notes"; LLPanelProfileView::LLPanelProfileView() : LLPanelProfile() +, mCacheNameCallbackConnected(false) { } @@ -57,32 +55,39 @@ LLPanelProfileView::~LLPanelProfileView(void) /*virtual*/ void LLPanelProfileView::onOpen(const LLSD& key) { - LLUUID id = key["id"]; - if (key.has("open_tab_name")) - mTabContainer->selectTabByName(key["open_tab_name"]); - - if(id.notNull() && mAvatarId != id) + LLUUID id; + if(key.has("id")) { - mAvatarId = id; - - mTabs[PANEL_PROFILE]->clear(); - mTabs[PANEL_PICKS]->clear(); - mTabs[PANEL_NOTES]->clear(); + id = key["id"]; + } + if(id.notNull() && getAvatarId() != id) + { + setAvatarId(id); } - mTabContainer->getCurrentPanel()->onOpen(mAvatarId); + LLPanelProfile::onOpen(key); + + // *HACK Profile View is created before gCacheName, as a result we can't call addObserver() + // in postBuild() and have to connect callback here. + // This will call addObserver() once per LLPanelProfileView instance. + if(!mCacheNameCallbackConnected) + { + gCacheName->addObserver(boost::bind(&LLPanelProfileView::cacheNameCallback, this, _1, _2, _3, _4)); + mCacheNameCallbackConnected = true; + } + // getFullName() will return "(Loading...)" for non cached names, + // in this case cacheNameCallback() will resolve the name. std::string full_name; - gCacheName->getFullName(mAvatarId,full_name); + gCacheName->getFullName(getAvatarId(),full_name); childSetValue("user_name",full_name); } - BOOL LLPanelProfileView::postBuild() { LLPanelProfile::postBuild(); - mTabs[PANEL_NOTES] = (getChild<LLPanelAvatarNotes>(PANEL_NOTES)); + getTabContainer()[PANEL_NOTES] = getChild<LLPanelAvatarNotes>(PANEL_NOTES); childSetCommitCallback("back",boost::bind(&LLPanelProfileView::onBackBtnClick,this),NULL); @@ -100,3 +105,11 @@ void LLPanelProfileView::onBackBtnClick() parent->openPreviousPanel(); } } + +void LLPanelProfileView::cacheNameCallback(const LLUUID& id, const std::string& first_name, const std::string& last_name, BOOL is_group) +{ + if(getAvatarId() == id) + { + childSetValue("user_name", first_name + " " + last_name); + } +} diff --git a/indra/newview/llpanelprofileview.h b/indra/newview/llpanelprofileview.h index 6c5fc77951..4d5e2997c1 100644 --- a/indra/newview/llpanelprofileview.h +++ b/indra/newview/llpanelprofileview.h @@ -35,24 +35,46 @@ #include "llpanel.h" #include "llpanelprofile.h" +#include "llavatarpropertiesprocessor.h" class LLPanelProfile; class LLPanelProfileTab; + +/** +* Panel for displaying Avatar's profile. It consists of three sub panels - Profile, +* Picks and Notes. +*/ class LLPanelProfileView : public LLPanelProfile { LOG_CLASS(LLPanelProfileView); friend class LLUICtrlFactory; public: + LLPanelProfileView(); - ~LLPanelProfileView(void); + /*virtual*/ ~LLPanelProfileView(); - void onOpen(const LLSD& key); + /*virtual*/ void onOpen(const LLSD& key); - BOOL postBuild(); + /*virtual*/ BOOL postBuild(); + + // LLCacheName will call this function when avatar name is loaded from server. + // This is required to display names that have not been cached yet. + void cacheNameCallback( + const LLUUID& id, + const std::string& first_name, + const std::string& last_name, + BOOL is_group); + +protected: + void onBackBtnClick(); + +private: + + bool mCacheNameCallbackConnected; }; #endif //LL_LLPANELPROFILEVIEW_H diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp index 5ae79f6c63..10561f5701 100644 --- a/indra/newview/llscreenchannel.cpp +++ b/indra/newview/llscreenchannel.cpp @@ -37,7 +37,10 @@ #include "lltextbox.h" #include "llscreenchannel.h" +#include "lltoastpanel.h" #include "llviewercontrol.h" +#include "llfloaterreg.h" +#include "lltrans.h" #include <algorithm> @@ -46,9 +49,10 @@ using namespace LLNotificationsUI; bool LLScreenChannel::mWasStartUpToastShown = false; //-------------------------------------------------------------------------- -LLScreenChannel::LLScreenChannel(): mUnreadToastsPanel(NULL), +LLScreenChannel::LLScreenChannel(): mOverflowToastPanel(NULL), + mStartUpToastPanel(NULL), mToastAlignment(NA_BOTTOM), - mStoreToasts(true), + mCanStoreToasts(true), mHiddenToastsNum(0), mOverflowToastHidden(false), mIsHovering(false), @@ -56,10 +60,8 @@ LLScreenChannel::LLScreenChannel(): mUnreadToastsPanel(NULL), { setFollows(FOLLOWS_RIGHT | FOLLOWS_BOTTOM | FOLLOWS_TOP); - //TODO: load as a resource string - mOverflowFormatString = "You have %d more notification"; + mOverflowFormatString = LLTrans::getString("OverflowInfoChannelString"); - mToastList.clear(); setMouseOpaque( false ); } @@ -85,44 +87,48 @@ void LLScreenChannel::reshape(S32 width, S32 height, BOOL called_from_parent) } //-------------------------------------------------------------------------- -LLToast* LLScreenChannel::addToast(LLUUID id, LLPanel* panel, bool is_not_tip) -{ - ToastElem new_toast_elem(id, panel); +void LLScreenChannel::addToast(LLToast::Params p) +{ + bool isSysWellWndShown = LLFloaterReg::getInstance("syswell_window")->getVisible(); + // we show toast in the following cases: + // - the StartUp Toast is already hidden and the SysWell's window is hidden + // - the SysWell's window is shown, but notification is a tip. We can't store it, so we show it + // - the channel has a CENTRE allignment, so it is intended for alerts. We always show alerts + bool show_toast = (mWasStartUpToastShown && !isSysWellWndShown) || (isSysWellWndShown && p.is_tip) || mToastAlignment == NA_CENTRE; + bool store_toast = !show_toast && !p.is_tip && mCanStoreToasts; + + // if we can't show or store a toast, then do nothing, just send ignore to a notification + if(!show_toast && !store_toast) + { + if(p.notification) + { + p.notification->setIgnored(TRUE); + p.notification->respond(p.notification->getResponseTemplate()); + } + return; + } + + ToastElem new_toast_elem(p); mOverflowToastHidden = false; - mToastList.push_back(new_toast_elem); getRootView()->addChild(new_toast_elem.toast); new_toast_elem.toast->setOnFadeCallback(boost::bind(&LLScreenChannel::onToastFade, this, new_toast_elem.toast)); if(mControlHovering) { new_toast_elem.toast->setOnToastHoverCallback(boost::bind(&LLScreenChannel::onToastHover, this, _1, _2)); } - - // don't show toasts until StartUp toast will fade, but show alerts - if(!mWasStartUpToastShown && mToastAlignment != NA_CENTRE) - { - new_toast_elem.toast->stopTimer(); - // Count and store only non tip notifications - if(is_not_tip) - { - mHiddenToastsNum++; - storeToast(new_toast_elem); - } - else - { - // destroy tip toasts at once - new_toast_elem.toast->close(); - } - // remove toast from channel - mToastList.pop_back(); - } - else + + if(show_toast) { + mToastList.push_back(new_toast_elem); showToasts(); + } + else // store_toast + { + mHiddenToastsNum++; + storeToast(new_toast_elem); } - - return new_toast_elem.toast; } //-------------------------------------------------------------------------- @@ -130,11 +136,12 @@ void LLScreenChannel::onToastFade(LLToast* toast) { std::vector<ToastElem>::iterator it = find(mToastList.begin(), mToastList.end(), static_cast<LLPanel*>(toast)); - bool destroy_toast = toast->isViewed() || !mStoreToasts || !toast->getCanBeStored(); + // *TODO: toast->isViewed() - seems unnecessary + bool destroy_toast = toast->isViewed() || !mCanStoreToasts || !toast->getCanBeStored(); if(destroy_toast) { mToastList.erase(it); - toast->mOnToastDestroy(toast, LLSD()); + toast->mOnToastDestroy(toast); } else { @@ -149,7 +156,14 @@ void LLScreenChannel::onToastFade(LLToast* toast) void LLScreenChannel::storeToast(ToastElem& toast_elem) { + // do not store clones + std::vector<ToastElem>::iterator it = find(mStoredToastList.begin(), mStoredToastList.end(), toast_elem.id); + if( it != mStoredToastList.end() ) + return; + + toast_elem.toast->stopTimer(); mStoredToastList.push_back(toast_elem); + mOnStoreToast(toast_elem.toast->getPanel(), toast_elem.id); } //-------------------------------------------------------------------------- @@ -173,16 +187,74 @@ void LLScreenChannel::loadStoredToastsToChannel() } //-------------------------------------------------------------------------- +void LLScreenChannel::loadStoredToastByIDToChannel(LLUUID id) +{ + std::vector<ToastElem>::iterator it = find(mStoredToastList.begin(), mStoredToastList.end(), id); + + if( it == mStoredToastList.end() ) + return; + + mOverflowToastHidden = false; + + LLToast* toast = (*it).toast; + toast->resetTimer(); + mToastList.push_back((*it)); + mStoredToastList.erase(it); + + showToasts(); +} + +//-------------------------------------------------------------------------- +void LLScreenChannel::removeStoredToastByID(LLUUID id) +{ + // *TODO: may be remove this function + std::vector<ToastElem>::iterator it = find(mStoredToastList.begin(), mStoredToastList.end(), id); + + if( it == mStoredToastList.end() ) + return; + + LLToast* toast = (*it).toast; + mStoredToastList.erase(it); + toast->discardNotification(); +} + +//-------------------------------------------------------------------------- void LLScreenChannel::killToastByNotificationID(LLUUID id) { + // searching among toasts on a screen std::vector<ToastElem>::iterator it = find(mToastList.begin(), mToastList.end(), id); if( it != mToastList.end()) { LLToast* toast = (*it).toast; - mToastList.erase(it); - toast->mOnToastDestroy(toast, LLSD()); - showToasts(); + // if it is a notification toast and notification is UnResponded - then respond on it + // else - simply destroy a toast + // + // NOTE: if a notification is unresponded this function will be called twice for the same toast. + // At first, the notification will be discarded, at second (it will be caused by discarding), + // the toast will be destroyed. + if(toast->getIsNotificationUnResponded()) + { + toast->discardNotification(); + } + else + { + mToastList.erase(it); + toast->mOnToastDestroy(toast); + showToasts(); + } + return; + } + + // searching among stored toasts + it = find(mStoredToastList.begin(), mStoredToastList.end(), id); + + if( it != mStoredToastList.end() ) + { + LLToast* toast = (*it).toast; + mStoredToastList.erase(it); + toast->discardNotification(); + toast->mOnToastDestroy(toast); } } @@ -197,7 +269,7 @@ void LLScreenChannel::modifyToastByNotificationID(LLUUID id, LLPanel* panel) LLPanel* old_panel = toast->getPanel(); toast->removeChild(old_panel); delete old_panel; - toast->arrange(panel); + toast->insertPanel(panel); toast->resetTimer(); showToasts(); } @@ -297,15 +369,16 @@ void LLScreenChannel::showToastsTop() void LLScreenChannel::createOverflowToast(S32 bottom, F32 timer) { LLRect toast_rect; - mUnreadToastsPanel = new LLToast(NULL); + LLToast::Params p; // *TODO: fill structure + mOverflowToastPanel = new LLToast(p); - if(!mUnreadToastsPanel) + if(!mOverflowToastPanel) return; - mUnreadToastsPanel->setOnFadeCallback(boost::bind(&LLScreenChannel::onOverflowToastHide, this)); + mOverflowToastPanel->setOnFadeCallback(boost::bind(&LLScreenChannel::onOverflowToastHide, this)); - LLTextBox* text_box = mUnreadToastsPanel->getChild<LLTextBox>("toast_text"); - LLIconCtrl* icon = mUnreadToastsPanel->getChild<LLIconCtrl>("icon"); + LLTextBox* text_box = mOverflowToastPanel->getChild<LLTextBox>("toast_text"); + LLIconCtrl* icon = mOverflowToastPanel->getChild<LLIconCtrl>("icon"); std::string text = llformat(mOverflowFormatString.c_str(),mHiddenToastsNum); if(mHiddenToastsNum == 1) { @@ -316,41 +389,107 @@ void LLScreenChannel::createOverflowToast(S32 bottom, F32 timer) text += "s."; } - toast_rect = mUnreadToastsPanel->getRect(); - mUnreadToastsPanel->reshape(getRect().getWidth(), toast_rect.getHeight(), true); + toast_rect = mOverflowToastPanel->getRect(); + mOverflowToastPanel->reshape(getRect().getWidth(), toast_rect.getHeight(), true); toast_rect.setLeftTopAndSize(getRect().mLeft, bottom + toast_rect.getHeight()+gSavedSettings.getS32("ToastMargin"), getRect().getWidth(), toast_rect.getHeight()); - mUnreadToastsPanel->setRect(toast_rect); - mUnreadToastsPanel->setAndStartTimer(timer); - getRootView()->addChild(mUnreadToastsPanel); + mOverflowToastPanel->setRect(toast_rect); + mOverflowToastPanel->setAndStartTimer(timer); + getRootView()->addChild(mOverflowToastPanel); text_box->setValue(text); text_box->setVisible(TRUE); icon->setVisible(TRUE); - mUnreadToastsPanel->setVisible(TRUE); + mOverflowToastPanel->setVisible(TRUE); } //-------------------------------------------------------------------------- void LLScreenChannel::onOverflowToastHide() { mOverflowToastHidden = true; + // *TODO: check whether it is needed: closeOverflowToastPanel(); +} + +//-------------------------------------------------------------------------- +void LLScreenChannel::closeOverflowToastPanel() +{ + if(mOverflowToastPanel != NULL) + { + mOverflowToastPanel->close(); + mOverflowToastPanel = NULL; + } +} + +//-------------------------------------------------------------------------- +void LLScreenChannel::createStartUpToast(S32 notif_num, S32 bottom, F32 timer) +{ + LLRect toast_rect; + LLToast::Params p; // *TODO: fill structure + mStartUpToastPanel = new LLToast(p); + + if(!mStartUpToastPanel) + return; + + mStartUpToastPanel->setOnFadeCallback(boost::bind(&LLScreenChannel::onStartUpToastHide, this)); + + LLTextBox* text_box = mStartUpToastPanel->getChild<LLTextBox>("toast_text"); + LLIconCtrl* icon = mStartUpToastPanel->getChild<LLIconCtrl>("icon"); + + std::string mStartUpFormatString; + + if(notif_num == 1) + { + mStartUpFormatString = LLTrans::getString("StartUpNotification"); + } + else + { + mStartUpFormatString = LLTrans::getString("StartUpNotifications"); + } + + + std::string text = llformat(mStartUpFormatString.c_str(), notif_num); + + toast_rect = mStartUpToastPanel->getRect(); + mStartUpToastPanel->reshape(getRect().getWidth(), toast_rect.getHeight(), true); + toast_rect.setLeftTopAndSize(getRect().mLeft, bottom + toast_rect.getHeight()+gSavedSettings.getS32("ToastMargin"), getRect().getWidth(), toast_rect.getHeight()); + mStartUpToastPanel->setRect(toast_rect); + mStartUpToastPanel->setAndStartTimer(timer); + getRootView()->addChild(mStartUpToastPanel); + + text_box->setValue(text); + text_box->setVisible(TRUE); + icon->setVisible(TRUE); + + mStartUpToastPanel->setVisible(TRUE); +} + +//-------------------------------------------------------------------------- +void LLScreenChannel::updateStartUpString(S32 num) +{ + // *TODO: update string if notifications are arriving while the StartUp toast is on a screen +} + +//-------------------------------------------------------------------------- +void LLScreenChannel::onStartUpToastHide() +{ onCommit(); } //-------------------------------------------------------------------------- -void LLScreenChannel::closeUnreadToastsPanel() +void LLScreenChannel::closeStartUpToast() { - if(mUnreadToastsPanel != NULL) + if(mStartUpToastPanel != NULL) { - mUnreadToastsPanel->close(); - mUnreadToastsPanel = NULL; + LLScreenChannel::setStartUpToastShown(); + mStartUpToastPanel->close(); + mStartUpToastPanel = NULL; } } //-------------------------------------------------------------------------- void LLScreenChannel::hideToastsFromScreen() { - closeUnreadToastsPanel(); + closeOverflowToastPanel(); for(std::vector<ToastElem>::iterator it = mToastList.begin(); it != mToastList.end(); it++) (*it).toast->setVisible(FALSE); } @@ -368,6 +507,24 @@ void LLScreenChannel::removeToastsFromChannel() } //-------------------------------------------------------------------------- +void LLScreenChannel::removeAndStoreAllVisibleToasts() +{ + if(mToastList.size() == 0) + return; + + hideToastsFromScreen(); + for(std::vector<ToastElem>::iterator it = mToastList.begin(); it != mToastList.end(); it++) + { + mStoredToastList.push_back(*it); + mOnStoreToast((*it).toast->getPanel(), (*it).id); + (*it).toast->stopTimer(); + (*it).toast->setVisible(FALSE); + } + + mToastList.clear(); +} + +//-------------------------------------------------------------------------- void LLScreenChannel::onToastHover(LLToast* toast, bool mouse_enter) { // because of LLViewerWindow::updateUI() that ALWAYS calls onMouseEnter BEFORE onMouseLeave diff --git a/indra/newview/llscreenchannel.h b/indra/newview/llscreenchannel.h index 579f41eac8..1ca70c72d0 100644 --- a/indra/newview/llscreenchannel.h +++ b/indra/newview/llscreenchannel.h @@ -71,7 +71,7 @@ public: // Operating with toasts // add a toast to a channel - LLToast* addToast(LLUUID id, LLPanel* panel, bool is_not_tip = true); + void addToast(LLToast::Params p); // kill or modify a toast by its ID void killToastByNotificationID(LLUUID id); void modifyToastByNotificationID(LLUUID id, LLPanel* panel); @@ -83,8 +83,16 @@ public: void showToasts(); // void loadStoredToastsToChannel(); - // - void closeUnreadToastsPanel(); + // finds a toast among stored by its ID and throws it on a screen to a channel + void loadStoredToastByIDToChannel(LLUUID id); + // removes a toast from stored finding it by its ID + void removeStoredToastByID(LLUUID id); + // remove all toasts from screen and store them + void removeAndStoreAllVisibleToasts(); + // close the Overflow Toast + void closeOverflowToastPanel(); + // close the StartUp Toast + void closeStartUpToast(); // Channel's behavior-functions // set whether a channel will control hovering inside itself or not @@ -92,14 +100,17 @@ public: // set Hovering flag for a channel void setHovering(bool hovering) { mIsHovering = hovering; } // set whether a channel will store faded toasts or not - void setStoreToasts(bool store) { mStoreToasts = store; } + void setCanStoreToasts(bool store) { mCanStoreToasts = store; } // tell all channels that the StartUp toast was shown and allow them showing of toasts static void setStartUpToastShown() { mWasStartUpToastShown = true; } + // + static bool getStartUpToastShown() { return mWasStartUpToastShown; } // Channel's other interface functions functions - S32 getNumberOfHiddenToasts() { return mHiddenToastsNum;} - // TODO: split StartUp and Overflow toasts - void setNumberOfHiddenToasts(S32 num) { mHiddenToastsNum = num;} + // get number of hidden notifications from a channel + S32 getNumberOfHiddenToasts() { return mHiddenToastsNum;} + // update number of notifications in the StartUp Toast + void updateStartUpString(S32 num); e_notification_toast_alignment getToastAlignment() {return mToastAlignment;} // Channel's callbacks @@ -114,9 +125,10 @@ private: { LLUUID id; LLToast* toast; - ToastElem(LLUUID lluuid, LLPanel* panel) : id(lluuid) + + ToastElem(LLToast::Params p) : id(p.id) { - toast = new LLToast(panel); + toast = new LLToast(p); } ToastElem(const ToastElem& toast_elem) @@ -140,6 +152,7 @@ private: void onToastHover(LLToast* toast, bool mouse_enter); void onToastFade(LLToast* toast); void onOverflowToastHide(); + void onStartUpToastHide(); // void storeToast(ToastElem& toast_elem); @@ -149,22 +162,29 @@ private: void showToastsCentre(); void showToastsTop(); - // create the OverflowToast + // create the Overflow Toast void createOverflowToast(S32 bottom, F32 timer); + // create the StartUp Toast + void createStartUpToast(S32 notif_num, S32 bottom, F32 timer); + // Channel's flags static bool mWasStartUpToastShown; bool mControlHovering; bool mIsHovering; - bool mStoreToasts; + bool mCanStoreToasts; bool mOverflowToastHidden; // e_notification_toast_alignment mToastAlignment; + // attributes for the Overflow Toast S32 mHiddenToastsNum; - LLToast* mUnreadToastsPanel; + LLToast* mOverflowToastPanel; std::string mOverflowFormatString; + // attributes for the StartUp Toast + LLToast* mStartUpToastPanel; + std::vector<ToastElem> mToastList; std::vector<ToastElem> mStoredToastList; std::map<LLToast*, bool> mToastEventStack; diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp index fec4798f7b..438b1b558f 100644 --- a/indra/newview/llsidetray.cpp +++ b/indra/newview/llsidetray.cpp @@ -281,7 +281,7 @@ bool LLSideTray::addTab ( const std::string& tab_name LLSideTrayTab* LLSideTray::getTab(const std::string& name) { - return getChild<LLSideTrayTab>(name,false,false); + return getChild<LLSideTrayTab>(name,false); } @@ -311,7 +311,7 @@ bool LLSideTray::selectTabByName (const std::string& name) { LLSideTrayTab* side_bar = getTab(name); - if(side_bar == NULL || side_bar == mActiveTab) + if(side_bar == mActiveTab) return false; //deselect old tab toggleTabButton(mActiveTab); diff --git a/indra/newview/llsidetray.h b/indra/newview/llsidetray.h index 1f8b6b402f..b691a42db1 100644 --- a/indra/newview/llsidetray.h +++ b/indra/newview/llsidetray.h @@ -89,10 +89,13 @@ private: LLView* mMainPanel; }; - -class LLSideTray : public LLPanel +// added inheritance from LLDestroyClass<LLSideTray> to enable Side Tray perform necessary actions +// while disconnecting viewer in LLAppViewer::disconnectViewer(). +// LLDestroyClassList::instance().fireCallbacks() calls destroyClass method. See EXT-245. +class LLSideTray : public LLPanel, private LLDestroyClass<LLSideTray> { friend class LLUICtrlFactory; + friend class LLDestroyClass<LLSideTray>; public: LOG_CLASS(LLSideTray); @@ -216,6 +219,15 @@ protected: void setPanelRect (); + +private: + // Implementation of LLDestroyClass<LLSideTray> + static void destroyClass() + { + // Disable SideTray to avoid crashes. EXT-245 + if (LLSideTray::instanceCreated()) + LLSideTray::getInstance()->setEnabled(FALSE); + } private: diff --git a/indra/newview/llslurl.cpp b/indra/newview/llslurl.cpp index bd93f5dd28..ffadeeddf2 100644 --- a/indra/newview/llslurl.cpp +++ b/indra/newview/llslurl.cpp @@ -106,6 +106,13 @@ std::string LLSLURL::buildSLURL(const std::string& regionname, S32 x, S32 y, S32 } // static +std::string LLSLURL::buildUnescapedSLURL(const std::string& regionname, S32 x, S32 y, S32 z) +{ + std::string unescapedslurl = PREFIX_SLURL + regionname + llformat("/%d/%d/%d",x,y,z); + return unescapedslurl; +} + +// static bool LLSLURL::matchPrefix(const std::string& url, const std::string& prefix) { std::string test_prefix = url.substr(0, prefix.length()); diff --git a/indra/newview/llslurl.h b/indra/newview/llslurl.h index 05788623d9..5c9fea3e96 100644 --- a/indra/newview/llslurl.h +++ b/indra/newview/llslurl.h @@ -69,11 +69,16 @@ public: static bool isSLURLHelp(const std::string& url); /** - * builds: http://slurl.com/secondlife/RegionName/x/y/z/ + * builds: http://slurl.com/secondlife/Region%20Name/x/y/z/ escaping result url. */ static std::string buildSLURL(const std::string& regionname, S32 x, S32 y, S32 z); /** + * builds: http://slurl.com/secondlife/Region Name/x/y/z/ without escaping result url. + */ + static std::string buildUnescapedSLURL(const std::string& regionname, S32 x, S32 y, S32 z); + + /** * Strip protocol part from the URL. */ static std::string stripProtocol(const std::string& url); diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp index 12fb811328..569e7b3397 100644 --- a/indra/newview/llstatusbar.cpp +++ b/indra/newview/llstatusbar.cpp @@ -48,6 +48,7 @@ #include "llfloaterscriptdebug.h" #include "llhudicon.h" #include "llfloaterinventory.h" +#include "llnavigationbar.h" #include "llkeyboard.h" #include "lllineeditor.h" #include "llmenugl.h" @@ -244,6 +245,30 @@ void LLStatusBar::draw() LLPanel::draw(); } +BOOL LLStatusBar::handleRightMouseUp(S32 x, S32 y, MASK mask) +{ + if (mHideNavbarContextMenu) + { + mHideNavbarContextMenu->buildDrawLabels(); + mHideNavbarContextMenu->updateParent(LLMenuGL::sMenuContainer); + LLMenuGL::showPopup(this, mHideNavbarContextMenu, x, y); + } + + return TRUE; +} + +BOOL LLStatusBar::postBuild() +{ + mCommitCallbackRegistrar.add("HideNavbarMenu.Action", boost::bind(&LLStatusBar::onHideNavbarContextMenuItemClicked, this, _2)); + mEnableCallbackRegistrar.add("HideNavbarMenu.EnableMenuItem", boost::bind(&LLStatusBar::onHideNavbarContextMenuItemEnabled, this, _2)); + + mHideNavbarContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_hide_navbar.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + gMenuHolder->addChild(mHideNavbarContextMenu); + + gMenuBarView->setRightClickedCallback(boost::bind(&LLStatusBar::onMainMenuRightClicked, this, _1, _2, _3, _4)); + + return TRUE; +} // Per-frame updates of visibility void LLStatusBar::refresh() @@ -716,6 +741,48 @@ void LLStatusBar::setupDate() } } +bool LLStatusBar::onHideNavbarContextMenuItemEnabled(const LLSD& userdata) +{ + std::string item = userdata.asString(); + + if (item == "show_navbar_navigation_panel") + { + return gSavedSettings.getBOOL("ShowNavbarNavigationPanel"); + } + else if (item == "show_navbar_favorites_panel") + { + return gSavedSettings.getBOOL("ShowNavbarFavoritesPanel"); + } + + return FALSE; +} + +void LLStatusBar::onHideNavbarContextMenuItemClicked(const LLSD& userdata) +{ + std::string item = userdata.asString(); + + if (item == "show_navbar_navigation_panel") + { + BOOL state = !gSavedSettings.getBOOL("ShowNavbarNavigationPanel"); + + LLNavigationBar::getInstance()->showNavigationPanel(state); + gSavedSettings.setBOOL("ShowNavbarNavigationPanel", state); + } + else if (item == "show_navbar_favorites_panel") + { + BOOL state = !gSavedSettings.getBOOL("ShowNavbarFavoritesPanel"); + + LLNavigationBar::getInstance()->showFavoritesPanel(state); + gSavedSettings.setBOOL("ShowNavbarFavoritesPanel", state); + } +} + + +void LLStatusBar::onMainMenuRightClicked(LLUICtrl* ctrl, S32 x, S32 y, MASK mask) +{ + handleRightMouseUp(x, y, mask); +} + // static void LLStatusBar::onCommitSearch(LLUICtrl*, void* data) { diff --git a/indra/newview/llstatusbar.h b/indra/newview/llstatusbar.h index 84dd761930..0cb3551768 100644 --- a/indra/newview/llstatusbar.h +++ b/indra/newview/llstatusbar.h @@ -34,6 +34,7 @@ #define LL_LLSTATUSBAR_H #include "llpanel.h" +#include <llmenugl.h> // "Constants" loaded from settings.xml at start time extern S32 STATUS_BAR_HEIGHT; @@ -57,6 +58,9 @@ public: /*virtual*/ void draw(); + /*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL postBuild(); + // MANIPULATORS void setBalance(S32 balance); void debitBalance(S32 debit); @@ -87,6 +91,10 @@ private: // simple method to setup the part that holds the date void setupDate(); + bool onHideNavbarContextMenuItemEnabled(const LLSD& userdata); + void onHideNavbarContextMenuItemClicked(const LLSD& userdata); + + void onMainMenuRightClicked(LLUICtrl* ctrl, S32 x, S32 y, MASK mask); static void onCommitSearch(LLUICtrl*, void* data); static void onClickSearch(void* data); static void onClickStatGraph(void* data); @@ -106,6 +114,7 @@ private: S32 mSquareMetersCommitted; LLFrameTimer* mBalanceTimer; LLFrameTimer* mHealthTimer; + LLMenuGL* mHideNavbarContextMenu; static std::vector<std::string> sDays; static std::vector<std::string> sMonths; diff --git a/indra/newview/llsyswellitem.cpp b/indra/newview/llsyswellitem.cpp new file mode 100644 index 0000000000..5ed8a8b604 --- /dev/null +++ b/indra/newview/llsyswellitem.cpp @@ -0,0 +1,105 @@ +/** + * @file llsyswellitem.cpp + * @brief // TODO + * + * $LicenseInfo:firstyear=2000&license=viewergpl$ + * + * Copyright (c) 2000-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + + +#include "llviewerprecompiledheaders.h" // must be first include + +#include "llsyswellitem.h" + +#include "llwindow.h" +#include "v4color.h" + +//--------------------------------------------------------------------------------- +LLSysWellItem::LLSysWellItem(const Params& p) : LLScrollingPanel(p), + mTitle(NULL), + mCloseBtn(NULL), + mIcon(NULL) +{ + LLUICtrlFactory::getInstance()->buildPanel(this, "panel_sys_well_item.xml"); + + mTitle = getChild<LLTextBox>("title"); + mCloseBtn = getChild<LLButton>("close_btn"); + mIcon = getChild<LLIconCtrl>("icon"); + + mTitle->setValue(p.title); + mCloseBtn->setClickedCallback(boost::bind(&LLSysWellItem::onClickCloseBtn,this)); + + mID = p.notification_id; +} + +//--------------------------------------------------------------------------------- +LLSysWellItem::~LLSysWellItem() +{ +} + +//--------------------------------------------------------------------------------- +void LLSysWellItem::setTitle( std::string title ) +{ + mTitle->setValue(title); +} + +//--------------------------------------------------------------------------------- +void LLSysWellItem::onClickCloseBtn() +{ + mOnItemClose(this); +} + +//--------------------------------------------------------------------------------- +void LLSysWellItem::updatePanel(BOOL allow_modify) +{ + //nothing to do here +} + +//--------------------------------------------------------------------------------- +BOOL LLSysWellItem::handleMouseDown(S32 x, S32 y, MASK mask) +{ + if(!mCloseBtn->getRect().pointInRect(x, y)) + mOnItemClick(this); + + return LLPanel::handleMouseDown(x, y, mask); +} + +//--------------------------------------------------------------------------------- +void LLSysWellItem::onMouseEnter(S32 x, S32 y, MASK mask) +{ + setTransparentColor(LLColor4(0.3f, 0.3f, 0.3f, 1.0f)); +} + +//--------------------------------------------------------------------------------- +void LLSysWellItem::onMouseLeave(S32 x, S32 y, MASK mask) +{ + setTransparentColor(LLColor4(0.0f, 0.0f, 0.0f, 0.0f)); +} + +//--------------------------------------------------------------------------------- + + diff --git a/indra/newview/llsyswellitem.h b/indra/newview/llsyswellitem.h new file mode 100644 index 0000000000..b0761f2790 --- /dev/null +++ b/indra/newview/llsyswellitem.h @@ -0,0 +1,90 @@ +/** + * @file llsyswellitem.h + * @brief // TODO + * + * $LicenseInfo:firstyear=2003&license=viewergpl$ + * + * Copyright (c) 2003-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLSYSWELLITEM_H +#define LL_LLSYSWELLITEM_H + +#include "llscrollingpanellist.h" +#include "lltextbox.h" +#include "llbutton.h" +#include "lliconctrl.h" + +#include <string> + +class LLSysWellItem : public LLScrollingPanel +{ +public: + struct Params : public LLInitParam::Block<Params, LLPanel::Params> + { + LLUUID notification_id; + std::string title; + Params() {}; + }; + + + LLSysWellItem(const Params& p); + virtual ~LLSysWellItem(); + + void updatePanel(BOOL allow_modify); + + // title + void setTitle( std::string title ); + + // get item's ID + LLUUID getID() { return mID; } + + // handlers + virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); + virtual void onMouseEnter(S32 x, S32 y, MASK mask); + virtual void onMouseLeave(S32 x, S32 y, MASK mask); + + //callbacks + typedef boost::function<void (LLSysWellItem* item)> syswell_item_callback_t; + typedef boost::signals2::signal<void (LLSysWellItem* item)> syswell_item_signal_t; + syswell_item_signal_t mOnItemClose; + syswell_item_signal_t mOnItemClick; + boost::signals2::connection setOnItemCloseCallback(syswell_item_callback_t cb) { return mOnItemClose.connect(cb); } + boost::signals2::connection setOnItemClickCallback(syswell_item_callback_t cb) { return mOnItemClick.connect(cb); } + +private: + + void onClickCloseBtn(); + + LLTextBox* mTitle; + LLButton* mCloseBtn; + LLIconCtrl* mIcon; + LLUUID mID; +}; + +#endif // LL_LLSYSWELLITEM_H + + diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp new file mode 100644 index 0000000000..c8eea5e7b4 --- /dev/null +++ b/indra/newview/llsyswellwindow.cpp @@ -0,0 +1,210 @@ +/** + * @file llsyswellwindow.cpp + * @brief // TODO + * $LicenseInfo:firstyear=2000&license=viewergpl$ + * + * Copyright (c) 2000-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + + +#include "llviewerprecompiledheaders.h" // must be first include + +#include "llsyswellwindow.h" + +#include "llbottomtray.h" +#include "llviewercontrol.h" + + +//--------------------------------------------------------------------------------- +LLSysWellWindow::LLSysWellWindow(const LLSD& key) : LLFloater(LLSD()), + mChannel(NULL), + mScrollContainer(NULL), + mNotificationList(NULL) +{ + // Ho to use: + // LLFloaterReg::showInstance("syswell_window"); + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_sys_well.xml", NULL); +} + +//--------------------------------------------------------------------------------- +BOOL LLSysWellWindow::postBuild() +{ + mCloseBtn = getChild<LLButton>("close_btn"); + mScrollContainer = getChild<LLScrollContainer>("notification_list_container"); + mNotificationList = getChild<LLScrollingPanelList>("notification_list"); + + mCloseBtn->setClickedCallback(boost::bind(&LLSysWellWindow::onClickCloseBtn,this)); + + return TRUE; +} + +//--------------------------------------------------------------------------------- +LLSysWellWindow::~LLSysWellWindow() +{ +} + +//--------------------------------------------------------------------------------- +void LLSysWellWindow::addItem(LLSysWellItem::Params p) +{ + // do not add clones + if( findItemByID(p.notification_id) >= 0 ) + return; + + LLSysWellItem* new_item = new LLSysWellItem(p); + mNotificationList->addPanel(dynamic_cast<LLScrollingPanel*>(new_item)); + reshapeWindow(); + adjustWindowPosition(); + + new_item->setOnItemCloseCallback(boost::bind(&LLSysWellWindow::onItemClose, this, _1)); + new_item->setOnItemClickCallback(boost::bind(&LLSysWellWindow::onItemClick, this, _1)); +} + +//--------------------------------------------------------------------------------- +void LLSysWellWindow::clear() +{ + // *TODO: fill later +} + +//--------------------------------------------------------------------------------- +S32 LLSysWellWindow::findItemByID(const LLUUID& id) +{ + const LLScrollingPanelList::panel_list_t list = mNotificationList->getPanelList(); + if(list.size() == 0) + return -1; + + LLScrollingPanelList::panel_list_t::const_iterator it = list.begin(); + S32 index = 0; + while(it != list.end()) + { + if( dynamic_cast<LLSysWellItem*>(*it)->getID() == id ) + break; + ++it; + ++index; + } + + if(it == list.end()) + return -1; + else + return index; + +} + +//--------------------------------------------------------------------------------- +void LLSysWellWindow::removeItemByID(const LLUUID& id) +{ + S32 index = findItemByID(id); + + if(index >= 0) + mNotificationList->removePanel(index); + else + return; + + reshapeWindow(); + adjustWindowPosition(); + // hide chiclet window if there are no items left + S32 items_left = mNotificationList->getPanelList().size(); + if(items_left == 0) + setVisible(FALSE); +} + +//--------------------------------------------------------------------------------- +void LLSysWellWindow::onItemClick(LLSysWellItem* item) +{ + LLUUID id = item->getID(); + mChannel->loadStoredToastByIDToChannel(id); +} + +//--------------------------------------------------------------------------------- +void LLSysWellWindow::onItemClose(LLSysWellItem* item) +{ + LLUUID id = item->getID(); + removeItemByID(id); + mChannel->killToastByNotificationID(id); +} + +//--------------------------------------------------------------------------------- +void LLSysWellWindow::onClickCloseBtn() +{ + setVisible(false); +} + +//--------------------------------------------------------------------------------- +void LLSysWellWindow::setVisible(BOOL visible) +{ + // on Show adjust position of SysWell chiclet's window + if(visible) + { + mChannel->removeAndStoreAllVisibleToasts(); + adjustWindowPosition(); + } + + LLFloater::setVisible(visible); +} + +//--------------------------------------------------------------------------------- +void LLSysWellWindow::adjustWindowPosition() +{ + const S32 WINDOW_MARGIN = 5; + + LLRect btm_rect = LLBottomTray::getInstance()->getRect(); + LLRect this_rect = getRect(); + setOrigin(btm_rect.mRight - this_rect.getWidth() - WINDOW_MARGIN, WINDOW_MARGIN); +} +//--------------------------------------------------------------------------------- +void LLSysWellWindow::reshapeWindow() +{ + // Get scrollbar size + const LLUICachedControl<S32> SCROLLBAR_SIZE("UIScrollbarSize", 0); + + // Get item list + const LLScrollingPanelList::panel_list_t list = mNotificationList->getPanelList(); + + // window's size constants + const S32 WINDOW_HEADER_HEIGHT = 30; + const S32 MAX_WINDOW_HEIGHT = 200; + const S32 MIN_WINDOW_WIDTH = 320; + + // Get height and border's width for a scrolling panel list + S32 list_height = mNotificationList->getRect().getHeight(); + S32 list_border_width = mScrollContainer->getBorderWidth() * 2; + + // Check that the floater doesn't exceed its parent view limits after reshape + S32 new_height = list_height + WINDOW_HEADER_HEIGHT + list_border_width; + + if(new_height > MAX_WINDOW_HEIGHT) + { + reshape(MIN_WINDOW_WIDTH + SCROLLBAR_SIZE, MAX_WINDOW_HEIGHT, FALSE); + } + else + { + reshape(MIN_WINDOW_WIDTH, new_height, FALSE); + } +} + +//--------------------------------------------------------------------------------- + + + diff --git a/indra/newview/llsyswellwindow.h b/indra/newview/llsyswellwindow.h new file mode 100644 index 0000000000..9554f3cb82 --- /dev/null +++ b/indra/newview/llsyswellwindow.h @@ -0,0 +1,89 @@ +/** + * @file llsyswellwindow.h + * @brief // TODO + * + * $LicenseInfo:firstyear=2003&license=viewergpl$ + * + * Copyright (c) 2003-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLSYSWELLWINDOW_H +#define LL_LLSYSWELLWINDOW_H + +#include "llsyswellitem.h" + +#include "llfloater.h" +#include "llbutton.h" +#include "llscreenchannel.h" +#include "llscrollcontainer.h" + +#include "boost/shared_ptr.hpp" + + + +class LLSysWellWindow : public LLFloater +{ + friend class LLFloaterReg; + +public: + LLSysWellWindow(const LLSD& key); + ~LLSysWellWindow(); + BOOL postBuild(); + + // change attributes + void setChannel(LLNotificationsUI::LLScreenChannel* channel) {mChannel = channel;} + + // Operating with items + void addItem(LLSysWellItem::Params p); + void clear( void ); + void removeItemByID(const LLUUID& id); + S32 findItemByID(const LLUUID& id); + + // Operating with outfit + virtual void setVisible(BOOL visible); + void adjustWindowPosition(); + + // Handlers + void onItemClick(LLSysWellItem* item); + void onItemClose(LLSysWellItem* item); + +private: + + void onClickCloseBtn(); + void reshapeWindow(); + + // pointer to a corresponding channel's instance + LLNotificationsUI::LLScreenChannel* mChannel; + + LLButton* mCloseBtn; + LLScrollContainer* mScrollContainer; + LLScrollingPanelList* mNotificationList; +}; + +#endif // LL_LLSYSWELLWINDOW_H + + + diff --git a/indra/newview/lltoast.cpp b/indra/newview/lltoast.cpp index 8a7c7708b9..a67ef85f87 100644 --- a/indra/newview/lltoast.cpp +++ b/indra/newview/lltoast.cpp @@ -41,36 +41,61 @@ using namespace LLNotificationsUI; //-------------------------------------------------------------------------- -LLToast::LLToast(LLPanel* panel) : - LLFloater(LLSD()), - mTimerValue(5), - mIsViewed(false), - mPanel(panel), - mCanFade(true), - mHideBtn(NULL), - mIsModal(false), - mCanBeStored(true), - mHideBtnPressed(false) +LLToast::LLToast(LLToast::Params p) : LLFloater(LLSD()), + mPanel(p.panel), + mTimerValue(p.timer_period), + mID(p.id), + mCanFade(p.can_fade), + mCanBeStored(p.can_be_stored), + mHideBtnEnabled(p.enable_hide_btn), + mIsModal(p.is_modal), + mIsTipNotification(p.is_tip), + mHideBtn(NULL), + mNotification(p.notification), + mIsViewed(false), + mHideBtnPressed(false) { - LLUICtrlFactory::getInstance()->buildPanel(this, "panel_toast.xml"); + LLUICtrlFactory::getInstance()->buildFloater(this, "panel_toast.xml", NULL); - mHideBtn = getChild<LLButton>("hide_btn"); - if(mHideBtn) + if(mPanel) + { + insertPanel(mPanel); + } + + if(mHideBtnEnabled) { + mHideBtn = getChild<LLButton>("hide_btn"); mHideBtn->setClickedCallback(boost::bind(&LLToast::hide,this)); } - if(mPanel) + + if(mIsModal) { - arrange(mPanel); + gFocusMgr.setMouseCapture( this ); + gFocusMgr.setTopCtrl( this ); + setFocus(TRUE); } - // disable unnecessary Floater's functionality - setTitleVisible(FALSE); - setCanMinimize(FALSE); - setCanClose(FALSE); - setCanTearOff(FALSE); - setCanResize(FALSE); - setCanDrag(FALSE); + + if(!p.on_toast_destroy.empty()) + mOnToastDestroy.connect(p.on_toast_destroy); + + if(!p.on_mouse_enter.empty()) + mOnMousEnter.connect(p.on_mouse_enter); +} + +//-------------------------------------------------------------------------- +BOOL LLToast::postBuild() +{ + if(mCanFade) + { + mTimer.start(); + } + else + { + mTimer.stop(); + } + + return TRUE; } //-------------------------------------------------------------------------- @@ -124,7 +149,7 @@ void LLToast::hide() setVisible(FALSE); mIsViewed = false; mTimer.stop(); - mOnFade(this, LLSD()); + mOnFade(this); } //-------------------------------------------------------------------------- @@ -142,12 +167,12 @@ void LLToast::tick() { setVisible(FALSE); mTimer.stop(); - mOnFade(this, LLSD()); + mOnFade(this); } } //-------------------------------------------------------------------------- -void LLToast::arrange(LLPanel* panel) +void LLToast::insertPanel(LLPanel* panel) { LLRect panel_rect, toast_rect; @@ -213,13 +238,12 @@ void LLToast::onMouseEnter(S32 x, S32 y, MASK mask) sendChildToFront(mHideBtn); if(mHideBtn && mHideBtn->getEnabled()) mHideBtn->setVisible(TRUE); - mOnMousEnter(this, LLSD()); + mOnMousEnter(this); } //-------------------------------------------------------------------------- void LLToast::onMouseLeave(S32 x, S32 y, MASK mask) { - llinfos << "MOUSE LEAVE: x = " << x << "y = " << y << llendl; mOnToastHover(this, MOUSE_LEAVE); if(mCanFade && !mIsViewed) @@ -249,5 +273,26 @@ BOOL LLToast::handleMouseDown(S32 x, S32 y, MASK mask) return LLFloater::handleMouseDown(x, y, mask); } +//-------------------------------------------------------------------------- +void LLToast::discardNotification() +{ + if(mNotification) + { + mNotification->setIgnored(TRUE); + mNotification->respond(mNotification->getResponseTemplate()); + } +} + +//-------------------------------------------------------------------------- +bool LLToast::getIsNotificationUnResponded() +{ + if(mNotification) + { + return !mNotification->isRespondedTo(); + } + return false; +} + +//-------------------------------------------------------------------------- diff --git a/indra/newview/lltoast.h b/indra/newview/lltoast.h index f998754585..a4dee1e386 100644 --- a/indra/newview/lltoast.h +++ b/indra/newview/lltoast.h @@ -37,7 +37,9 @@ #include "llpanel.h" #include "llfloater.h" #include "lltimer.h" -#include "lldate.h" +#include "llnotifications.h" + +#include "llviewercontrol.h" #define MOUSE_LEAVE false #define MOUSE_ENTER true @@ -52,53 +54,108 @@ namespace LLNotificationsUI class LLToast : public LLFloater { public: - LLToast(LLPanel* panel); + typedef boost::function<void (LLToast* toast)> toast_callback_t; + typedef boost::signals2::signal<void (LLToast* toast)> toast_signal_t; + + struct Params : public LLInitParam::Block<Params, LLFloater::Params> + { + LLPanel* panel; + LLUUID id; //notification or message ID + LLNotificationPtr notification; + F32 timer_period; + toast_callback_t on_toast_destroy; + toast_callback_t on_mouse_enter; + bool can_fade; + bool can_be_stored; + bool enable_hide_btn; + bool is_modal; + bool is_tip; + + Params() : can_fade(true), + can_be_stored(true), + is_modal(false), + is_tip(false), + enable_hide_btn(true), + panel(NULL), + timer_period(gSavedSettings.getS32("NotificationToastTime")) + + {}; + }; + + LLToast(LLToast::Params p); virtual ~LLToast(); + BOOL postBuild(); + // Toast handlers virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); - // - bool isViewed() { return mIsViewed; } - - void setCanFade(bool can_fade); + virtual void onMouseEnter(S32 x, S32 y, MASK mask); + virtual void onMouseLeave(S32 x, S32 y, MASK mask); + // Operating with toasts + // insert a panel to a toast + void insertPanel(LLPanel* panel); + // get toast's panel + LLPanel* getPanel() { return mPanel; } + // discard notification + void discardNotification(); + // enable/disable Toast's Hide button void setHideButtonEnabled(bool enabled); - - void setCanBeStored(bool can_be_stored) { mCanBeStored = can_be_stored; } - bool getCanBeStored() { return mCanBeStored; } - // + // initialize and start Toast's timer void setAndStartTimer(F32 period); - // + // void resetTimer() { mTimer.start(); } + // void stopTimer() { mTimer.stop(); } + // void close() { die(); } + // virtual void draw(); + // virtual void setVisible(BOOL show); - virtual void onMouseEnter(S32 x, S32 y, MASK mask); - virtual void onMouseLeave(S32 x, S32 y, MASK mask); + // virtual void hide(); - LLPanel* getPanel() { return mPanel; } - void arrange(LLPanel* panel); + + + + // get/set Toast's flags or states + // get information whether the notification corresponding to the toast is responded or not + bool getIsNotificationUnResponded(); + // + bool isViewed() { return mIsViewed; } + // + void setCanFade(bool can_fade); + // + void setCanBeStored(bool can_be_stored) { mCanBeStored = can_be_stored; } + // + bool getCanBeStored() { return mCanBeStored; } + // void setModal(bool modal); // Registers callbacks for events - boost::signals2::connection setOnFadeCallback(commit_callback_t cb) { return mOnFade.connect(cb); } - boost::signals2::connection setOnMouseEnterCallback(commit_callback_t cb) { return mOnMousEnter.connect(cb); } - boost::signals2::connection setOnToastDestroyCallback(commit_callback_t cb) { return mOnToastDestroy.connect(cb); } + toast_signal_t mOnFade; + toast_signal_t mOnMousEnter; + toast_signal_t mOnToastDestroy; + boost::signals2::connection setOnFadeCallback(toast_callback_t cb) { return mOnFade.connect(cb); } + boost::signals2::connection setOnMouseEnterCallback(toast_callback_t cb) { return mOnMousEnter.connect(cb); } + boost::signals2::connection setOnToastDestroyCallback(toast_callback_t cb) { return mOnToastDestroy.connect(cb); } + typedef boost::function<void (LLToast* toast, bool mouse_enter)> toast_hover_check_callback_t; typedef boost::signals2::signal<void (LLToast* toast, bool mouse_enter)> toast_hover_check_signal_t; toast_hover_check_signal_t mOnToastHover; boost::signals2::connection setOnToastHoverCallback(toast_hover_check_callback_t cb) { return mOnToastHover.connect(cb); } - commit_signal_t mOnFade; - commit_signal_t mOnMousEnter; - commit_signal_t mOnToastDestroy; private: + // check timer bool timerHasExpired(); + // on timer finished function void tick(); + LLUUID mID; + LLNotificationPtr mNotification; + LLTimer mTimer; F32 mTimerValue; @@ -107,9 +164,11 @@ private: LLColor4 mBgColor; bool mIsViewed; + bool mIsTipNotification; bool mCanFade; bool mIsModal; bool mCanBeStored; + bool mHideBtnEnabled; bool mHideBtnPressed; }; diff --git a/indra/newview/lltoastgroupnotifypanel.cpp b/indra/newview/lltoastgroupnotifypanel.cpp index f5ed7f8710..8a61f6cfda 100644 --- a/indra/newview/lltoastgroupnotifypanel.cpp +++ b/indra/newview/lltoastgroupnotifypanel.cpp @@ -44,7 +44,6 @@ #include "lluiconstants.h" #include "llui.h" #include "llviewercontrol.h" -#include "llfloatergroupinfo.h" #include "lltrans.h" #include "llinitparam.h" @@ -76,14 +75,14 @@ LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(LLNotificationPtr& notification const std::string& from_name = payload["sender_name"].asString(); std::stringstream from; from << from_name << "/" << groupData.mName; - LLTextBox* pTitleText = this->getChild<LLTextBox>("title", TRUE, FALSE); + LLTextBox* pTitleText = this->getChild<LLTextBox>("title"); pTitleText->setValue(from.str()); //message body const std::string& subject = payload["subject"].asString(); const std::string& message = payload["message"].asString(); - LLTextEditor* pMessageText = getChild< LLTextEditor>("message", TRUE, FALSE); + LLTextEditor* pMessageText = getChild< LLTextEditor>("message"); pMessageText->setValue(""); pMessageText->setEnabled(FALSE); pMessageText->setTakesFocus(FALSE); @@ -113,7 +112,7 @@ LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(LLNotificationPtr& notification //attachment BOOL hasInventory = payload["inventory_offer"].isDefined(); - LLTextBox * pAttachLink = getChild<LLTextBox>("attachment", TRUE, FALSE); + LLTextBox * pAttachLink = getChild<LLTextBox>("attachment"); pAttachLink->setVisible(hasInventory); if (hasInventory) { pAttachLink->setValue(payload["inventory_name"]); @@ -130,7 +129,7 @@ LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(LLNotificationPtr& notification } //ok button - LLButton* pOkBtn = getChild<LLButton>("btn_ok", TRUE, FALSE); + LLButton* pOkBtn = getChild<LLButton>("btn_ok"); pOkBtn->setClickedCallback((boost::bind(&LLToastGroupNotifyPanel::onClickOk, this))); setDefaultBtn(pOkBtn); } @@ -167,8 +166,7 @@ void LLToastGroupNotifyPanel::onClickAttachment() if (mInventoryOffer != NULL) { mInventoryOffer->forceResponse(IOR_ACCEPT); - LLTextBox * pAttachLink = getChild<LLTextBox> ("attachment", TRUE, - FALSE); + LLTextBox * pAttachLink = getChild<LLTextBox> ("attachment"); static const LLUIColor textColor = LLUIColorTable::instance().getColor( "GroupNotifyDimmedTextColor"); pAttachLink->setColor(textColor); diff --git a/indra/newview/lltoastpanel.cpp b/indra/newview/lltoastpanel.cpp index 79a7d45bbf..c39bac97a8 100644 --- a/indra/newview/lltoastpanel.cpp +++ b/indra/newview/lltoastpanel.cpp @@ -34,9 +34,28 @@ #include "lltoastpanel.h" -LLToastPanel::LLToastPanel(LLNotificationPtr& notification) { +LLToastPanel::LLToastPanel(LLNotificationPtr& notification) +{ mNotification = notification; } -LLToastPanel::~LLToastPanel() { +LLToastPanel::~LLToastPanel() +{ } + +std::string LLToastPanel::getTitle() +{ +// *TODO: localize header of Title +/* std::string title; + std::string notification_type = mNotification->getType(); + + if( notification_type == "groupnotify" ) + { + title = LLTrans::getString("TitleGroup"); + } +*/ + return (mNotification->getName() + "\n" + mNotification->getMessage()); +} + + + diff --git a/indra/newview/lltoastpanel.h b/indra/newview/lltoastpanel.h index 82e2a74672..2258eca273 100644 --- a/indra/newview/lltoastpanel.h +++ b/indra/newview/lltoastpanel.h @@ -36,6 +36,8 @@ #include "llpanel.h" #include "llnotifications.h" +#include <string> + /** * Base class for all panels that can be added to the toast. * All toast panels should contain necessary logic for representing certain notification @@ -46,6 +48,9 @@ class LLToastPanel: public LLPanel { public: LLToastPanel(LLNotificationPtr&); virtual ~LLToastPanel() = 0; + + virtual std::string getTitle(); + virtual const LLUUID& getID() { return mNotification->id();} protected: LLNotificationPtr mNotification; }; diff --git a/indra/newview/llurllineeditorctrl.cpp b/indra/newview/llurllineeditorctrl.cpp new file mode 100644 index 0000000000..046b3e619b --- /dev/null +++ b/indra/newview/llurllineeditorctrl.cpp @@ -0,0 +1,97 @@ +/** + * @file llurllineeditorctrl.cpp + * @brief LLURLLineEditor base class + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llclipboard.h" +#include "lluictrlfactory.h" + +#include "llurllineeditorctrl.h" + +#include "llweb.h" + +//Constructor +LLURLLineEditor::LLURLLineEditor(const LLLineEditor::Params& p) +: LLLineEditor(p){ + +} + +// copy selection to clipboard +void LLURLLineEditor::copy() +{ + if( canCopy() ) + { + copyEscapedURLToClipboard(); + } +} + +// cut selection to clipboard +void LLURLLineEditor::cut() +{ + if( canCut() ) + { + // Prepare for possible rollback + LLURLLineEditorRollback rollback( this ); + + copyEscapedURLToClipboard(); + + deleteSelection(); + + // Validate new string and rollback the if needed. + BOOL need_to_rollback = ( mPrevalidateFunc && !mPrevalidateFunc( mText.getWString() ) ); + if( need_to_rollback ) + { + rollback.doRollback( this ); + reportBadKeystroke(); + } + else + if( mKeystrokeCallback ) + { + mKeystrokeCallback( this ); + } + } +} +// Copies escaped URL to clipboard +void LLURLLineEditor::copyEscapedURLToClipboard() +{ + S32 left_pos = llmin( mSelectionStart, mSelectionEnd ); + S32 length = llabs( mSelectionStart - mSelectionEnd ); + + const std::string unescaped_text = wstring_to_utf8str(mText.getWString().substr(left_pos, length)); + LLWString selected_escaped_text = utf8str_to_wstring(LLWeb::escapeURL(unescaped_text)); + gClipboard.copyFromString( selected_escaped_text ); +} +// Makes UISndBadKeystroke sound +void LLURLLineEditor::reportBadKeystroke() +{ + make_ui_sound("UISndBadKeystroke"); +} diff --git a/indra/newview/llurllineeditorctrl.h b/indra/newview/llurllineeditorctrl.h new file mode 100644 index 0000000000..618f29dfbf --- /dev/null +++ b/indra/newview/llurllineeditorctrl.h @@ -0,0 +1,100 @@ +/** + * @file llurllineeditorctrl.h + * @brief Combobox-like location input control + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LLURLLINEEDITOR_H_ +#define LLURLLINEEDITOR_H_ + +#include "linden_common.h" + +#include "lllineeditor.h" +#include "lluictrl.h" + +// LLURLLineEditor class performing escaping of an URL while copying or cutting the target text +class LLURLLineEditor: public LLLineEditor { + LOG_CLASS( LLURLLineEditor); + +public: + // LLLineEditor overrides to do necessary escaping + /*virtual*/ void copy(); + /*virtual*/ void cut(); + +protected: + LLURLLineEditor(const Params&); + friend class LLUICtrlFactory; + friend class LLFloaterEditUI; + +private: + // util function to escape selected text and copy it to clipboard + void copyEscapedURLToClipboard(); + // send a beep signal if keystroke is bad. As it is private at LLLineEditor we need own function + void reportBadKeystroke(); + + // Helper class to do rollback if needed + class LLURLLineEditorRollback + { + public: + LLURLLineEditorRollback( LLURLLineEditor* ed ) + : + mCursorPos( ed->mCursorPos ), + mScrollHPos( ed->mScrollHPos ), + mIsSelecting( ed->mIsSelecting ), + mSelectionStart( ed->mSelectionStart ), + mSelectionEnd( ed->mSelectionEnd ) + { + mText = ed->getText(); + } + + void doRollback( LLURLLineEditor* ed ) + { + ed->mCursorPos = mCursorPos; + ed->mScrollHPos = mScrollHPos; + ed->mIsSelecting = mIsSelecting; + ed->mSelectionStart = mSelectionStart; + ed->mSelectionEnd = mSelectionEnd; + ed->mText = mText; + ed->mPrevText = mText; + } + + std::string getText() { return mText; } + + private: + std::string mText; + S32 mCursorPos; + S32 mScrollHPos; + BOOL mIsSelecting; + S32 mSelectionStart; + S32 mSelectionEnd; + }; // end class LLURLLineEditorRollback + +}; + +#endif /* LLURLLINEEDITOR_H_ */ diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index f573a0858b..c1915d2ead 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -63,7 +63,6 @@ #include "llfloaterfonttest.h" #include "llfloatergesture.h" #include "llfloatergodtools.h" -#include "llfloatergroupinfo.h" #include "llfloatergroups.h" #include "llfloaterhardwaresettings.h" #include "llfloaterhtmlcurrency.h" @@ -113,12 +112,12 @@ #include "llpreviewanim.h" #include "llpreviewgesture.h" -#include "llpreviewlandmark.h" #include "llpreviewnotecard.h" #include "llpreviewscript.h" #include "llpreviewsound.h" #include "llpreviewtexture.h" #include "llfloaterminiinspector.h" +#include "llsyswellwindow.h" //class LLLLFloaterObjectIMInfo; @@ -160,7 +159,6 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("gestures", "floater_gesture.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterGesture>); LLFloaterReg::add("god_tools", "floater_god_tools.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterGodTools>); - LLFloaterReg::add("group_info", "floater_groupinfo.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterGroupInfo>); LLFloaterReg::add("group_picker", "floater_choose_group.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterGroupPicker>); LLFloaterReg::add("hud", "floater_hud.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHUD>); @@ -182,6 +180,7 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("mute_object", "floater_mute_object.xml", &LLFloaterMute::buildFloaterMuteObjectUI); LLFloaterReg::add("mini_map", "floater_map.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMap>); LLFloaterReg::add("mini_inspector", "panel_mini_inspector.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMiniInspector>); + LLFloaterReg::add("syswell_window", "floater_sys_well.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLSysWellWindow>); LLFloaterReg::add("notifications_console", "floater_notifications_console.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterNotificationConsole>); LLFloaterReg::add("nearby_chat", "floater_nearby_chat.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLNearbyChat>); @@ -201,7 +200,6 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("pref_voicedevicesettings", "floater_device_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterVoiceDeviceSettings>); LLFloaterReg::add("preview_anim", "floater_preview_animation.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewAnim>, "preview"); LLFloaterReg::add("preview_gesture", "floater_preview_gesture.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewGesture>, "preview"); - LLFloaterReg::add("preview_landmark", "floater_preview_existing_landmark.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewLandmark>, "preview"); LLFloaterReg::add("preview_notecard", "floater_preview_notecard.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewNotecard>, "preview"); LLFloaterReg::add("preview_script", "floater_script_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewLSL>, "preview"); LLFloaterReg::add("preview_scriptedit", "floater_live_lsleditor.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLLiveLSLEditor>, "preview"); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 66b1869aef..db65203950 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -102,7 +102,6 @@ #include "llfloaterfonttest.h" #include "llfloatergesture.h" #include "llfloatergodtools.h" -#include "llfloatergroupinfo.h" #include "llfloatergroupinvite.h" #include "llfloatergroups.h" #include "llfloaterhtml.h" diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index f8b6e0f687..5849a40726 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -78,7 +78,6 @@ #include "llfloaterbuycurrency.h" #include "llfloaterbuyland.h" #include "llfloaterchat.h" -#include "llfloatergroupinfo.h" #include "llfloaterimagepreview.h" #include "llfloaterland.h" #include "llfloaterregioninfo.h" @@ -136,6 +135,7 @@ #include "llfloaterworldmap.h" #include "llviewerdisplay.h" #include "llkeythrottle.h" +#include "llgroupactions.h" #include <boost/tokenizer.hpp> #include <boost/algorithm/string/split.hpp> @@ -640,7 +640,7 @@ bool join_group_response(const LLSD& notification, const LLSD& response) if (option == 2 && !group_id.isNull()) { - LLFloaterGroupInfo::showFromUUID(group_id); + LLGroupActions::show(group_id); LLSD args; args["MESSAGE"] = message; LLNotifications::instance().add("JoinGroup", args, notification["payload"]); @@ -1743,7 +1743,8 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) // Also send down the old path for now. if (IM_GROUP_NOTICE_REQUESTED == dialog) { - LLFloaterGroupInfo::showNotice(subj,mes,group_id,has_inventory,item_name,info); + + LLPanelGroup::showNotice(subj,mes,group_id,has_inventory,item_name,info); } } break; diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index 3aefa84295..8497a45466 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -45,7 +45,6 @@ // Viewer includes #include "llagent.h" -#include "llfloatergroupinfo.h" #include "llviewerwindow.h" #include "llviewercontrol.h" #include "llfirstuse.h" diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp index afee30293a..9e0713b494 100644 --- a/indra/newview/llviewertexteditor.cpp +++ b/indra/newview/llviewertexteditor.cpp @@ -50,7 +50,6 @@ #include "llpreview.h" #include "llpreviewtexture.h" #include "llpreviewnotecard.h" -#include "llpreviewlandmark.h" #include "llscrollbar.h" #include "llsidetray.h" #include "lltooldraganddrop.h" @@ -1377,12 +1376,6 @@ void LLViewerTextEditor::openEmbeddedLandmark( LLInventoryItem* item, llwchar wc { panel->setItem(item); } - -// LLPreviewLandmark* preview = LLFloaterReg::showTypedInstance<LLPreviewLandmark>("preview_landmark", LLSD(item->getUUID()), TAKE_FOCUS_YES); -// if (preview) -// { -// preview->setItem( item ); -// } } void LLViewerTextEditor::openEmbeddedNotecard( LLInventoryItem* item, llwchar wc ) diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index b502dbe6fc..2747763cd9 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1559,9 +1559,6 @@ void LLViewerWindow::initWorldUI() getRootView()->sendChildToFront(gSnapshotFloaterView); // new bottom panel - getRootView()->addChild(LLBottomTray::getInstance()); - // Make sure Bottom Tray is behind Side Tray regardless "addChild" order. - getRootView()->sendChildToBack(LLBottomTray::getInstance()); LLRect rc = LLBottomTray::getInstance()->getRect(); rc.mLeft = 0; rc.mRight = mRootView->getRect().getWidth(); @@ -1634,6 +1631,16 @@ void LLViewerWindow::initWorldUI() navbar->translate(0, root_rect.getHeight() - menu_bar_height - navbar->getRect().getHeight()); // FIXME navbar->setBackgroundColor(gMenuBarView->getBackgroundColor().get()); + if (!gSavedSettings.getBOOL("ShowNavbarNavigationPanel")) + { + navbar->showNavigationPanel(FALSE); + } + + if (!gSavedSettings.getBOOL("ShowNavbarFavoritesPanel")) + { + navbar->showFavoritesPanel(FALSE); + } + getRootView()->addChild(gStatusBar); getRootView()->addChild(navbar); diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index f1d4520370..2304571cf1 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -1510,6 +1510,7 @@ std::string LLVoiceClientStatusObserver::status2string(LLVoiceClientStatusObserv CASE(STATUS_JOINED); CASE(STATUS_LEFT_CHANNEL); CASE(STATUS_VOICE_DISABLED); + CASE(STATUS_VOICE_ENABLED); CASE(BEGIN_ERROR_STATUS); CASE(ERROR_CHANNEL_FULL); CASE(ERROR_CHANNEL_LOCKED); @@ -5786,7 +5787,7 @@ bool LLVoiceClient::getMuteMic() const void LLVoiceClient::setUserPTTState(bool ptt) { mUserPTTState = ptt; - LLNearbyChatBar::getInstance()->setPTTState(ptt); + if (LLNearbyChatBar::instanceExists()) LLNearbyChatBar::getInstance()->setPTTState(ptt); } bool LLVoiceClient::getUserPTTState() @@ -5797,7 +5798,7 @@ bool LLVoiceClient::getUserPTTState() void LLVoiceClient::toggleUserPTTState(void) { mUserPTTState = !mUserPTTState; - LLNearbyChatBar::getInstance()->setPTTState(mUserPTTState); + if (LLNearbyChatBar::instanceExists()) LLNearbyChatBar::getInstance()->setPTTState(mUserPTTState); } void LLVoiceClient::setVoiceEnabled(bool enabled) @@ -5805,15 +5806,21 @@ void LLVoiceClient::setVoiceEnabled(bool enabled) if (enabled != mVoiceEnabled) { mVoiceEnabled = enabled; + LLVoiceClientStatusObserver::EStatusType status; + if (enabled) { LLVoiceChannel::getCurrentVoiceChannel()->activate(); + status = LLVoiceClientStatusObserver::STATUS_VOICE_ENABLED; } else { // Turning voice off looses your current channel -- this makes sure the UI isn't out of sync when you re-enable it. LLVoiceChannel::getCurrentVoiceChannel()->deactivate(); + status = LLVoiceClientStatusObserver::STATUS_VOICE_DISABLED; } + + notifyStatusObservers(status); } } diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h index 8b3bbb68bb..fe99e787da 100644 --- a/indra/newview/llvoiceclient.h +++ b/indra/newview/llvoiceclient.h @@ -65,6 +65,11 @@ public: STATUS_JOINED, STATUS_LEFT_CHANNEL, STATUS_VOICE_DISABLED, + + // Adding STATUS_VOICE_ENABLED as pair status for STATUS_VOICE_DISABLED + // See LLVoiceClient::setVoiceEnabled() + STATUS_VOICE_ENABLED, + BEGIN_ERROR_STATUS, ERROR_CHANNEL_FULL, ERROR_CHANNEL_LOCKED, diff --git a/indra/newview/skins/default/xui/en/favorites_bar_button.xml b/indra/newview/skins/default/xui/en/favorites_bar_button.xml new file mode 100644 index 0000000000..4525df31b6 --- /dev/null +++ b/indra/newview/skins/default/xui/en/favorites_bar_button.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<!-- *NOTE: mantipov: to use the "use_ellipses" attribute label should be LEFT aligned +untill LLFontGL::render() is fixed to avoid this requirement--> +<!-- *NOTE: mantipov: top & height should be synchronized with <favorites_bar> in the panel_navigation_bar.xml--> +<!-- All buttons in the Favorites bar will be created from this one --> +<button + follows="left|bottom" + halign="left" + height="23" + image_disabled="transparent.j2c" + image_disabled_selected="PushButton_Selected" + image_hover_selected="PushButton_Selected" + image_hover_unselected="PushButton_Off" + image_selected="PushButton_Selected" + image_unselected="transparent.j2c" + layout="topleft" + left="2" + name="favorites_bar_btn" + tab_stop="false" + top="2" + use_ellipses="true" + width="120" /> diff --git a/indra/newview/skins/default/xui/en/floater_avatar_picker.xml b/indra/newview/skins/default/xui/en/floater_avatar_picker.xml index 0012294160..b0472eb7e2 100644 --- a/indra/newview/skins/default/xui/en/floater_avatar_picker.xml +++ b/indra/newview/skins/default/xui/en/floater_avatar_picker.xml @@ -157,7 +157,7 @@ label="Range" layout="topleft" left="10" - max_val="40" + max_val="130" min_val="5" name="near_me_range" top="32" diff --git a/indra/newview/skins/default/xui/en/floater_sys_well.xml b/indra/newview/skins/default/xui/en/floater_sys_well.xml new file mode 100644 index 0000000000..468d41e2f0 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_sys_well.xml @@ -0,0 +1,99 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater + background_opaque="false" + background_visible="true" + bevel_style="in" + bg_alpha_color="0.0 0.0 0.0 0.0" + height="60" + left="0" + top="0" + follows="right|bottom" + layout="topleft" + name="notification_chiclet" + save_rect="true" + title="" + width="320" + can_minimize="false" + can_tear_off="false" + can_resize="false" + can_drag_on_left="false" + can_close="false" + can_dock="false" +> + <scroll_container + follows="top|bottom" + layout="topleft" + name="notification_list_container" + left="1" + top="30" + width="336" + height="30"> + <scrolling_panel_list + follows="left|right" + layout="topleft" + name="notification_list" + left="0" + top="0" + height="20" + width="320" /> + </scroll_container> + + <panel + top="0" + width="320" + height="30" + layout="topleft" + follows="top|left|right" + background_visible="true" + background_opaque="false" + bg_alpha_color="0.0 0.0 0.0 1.0" + name="notification_caption" + > + <text + width="255" + left="25" + height="20" + layout="topleft" + follows="left|right|top" + font="SansSerifBoldBig" + text_color="white" + word_wrap="true" + mouse_opaque="true" + name="sender_name" + > + NOTIFICATIONS + </text> + <button + top="5" + left="270" + width="15" + height="15" + layout="topleft" + follows="right" + label="" + toggle="true" + image_unselected="arrow_up.tga" + image_disabled="arrow_up.tga" + image_selected="arrow_down.tga" + image_hover_selected="arrow_down.tga" + image_disabled_selected="arrow_down.tga" + name="tear_btn" + /> + <button + top="5" + left="300" + width="15" + height="15" + layout="topleft" + follows="right" + label="" + image_unselected="closebox.tga" + image_disabled="closebox.tga" + image_selected="closebox.tga" + image_hover_selected="closebox.tga" + image_disabled_selected="closebox.tga" + name="close_btn" + /> + </panel> + +</floater> diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml index 4c880f6dc0..91039539f9 100644 --- a/indra/newview/skins/default/xui/en/panel_bottomtray.xml +++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml @@ -127,8 +127,8 @@ <split_button.item image_selected="camera_presets/camera_presets_34_view.png" image_unselected="camera_presets/camera_presets_34_view.png" - name="3/4_view" - tool_tip="3/4 View" + name="group_view" + tool_tip="Group View" /> <split_button.item image_selected="camera_presets/camera_presets_fron_view.png" diff --git a/indra/newview/skins/default/xui/en/panel_group_general.xml b/indra/newview/skins/default/xui/en/panel_group_general.xml index fcae65dd69..b9a384bf8f 100644 --- a/indra/newview/skins/default/xui/en/panel_group_general.xml +++ b/indra/newview/skins/default/xui/en/panel_group_general.xml @@ -4,6 +4,7 @@ follows="all" height="514" label="General" + class="panel_group_general" layout="topleft" left="1" name="general_tab" diff --git a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml new file mode 100644 index 0000000000..4f179d7a16 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml @@ -0,0 +1,88 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> + +<panel + follows="left|top|right|bottom" + height="660" + label="Group Info" + layout="topleft" + name="panel_group_info" + border="false" + width="300"> + <panel.string + name="default_needs_apply_text"> + There are unapplied changes on the current tab. + </panel.string> + <panel.string + name="want_apply_text"> + Do you want to apply these changes? + </panel.string> + + <button + layout="topleft" + name="back" + left="5" + top="5" + width="20" + height="20" + label="" + follows="top|left" + image_selected="navbar_bg_button.tga" + image_unselected="navbar_bg_button.tga" + image_overlay="navbar_back.tga"/> + <text + layout="topleft" + top="5" + left_pad="15" + width="200" + height="20" + font="SansSerifBold" + text_color="white" + follows="top|left|right" + mouse_opaque="true" + name="group_name">(Loading...)</text> + <button + top="632" + height="20" + font="SansSerifSmall" + label="Apply" + label_selected="Apply" + name="btn_apply" + left="5" + width="65" /> + <button + top="632" + left="75" + height="20" + ont="SansSerifSmall" + label="Refresh" + label_selected="Refresh" + name="btn_refresh" + follows="top|left" + width="65" /> + <button + top="632" + height="20" + font="SansSerifSmall" + label="Create" + label_selected="Create" + name="btn_create" + left="5" + visible="false" + width="65" /> + <accordion layout="topleft" left="2" width="296" top="28" height="600" follows="all" name="panel_me_profile"> + <accordion_tab min_height="515" title="Group General" name="group_general_tab"> + <panel class="panel_group_general" filename="panel_group_general.xml" name="group_general_tab_panel"/> + </accordion_tab> + <accordion_tab min_height="380" title="Group Roles" name="group_roles_tab" can_resize="false"> + <panel class="panel_group_roles" filename="panel_group_roles.xml" name="group_roles_tab_panel"/> + </accordion_tab> + <accordion_tab min_height="530" title="Group Notices" name="group_notices_tab" can_resize="false"> + <panel class="panel_group_notices" filename="panel_group_notices.xml" name="group_notices_tab_panel"/> + </accordion_tab> + <accordion_tab min_height="270" title="Group Land Money" name="group_land_tab" can_resize="false"> + <panel class="panel_group_land_money" filename="panel_group_land_money.xml" name="group_land_tab_panel"/> + </accordion_tab> + </accordion> + + +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_group_land_money.xml b/indra/newview/skins/default/xui/en/panel_group_land_money.xml index b96421ca2f..c52994b43d 100644 --- a/indra/newview/skins/default/xui/en/panel_group_land_money.xml +++ b/indra/newview/skins/default/xui/en/panel_group_land_money.xml @@ -2,7 +2,7 @@ <panel border="true" follows="all" - height="514" + height="420" label="Land & L$" layout="topleft" left="1" @@ -281,7 +281,7 @@ bg_readonly_color="0.784314 0.819608 0.8 1" follows="all" font="Monospace" - height="150" + height="180" layout="topleft" left="8" max_length="4096" diff --git a/indra/newview/skins/default/xui/en/panel_group_roles.xml b/indra/newview/skins/default/xui/en/panel_group_roles.xml index dd6cd8c95e..132c06d028 100644 --- a/indra/newview/skins/default/xui/en/panel_group_roles.xml +++ b/indra/newview/skins/default/xui/en/panel_group_roles.xml @@ -1,12 +1,11 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <panel border="true" - height="530" + height="380" label="Members & Roles" layout="topleft" left="1" name="roles_tab" - top="530" width="280"> <panel.string name="default_needs_apply_text"> @@ -31,7 +30,7 @@ --> <panel follows="left|top" - height="24" + height="80" layout="topleft" left="10" name="members_header" @@ -174,7 +173,7 @@ left_delta="0" name="roles_tab_container" tab_position="top" - top="70" + top="80" width="265"> <panel border="true" @@ -185,6 +184,7 @@ name="members_sub_tab" tool_tip="Members" top="16" + class="panel_group_members_subtab" width="265"> <panel.string name="help_text"> @@ -279,6 +279,7 @@ clicking on their names. layout="topleft" left_delta="0" name="roles_sub_tab" + class="panel_group_roles_subtab" top_delta="0" width="265"> <panel.string @@ -384,6 +385,7 @@ including the Everyone and Owner Roles. layout="topleft" left_delta="0" name="actions_sub_tab" + class="panel_group_actions_subtab" top_delta="0" width="265"> <panel.string diff --git a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml index 4904a0d40a..8d90c6ebf0 100644 --- a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml +++ b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml @@ -8,118 +8,124 @@ layout="topleft" name="navigation_bar" width="600"> - <button - follows="left|top" - font="SansSerifSmall" - height="23" - image_disabled="PushButton_Disabled" - image_disabled_selected="PushButton_Disabled" - image_overlay="Arrow_Left_Off" - image_selected="PushButton_Selected" - image_unselected="PushButton_Off" - hover_glow_amount="0.15" - layout="topleft" - left="10" - name="back_btn" - picture_style="true" - tool_tip="Go back to previous location" - top="8" - width="31" /> - - <button - follows="left|top" - font="SansSerifSmall" - height="23" - image_disabled="PushButton_Disabled" - image_disabled_selected="PushButton_Disabled" - image_overlay="Arrow_Right_Off" - image_selected="PushButton_Selected" - image_unselected="PushButton_Off" - hover_glow_amount="0.15" - layout="topleft" - left_pad="0" - name="forward_btn" - picture_style="true" - tool_tip="Go forward one location" - top_delta="0" - width="31" /> - <button - follows="left|top" - font="SansSerifSmall" - height="23" - image_disabled="PushButton_Disabled" - image_disabled_selected="PushButton_Disabled" - image_overlay="Home_Off" - image_selected="PushButton_Selected" - image_unselected="PushButton_Off" - hover_glow_amount="0.15" - layout="topleft" - left_pad="7" - name="home_btn" - picture_style="true" - tool_tip="Teleport to your home location" - top_delta="0" - width="32" /> - <location_input - follows="left|right|top" - halign="right" - height="22" - label="Location" - layout="topleft" - left_pad="7" - max_chars="254" - mouse_opaque="false" - name="location_combo" - top_delta="0" - width="266"> - <!-- *TODO: Delete. Let the location_input use the correct art sizes. - <location_input.add_landmark_button - height="18" - name="location_combo_add" - width="20" /> - <location_input.info_button - height="18" - name="location_combo_info" - width="20" /> - --> - </location_input> - -<!-- <button --> -<!-- follows="right|top" --> -<!-- height="20" --> -<!-- image_disabled="TextField_Search_Off" --> -<!-- image_disabled_selected="TextField_Search_Off" --> -<!-- image_hover_selected="TextField_Search_Off" --> -<!-- image_hover_unselected="TextField_Search_Off" --> -<!-- image_selected="TextField_Search_Off" --> -<!-- image_unselected="TextField_Search_Off" --> -<!-- layout="topleft" --> -<!-- left_pad="5" --> -<!-- mouse_opaque="false" --> -<!-- name="search_bg" --> -<!-- picture_style="true" --> -<!-- top_delta="0" --> -<!-- width="168" /> --> - - <search_editor - bevel_style="none" - border_style="line" - border.border_thickness="0" - commit_on_focus_lost="false" - follows="right|top" - halign="right" - height="22" - label="Search All" - layout="topleft" - left_pad="7" - mouse_opaque="false" - name="search_input" - tool_tip="Search All" - top_delta="0" - width="200" /> - - - + <panel + background_visible="false" + follows="left|top|right" + height="60" + layout="topleft" + name="navigation_panel" + width="600"> + <button + follows="left|top" + font="SansSerifSmall" + height="23" + image_disabled="PushButton_Disabled" + image_disabled_selected="PushButton_Disabled" + image_overlay="Arrow_Left_Off" + image_selected="PushButton_Selected" + image_unselected="PushButton_Off" + hover_glow_amount="0.15" + layout="topleft" + left="10" + name="back_btn" + picture_style="true" + tool_tip="Go back to previous location" + top="3" + width="31" /> + + <button + follows="left|top" + font="SansSerifSmall" + height="23" + image_disabled="PushButton_Disabled" + image_disabled_selected="PushButton_Disabled" + image_overlay="Arrow_Right_Off" + image_selected="PushButton_Selected" + image_unselected="PushButton_Off" + hover_glow_amount="0.15" + layout="topleft" + left_pad="0" + name="forward_btn" + picture_style="true" + tool_tip="Go forward one location" + top_delta="0" + width="31" /> + <button + follows="left|top" + font="SansSerifSmall" + height="23" + image_disabled="PushButton_Disabled" + image_disabled_selected="PushButton_Disabled" + image_overlay="Home_Off" + image_selected="PushButton_Selected" + image_unselected="PushButton_Off" + hover_glow_amount="0.15" + layout="topleft" + left_pad="7" + name="home_btn" + picture_style="true" + tool_tip="Teleport to your home location" + top_delta="0" + width="32" /> + <location_input + follows="left|right|top" + halign="right" + height="22" + label="Location" + layout="topleft" + left_pad="7" + max_chars="254" + mouse_opaque="false" + name="location_combo" + top_delta="0" + width="266"> + <!-- *TODO: Delete. Let the location_input use the correct art sizes. + <location_input.add_landmark_button + height="18" + name="location_combo_add" + width="20" /> + <location_input.info_button + height="18" + name="location_combo_info" + width="20" /> + --> + </location_input> + + <!-- <button --> + <!-- follows="right|top" --> + <!-- height="20" --> + <!-- image_disabled="TextField_Search_Off" --> + <!-- image_disabled_selected="TextField_Search_Off" --> + <!-- image_hover_selected="TextField_Search_Off" --> + <!-- image_hover_unselected="TextField_Search_Off" --> + <!-- image_selected="TextField_Search_Off" --> + <!-- image_unselected="TextField_Search_Off" --> + <!-- layout="topleft" --> + <!-- left_pad="5" --> + <!-- mouse_opaque="false" --> + <!-- name="search_bg" --> + <!-- picture_style="true" --> + <!-- top_delta="0" --> + <!-- width="168" /> --> + + <search_editor + bevel_style="none" + border_style="line" + border.border_thickness="0" + commit_on_focus_lost="false" + follows="right|top" + halign="right" + height="22" + label="Search All" + layout="topleft" + left_pad="7" + mouse_opaque="false" + name="search_input" + tool_tip="Search All" + top_delta="0" + width="200" /> + </panel> + <favorites_bar follows="left|right|top" height="25" diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml index dc12bb7239..bccc04e30c 100644 --- a/indra/newview/skins/default/xui/en/panel_people.xml +++ b/indra/newview/skins/default/xui/en/panel_people.xml @@ -20,7 +20,6 @@ height="23" follows="left|top|right" max_length="270" - label="Filter People" name="filter_input" font="SansSerif" background_image="TextField_Search_Off" @@ -494,4 +493,10 @@ <string name="no_groups"> No groups </string> + <string name="people_filter_label"> + Filter People + </string> + <string name="groups_filter_label"> + Filter Groups + </string> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_profile.xml b/indra/newview/skins/default/xui/en/panel_profile.xml index 7d2f76da5e..2a49db8d4f 100644 --- a/indra/newview/skins/default/xui/en/panel_profile.xml +++ b/indra/newview/skins/default/xui/en/panel_profile.xml @@ -181,7 +181,7 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet ipsum. </text> </panel> - <text + <link type="string" follows="left|top|right" font="SansSerifSmall" @@ -191,9 +191,10 @@ left="10" name="homepage_edit" text_color="HTMLLinkColor" + hover_color="0.5 0.4 1 1" width="280"> TODO - </text> + </link> <text type="string" follows="left|top" @@ -286,7 +287,7 @@ word_wrap="true"> [FIRST] [LAST] </text> - <text + <link type="string" follows="top|right" font="SansSerifSmall" @@ -295,10 +296,11 @@ left_delta="0" name="partner_edit_link" text_color="HTMLLinkColor" + hover_color="0.5 0.4 1 1" top_delta="15" width="40"> Edit - </text> + </link> </panel> <text type="string" @@ -336,7 +338,7 @@ top_pad="30" name="account_actions_panel" width="200"> - <text + <link type="string" follows="left|top" font="SansSerif" @@ -345,12 +347,12 @@ left="0" name="payment_update_link" text_color="HTMLLinkColor" + hover_color="0.5 0.4 1 1" top="0" width="100"> Update - </text> - <text - type="string" + </link> + <link follows="left|top" font="SansSerif" height="15" @@ -358,10 +360,11 @@ left="70" name="my_account_link" text_color="HTMLLinkColor" + hover_color="0.5 0.4 1 1" top="0" width="80"> My Account - </text> + </link> </panel--> diff --git a/indra/newview/skins/default/xui/en/panel_side_tray.xml b/indra/newview/skins/default/xui/en/panel_side_tray.xml index 8953633276..a7b66d8555 100644 --- a/indra/newview/skins/default/xui/en/panel_side_tray.xml +++ b/indra/newview/skins/default/xui/en/panel_side_tray.xml @@ -50,9 +50,16 @@ filename="panel_profile_view.xml" border="true" /> + <panel + class="panel_group_info_sidetray" + name="panel_group_info_sidetray" + filename="panel_group_info_sidetray.xml" + label="Group Info" + border="true" + /> + </panel_container> </sidetray_tab> - <!-- *TODO Vadim: isn't the sidetray_tab "label" attribute redundant since we have "tab_title" ? --> <sidetray_tab name="sidebar_places" tab_title="Places" @@ -82,94 +89,14 @@ bg_opaque_color="0.5 0.5 0.5 1.0" > <panel - class="panel_me_profile" + class="panel_me_profile_view" name="panel_me_profile" filename="panel_me_profile.xml" label="Me" border="true" /> </sidetray_tab> - <!-- - <sidetray_tab - name="sidebar_group" - mouse_opaque="false" - background_visible="true" - bg_opaque_color="0.5 0.5 0.5 1.0" - image="icn_voice-groupfocus.tga" - tab_title="Groups" - description="Manage Groups." - > - <accordion_tab - name="group_accordion" - title="Group General" - expanded="true" - collapsible="true" - min_width="200" - min_height="200" - header_visible="true" - > - <panel - class="panel_group_general" - name="panel_group_general" - filename="panel_group_general.xml" - label="Group" - border="true" - /> - </accordion_tab> - <accordion_tab - name="groupland_accordion" - title="Group Land and Money" - expanded="false" - collapsible="true" - min_width="200" - min_height="200" - header_visible="true" - > - <panel - class="panel_group_land" - name="panel_group_land" - filename="panel_group_land_money.xml" - label="Group" - border="true" - /> - </accordion_tab> - <accordion_tab - name="groupnotices_accordion" - title="Group Notices" - expanded="false" - collapsible="true" - min_width="200" - min_height="200" - header_visible="true" - > - <panel - class="panel_group_roles" - name="panel_group_roles" - filename="panel_group_roles.xml" - label="Group" - border="true" - /> - </accordion_tab> - <accordion_tab - name="grouproles_accordion" - title="Group Roles" - expanded="false" - collapsible="true" - min_width="200" - min_height="200" - header_visible="true" - > - <panel - class="panel_group_roles" - name="panel_group_roles" - filename="panel_group_roles.xml" - label="Group" - border="true" - /> - </accordion_tab> - </sidetray_tab> - <sidetray_tab name="sidebar_previews" diff --git a/indra/newview/skins/default/xui/en/panel_sys_well_item.xml b/indra/newview/skins/default/xui/en/panel_sys_well_item.xml new file mode 100644 index 0000000000..eccb919b04 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_sys_well_item.xml @@ -0,0 +1,64 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<!-- All our XML is utf-8 encoded. --> + +<panel + name="sys_well_item" + title="sys_well_item" + visible="false" + top="0" + left="0" + width="318" + height="35" + layout="topleft" + follows="top" + background_opaque="false" + background_visible="true" + bg_alpha_color="0.0 0.0 0.0 0.0" > + + <icon + top="8" + left="8" + width="20" + height="20" + layout="topleft" + follows="left" + name="icon" + label="" + mouse_opaque="false" + image_name="lag_status_warning.tga" + /> + + <text + top="2" + left_pad="8" + width="255" + height="28" + layout="topleft" + follows="right|left" + font="SansSerifBold" + text_color="white" + use_ellipses="true" + word_wrap="true" + mouse_opaque="false" + name="title" > + Select your streaming media preference. Select your streaming media preference. + </text> + + <button + top="5" + left_pad="5" + width="15" + height="15" + layout="topleft" + follows="right" + name="close_btn" + mouse_opaque="true" + label="" + image_unselected="toast_hide_btn.tga" + image_disabled="toast_hide_btn.tga" + image_selected="toast_hide_btn.tga" + image_hover_selected="toast_hide_btn.tga" + image_disabled_selected="toast_hide_btn.tga" + /> + +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_toast.xml b/indra/newview/skins/default/xui/en/panel_toast.xml index ba4915e074..f7d8cf948e 100644 --- a/indra/newview/skins/default/xui/en/panel_toast.xml +++ b/indra/newview/skins/default/xui/en/panel_toast.xml @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <!-- All our XML is utf-8 encoded. --> -<panel +<floater name="toast" - title="toast" + title="" visible="false" layout="topleft" width="350" @@ -14,6 +14,12 @@ background_opaque="true" background_visible="true" bevel_style="in" + can_minimize="false" + can_tear_off="false" + can_resize="false" + can_drag_on_left="false" + can_close="false" + can_dock="false" bg_alpha_color="0.3 0.3 0.3 1.0"> <text @@ -62,4 +68,4 @@ image_hover_selected="toast_hide_btn.tga" image_disabled_selected="toast_hide_btn.tga" /> -</panel> +</floater> diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index fb3d3b4dea..ec4898448a 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -320,7 +320,14 @@ <string name="GroupNotifyViewPastNotices">View past notices or opt-out of receiving these messages here.</string> <string name="GroupNotifyOpenAttachment">Open Attachment</string> <string name="GroupNotifySaveAttachment">Save Attachment</string> - + <string name="TeleportOffer">Teleport offering</string> + <!-- start-up toast's string--> + <string name="StartUpNotification">%d new notification arrived while you were away...</string> + <string name="StartUpNotifications">%d new notifications arrived while you were away...</string> + <!-- overflow toast's string--> + <string name="OverflowInfoChannelString">You have %d more notification</string> + + <!-- body parts --> <string name="BodyPartsRightArm">Right Arm</string> <string name="BodyPartsHead">Head</string> diff --git a/indra/newview/skins/default/xui/en/widgets/location_input.xml b/indra/newview/skins/default/xui/en/widgets/location_input.xml index eb9bb99b20..777651c452 100644 --- a/indra/newview/skins/default/xui/en/widgets/location_input.xml +++ b/indra/newview/skins/default/xui/en/widgets/location_input.xml @@ -42,7 +42,7 @@ <combo_list bg_writeable_color="MenuDefaultBgColor"/> <combo_editor name="Combo Text Entry" text_pad_left="20" - select_on_focus="true" + select_on_focus="false" font="SansSerifSmall" bevel_style="none" border_style="line" |