diff options
Diffstat (limited to 'indra/newview')
55 files changed, 1197 insertions, 689 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index e52b523a7f..58d7a983a2 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -65,6 +65,7 @@ include_directories( set(viewer_SOURCE_FILES llaccordionctrltab.cpp llaccordionctrl.cpp + llactiveimwindow.cpp llagent.cpp llagentaccess.cpp llagentdata.cpp @@ -508,6 +509,7 @@ set(viewer_HEADER_FILES ViewerInstall.cmake llaccordionctrltab.h llaccordionctrl.h + llactiveimwindow.h llagent.h llagentaccess.h llagentdata.h diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index f42ce2136f..06873c599c 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -3216,7 +3216,7 @@ <key>Value</key> <array> <real>1.5</real> - <real>0.5</real> + <real>0.7</real> <real>1.0</real> </array> </map> @@ -9727,16 +9727,5 @@ <key>Value</key> <integer>0</integer> </map> - <key>GroupTeleportMembersLimit</key> - <map> - <key>Comment</key> - <string>Max number of members of group to offer teleport</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>U32</string> - <key>Value</key> - <integer>100</integer> - </map> </map> </llsd> diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 513988789b..4166d96219 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -5272,6 +5272,7 @@ BOOL LLAgent::buildLocationString(std::string& str, ELocationFormat fmt) case LOCATION_FORMAT_NORMAL: buffer = llformat("%s", region_name.c_str()); break; + case LOCATION_FORMAT_WITHOUT_SIM: case LOCATION_FORMAT_FULL: buffer = llformat("%s (%d, %d, %d)", region_name.c_str(), @@ -5292,6 +5293,12 @@ BOOL LLAgent::buildLocationString(std::string& str, ELocationFormat fmt) region_name.c_str(), parcel_name.c_str()); break; + case LOCATION_FORMAT_WITHOUT_SIM: + buffer = llformat("%s, %s (%d, %d, %d)", + region_name.c_str(), + parcel_name.c_str(), + pos_x, pos_y, pos_z); + break; case LOCATION_FORMAT_FULL: std::string sim_access_string = region->getSimAccessString(); buffer = llformat("%s, %s (%d, %d, %d)%s%s", diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index ff9e7f574f..3a8cf5fd97 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -268,6 +268,7 @@ public: { LOCATION_FORMAT_NORMAL, LOCATION_FORMAT_LANDMARK, + LOCATION_FORMAT_WITHOUT_SIM, LOCATION_FORMAT_FULL, }; void setRegion(LLViewerRegion *regionp); diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp index bfb2d26870..2687feb68b 100644 --- a/indra/newview/llbottomtray.cpp +++ b/indra/newview/llbottomtray.cpp @@ -42,6 +42,7 @@ #include "llsplitbutton.h" #include "llfloatercamera.h" #include "llimpanel.h" +#include "llactiveimwindow.h" LLBottomTray::LLBottomTray(const LLSD&) : mChicletPanel(NULL), @@ -75,6 +76,8 @@ LLBottomTray::LLBottomTray(const LLSD&) // Necessary for focus movement among child controls setFocusRoot(TRUE); + + LLActiveIMWindow::init(mIMWell); } BOOL LLBottomTray::postBuild() @@ -104,8 +107,10 @@ void LLBottomTray::onChicletClick(LLUICtrl* ctrl) // Show after comm window so it is frontmost (and hence will not // auto-hide) - LLIMFloater::show(chiclet->getSessionId()); - chiclet->setCounter(0); + +// this logic has been moved to LLIMChiclet::handleMouseDown +// LLIMFloater::show(chiclet->getSessionId()); +// chiclet->setCounter(0); } } @@ -130,6 +135,7 @@ void LLBottomTray::sessionAdded(const LLUUID& session_id, const std::string& nam chiclet->setOtherParticipantId(other_participant_id); } } + updateImChicletCount(); } //virtual @@ -139,6 +145,7 @@ void LLBottomTray::sessionRemoved(const LLUUID& session_id) { getChicletPanel()->removeChiclet(session_id); } + updateImChicletCount(); } //virtual @@ -177,3 +184,8 @@ void LLBottomTray::setVisible(BOOL visible) } } } + +void LLBottomTray::updateImChicletCount() { + U32 chicletCount = mChicletPanel->getChicletCount(); + mIMWell->setCounter(chicletCount); +} diff --git a/indra/newview/llbottomtray.h b/indra/newview/llbottomtray.h index fec533f9f3..7f606339bc 100644 --- a/indra/newview/llbottomtray.h +++ b/indra/newview/llbottomtray.h @@ -68,6 +68,9 @@ public: virtual void onFocusLost(); virtual void setVisible(BOOL visible); +private: + void updateImChicletCount(); + protected: LLBottomTray(const LLSD& key = LLSD()); diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp index a63477a442..45b322e106 100644 --- a/indra/newview/llchatitemscontainerctrl.cpp +++ b/indra/newview/llchatitemscontainerctrl.cpp @@ -246,7 +246,9 @@ void LLChatItemCtrl::setHeaderVisibility(EShowItemHeader e) bool LLChatItemCtrl::canAddText () { - LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text", false); + LLChatMsgBox* msg_text = findChild<LLChatMsgBox>("msg_text"); + if(!msg_text) + return false; return msg_text->getTextLinesNum()<10; } diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp index 80e27bd366..d98f03eccb 100644 --- a/indra/newview/llchiclet.cpp +++ b/indra/newview/llchiclet.cpp @@ -54,6 +54,9 @@ static LLDefaultChildRegistry::Register<LLTalkButton> t2("chiclet_talk"); static LLDefaultChildRegistry::Register<LLNotificationChiclet> t3("chiclet_notification"); static LLDefaultChildRegistry::Register<LLIMChiclet> t4("chiclet_im"); +boost::signals2::signal<LLChiclet* (const LLUUID&), + LLIMChiclet::CollectChicletCombiner<std::list<LLChiclet*> > > + LLIMChiclet::sFindChicletsSignal; ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// @@ -290,6 +293,16 @@ void LLIMChiclet::setOtherParticipantId(const LLUUID& other_participant_id) } } +LLUUID LLIMChiclet::getOtherParticipantId() +{ + LLUUID res = LLUUID::null; + if (mAvatarCtrl) + { + res = mAvatarCtrl->getAvatarId(); + } + return res; +} + void LLIMChiclet::updateMenuItems() { if(!mPopupMenu) @@ -306,6 +319,13 @@ void LLIMChiclet::updateMenuItems() } } +BOOL LLIMChiclet::handleMouseDown(S32 x, S32 y, MASK mask) +{ + LLIMFloater::show(getSessionId()); + setCounter(0); + return LLChiclet::handleMouseDown(x, y, mask); +} + void LLIMChiclet::setShowSpeaker(bool show) { bool needs_resize = getShowSpeaker() != show; @@ -491,16 +511,20 @@ LLChicletPanel::~LLChicletPanel() void im_chiclet_callback(LLChicletPanel* panel, const LLSD& data){ LLUUID session_id = data["session_id"].asUUID(); - LLChiclet* chiclet = panel->findChiclet<LLChiclet>(session_id); - - if (chiclet) - { - chiclet->setCounter(data["num_unread"].asInteger()); + std::list<LLChiclet*> chiclets = LLIMChiclet::sFindChicletsSignal(session_id); + std::list<LLChiclet *>::iterator iter; + for (iter = chiclets.begin(); iter != chiclets.end(); iter++) { + LLChiclet* chiclet = *iter; + if (chiclet != NULL) + { + chiclet->setCounter(data["num_unread"].asInteger()); + } + else + { + llwarns << "Unable to set counter for chiclet " << session_id << llendl; + } } - else - { - llwarns << "Unable to set counter for chiclet " << session_id << llendl; - } + } @@ -508,6 +532,7 @@ BOOL LLChicletPanel::postBuild() { LLPanel::postBuild(); LLIMModel::instance().addChangedCallback(boost::bind(im_chiclet_callback, this, _1)); + LLIMChiclet::sFindChicletsSignal.connect(boost::bind(&LLChicletPanel::findChiclet<LLChiclet>, this, _1)); return TRUE; } diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h index 103443ccd8..f66d799c25 100644 --- a/indra/newview/llchiclet.h +++ b/indra/newview/llchiclet.h @@ -264,6 +264,11 @@ public: virtual void setOtherParticipantId(const LLUUID& other_participant_id); /* + * Gets id of person/group user is chatting with. + */ + virtual LLUUID getOtherParticipantId(); + + /* * Shows/hides voice chat status control. */ virtual void setShowSpeaker(bool show); @@ -326,6 +331,8 @@ protected: */ /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); + protected: LLChicletAvatarIconCtrl* mAvatarCtrl; LLChicletNotificationCounterCtrl* mCounterCtrl; @@ -334,6 +341,27 @@ protected: LLMenuGL* mPopupMenu; bool mShowSpeaker; + + template<typename Container> + struct CollectChicletCombiner { + typedef Container result_type; + + template<typename InputIterator> + Container operator()(InputIterator first, InputIterator last) const { + Container c = Container(); + for (InputIterator iter = first; iter != last; iter++) { + if (*iter != NULL) { + c.push_back(*iter); + } + } + return c; + } + }; + +public: + static boost::signals2::signal<LLChiclet* (const LLUUID&), + CollectChicletCombiner<std::list<LLChiclet*> > > + sFindChicletsSignal; }; /* diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp index 9cb3ea127f..9dfc7bcee7 100644 --- a/indra/newview/llfavoritesbar.cpp +++ b/indra/newview/llfavoritesbar.cpp @@ -41,8 +41,12 @@ #include "llmenugl.h" #include "llagent.h" +#include "llclipboard.h" +#include "llinventoryclipboard.h" #include "llinventorybridge.h" #include "llinventorymodel.h" +#include "llfloaterworldmap.h" +#include "lllandmarkactions.h" #include "llsidetray.h" #include "lltoggleablemenu.h" #include "llviewerinventory.h" @@ -71,11 +75,17 @@ struct LLFavoritesSort } }; +LLFavoritesBarCtrl::Params::Params() +: chevron_button_tool_tip("chevron_button_tool_tip") +{ +} + LLFavoritesBarCtrl::LLFavoritesBarCtrl(const LLFavoritesBarCtrl::Params& p) : LLUICtrl(p), mFont(p.font.isProvided() ? p.font() : LLFontGL::getFontSansSerifSmall()), mPopupMenuHandle(), - mInventoryItemsPopupMenuHandle() + mInventoryItemsPopupMenuHandle(), + mChevronButtonToolTip(p.chevron_button_tool_tip) { // Register callback for menus with current registrar (will be parent panel's registrar) LLUICtrl::CommitCallbackRegistry::currentRegistrar().add("Favorites.DoToSelected", @@ -314,6 +324,7 @@ void LLFavoritesBarCtrl::updateButtons(U32 bar_width) bparams.tab_stop(false); bparams.font(mFont); bparams.name(">>"); + bparams.tool_tip(mChevronButtonToolTip); bparams.click_callback.function(boost::bind(&LLFavoritesBarCtrl::showDropDownMenu, this)); addChildInBack(LLUICtrlFactory::create<LLButton> (bparams)); @@ -548,6 +559,12 @@ void LLFavoritesBarCtrl::onButtonRightClick( LLUUID item_id,LLView* fav_button,S LLMenuGL::showPopup(fav_button, menu, x, y); } +void copy_slurl_to_clipboard_cb(const LLVector3d& posGlobal, std::string& slurl) +{ + gClipboard.copyFromString(utf8str_to_wstring(slurl)); +} + + void LLFavoritesBarCtrl::doToSelected(const LLSD& userdata) { std::string action = userdata.asString(); @@ -569,13 +586,102 @@ void LLFavoritesBarCtrl::doToSelected(const LLSD& userdata) LLSideTray::getInstance()->showPanel("panel_places", key); } - else if (action == "rename") + else if (action == "copy_slurl") { - // Would need to re-implement this: - // folder->startRenamingSelectedItem(); + LLVector3d posGlobal; + LLLandmarkActions::getLandmarkGlobalPos(mSelectedItemID, posGlobal); + + if (!posGlobal.isExactlyZero()) + { + LLLandmarkActions::getSLURLfromPosGlobal(posGlobal, copy_slurl_to_clipboard_cb); + } + } + else if (action == "show_on_map") + { + LLFloaterWorldMap* worldmap_instance = LLFloaterWorldMap::getInstance(); + + LLVector3d posGlobal; + LLLandmarkActions::getLandmarkGlobalPos(mSelectedItemID, posGlobal); + + if (!posGlobal.isExactlyZero() && worldmap_instance) + { + worldmap_instance->trackLocation(posGlobal); + LLFloaterReg::showInstance("world_map", "center"); + } + } + else if (action == "cut") + { + } + else if (action == "copy") + { + LLInventoryClipboard::instance().add(mSelectedItemID); + } + else if (action == "paste") + { + pastFromClipboard(); } else if (action == "delete") { gInventory.removeItem(mSelectedItemID); } } + +BOOL LLFavoritesBarCtrl::isClipboardPasteable() const +{ + if (!LLInventoryClipboard::instance().hasContents()) + { + return FALSE; + } + + LLDynamicArray<LLUUID> objects; + LLInventoryClipboard::instance().retrieve(objects); + S32 count = objects.count(); + for(S32 i = 0; i < count; i++) + { + const LLUUID &item_id = objects.get(i); + + // Can't paste folders + const LLInventoryCategory *cat = gInventory.getCategory(item_id); + if (cat) + { + return FALSE; + } + + const LLInventoryItem *item = gInventory.getItem(item_id); + if (item && LLAssetType::AT_LANDMARK != item->getType()) + { + return FALSE; + } + } + return TRUE; +} + +void LLFavoritesBarCtrl::pastFromClipboard() const +{ + LLInventoryModel* model = &gInventory; + if(model && isClipboardPasteable()) + { + LLInventoryItem* item = NULL; + LLDynamicArray<LLUUID> objects; + LLInventoryClipboard::instance().retrieve(objects); + S32 count = objects.count(); + LLUUID parent_id(mFavoriteFolderId); + for(S32 i = 0; i < count; i++) + { + item = model->getItem(objects.get(i)); + if (item) + { + copy_inventory_item( + gAgent.getID(), + item->getPermissions().getOwner(), + item->getUUID(), + parent_id, + std::string(), + LLPointer<LLInventoryCallback>(NULL)); + } + } + } +} + + +// EOF diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h index 7da33e2f6e..824b396add 100644 --- a/indra/newview/llfavoritesbar.h +++ b/indra/newview/llfavoritesbar.h @@ -40,7 +40,12 @@ class LLFavoritesBarCtrl : public LLUICtrl, public LLInventoryObserver { public: - struct Params : public LLUICtrl::Params{}; + struct Params : public LLInitParam::Block<Params, LLUICtrl::Params> + { + Optional<std::string> chevron_button_tool_tip; + Params(); + }; + protected: LLFavoritesBarCtrl(const Params&); friend class LLUICtrlFactory; @@ -69,6 +74,9 @@ protected: void onButtonRightClick(LLUUID id,LLView* button,S32 x,S32 y,MASK mask); void doToSelected(const LLSD& userdata); + BOOL isClipboardPasteable() const; + void pastFromClipboard() const; + void showDropDownMenu(); @@ -84,6 +92,8 @@ protected: LLUUID mSelectedItemID; LLRect mChevronRect; + + std::string mChevronButtonToolTip; }; diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp index b14f23f9cf..7af77e2056 100644 --- a/indra/newview/llgroupactions.cpp +++ b/indra/newview/llgroupactions.cpp @@ -38,9 +38,6 @@ #include "llagent.h" #include "llfloaterreg.h" #include "llimview.h" // for gIMMgr -#include "llgroupmgr.h" -#include "llavataractions.h" -#include "llviewercontrol.h" #include "llsidetray.h" #include "llcommandhandler.h" @@ -103,126 +100,6 @@ public: }; LLGroupHandler gGroupHandler; - - -// LLGroupActions::teleport helper -// -// Method is offerTeleport should be called. -// First it checks, whether LLGroupMgr contains LLGroupMgrGroupData for this group already. -// If it's there, processMembersList can be called, which builds vector of ID's for online members and -// calls LLAvatarActions::offerTeleport. -// If LLGroupMgr doesn't contain LLGroupMgrGroupData, then ID of group should be saved in -// mID or queue, if mID is not empty. After that processQueue uses ID from mID or queue, -// registers LLGroupTeleporter as observer at LLGroupMgr and sends request for group members. -// LLGroupMgr notifies about response on this request by calling method 'changed'. -// It calls processMembersList, sets mID to null, to indicate that current group is processed, -// and calls processQueue to process remaining groups. -// The reason of calling of LLGroupMgr::addObserver and LLGroupMgr::removeObserver in -// processQueue and 'changed' methods is that LLGroupMgr notifies observers of only particular group, -// so, for each group mID should be updated and addObserver/removeObserver is called. - -class LLGroupTeleporter : public LLGroupMgrObserver -{ -public: - LLGroupTeleporter() : LLGroupMgrObserver(LLUUID()) {} - - void offerTeleport(const LLUUID& group_id); - - // LLGroupMgrObserver trigger - virtual void changed(LLGroupChange gc); -private: - void processQueue(); - void processMembersList(LLGroupMgrGroupData* gdatap); - - std::queue<LLUUID> mGroupsQueue; -}; - -void LLGroupTeleporter::offerTeleport(const LLUUID& group_id) -{ - LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(group_id); - - if (!gdatap || !gdatap->isMemberDataComplete()) - { - if (mID.isNull()) - mID = group_id; - else - // Not null mID means that user requested next group teleport before - // previous group is processed, so this group goes to queue - mGroupsQueue.push(group_id); - - processQueue(); - } - else - { - processMembersList(gdatap); - } -} - -// Sends request for group in mID or one group in queue -void LLGroupTeleporter::processQueue() -{ - // Get group from queue, if mID is empty - if (mID.isNull() && !mGroupsQueue.empty()) - { - mID = mGroupsQueue.front(); - mGroupsQueue.pop(); - } - - if (mID.notNull()) - { - LLGroupMgr::getInstance()->addObserver(this); - LLGroupMgr::getInstance()->sendGroupMembersRequest(mID); - } -} - -// Collects all online members of group and offers teleport to them -void LLGroupTeleporter::processMembersList(LLGroupMgrGroupData* gdatap) -{ - U32 limit = gSavedSettings.getU32("GroupTeleportMembersLimit"); - - LLDynamicArray<LLUUID> ids; - for (LLGroupMgrGroupData::member_list_t::iterator iter = gdatap->mMembers.begin(); iter != gdatap->mMembers.end(); iter++) - { - LLGroupMemberData* member = iter->second; - if (!member) - continue; - - if (member->getID() == gAgent.getID()) - // No need to teleport own avatar - continue; - - if (member->getOnlineStatus() == "Online") - ids.push_back(member->getID()); - - if ((U32)ids.size() >= limit) - break; - } - - LLAvatarActions::offerTeleport(ids); -} - -// LLGroupMgrObserver trigger -void LLGroupTeleporter::changed(LLGroupChange gc) -{ - if (gc == GC_MEMBER_DATA) - { - LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mID); - - if (gdatap && gdatap->isMemberDataComplete()) - processMembersList(gdatap); - - LLGroupMgr::getInstance()->removeObserver(this); - - // group in mID is processed - mID.setNull(); - - // process other groups in queue, if any - processQueue(); - } -} - -static LLGroupTeleporter sGroupTeleporter; - // static void LLGroupActions::search() { @@ -348,12 +225,6 @@ void LLGroupActions::startChat(const LLUUID& group_id) } } -// static -void LLGroupActions::offerTeleport(const LLUUID& group_id) -{ - sGroupTeleporter.offerTeleport(group_id); -} - //-- Private methods ---------------------------------------------------------- // static diff --git a/indra/newview/llgroupactions.h b/indra/newview/llgroupactions.h index 70170d3cfe..eb366bd779 100644 --- a/indra/newview/llgroupactions.h +++ b/indra/newview/llgroupactions.h @@ -81,11 +81,6 @@ public: * Start group instant messaging session. */ static void startChat(const LLUUID& group_id); - - /** - * Offers teleport for online members of group - */ - static void offerTeleport(const LLUUID& group_id); private: static bool onLeaveGroup(const LLSD& notification, const LLSD& response); diff --git a/indra/newview/lllandmarkactions.cpp b/indra/newview/lllandmarkactions.cpp index b51064f226..608b9b20e6 100644 --- a/indra/newview/lllandmarkactions.cpp +++ b/indra/newview/lllandmarkactions.cpp @@ -33,16 +33,23 @@ #include "llviewerprecompiledheaders.h" #include "lllandmarkactions.h" -#include "llagent.h" +#include "roles_constants.h" + #include "llinventory.h" -#include "llinventorymodel.h" #include "lllandmark.h" -#include "lllandmarklist.h" -#include "llnotifications.h" #include "llparcel.h" + +#include "llnotifications.h" + +#include "llagent.h" +#include "llinventorymodel.h" +#include "lllandmarklist.h" +#include "llslurl.h" #include "llviewerinventory.h" #include "llviewerparcelmgr.h" -#include "roles_constants.h" +#include "llworldmap.h" +#include "lllandmark.h" +#include "llinventorymodel.h" // Returns true if the given inventory item is a landmark pointing to the current parcel. // Used to filter inventory items. @@ -66,18 +73,53 @@ public: } }; -bool LLLandmarkActions::landmarkAlreadyExists() +class LLFetchLandmarksByName : public LLInventoryCollectFunctor +{ +private: + std::string name; + +public: +LLFetchLandmarksByName(std::string &landmark_name) +:name(landmark_name) + { + } + +public: + /*virtual*/ bool operator()(LLInventoryCategory* cat, LLInventoryItem* item) + { + if (!item || item->getType() != LLAssetType::AT_LANDMARK) + return false; + + LLLandmark* landmark = gLandmarkList.getAsset(item->getAssetUUID()); + if (!landmark) // the landmark not been loaded yet + return false; + + if (item->getName() == name) + { + return true; + } + + return false; + } +}; + +LLInventoryModel::item_array_t LLLandmarkActions::fetchLandmarksByName(std::string& name) { - // Determine whether there are landmarks pointing to the current parcel. LLInventoryModel::cat_array_t cats; LLInventoryModel::item_array_t items; - LLIsAgentParcelLandmark is_current_parcel_landmark; + LLFetchLandmarksByName fetchLandmarks(name); gInventory.collectDescendentsIf(gInventory.getRootFolderID(), - cats, - items, - LLInventoryModel::EXCLUDE_TRASH, - is_current_parcel_landmark); - + cats, + items, + LLInventoryModel::EXCLUDE_TRASH, + fetchLandmarks); + return items; +} +bool LLLandmarkActions::landmarkAlreadyExists() +{ + // Determine whether there are landmarks pointing to the current parcel. + LLInventoryModel::item_array_t items; + collectParcelLandmark(items); return !items.empty(); } @@ -139,3 +181,75 @@ void LLLandmarkActions::createLandmarkHere() createLandmarkHere(landmark_name, landmark_desc, folder_id); } + +void LLLandmarkActions::getSLURLfromPosGlobal(const LLVector3d& global_pos, slurl_signal_t signal) +{ + std::string sim_name; + bool gotSimName = LLWorldMap::getInstance()->simNameFromPosGlobal(global_pos, sim_name); + if (gotSimName) + { + std::string slurl = LLSLURL::buildSLURLfromPosGlobal(sim_name, global_pos); + + signal(global_pos, slurl); + + return; + } + else + { + U64 new_region_handle = to_region_handle(global_pos); + + LLWorldMap::url_callback_t cb = boost::bind(&LLLandmarkActions::onRegionResponse, + signal, + global_pos, + _1, _2, _3, _4); + + LLWorldMap::getInstance()->sendHandleRegionRequest(new_region_handle, cb, std::string("unused"), false); + } +} + +void LLLandmarkActions::onRegionResponse(slurl_signal_t signal, + const LLVector3d& global_pos, + U64 region_handle, + const std::string& url, + const LLUUID& snapshot_id, + bool teleport) +{ + std::string sim_name; + std::string slurl; + bool gotSimName = LLWorldMap::getInstance()->simNameFromPosGlobal(global_pos, sim_name); + if (gotSimName) + { + slurl = LLSLURL::buildSLURLfromPosGlobal(sim_name, global_pos); + } + else + { + slurl = ""; + } + + signal(global_pos, slurl); +} + +bool LLLandmarkActions::getLandmarkGlobalPos(const LLUUID& landmarkInventoryItemID, LLVector3d& posGlobal) +{ + LLViewerInventoryItem* item = gInventory.getItem(landmarkInventoryItemID); + if (NULL == item) + return false; + + const LLUUID& asset_id = item->getAssetUUID(); + LLLandmark* landmark = gLandmarkList.getAsset(asset_id, NULL); + + if (NULL == landmark) + return false; + + return landmark->getGlobalPos(posGlobal); +} + +void LLLandmarkActions::collectParcelLandmark(LLInventoryModel::item_array_t& items){ + LLInventoryModel::cat_array_t cats; + LLIsAgentParcelLandmark is_current_parcel_landmark; + gInventory.collectDescendentsIf(gInventory.getRootFolderID(), + cats, + items, + LLInventoryModel::EXCLUDE_TRASH, + is_current_parcel_landmark); +} diff --git a/indra/newview/lllandmarkactions.h b/indra/newview/lllandmarkactions.h index e1e94edb75..e04d1bf543 100644 --- a/indra/newview/lllandmarkactions.h +++ b/indra/newview/lllandmarkactions.h @@ -1,68 +1,107 @@ /** -* @file lllandmarkactions.h -* @brief LLLandmark class declaration -* -* $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$ -*/ + * @file lllandmarkactions.h + * @brief LLLandmark class declaration + * + * $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$ + */ #ifndef LL_LLLANDMARKACTIONS_H #define LL_LLLANDMARKACTIONS_H +#include "llinventorymodel.h" + /** -* @brief Provides helper functions to manage landmarks -*/ + * @brief Provides helper functions to manage landmarks + */ class LLLandmarkActions { public: + typedef boost::function<void(const LLVector3d& global_pos, std::string& slurl)> slurl_signal_t; /** - * @brief Checks whether landmark exists for current parcel. - */ + * @brief Fetches landmark LLViewerInventoryItems for the given landmark name. + */ + static LLInventoryModel::item_array_t fetchLandmarksByName(std::string& name); + /** + * @brief Checks whether landmark exists for current parcel. + */ static bool landmarkAlreadyExists(); /** - * @brief Checks whether agent has rights to create landmark for current parcel. - */ + * @brief Checks whether agent has rights to create landmark for current parcel. + */ static bool canCreateLandmarkHere(); /** - * @brief Creates landmark for current parcel. - */ + * @brief Creates landmark for current parcel. + */ static void createLandmarkHere(); /** - * @brief Creates landmark for current parcel. - */ + * @brief Creates landmark for current parcel. + */ static void createLandmarkHere( const std::string& name, const std::string& desc, const LLUUID& folder_id); + /** + * @brief Trying to find in inventory a landmark of the current parcel. + * Normally items should contain only one item, + * because we can create the only landmark per parcel according to Navigation spec. + */ + static void collectParcelLandmark(LLInventoryModel::item_array_t& items); + + /** + * @brief Creates SLURL for given global position. + */ + static void getSLURLfromPosGlobal(const LLVector3d& global_pos, slurl_signal_t signal); + + /** + * @brief Gets landmark global position specified by inventory LLUUID. + * Found position is placed into "posGlobal" variable. + *. + * @return - true if specified item exists in Inventory and an appropriate landmark found. + * and its position is known, false otherwise. + */ + // *TODO: mantipov: profide callback for cases, when Landmark is not loaded yet. + static bool getLandmarkGlobalPos(const LLUUID& landmarkInventoryItemID, LLVector3d& posGlobal); + +private: + LLLandmarkActions(); + LLLandmarkActions(const LLLandmarkActions&); + + static void onRegionResponse(slurl_signal_t signal, + const LLVector3d& global_pos, + U64 region_handle, + const std::string& url, + const LLUUID& snapshot_id, + bool teleport); }; #endif //LL_LLLANDMARKACTIONS_H diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp index e2dc7d69a1..a6662ef379 100644 --- a/indra/newview/lllocationinputctrl.cpp +++ b/indra/newview/lllocationinputctrl.cpp @@ -37,24 +37,23 @@ // common includes #include "llbutton.h" -#include "llfloaterreg.h" #include "llfocusmgr.h" -#include "llkeyboard.h" +#include "llmenugl.h" #include "llstring.h" #include "lluictrlfactory.h" -#include "v2math.h" // newview includes #include "llagent.h" -#include "llfloaterland.h" #include "llinventorymodel.h" #include "lllandmarkactions.h" #include "lllandmarklist.h" #include "lllocationhistory.h" #include "llsidetray.h" +#include "lltrans.h" #include "llviewerinventory.h" #include "llviewerparcelmgr.h" #include "llviewercontrol.h" +#include "llviewermenu.h" #include "llurllineeditorctrl.h" //============================================================================ /* @@ -161,6 +160,7 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p) : LLComboBox(p), mAddLandmarkHPad(p.add_landmark_hpad), mInfoBtn(NULL), + mLocationContextMenu(NULL), mAddLandmarkBtn(NULL) { // Lets replace default LLLineEditor with LLLocationLineEditor @@ -212,9 +212,21 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p) enableAddLandmarkButton(true); addChild(mAddLandmarkBtn); + // Register callbacks and load the location field context menu (NB: the order matters). + LLUICtrl::CommitCallbackRegistry::currentRegistrar().add("Navbar.Action", boost::bind(&LLLocationInputCtrl::onLocationContextMenuItemClicked, this, _2)); + LLUICtrl::EnableCallbackRegistry::currentRegistrar().add("Navbar.EnableMenuItem", boost::bind(&LLLocationInputCtrl::onLocationContextMenuItemEnabled, this, _2)); + setPrearrangeCallback(boost::bind(&LLLocationInputCtrl::onLocationPrearrange, this, _2)); - getTextEntry()->setMouseUpCallback(boost::bind(&LLLocationInputCtrl::onTextEditorMouseUp, this, _2,_3,_4)); + getTextEntry()->setMouseUpCallback(boost::bind(&LLLocationInputCtrl::changeLocationPresentation, this)); + // Load the location field context menu + mLocationContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_navbar.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + if (!mLocationContextMenu) + { + llwarns << "Error loading navigation bar context menu" << llendl; + + } + getTextEntry()->setRightClickedCallback(boost::bind(&LLLocationInputCtrl::onTextEditorRightClicked,this,_2,_3,_4)); updateWidgetlayout(); // - Make the "Add landmark" button updated when either current parcel gets changed @@ -401,11 +413,18 @@ 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) + +void LLLocationInputCtrl::onTextEditorRightClicked(S32 x, S32 y, MASK mask) { - if (!mTextEntry->hasSelection()) { - setText(gAgent.getUnescapedSLURL()); - mTextEntry->selectAll(); + if (mLocationContextMenu) + { + updateContextMenu(); + mLocationContextMenu->buildDrawLabels(); + mLocationContextMenu->updateParent(LLMenuGL::sMenuContainer); + hideList(); + setFocus(true); + changeLocationPresentation(); + LLMenuGL::showPopup(this, mLocationContextMenu, x, y); } } @@ -429,7 +448,7 @@ void LLLocationInputCtrl::refreshLocation() // Update location field. std::string location_name; LLAgent::ELocationFormat format = (gSavedSettings.getBOOL("ShowCoordinatesOption") ? - LLAgent::LOCATION_FORMAT_FULL: LLAgent::LOCATION_FORMAT_NORMAL); + LLAgent::LOCATION_FORMAT_WITHOUT_SIM: LLAgent::LOCATION_FORMAT_NORMAL); if (!gAgent.buildLocationString(location_name,format)) location_name = "Unknown"; @@ -482,6 +501,21 @@ void LLLocationInputCtrl::updateAddLandmarkButton() enableAddLandmarkButton(!LLLandmarkActions::landmarkAlreadyExists()); } +void LLLocationInputCtrl::updateContextMenu(){ + + if (mLocationContextMenu) + { + LLMenuItemGL* landmarkItem = mLocationContextMenu->getChild<LLMenuItemGL>("Landmark"); + if (!LLLandmarkActions::landmarkAlreadyExists()) + { + landmarkItem->setLabel(LLTrans::getString("AddLandmarkNavBarMenu")); + } + else + { + landmarkItem->setLabel(LLTrans::getString("EditLandmarkNavBarMenu")); + } + } +} void LLLocationInputCtrl::updateWidgetlayout() { const LLRect& rect = getLocalRect(); @@ -503,3 +537,88 @@ void LLLocationInputCtrl::updateWidgetlayout() mAddLandmarkBtn->setRect(al_btn_rect); } } + +void LLLocationInputCtrl::changeLocationPresentation() +{ + // change location presentation only if user select anything. + if(mTextEntry && !mTextEntry->hasSelection() ) + { + mTextEntry->setText(gAgent.getUnescapedSLURL()); + mTextEntry->selectAll(); + } +} + +void LLLocationInputCtrl::onLocationContextMenuItemClicked(const LLSD& userdata) +{ + std::string item = userdata.asString(); + + if (item == std::string("show_coordinates")) + { + gSavedSettings.setBOOL("ShowCoordinatesOption",!gSavedSettings.getBOOL("ShowCoordinatesOption")); + } + else if (item == std::string("landmark")) + { + LLInventoryModel::item_array_t items; + LLLandmarkActions::collectParcelLandmark(items); + + if(items.empty()) + { + LLSideTray::getInstance()->showPanel("panel_places", LLSD().insert("type", "create_landmark")); + }else{ + LLSideTray::getInstance()->showPanel("panel_places", + LLSD().insert("type", "landmark").insert("id",items.get(0)->getUUID())); + } + } + else if (item == std::string("cut")) + { + mTextEntry->cut(); + } + else if (item == std::string("copy")) + { + mTextEntry->copy(); + } + else if (item == std::string("paste")) + { + mTextEntry->paste(); + } + else if (item == std::string("delete")) + { + mTextEntry->deleteSelection(); + } + else if (item == std::string("select_all")) + { + mTextEntry->selectAll(); + } +} + +bool LLLocationInputCtrl::onLocationContextMenuItemEnabled(const LLSD& userdata) +{ + std::string item = userdata.asString(); + + if (item == std::string("can_cut")) + { + return mTextEntry->canCut(); + } + else if (item == std::string("can_copy")) + { + return mTextEntry->canCopy(); + } + else if (item == std::string("can_paste")) + { + return mTextEntry->canPaste(); + } + else if (item == std::string("can_delete")) + { + return mTextEntry->canDeselect(); + } + else if (item == std::string("can_select_all")) + { + return mTextEntry->canSelectAll(); + } + else if(item == std::string("show_coordinates")){ + + return gSavedSettings.getBOOL("ShowCoordinatesOption"); + } + + return false; +} diff --git a/indra/newview/lllocationinputctrl.h b/indra/newview/lllocationinputctrl.h index 0196aae4e7..1b26a07d83 100644 --- a/indra/newview/lllocationinputctrl.h +++ b/indra/newview/lllocationinputctrl.h @@ -40,6 +40,7 @@ class LLLandmark; // internals class LLAddLandmarkObserver; class LLRemoveLandmarkObserver; +class LLMenuGL; /** * Location input control. @@ -98,16 +99,22 @@ private: void rebuildLocationHistory(std::string filter = ""); void setText(const LLStringExplicit& text); void updateAddLandmarkButton(); + void updateContextMenu(); void updateWidgetlayout(); + void changeLocationPresentation(); void onInfoButtonClicked(); void onLocationHistoryLoaded(); void onLocationPrearrange(const LLSD& data); - void onTextEditorMouseUp(S32 x, S32 y, MASK mask); + void onTextEditorRightClicked(S32 x, S32 y, MASK mask); void onLandmarkLoaded(LLLandmark* lm); void onAddLandmarkButtonClicked(); void onAgentParcelChange(); + // callbacks + bool onLocationContextMenuItemEnabled(const LLSD& userdata); + void onLocationContextMenuItemClicked(const LLSD& userdata); + LLMenuGL* mLocationContextMenu; LLButton* mAddLandmarkBtn; LLButton* mInfoBtn; S32 mAddLandmarkHPad; diff --git a/indra/newview/llmoveview.cpp b/indra/newview/llmoveview.cpp index fc425d1b33..92b1ecfd16 100644 --- a/indra/newview/llmoveview.cpp +++ b/indra/newview/llmoveview.cpp @@ -549,6 +549,7 @@ void LLPanelStandStopFlying::onStandButtonClick() LLSelectMgr::getInstance()->deselectAllForStandingUp(); gAgent.setControlFlags(AGENT_CONTROL_STAND_UP); + setFocus(FALSE); // EXT-482 setVisible(FALSE); } @@ -556,6 +557,7 @@ void LLPanelStandStopFlying::onStopFlyingButtonClick() { gAgent.setFlying(FALSE); + setFocus(FALSE); // EXT-482 setVisible(FALSE); } diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp index 0f719f29e9..e3c4cd4895 100644 --- a/indra/newview/llnavigationbar.cpp +++ b/indra/newview/llnavigationbar.cpp @@ -38,11 +38,8 @@ #include <llfocusmgr.h> #include <lliconctrl.h> #include <llmenugl.h> -#include <llwindow.h> #include "llagent.h" -#include "llfloaterhtmlhelp.h" -#include "lllandmarkactions.h" #include "lllocationhistory.h" #include "lllocationinputctrl.h" #include "llteleporthistory.h" @@ -51,11 +48,14 @@ #include "llslurl.h" #include "llurlsimstring.h" #include "llviewerinventory.h" -#include "llviewermenu.h" #include "llviewerparcelmgr.h" #include "llworldmap.h" #include "llappviewer.h" #include "llviewercontrol.h" + +#include "llinventorymodel.h" +#include "lllandmarkactions.h" + #include "llfavoritesbar.h" //-- LLTeleportHistoryMenuItem ----------------------------------------------- @@ -176,7 +176,6 @@ LLNavigationBar* LLNavigationBar::getInstance() LLNavigationBar::LLNavigationBar() : mTeleportHistoryMenu(NULL), - mLocationContextMenu(NULL), mBtnBack(NULL), mBtnForward(NULL), mBtnHome(NULL), @@ -190,10 +189,6 @@ LLNavigationBar::LLNavigationBar() mParcelMgrConnection = LLViewerParcelMgr::getInstance()->setAgentParcelChangedCallback( boost::bind(&LLNavigationBar::onTeleportFinished, this)); - // Register callbacks and load the location field context menu (NB: the order matters). - mCommitCallbackRegistrar.add("Navbar.Action", boost::bind(&LLNavigationBar::onLocationContextMenuItemClicked, this, _2)); - mEnableCallbackRegistrar.add("Navbar.EnableMenuItem", boost::bind(&LLNavigationBar::onLocationContextMenuItemEnabled, this, _2)); - LLUICtrlFactory::getInstance()->buildPanel(this, "panel_navigation_bar.xml"); // navigation bar can never get a tab @@ -242,14 +237,6 @@ BOOL LLNavigationBar::postBuild() mLeSearch->setCommitCallback(boost::bind(&LLNavigationBar::onSearchCommit, this)); - // Load the location field context menu - mLocationContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_navbar.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); - if (!mLocationContextMenu) - { - llwarns << "Error loading navigation bar context menu" << llendl; - return FALSE; - } - mDefaultNbRect = getRect(); mDefaultFpRect = getChild<LLFavoritesBarCtrl>("favorite")->getRect(); @@ -271,32 +258,6 @@ void LLNavigationBar::draw() LLPanel::draw(); } -BOOL LLNavigationBar::handleRightMouseUp(S32 x, S32 y, MASK mask) -{ - // *HACK. We should use mCmbLocation's right click callback instead. - - // If the location field is clicked then show its context menu. - if (mCmbLocation->getRect().pointInRect(x, y)) - { - // Pass the focus to the line editor when it is right-clicked - mCmbLocation->setFocus(TRUE); - - if (mLocationContextMenu) - { - 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; - } - return LLPanel:: handleRightMouseUp(x, y, mask); -} - void LLNavigationBar::onBackButtonClicked() { LLTeleportHistory::getInstance()->goBack(); @@ -358,6 +319,22 @@ void LLNavigationBar::onLocationSelection() if (region_name != typed_location) { local_coords.set(x, y, z); + } + else + { + LLInventoryModel::item_array_t landmark_items = LLLandmarkActions::fetchLandmarksByName(typed_location); + LLViewerInventoryItem* item = NULL; + if ( !landmark_items.empty() ) + { + item = landmark_items[0]; + } + + if (item) + { + mUpdateTypedLocationHistory = true; + gAgent.teleportViaLandmark(item->getAssetUUID()); + return; + } } // Treat it as region name. // region_name = typed_location; @@ -371,7 +348,8 @@ void LLNavigationBar::onLocationSelection() LLWorldMap::getInstance()->sendNamedRegionRequest(region_name, cb, std::string("unused"), false); } -void LLNavigationBar::onTeleportFinished() { +void LLNavigationBar::onTeleportFinished() +{ if (mUpdateTypedLocationHistory) { LLLocationHistory* lh = LLLocationHistory::getInstance(); @@ -496,77 +474,6 @@ void LLNavigationBar::showTeleportHistoryMenu() gFocusMgr.setMouseCapture( NULL ); } -void LLNavigationBar::onLocationContextMenuItemClicked(const LLSD& userdata) -{ - std::string item = userdata.asString(); - LLLineEditor* location_entry = mCmbLocation->getTextEntry(); - - if (item == std::string("show_coordinates")) - { - gSavedSettings.setBOOL("ShowCoordinatesOption",!gSavedSettings.getBOOL("ShowCoordinatesOption")); - } - else if (item == std::string("landmark")) - { - LLSideTray::getInstance()->showPanel("panel_places", LLSD().insert("type", "create_landmark")); - } - else if (item == std::string("cut")) - { - location_entry->cut(); - } - else if (item == std::string("copy")) - { - location_entry->copy(); - } - else if (item == std::string("paste")) - { - location_entry->paste(); - } - else if (item == std::string("delete")) - { - location_entry->deleteSelection(); - } - else if (item == std::string("select_all")) - { - location_entry->selectAll(); - } -} - -bool LLNavigationBar::onLocationContextMenuItemEnabled(const LLSD& userdata) -{ - std::string item = userdata.asString(); - const LLLineEditor* location_entry = mCmbLocation->getTextEntry(); - - if (item == std::string("can_cut")) - { - return location_entry->canCut(); - } - else if (item == std::string("can_copy")) - { - return location_entry->canCopy(); - } - else if (item == std::string("can_paste")) - { - return location_entry->canPaste(); - } - else if (item == std::string("can_delete")) - { - return location_entry->canDeselect(); - } - else if (item == std::string("can_select_all")) - { - return location_entry->canSelectAll(); - } - else if(item == std::string("can_landmark")) - { - return !LLLandmarkActions::landmarkAlreadyExists(); - }else if(item == std::string("show_coordinates")){ - - return gSavedSettings.getBOOL("ShowCoordinatesOption"); - } - - return false; -} - void LLNavigationBar::handleLoginComplete() { mCmbLocation->handleLoginComplete(); diff --git a/indra/newview/llnavigationbar.h b/indra/newview/llnavigationbar.h index c533953a02..eeaec4e668 100644 --- a/indra/newview/llnavigationbar.h +++ b/indra/newview/llnavigationbar.h @@ -56,7 +56,6 @@ public: /*virtual*/ void draw(); /*virtual*/ BOOL postBuild(); - /*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask); void handleLoginComplete(); void clearHistoryCache(); @@ -75,8 +74,6 @@ private: static std::string extractLocalCoordsFromRegName(const std::string & reg_name, S32* x, S32* y, S32* z); // callbacks - bool onLocationContextMenuItemEnabled(const LLSD& userdata); - void onLocationContextMenuItemClicked(const LLSD& userdata); void onTeleportHistoryMenuItemClicked(const LLSD& userdata); void onTeleportHistoryChanged(); void onBackButtonClicked(); @@ -97,7 +94,6 @@ private: static LLNavigationBar *sInstance; - LLMenuGL* mLocationContextMenu; LLMenuGL* mTeleportHistoryMenu; LLButton* mBtnBack; LLButton* mBtnForward; diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp index c89715e815..2683109829 100644 --- a/indra/newview/llnearbychat.cpp +++ b/indra/newview/llnearbychat.cpp @@ -54,6 +54,8 @@ #include "llviewertexteditor.h" #include "llstylemap.h" +#include "lldraghandle.h" + static const S32 RESIZE_BAR_THICKNESS = 3; @@ -88,6 +90,8 @@ BOOL LLNearbyChat::postBuild() mResizeHandle[2]->setVisible(false); mResizeHandle[3]->setVisible(false); + getDragHandle()->setVisible(false); + //menu LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar; @@ -415,6 +419,8 @@ void LLNearbyChat::pinn_panel() mResizeBar[LLResizeBar::LEFT]->setVisible(false); mResizeBar[LLResizeBar::RIGHT]->setVisible(false); + getDragHandle()->setVisible(false); + } void LLNearbyChat::float_panel() @@ -427,6 +433,8 @@ void LLNearbyChat::float_panel() mResizeBar[LLResizeBar::LEFT]->setVisible(true); mResizeBar[LLResizeBar::RIGHT]->setVisible(true); + getDragHandle()->setVisible(true); + translate(4,4); } diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp index 086b06c1a3..615a41b143 100644 --- a/indra/newview/llpanelgroup.cpp +++ b/indra/newview/llpanelgroup.cpp @@ -180,21 +180,32 @@ void LLPanelGroup::reshape(S32 width, S32 height, BOOL called_from_parent ) { LLPanel::reshape(width, height, called_from_parent ); - 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); + LLRect 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); + LLButton* button = findChild<LLButton>("btn_apply"); + if(button) + { + btn_rect = button->getRect(); + btn_rect.setLeftTopAndSize( btn_rect.mLeft, 28, btn_rect.getWidth(), btn_rect.getHeight()); + button->setRect(btn_rect); + } + + button = findChild<LLButton>("btn_create"); + if(button) + { + 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); + button = findChild<LLButton>("btn_refresh"); + if(button) + { + btn_rect = button->getRect(); + btn_rect.setLeftTopAndSize( btn_rect.mLeft, 28, btn_rect.getWidth(), btn_rect.getHeight()); + button->setRect(btn_rect); + } } void LLPanelGroup::onBackBtnClick() @@ -259,22 +270,27 @@ void LLPanelGroup::setGroupID(const LLUUID& group_id) 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"); + LLButton* button_apply = findChild<LLButton>("btn_apply"); + LLButton* button_refresh = findChild<LLButton>("btn_refresh"); + LLButton* button_create = findChild<LLButton>("btn_create"); bool is_null_group_id = group_id == LLUUID::null; - - button_apply->setVisible(!is_null_group_id); - button_refresh->setVisible(!is_null_group_id); - button_create->setVisible(is_null_group_id); + if(button_apply) + button_apply->setVisible(!is_null_group_id); + if(button_refresh) + button_refresh->setVisible(!is_null_group_id); + if(button_create) + button_create->setVisible(is_null_group_id); 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"); + if(!tab_general || !tab_roles || !tab_notices || !tab_land) + return; + if(is_null_group_id)//creating new group { if(!tab_general->getDisplayChildren()) diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index 630970fcf5..19a5f3a5f1 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -92,7 +92,10 @@ public: * * This may start repeated updates until all names are complete. */ - virtual void forceUpdate() {} + virtual void forceUpdate() + { + updateList(); + } /** * Activate/deactivate updater. @@ -209,11 +212,6 @@ public: } } - /*virtual*/ void forceUpdate() - { - updateList(); - } - /*virtual*/ BOOL tick() { updateList(); @@ -283,11 +281,6 @@ public: gAgent.removeListener(this); } - /*virtual*/ void forceUpdate() - { - updateList(); - } - /*virtual*/ bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) { // Why is "new group" sufficient? @@ -308,7 +301,8 @@ LLPanelPeople::LLPanelPeople() mFilterSubString(LLStringUtil::null), mFilterEditor(NULL), mTabContainer(NULL), - mFriendList(NULL), + mOnlineFriendList(NULL), + mOfflineFriendList(NULL), mNearbyList(NULL), mRecentList(NULL) { @@ -337,9 +331,10 @@ BOOL LLPanelPeople::postBuild() mTabContainer = getChild<LLTabContainer>("tabs"); mTabContainer->setCommitCallback(boost::bind(&LLPanelPeople::onTabSelected, this, _2)); - mTabContainer->selectTabByName(FRIENDS_TAB_NAME); // must go after setting commit callback - mFriendList = getChild<LLPanel>(FRIENDS_TAB_NAME)->getChild<LLAvatarList>("avatar_list"); + mOnlineFriendList = getChild<LLPanel>(FRIENDS_TAB_NAME)->getChild<LLAvatarList>("avatars_online"); + mOfflineFriendList = getChild<LLPanel>(FRIENDS_TAB_NAME)->getChild<LLAvatarList>("avatars_offline"); + mNearbyList = getChild<LLPanel>(NEARBY_TAB_NAME)->getChild<LLAvatarList>("avatar_list"); mRecentList = getChild<LLPanel>(RECENT_TAB_NAME)->getChild<LLAvatarList>("avatar_list"); mGroupList = getChild<LLGroupList>("group_list"); @@ -353,10 +348,12 @@ BOOL LLPanelPeople::postBuild() friends_panel->childSetAction("add_btn", boost::bind(&LLPanelPeople::onAddFriendWizButtonClicked, this)); friends_panel->childSetAction("del_btn", boost::bind(&LLPanelPeople::onDeleteFriendButtonClicked, this)); - mFriendList->setDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, mFriendList)); + mOnlineFriendList->setDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, mOnlineFriendList)); + mOfflineFriendList->setDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, mOfflineFriendList)); mNearbyList->setDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, mNearbyList)); mRecentList->setDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, mRecentList)); - mFriendList->setCommitCallback(boost::bind(&LLPanelPeople::onAvatarListCommitted, this, mFriendList)); + mOnlineFriendList->setCommitCallback(boost::bind(&LLPanelPeople::onAvatarListCommitted, this, mOnlineFriendList)); + mOfflineFriendList->setCommitCallback(boost::bind(&LLPanelPeople::onAvatarListCommitted, this, mOfflineFriendList)); mNearbyList->setCommitCallback(boost::bind(&LLPanelPeople::onAvatarListCommitted, this, mNearbyList)); mRecentList->setCommitCallback(boost::bind(&LLPanelPeople::onAvatarListCommitted, this, mRecentList)); @@ -373,6 +370,9 @@ BOOL LLPanelPeople::postBuild() buttonSetAction("share_btn", boost::bind(&LLPanelPeople::onShareButtonClicked, this)); buttonSetAction("more_btn", boost::bind(&LLPanelPeople::onMoreButtonClicked, this)); + // Must go after setting commit callback and initializing all pointers to children. + mTabContainer->selectTabByName(FRIENDS_TAB_NAME); + // Create menus. LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; registrar.add("People.Group.Plus.Action", boost::bind(&LLPanelPeople::onGroupPlusMenuItemClicked, this, _2)); @@ -381,8 +381,9 @@ BOOL LLPanelPeople::postBuild() // Perform initial update. mFriendListUpdater->forceUpdate(); - updateGroupList(); - updateRecentList(); + mRecentListUpdater->forceUpdate(); + mGroupListUpdater->forceUpdate(); + mRecentListUpdater->forceUpdate(); return TRUE; } @@ -393,16 +394,24 @@ bool LLPanelPeople::updateFriendList(U32 changed_mask) if (changed_mask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE | LLFriendObserver::ONLINE)) { // get all buddies we know about + const LLAvatarTracker& av_tracker = LLAvatarTracker::instance(); LLAvatarTracker::buddy_map_t all_buddies; - LLAvatarTracker::instance().copyBuddyList(all_buddies); + av_tracker.copyBuddyList(all_buddies); - // *TODO: it's suboptimal to rebuild the whole list on online status change. + // *TODO: it's suboptimal to rebuild the whole lists on online status change. - // convert the buddy map to vector - mFriendVec.clear(); + // save them to the online and offline friends vectors + mOnlineFriendVec.clear(); + mOfflineFriendVec.clear(); LLAvatarTracker::buddy_map_t::const_iterator buddy_it = all_buddies.begin(); for (; buddy_it != all_buddies.end(); ++buddy_it) - mFriendVec.push_back(buddy_it->first); + { + LLUUID buddy_id = buddy_it->first; + if (av_tracker.isBuddyOnline(buddy_id)) + mOnlineFriendVec.push_back(buddy_id); + else + mOfflineFriendVec.push_back(buddy_id); + } return filterFriendList(); } @@ -428,6 +437,9 @@ bool LLPanelPeople::updateRecentList() bool LLPanelPeople::updateGroupList() { + if (!mGroupList) + return true; // there's no point in further updates + bool have_names = mGroupList->update(mFilterSubString); if (mGroupList->isEmpty()) @@ -438,11 +450,19 @@ bool LLPanelPeople::updateGroupList() bool LLPanelPeople::filterFriendList() { + if (!mOnlineFriendList || !mOfflineFriendList) + return true; // there's no point in further updates + // We must always update Friends list to clear the latest removed friend. - bool have_names = mFriendList->update(mFriendVec, mFilterSubString); + bool have_names = + mOnlineFriendList->update(mOnlineFriendVec, mFilterSubString) & + mOfflineFriendList->update(mOfflineFriendVec, mFilterSubString); - if (mFriendVec.size() == 0) - mFriendList->setCommentText(getString("no_friends")); + if (mOnlineFriendVec.size() == 0) + mOnlineFriendList->setCommentText(getString("no_friends_online")); + + if (mOfflineFriendVec.size() == 0) + mOfflineFriendList->setCommentText(getString("no_friends_offline")); return have_names; } @@ -459,6 +479,9 @@ bool LLPanelPeople::filterNearbyList() bool LLPanelPeople::filterRecentList() { + if (!mRecentList) + return true; + if (mRecentVec.size() > 0) return mRecentList->update(mRecentVec, mFilterSubString); @@ -495,7 +518,7 @@ void LLPanelPeople::buttonSetAction(const std::string& btn_name, const commit_si void LLPanelPeople::updateButtons() { - std::string cur_tab = mTabContainer->getCurrentPanel()->getName(); + std::string cur_tab = getActiveTabName(); bool nearby_tab_active = (cur_tab == NEARBY_TAB_NAME); bool friends_tab_active = (cur_tab == FRIENDS_TAB_NAME); bool group_tab_active = (cur_tab == GROUP_TAB_NAME); @@ -507,7 +530,7 @@ void LLPanelPeople::updateButtons() buttonSetVisible("add_friend_btn", nearby_tab_active || recent_tab_active); buttonSetVisible("view_profile_btn", !group_tab_active); buttonSetVisible("im_btn", !group_tab_active); - buttonSetVisible("teleport_btn", friends_tab_active || group_tab_active); + buttonSetVisible("teleport_btn", friends_tab_active); buttonSetVisible("share_btn", !recent_tab_active && false); // not implemented yet if (group_tab_active) @@ -529,10 +552,9 @@ void LLPanelPeople::updateButtons() else { bool is_friend = true; - LLAvatarList* list; // Check whether selected avatar is our friend. - if ((list = getActiveAvatarList()) && (selected_id = list->getCurrentID()).notNull()) + if ((selected_id = getCurrentItemID()).notNull()) { is_friend = LLAvatarTracker::instance().getBuddyInfo(selected_id) != NULL; } @@ -541,7 +563,7 @@ void LLPanelPeople::updateButtons() } bool item_selected = selected_id.notNull(); - buttonSetEnabled("teleport_btn", (friends_tab_active || group_tab_active) && item_selected); + buttonSetEnabled("teleport_btn", friends_tab_active && item_selected); buttonSetEnabled("view_profile_btn", item_selected); buttonSetEnabled("im_btn", item_selected); buttonSetEnabled("call_btn", item_selected && false); // not implemented yet @@ -550,26 +572,36 @@ void LLPanelPeople::updateButtons() buttonSetEnabled("chat_btn", item_selected); } -LLAvatarList* LLPanelPeople::getActiveAvatarList() const +const std::string& LLPanelPeople::getActiveTabName() const { - std::string cur_tab = mTabContainer->getCurrentPanel()->getName(); + return mTabContainer->getCurrentPanel()->getName(); +} + +LLUUID LLPanelPeople::getCurrentItemID() const +{ + std::string cur_tab = getActiveTabName(); + + if (cur_tab == FRIENDS_TAB_NAME) // this tab has two lists + { + LLUUID cur_online_friend; + + if ((cur_online_friend = mOnlineFriendList->getCurrentID()).notNull()) + return cur_online_friend; + + return mOfflineFriendList->getCurrentID(); + } - if (cur_tab == FRIENDS_TAB_NAME) - return mFriendList; if (cur_tab == NEARBY_TAB_NAME) - return mNearbyList; + return mNearbyList->getCurrentID(); + if (cur_tab == RECENT_TAB_NAME) - return mRecentList; + return mRecentList->getCurrentID(); - return NULL; -} + if (cur_tab == GROUP_TAB_NAME) + return mGroupList->getCurrentID(); -LLUUID LLPanelPeople::getCurrentItemID() const -{ - LLAvatarList* alist = getActiveAvatarList(); - if (alist) - return alist->getCurrentID(); - return mGroupList->getCurrentID(); + llassert(0 && "unknown tab selected"); + return LLUUID::null; } void LLPanelPeople::showGroupMenu(LLMenuGL* menu) @@ -653,9 +685,7 @@ void LLPanelPeople::onAvatarListDoubleClicked(LLAvatarList* list) return; #if 0 // SJB: Useful for testing, but not currently functional or to spec - // Open mini-inspector for the avatar being clicked - LLFloaterReg::showInstance("mini_inspector", clicked_id); - // inspector will delete itself on close + LLAvatarActions::showProfile(clicked_id); #else // spec says open IM window LLAvatarActions::startIM(clicked_id); #endif @@ -663,7 +693,17 @@ void LLPanelPeople::onAvatarListDoubleClicked(LLAvatarList* list) void LLPanelPeople::onAvatarListCommitted(LLAvatarList* list) { - (void) list; + // Make sure only one of the friends lists (online/offline) has selection. + if (getActiveTabName() == FRIENDS_TAB_NAME) + { + if (list == mOnlineFriendList) + mOfflineFriendList->deselectAllItems(TRUE); + else if (list == mOfflineFriendList) + mOnlineFriendList->deselectAllItems(TRUE); + else + llassert(0 && "commit on unknown friends list"); + } + updateButtons(); } @@ -778,16 +818,7 @@ void LLPanelPeople::onCallButtonClicked() void LLPanelPeople::onTeleportButtonClicked() { - std::string cur_tab = mTabContainer->getCurrentPanel()->getName(); - - if (cur_tab == FRIENDS_TAB_NAME) - { - LLAvatarActions::offerTeleport(getCurrentItemID()); - } - else if (cur_tab == GROUP_TAB_NAME) - { - LLGroupActions::offerTeleport(getCurrentItemID()); - } + LLAvatarActions::offerTeleport(getCurrentItemID()); } void LLPanelPeople::onShareButtonClicked() diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h index 58ed77f0f2..2b821a432b 100644 --- a/indra/newview/llpanelpeople.h +++ b/indra/newview/llpanelpeople.h @@ -57,15 +57,17 @@ public: class Updater; private: + // methods indirectly called by the updaters bool updateFriendList(U32 changed_mask); bool updateNearbyList(); bool updateRecentList(); bool updateGroupList(); + bool filterFriendList(); bool filterNearbyList(); bool filterRecentList(); void updateButtons(); - LLAvatarList* getActiveAvatarList() const; + const std::string& getActiveTabName() const; LLUUID getCurrentItemID() const; void buttonSetVisible(std::string btn_name, BOOL visible); void buttonSetEnabled(const std::string& btn_name, bool enabled); @@ -106,7 +108,8 @@ private: LLFilterEditor* mFilterEditor; LLTabContainer* mTabContainer; - LLAvatarList* mFriendList; + LLAvatarList* mOnlineFriendList; + LLAvatarList* mOfflineFriendList; LLAvatarList* mNearbyList; LLAvatarList* mRecentList; LLGroupList* mGroupList; @@ -128,7 +131,8 @@ private: // since re-fetching the groups list is always fast. typedef std::vector<LLUUID> uuid_vector_t; uuid_vector_t mNearbyVec; - uuid_vector_t mFriendVec; + uuid_vector_t mOnlineFriendVec; + uuid_vector_t mOfflineFriendVec; uuid_vector_t mRecentVec; }; diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp index 51cd05376a..8b378c33e3 100644 --- a/indra/newview/llpanelteleporthistory.cpp +++ b/indra/newview/llpanelteleporthistory.cpp @@ -200,7 +200,7 @@ void LLTeleportHistoryPanel::showTeleportHistory() index_column["type"] = "text"; index_column["value"] = index; - mHistoryItems->addElement(row); + mHistoryItems->addElement(row, ADD_TOP); if (cur_item == index) { diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp index 10561f5701..ab8d61f305 100644 --- a/indra/newview/llscreenchannel.cpp +++ b/indra/newview/llscreenchannel.cpp @@ -136,8 +136,7 @@ void LLScreenChannel::onToastFade(LLToast* toast) { std::vector<ToastElem>::iterator it = find(mToastList.begin(), mToastList.end(), static_cast<LLPanel*>(toast)); - // *TODO: toast->isViewed() - seems unnecessary - bool destroy_toast = toast->isViewed() || !mCanStoreToasts || !toast->getCanBeStored(); + bool destroy_toast = !mCanStoreToasts || !toast->getCanBeStored(); if(destroy_toast) { mToastList.erase(it); @@ -369,7 +368,8 @@ void LLScreenChannel::showToastsTop() void LLScreenChannel::createOverflowToast(S32 bottom, F32 timer) { LLRect toast_rect; - LLToast::Params p; // *TODO: fill structure + LLToast::Params p; + p.timer_period = timer; mOverflowToastPanel = new LLToast(p); if(!mOverflowToastPanel) @@ -393,7 +393,6 @@ void LLScreenChannel::createOverflowToast(S32 bottom, F32 timer) 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()); mOverflowToastPanel->setRect(toast_rect); - mOverflowToastPanel->setAndStartTimer(timer); getRootView()->addChild(mOverflowToastPanel); text_box->setValue(text); @@ -424,7 +423,8 @@ void LLScreenChannel::closeOverflowToastPanel() void LLScreenChannel::createStartUpToast(S32 notif_num, S32 bottom, F32 timer) { LLRect toast_rect; - LLToast::Params p; // *TODO: fill structure + LLToast::Params p; + p.timer_period = timer; mStartUpToastPanel = new LLToast(p); if(!mStartUpToastPanel) @@ -453,7 +453,6 @@ void LLScreenChannel::createStartUpToast(S32 notif_num, S32 bottom, F32 timer) 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); @@ -515,9 +514,12 @@ void LLScreenChannel::removeAndStoreAllVisibleToasts() 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(); + if((*it).toast->getCanBeStored()) + { + mStoredToastList.push_back(*it); + mOnStoreToast((*it).toast->getPanel(), (*it).id); + (*it).toast->stopTimer(); + } (*it).toast->setVisible(FALSE); } diff --git a/indra/newview/llslurl.cpp b/indra/newview/llslurl.cpp index ffadeeddf2..f6c4710d60 100644 --- a/indra/newview/llslurl.cpp +++ b/indra/newview/llslurl.cpp @@ -113,6 +113,19 @@ std::string LLSLURL::buildUnescapedSLURL(const std::string& regionname, S32 x, S } // static +std::string LLSLURL::buildSLURLfromPosGlobal(const std::string& regionname, + const LLVector3d& global_pos) +{ + F32 region_x = (F32)fmod(global_pos.mdV[VX], (F64)REGION_WIDTH_METERS); + F32 region_y = (F32)fmod(global_pos.mdV[VY], (F64)REGION_WIDTH_METERS); + + return buildSLURL(regionname, + llround(region_x), + llround(region_y), + llround((F32)global_pos.mdV[VZ])); +} + +// 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 5c9fea3e96..cb1b8cca9e 100644 --- a/indra/newview/llslurl.h +++ b/indra/newview/llslurl.h @@ -79,6 +79,11 @@ public: static std::string buildUnescapedSLURL(const std::string& regionname, S32 x, S32 y, S32 z); /** + * builds SLURL from global position escaping result url. + */ + static std::string buildSLURLfromPosGlobal(const std::string& regionname, + const LLVector3d& global_pos); + /** * Strip protocol part from the URL. */ static std::string stripProtocol(const std::string& url); diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 993a092eba..1fc2245a8f 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -314,6 +314,59 @@ void update_texture_fetch() static std::vector<std::string> sAuthUris; static S32 sAuthUriNum = -1; +//Copies landmarks from the "Library" to "My Favorites" +void populate_favorites_bar() +{ + //*TODO consider extending LLInventoryModel::findCategoryUUIDForType(...) to support both root's + LLInventoryModel::cat_array_t* lib_cats = NULL; + LLInventoryModel::item_array_t* lib_items = NULL; + gInventory.getDirectDescendentsOf(gInventory.getLibraryRootFolderID(), lib_cats, lib_items); + if (!lib_cats) return; + + LLUUID lib_landmarks(LLUUID::null); + S32 count = lib_cats->count(); + for(S32 i = 0; i < count; ++i) + { + if(lib_cats->get(i)->getPreferredType() == LLAssetType::AT_LANDMARK) + { + lib_landmarks = lib_cats->get(i)->getUUID(); + break; + } + } + if (lib_landmarks.isNull()) + { + llerror("Library inventory is missing Landmarks", 0); + return; + } + + LLInventoryModel::cat_array_t* lm_cats = NULL; + LLInventoryModel::item_array_t* lm_items = NULL; + gInventory.getDirectDescendentsOf(lib_landmarks, lm_cats, lm_items); + if (!lm_items) return; + + LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_FAVORITE); + if (favorites_id.isNull()) + { + llerror("My Inventory is missing My Favorites", 0); + return; + } + + S32 lm_count = lm_items->count(); + for (S32 i = 0; i < lm_count; ++i) + { + LLInventoryItem* item = lm_items->get(i); + if (item->getUUID().isNull()) continue; + + copy_inventory_item(gAgent.getID(), + item->getPermissions().getOwner(), + item->getUUID(), + favorites_id, + std::string(), + LLPointer<LLInventoryCallback>(NULL)); + } +} + + // Returns false to skip other idle processing. Should only return // true when all initialization done. bool idle_startup() @@ -2085,7 +2138,7 @@ bool idle_startup() } - //all categories loaded. lets create "My Favourites" category + //all categories loaded. lets create "My Favorites" category gInventory.findCategoryUUIDForType(LLAssetType::AT_FAVORITE,true); gInventory.buildParentChildMap(); @@ -2120,6 +2173,12 @@ bool idle_startup() llinfos << "Creating Inventory Views" << llendl; LLFloaterReg::getInstance("inventory"); + //default initial content for Favorites Bar + if (gAgent.isFirstLogin()) + { + populate_favorites_bar(); + } + LLStartUp::setStartupState( STATE_MISC ); return FALSE; } diff --git a/indra/newview/llsyswellitem.cpp b/indra/newview/llsyswellitem.cpp index 5ed8a8b604..7d9ebc7208 100644 --- a/indra/newview/llsyswellitem.cpp +++ b/indra/newview/llsyswellitem.cpp @@ -37,6 +37,7 @@ #include "llwindow.h" #include "v4color.h" +#include "lluicolortable.h" //--------------------------------------------------------------------------------- LLSysWellItem::LLSysWellItem(const Params& p) : LLScrollingPanel(p), @@ -76,7 +77,10 @@ void LLSysWellItem::onClickCloseBtn() //--------------------------------------------------------------------------------- void LLSysWellItem::updatePanel(BOOL allow_modify) { - //nothing to do here + S32 parent_width = getParent()->getRect().getWidth(); + S32 panel_height = getRect().getHeight(); + + reshape(parent_width, panel_height, TRUE); } //--------------------------------------------------------------------------------- @@ -91,13 +95,13 @@ BOOL LLSysWellItem::handleMouseDown(S32 x, S32 y, MASK mask) //--------------------------------------------------------------------------------- void LLSysWellItem::onMouseEnter(S32 x, S32 y, MASK mask) { - setTransparentColor(LLColor4(0.3f, 0.3f, 0.3f, 1.0f)); + setTransparentColor(LLUIColorTable::instance().getColor( "SysWellItemSelected" )); } //--------------------------------------------------------------------------------- void LLSysWellItem::onMouseLeave(S32 x, S32 y, MASK mask) { - setTransparentColor(LLColor4(0.0f, 0.0f, 0.0f, 0.0f)); + setTransparentColor(LLUIColorTable::instance().getColor( "SysWellItemUnselected" )); } //--------------------------------------------------------------------------------- diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp index c8eea5e7b4..bf1cd7002e 100644 --- a/indra/newview/llsyswellwindow.cpp +++ b/indra/newview/llsyswellwindow.cpp @@ -36,7 +36,7 @@ #include "llbottomtray.h" #include "llviewercontrol.h" - +#include "llviewerwindow.h" //--------------------------------------------------------------------------------- LLSysWellWindow::LLSysWellWindow(const LLSD& key) : LLFloater(LLSD()), @@ -44,19 +44,18 @@ LLSysWellWindow::LLSysWellWindow(const LLSD& key) : LLFloater(LLSD()), 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)); + //gViewerWindow->setOnBottomTrayWidthChanged(boost::bind(&LLSysWellWindow::adjustWindowPosition, this)); // *TODO: won't be necessary after docking is realized + mScrollContainer->setBorderVisible(FALSE); + + mDockTongue = LLUI::getUIImage("windows/Flyout_Pointer.png"); return TRUE; } @@ -76,7 +75,7 @@ void LLSysWellWindow::addItem(LLSysWellItem::Params p) LLSysWellItem* new_item = new LLSysWellItem(p); mNotificationList->addPanel(dynamic_cast<LLScrollingPanel*>(new_item)); reshapeWindow(); - adjustWindowPosition(); + //adjustWindowPosition(); // *TODO: won't be necessary after docking is realized new_item->setOnItemCloseCallback(boost::bind(&LLSysWellWindow::onItemClose, this, _1)); new_item->setOnItemClickCallback(boost::bind(&LLSysWellWindow::onItemClick, this, _1)); @@ -95,14 +94,12 @@ S32 LLSysWellWindow::findItemByID(const LLUUID& id) if(list.size() == 0) return -1; - LLScrollingPanelList::panel_list_t::const_iterator it = list.begin(); + LLScrollingPanelList::panel_list_t::const_iterator it; S32 index = 0; - while(it != list.end()) + for(it = list.begin(); it != list.end(); ++it, ++index) { if( dynamic_cast<LLSysWellItem*>(*it)->getID() == id ) break; - ++it; - ++index; } if(it == list.end()) @@ -123,7 +120,7 @@ void LLSysWellWindow::removeItemByID(const LLUUID& id) return; reshapeWindow(); - adjustWindowPosition(); + //adjustWindowPosition(); // *TODO: won't be necessary after docking is realized // hide chiclet window if there are no items left S32 items_left = mNotificationList->getPanelList().size(); if(items_left == 0) @@ -146,9 +143,9 @@ void LLSysWellWindow::onItemClose(LLSysWellItem* item) } //--------------------------------------------------------------------------------- -void LLSysWellWindow::onClickCloseBtn() +void LLSysWellWindow::toggleWindow() { - setVisible(false); + setVisible(!getVisible()); } //--------------------------------------------------------------------------------- @@ -158,14 +155,14 @@ void LLSysWellWindow::setVisible(BOOL visible) if(visible) { mChannel->removeAndStoreAllVisibleToasts(); - adjustWindowPosition(); + //adjustWindowPosition(); // *TODO: won't be necessary after docking is realized } LLFloater::setVisible(visible); } //--------------------------------------------------------------------------------- -void LLSysWellWindow::adjustWindowPosition() +void LLSysWellWindow::adjustWindowPosition() // *TODO: won't be necessary after docking is realized { const S32 WINDOW_MARGIN = 5; @@ -176,32 +173,31 @@ void LLSysWellWindow::adjustWindowPosition() //--------------------------------------------------------------------------------- void LLSysWellWindow::reshapeWindow() { - // Get scrollbar size + // Get size for scrollbar and floater's header const LLUICachedControl<S32> SCROLLBAR_SIZE("UIScrollbarSize", 0); + const LLUICachedControl<S32> HEADER_SIZE("UIFloaterHeaderSize", 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; + // Get height for a scrolling panel list + S32 list_height = mNotificationList->getRect().getHeight(); // Check that the floater doesn't exceed its parent view limits after reshape - S32 new_height = list_height + WINDOW_HEADER_HEIGHT + list_border_width; + S32 new_height = list_height + LLScrollingPanelList::GAP_BETWEEN_PANELS + HEADER_SIZE; if(new_height > MAX_WINDOW_HEIGHT) { - reshape(MIN_WINDOW_WIDTH + SCROLLBAR_SIZE, MAX_WINDOW_HEIGHT, FALSE); + reshape(MIN_WINDOW_WIDTH, MAX_WINDOW_HEIGHT, FALSE); + mNotificationList->reshape(MIN_PANELLIST_WIDTH - SCROLLBAR_SIZE, list_height, TRUE); } else { reshape(MIN_WINDOW_WIDTH, new_height, FALSE); + mNotificationList->reshape(MIN_PANELLIST_WIDTH, list_height, TRUE); } + + mNotificationList->updatePanels(TRUE); } //--------------------------------------------------------------------------------- diff --git a/indra/newview/llsyswellwindow.h b/indra/newview/llsyswellwindow.h index 9554f3cb82..7a107af0d1 100644 --- a/indra/newview/llsyswellwindow.h +++ b/indra/newview/llsyswellwindow.h @@ -46,8 +46,6 @@ class LLSysWellWindow : public LLFloater { - friend class LLFloaterReg; - public: LLSysWellWindow(const LLSD& key); ~LLSysWellWindow(); @@ -65,20 +63,25 @@ public: // Operating with outfit virtual void setVisible(BOOL visible); void adjustWindowPosition(); + void toggleWindow(); // Handlers void onItemClick(LLSysWellItem* item); void onItemClose(LLSysWellItem* item); + // size constants for the window and for its elements + static const S32 MAX_WINDOW_HEIGHT = 200; + static const S32 MIN_WINDOW_WIDTH = 320; + static const S32 MIN_PANELLIST_WIDTH = 318; + private: - void onClickCloseBtn(); void reshapeWindow(); // pointer to a corresponding channel's instance LLNotificationsUI::LLScreenChannel* mChannel; - LLButton* mCloseBtn; + LLUIImagePtr mDockTongue; LLScrollContainer* mScrollContainer; LLScrollingPanelList* mNotificationList; }; diff --git a/indra/newview/lltoast.cpp b/indra/newview/lltoast.cpp index a67ef85f87..07f802cf54 100644 --- a/indra/newview/lltoast.cpp +++ b/indra/newview/lltoast.cpp @@ -49,10 +49,8 @@ LLToast::LLToast(LLToast::Params p) : LLFloater(LLSD()), 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()->buildFloater(this, "panel_toast.xml", NULL); @@ -147,7 +145,6 @@ bool LLToast::timerHasExpired() void LLToast::hide() { setVisible(FALSE); - mIsViewed = false; mTimer.stop(); mOnFade(this); } @@ -230,7 +227,7 @@ void LLToast::onMouseEnter(S32 x, S32 y, MASK mask) setVisibleAndFrontmost(); setBackgroundOpaque(TRUE); - if(mCanFade && !mIsViewed) + if(mCanFade) { mTimer.stop(); } @@ -246,7 +243,7 @@ void LLToast::onMouseLeave(S32 x, S32 y, MASK mask) { mOnToastHover(this, MOUSE_LEAVE); - if(mCanFade && !mIsViewed) + if(mCanFade) { mTimer.start(); } diff --git a/indra/newview/lltoast.h b/indra/newview/lltoast.h index a4dee1e386..f1a9f2ec46 100644 --- a/indra/newview/lltoast.h +++ b/indra/newview/lltoast.h @@ -121,8 +121,6 @@ public: // 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; } @@ -163,8 +161,6 @@ private: LLButton* mHideBtn; LLColor4 mBgColor; - bool mIsViewed; - bool mIsTipNotification; bool mCanFade; bool mIsModal; bool mCanBeStored; diff --git a/indra/newview/lltoastpanel.cpp b/indra/newview/lltoastpanel.cpp index c39bac97a8..28052a33be 100644 --- a/indra/newview/lltoastpanel.cpp +++ b/indra/newview/lltoastpanel.cpp @@ -45,16 +45,8 @@ 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()); + // *TODO: create Title and localize it. If it will be required. + return mNotification->getMessage(); } diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index db65203950..499632def3 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -3458,7 +3458,10 @@ class LLSelfFriends : public view_listener_t bool handleEvent(const LLSD& userdata) { // Open "Friends" tab of the "People" panel in side tray. - LLSideTray::getInstance()->showPanel("panel_people", "friends_panel"); + LLSD param; + param["people_panel_tab_name"] = "friends_panel"; + + LLSideTray::getInstance()->showPanel("panel_people", param); return true; } }; @@ -3468,7 +3471,9 @@ class LLSelfGroups : public view_listener_t bool handleEvent(const LLSD& userdata) { // Open "Groups" tab of the "People" panel in side tray. - LLSideTray::getInstance()->showPanel("panel_people", "groups_panel"); + LLSD param; + param["people_panel_tab_name"] = "groups_panel"; + LLSideTray::getInstance()->showPanel("panel_people", param); return true; } }; diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 2747763cd9..e757090da8 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -2422,6 +2422,7 @@ void LLViewerWindow::updateBottomTrayRect() rc.mRight = right; bottom_tray->reshape(rc.getWidth(), rc.getHeight(), FALSE); bottom_tray->setRect(rc); + mOnBottomTrayWidthChanged(); } } } diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index a823e5bd99..7afb77bed8 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -186,6 +186,12 @@ public: /*virtual*/ std::string translateString(const char* tag); /*virtual*/ std::string translateString(const char* tag, const std::map<std::string, std::string>& args); + + // signal on bottom tray width changed + typedef boost::function<void (void)> bottom_tray_callback_t; + typedef boost::signals2::signal<void (void)> bottom_tray_signal_t; + bottom_tray_signal_t mOnBottomTrayWidthChanged; + boost::signals2::connection setOnBottomTrayWidthChanged(bottom_tray_callback_t cb) { return mOnBottomTrayWidthChanged.connect(cb); } // // ACCESSORS diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index 73f0d32d12..c739d4d455 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -664,4 +664,11 @@ <color name="OutputMonitorMutedColor" reference="DkGray2" /> + <color + name="SysWellItemUnselected" + value="0 0 0 0" /> + <color + name="SysWellItemSelected" + value="0.3 0.3 0.3 1.0" /> + </colors> diff --git a/indra/newview/skins/default/xui/en/favorites_bar_button.xml b/indra/newview/skins/default/xui/en/favorites_bar_button.xml index 4525df31b6..02784bb74b 100644 --- a/indra/newview/skins/default/xui/en/favorites_bar_button.xml +++ b/indra/newview/skins/default/xui/en/favorites_bar_button.xml @@ -5,7 +5,7 @@ untill LLFontGL::render() is fixed to avoid this requirement--> <!-- All buttons in the Favorites bar will be created from this one --> <button follows="left|bottom" - halign="left" + halign="center" height="23" image_disabled="transparent.j2c" image_disabled_selected="PushButton_Selected" diff --git a/indra/newview/skins/default/xui/en/floater_activeim.xml b/indra/newview/skins/default/xui/en/floater_activeim.xml new file mode 100644 index 0000000000..38c6d44fdf --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_activeim.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + name="floater_activeim" + title="ACTIVE IM" + top="26" + left="0" + height="22" + width="350" + follows="right|bottom" + background_visible="true" + can_close="true" + can_dock="true" + can_minimize="false" + visible="true" + bg_alpha_color="0 0 0 0"> + <scroll_container + follows="top|bottom" + layout="topleft" + top="20" + left="1" + width="349" + height="2" + name="panel_list_container"> + <scrolling_panel_list + follows="left|right" + layout="topleft" + name="chiclet_row_panel_list" + width="335"/> + </scroll_container> +</floater>
\ No newline at end of file diff --git a/indra/newview/skins/default/xui/en/floater_nearby_chat.xml b/indra/newview/skins/default/xui/en/floater_nearby_chat.xml index 2d67e3d5a9..674bfa42da 100644 --- a/indra/newview/skins/default/xui/en/floater_nearby_chat.xml +++ b/indra/newview/skins/default/xui/en/floater_nearby_chat.xml @@ -9,6 +9,7 @@ name="nearby_chat" save_rect="true" title="Nearby Chat" + single_instance="true" width="320"> <panel top="20" width="320" height="30" background_visible="true" background_opaque="false" bg_alpha_color="0.0 0.0 0.0 1.0" name="chat_caption"> <text diff --git a/indra/newview/skins/default/xui/en/floater_sys_well.xml b/indra/newview/skins/default/xui/en/floater_sys_well.xml index 468d41e2f0..46c8960fbd 100644 --- a/indra/newview/skins/default/xui/en/floater_sys_well.xml +++ b/indra/newview/skins/default/xui/en/floater_sys_well.xml @@ -4,96 +4,37 @@ background_visible="true" bevel_style="in" bg_alpha_color="0.0 0.0 0.0 0.0" - height="60" + height="30" left="0" top="0" follows="right|bottom" layout="topleft" name="notification_chiclet" save_rect="true" - title="" + title="NOTIFICATIONS" width="320" + min_width="320" can_minimize="false" can_tear_off="false" can_resize="false" can_drag_on_left="false" can_close="false" - can_dock="false" + can_dock="true" > <scroll_container follows="top|bottom" layout="topleft" name="notification_list_container" - left="1" - top="30" - width="336" - height="30"> + left="0" + top="18" + width="320" + height="12"> <scrolling_panel_list - follows="left|right" layout="topleft" name="notification_list" - left="0" + left="1" top="0" - height="20" - width="320" /> + height="10" + width="318" /> </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/menu_favorites.xml b/indra/newview/skins/default/xui/en/menu_favorites.xml index 7e4bbe3c9d..76c132aeb7 100644 --- a/indra/newview/skins/default/xui/en/menu_favorites.xml +++ b/indra/newview/skins/default/xui/en/menu_favorites.xml @@ -7,27 +7,59 @@ <menu_item_call label="Teleport" layout="topleft" - name="Landmark Open"> + name="Teleport To Landmark"> <menu_item_call.on_click function="Favorites.DoToSelected" parameter="open" /> </menu_item_call> <menu_item_call - label="About Landmark" + label="View/Edit Landmark" layout="topleft" - name="Teleport To Landmark"> + name="Landmark Open"> <menu_item_call.on_click function="Favorites.DoToSelected" parameter="about" /> </menu_item_call> -<!-- <menu_item_call --> -<!-- label="Rename" --> -<!-- layout="topleft" --> -<!-- name="Rename"> --> -<!-- <menu_item_call.on_click --> -<!-- function="Favorites.DoToSelected" --> -<!-- parameter="rename" /> --> -<!-- </menu_item_call> --> + <menu_item_call + label="Copy SLURL" + layout="topleft" + name="Copy slurl"> + <menu_item_call.on_click + function="Favorites.DoToSelected" + parameter="copy_slurl" /> + </menu_item_call> + <menu_item_call + label="Show On Map" + layout="topleft" + name="Show On Map"> + <menu_item_call.on_click + function="Favorites.DoToSelected" + parameter="show_on_map" /> + </menu_item_call> + + <menu_item_separator + layout="topleft" /> + + <menu_item_call + label="Copy" + layout="topleft" + name="Landmark Copy"> + <menu_item_call.on_click + function="Favorites.DoToSelected" + parameter="copy" /> + </menu_item_call> + <menu_item_call + label="Paste" + layout="topleft" + name="Landmark Paste"> + <menu_item_call.on_click + function="Favorites.DoToSelected" + parameter="paste" /> + </menu_item_call> + + <menu_item_separator + layout="topleft" /> + <menu_item_call label="Delete" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/menu_hide_navbar.xml b/indra/newview/skins/default/xui/en/menu_hide_navbar.xml new file mode 100644 index 0000000000..1ad10abbeb --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_hide_navbar.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<menu + height="201" + layout="topleft" + left="100" + mouse_opaque="false" + name="hide_navbar_menu" + top="624" + visible="false" + width="128"> + <menu_item_check + label="Show Navigation Bar" + layout="topleft" + name="Show Navigation Bar"> + <menu_item_check.on_click + function="HideNavbarMenu.Action" + parameter="show_navbar_navigation_panel" /> + <menu_item_check.on_check + function="HideNavbarMenu.EnableMenuItem" + parameter="show_navbar_navigation_panel" /> + </menu_item_check> + <menu_item_check + label="Show Favorites Bar" + layout="topleft" + name="Show Favorites Bar"> + <menu_item_check.on_click + function="HideNavbarMenu.Action" + parameter="show_navbar_favorites_panel" /> + <menu_item_check.on_check + function="HideNavbarMenu.EnableMenuItem" + parameter="show_navbar_favorites_panel" /> + </menu_item_check> +</menu> diff --git a/indra/newview/skins/default/xui/en/menu_navbar.xml b/indra/newview/skins/default/xui/en/menu_navbar.xml index 435d928f00..89469fb013 100644 --- a/indra/newview/skins/default/xui/en/menu_navbar.xml +++ b/indra/newview/skins/default/xui/en/menu_navbar.xml @@ -19,16 +19,15 @@ function="Navbar.EnableMenuItem" parameter="show_coordinates" /> </menu_item_check> + <!-- Label of 'Landmark' item is changing in runtime, + see AddLandmarkNavBarMenu/EditLandmarkNavBarMenu in strings.xml --> <menu_item_call - label="Add Landmark..." + label="Landmark" layout="topleft" - name="Add Landmark"> + name="Landmark"> <menu_item_call.on_click function="Navbar.Action" parameter="landmark" /> - <menu_item_call.on_enable - function="Navbar.EnableMenuItem" - parameter="can_landmark" /> </menu_item_call> <menu_item_separator layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_activeim_row.xml b/indra/newview/skins/default/xui/en/panel_activeim_row.xml new file mode 100644 index 0000000000..8977f30a51 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_activeim_row.xml @@ -0,0 +1,47 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + follows="bottom|right" + name="panel_activeim_row" + layout="topleft" + top="0" + left="0" + height="40" + width="332" + background_visible="true" + bevel_style="in" + bg_alpha_color="0 0 0 0"> + <chiclet_im + name="chiclet" + layout="topleft" + top="4" + left="10" + height="26" + width="45"> + </chiclet_im> + <text + type="string" + name="contact_name" + layout="topleft" + top="8" + left="70" + height="20" + width="230" + length="1" + follows="left|top|right|bottom" + font="SansSerifBigBold" + text_color="White">Contact Name</text> + <button + name="hide_btn" + layout="topleft" + top="10" + left="310" + height="20" + width="20" + 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"> + </button> +</panel>
\ No newline at end of file diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml index 5e2e2267f6..9910f99c17 100644 --- a/indra/newview/skins/default/xui/en/panel_bottomtray.xml +++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml @@ -245,9 +245,11 @@ height="20" left="18" top="23"/> +<!-- <chiclet_notification.commit_callback function="Notification.Show" parameter="ClickUnimplemented" /> + --> </chiclet_notification> </layout_panel> <icon 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 index 4f179d7a16..93fc938622 100644 --- a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml +++ b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml @@ -53,7 +53,7 @@ top="632" left="75" height="20" - ont="SansSerifSmall" + font="SansSerifSmall" label="Refresh" label_selected="Refresh" name="btn_refresh" @@ -69,7 +69,7 @@ left="5" visible="false" width="65" /> - <accordion layout="topleft" left="2" width="296" top="28" height="600" follows="all" name="panel_me_profile"> + <accordion layout="topleft" left="2" width="296" top="28" height="600" follows="all" name="group_general_tab"> <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> 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 8d90c6ebf0..f821dcd839 100644 --- a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml +++ b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml @@ -132,6 +132,7 @@ layout="topleft" left="5" name="favorite" + chevron_button_tool_tip="Show more of My Favorites" top="32" width="590" /> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml index b934312971..1efe287cbe 100644 --- a/indra/newview/skins/default/xui/en/panel_people.xml +++ b/indra/newview/skins/default/xui/en/panel_people.xml @@ -16,11 +16,20 @@ name="no_one_near" value="No-one near" /> <string - name="no_friends" - value="No friends" /> + name="no_friends_online" + value="No friends online" /> + <string + name="no_friends_offline" + value="No friends offline" /> <string name="no_groups" value="No groups" /> + <string + name="people_filter_label" + value="Filter People" /> + <string + name="groups_filter_label" + value="Filter Groups" /> <filter_editor background_image="TextField_Search_Off" follows="left|top|right" @@ -85,7 +94,7 @@ width="285"> <button enabled="false" - follows="bottom|right" + follows="bottom|left" font="SansSerifBigBold" height="18" image_selected="OptionsMenu_Press" @@ -107,14 +116,65 @@ layout="topleft" name="friends_panel" width="285"> - <avatar_list + <accordion follows="left|top|right|bottom" height="357" layout="topleft" left="0" - name="avatar_list" + name="friends_accordion" top="2" - width="285" /> + width="285"> + <accordion_tab + can_resize="false" + layout="topleft" + min_height="100" + name="tab_online" + title="Online"> + <panel + follows="all" + height="150" + layout="topleft" + left="0" + name="tab_online_panel" + top="100" + width="285"> + <avatar_list + draw_heading="false" + follows="all" + height="145" + layout="topleft" + left="0" + name="avatars_online" + top="0" + width="285" /> + </panel> + </accordion_tab> + <accordion_tab + can_resize="false" + layout="topleft" + min_height="100" + name="tab_offline" + title="Offline"> + <panel + follows="all" + height="260" + layout="topleft" + left="0" + name="tab_offline_panel" + top="100" + width="285"> + <avatar_list + draw_heading="false" + follows="all" + height="255" + layout="topleft" + left="0" + name="avatars_offline" + top="0" + width="285" /> + </panel> + </accordion_tab> + </accordion> <panel background_visible="true" bevel_style="none" @@ -128,7 +188,7 @@ width="285"> <button enabled="false" - follows="bottom|right" + follows="bottom|left" font="SansSerifBigBold" height="18" image_selected="OptionsMenu_Press" @@ -195,7 +255,7 @@ width="285"> <button enabled="false" - follows="bottom|right" + follows="bottom|left" font="SansSerifBigBold" height="18" image_selected="OptionsMenu_Press" @@ -275,7 +335,7 @@ width="285"> <button enabled="false" - follows="bottom|right" + follows="bottom|left" font="SansSerifBigBold" height="18" image_selected="OptionsMenu_Press" @@ -298,7 +358,6 @@ left="10" name="button_bar" orientation="horizontal" - top_pad="0" width="295"> <layout_panel default_tab_group="1" @@ -318,17 +377,17 @@ name="view_profile_btn" width="65" /> </layout_panel> -<!-- <layout_panel + <layout_panel default_tab_group="1" follows="left|top|right" height="25" layout="topleft" - left_pad="0" + left_delta="0" min_width="85" name="add_friend_btn_panel" top_delta="0" width="85"> - <button + <button follows="top|left|right" font="SansSerifSmallBold" height="25" @@ -336,13 +395,12 @@ layout="topleft" name="add_friend_btn" width="85" /> - </layout_panel>--> + </layout_panel> <layout_panel default_tab_group="1" follows="left|top|right" height="25" layout="topleft" - left_pad="0" min_width="80" name="group_info_btn_panel" width="80"> @@ -360,7 +418,6 @@ follows="left|top|right" height="25" layout="topleft" - left_pad="0" min_width="45" name="chat_btn_panel" top_delta="0" @@ -379,7 +436,6 @@ follows="left|top|right" height="25" layout="topleft" - left_pad="0" min_width="35" name="im_btn_panel" top_delta="0" @@ -398,7 +454,6 @@ follows="left|top|right" height="25" layout="topleft" - left_pad="0" min_width="40" name="call_btn_panel" top_delta="0" @@ -419,7 +474,6 @@ follows="left|top|right" height="25" layout="topleft" - left_pad="0" min_width="65" name="teleport_btn_panel" top_delta="0" @@ -439,7 +493,6 @@ follows="left|top|right" height="25" layout="topleft" - left_pad="0" min_width="50" name="share_btn_panel" top_delta="0" @@ -455,31 +508,5 @@ name="share_btn" width="50" /> </layout_panel> -<!-- <layout_panel - default_tab_group="1" - follows="left|top|right" - height="25" - layout="topleft" - left_pad="0" - min_width="40" - name="more_btn_panel" - top_delta="0" - width="40"> - <button - enabled="false" - follows="top|right" - font="SansSerifSmallBold" - height="25" - label=">>" - layout="topleft" - name="more_btn" - width="40" /> - </layout_panel>--> </layout_stack> - <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_places.xml b/indra/newview/skins/default/xui/en/panel_places.xml index 73cd988103..edaa8f7fa7 100644 --- a/indra/newview/skins/default/xui/en/panel_places.xml +++ b/indra/newview/skins/default/xui/en/panel_places.xml @@ -40,78 +40,91 @@ scale_image="false" top="8" width="13" /> + <tab_container - follows="left|top|right|bottom" + follows="all" height="326" layout="topleft" left="9" name="Places Tabs" tab_position="top" - top_pad="15" + top="30" width="285" /> - <button - follows="bottom|left" - font="SansSerifSmallBold" - height="25" - image_disabled="widgets/SegmentedBtn_Left_Disabled.png" - image_selected="widgets/SegmentedBtn_Left_Selected.png" - image_unselected="widgets/SegmentedBtn_Left_Off.png" - label="Create" - layout="topleft" - left="10" - name="create_landmark_btn" - top_pad="5" - visible="false" - width="60" /> - <button - follows="bottom|left" - font="SansSerifSmallBold" - height="25" - image_disabled="widgets/ComboButton_Disabled.png" - image_selected="widgets/ComboButton_Selected.png" - image_unselected="widgets/ComboButton_Off.png" - label="▼" - layout="topleft" - top_pad="0" - name="folder_menu_btn" - visible="false" - left_pad="5" - width="20" /> - <button - follows="bottom|left" - font="SansSerifSmallBold" - height="25" - label="Teleport" - layout="topleft" - left="10" - top_pad="0" - name="teleport_btn" - width="80" /> - <button - follows="bottom|left" - font="SansSerifSmallBold" - height="25" - label="Map" - layout="topleft" - name="map_btn" - left_pad="5" - width="80" /> - <button - enabled="false" - follows="bottom|left" - font="SansSerifSmallBold" - height="25" - left_pad="5" - label="Share" - layout="topleft" - name="share_btn" - width="60" /> <panel class="panel_place_info" filename="panel_place_info.xml" follows="all" layout="topleft" + top="30" + height="326" left="0" name="panel_place_info" visible="false" /> + + <panel + name="button_panel" + layout="topleft" + height="25" + left="0" + top_pad="10" + width="305"> + <button + follows="bottom|left" + font="SansSerifSmallBold" + height="25" + label="Teleport" + layout="topleft" + left="5" + top="0" + name="teleport_btn" + width="80" /> + <button + follows="bottom|left" + font="SansSerifSmallBold" + height="25" + label="Map" + layout="topleft" + name="map_btn" + left_pad="5" + top="0" + width="80" /> + <button + enabled="false" + follows="bottom|left" + font="SansSerifSmallBold" + height="25" + left_pad="5" + top="0" + label="Share" + layout="topleft" + name="share_btn" + width="60" /> + + <button + follows="bottom|left" + font="SansSerifSmallBold" + height="25" + image_disabled="widgets/SegmentedBtn_Left_Disabled.png" + image_selected="widgets/SegmentedBtn_Left_Selected.png" + image_unselected="widgets/SegmentedBtn_Left_Off.png" + label="Create" + layout="topleft" + left="5" + top="0" + name="create_landmark_btn" + width="60" /> + <button + follows="bottom|left" + font="SansSerifSmallBold" + height="25" + image_disabled="widgets/ComboButton_Disabled.png" + image_selected="widgets/ComboButton_Selected.png" + image_unselected="widgets/ComboButton_Off.png" + label="▼" + layout="topleft" + name="folder_menu_btn" + left_pad="0" + top="0" + width="20" /> + </panel> </panel> 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 index eccb919b04..3c49ce311a 100644 --- a/indra/newview/skins/default/xui/en/panel_sys_well_item.xml +++ b/indra/newview/skins/default/xui/en/panel_sys_well_item.xml @@ -10,7 +10,7 @@ width="318" height="35" layout="topleft" - follows="top" + follows="left|right" background_opaque="false" background_visible="true" bg_alpha_color="0.0 0.0 0.0 0.0" > diff --git a/indra/newview/skins/default/xui/en/panel_teleport_history.xml b/indra/newview/skins/default/xui/en/panel_teleport_history.xml index 05ebcbb50b..82d6945e0f 100644 --- a/indra/newview/skins/default/xui/en/panel_teleport_history.xml +++ b/indra/newview/skins/default/xui/en/panel_teleport_history.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <panel name="Teleport History" bottom="0" height="326" left="0" width="380" border="true" follows="left|top|right|bottom"> - <scroll_list bottom="0" column_padding="0" draw_heading="true" + <scroll_list bottom="0" column_padding="0" draw_heading="false" draw_stripes="false" follows="left|top|bottom|right" left="0" multi_select="false" name="history_items" search_column="1" sort_column="1" height="326" width="380" > diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 0ed473a01a..fb1aa25b25 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -610,6 +610,8 @@ you managed for [OWNER] Unknown file extension .%s Expected .wav, .tga, .bmp, .jpg, .jpeg, or .bvh </string> + <string name="AddLandmarkNavBarMenu">Add Landmark...</string> + <string name="EditLandmarkNavBarMenu">Edit Landmark...</string> <!-- Previews --> <string name="FileSaved">File Saved</string> |