diff -r e843e274fa58 indra/newview/app_settings/settings.xml --- a/indra/newview/app_settings/settings.xml Sun Dec 05 06:34:17 2010 -0800 +++ b/indra/newview/app_settings/settings.xml Mon Dec 06 17:56:38 2010 +0200 @@ -12332,5 +12332,16 @@ Value name + ShowFavoritesOnLogin + + Comment + Determines whether favorites of last logged in user will be saved on exit from viewer and shown on login screen + Persist + 1 + Type + Boolean + Value + 0 + diff -r e843e274fa58 indra/newview/llfavoritesbar.cpp --- a/indra/newview/llfavoritesbar.cpp Sun Dec 05 06:34:17 2010 -0800 +++ b/indra/newview/llfavoritesbar.cpp Mon Dec 06 17:56:38 2010 +0200 @@ -606,6 +606,16 @@ } else { + LLInventoryModel::item_array_t items; + LLInventoryModel::cat_array_t cats; + LLIsType is_type(LLAssetType::AT_LANDMARK); + gInventory.collectDescendentsIf(mFavoriteFolderId, cats, items, LLInventoryModel::EXCLUDE_TRASH, is_type); + + S32 sortField = 0; + for (LLInventoryModel::item_array_t::iterator i = items.begin(); i != items.end(); ++i) + { + (*i)->setSortField(++sortField); + } updateButtons(); } } diff -r e843e274fa58 indra/newview/llfloaterpreference.h --- a/indra/newview/llfloaterpreference.h Sun Dec 05 06:34:17 2010 -0800 +++ b/indra/newview/llfloaterpreference.h Mon Dec 06 17:56:38 2010 +0200 @@ -162,6 +162,7 @@ bool mLanguageChanged; bool mOriginalHideOnlineStatus; + bool mFavoritesFileMayExist; std::string mDirectoryVisibility; }; @@ -183,6 +184,8 @@ private: //for "Only friends and groups can call or IM me" static void showFriendsOnlyWarning(LLUICtrl*, const LLSD&); + //for "Show my Favorite Landmarks at Login" + static void showFavoritesOnLoginWarning(LLUICtrl* checkbox, const LLSD& value); typedef std::map control_values_map_t; control_values_map_t mSavedValues; diff -r e843e274fa58 indra/newview/llfloaterpreference.cpp --- a/indra/newview/llfloaterpreference.cpp Sun Dec 05 06:34:17 2010 -0800 +++ b/indra/newview/llfloaterpreference.cpp Mon Dec 06 17:56:38 2010 +0200 @@ -330,6 +330,8 @@ gSavedSettings.getControl("NameTagShowUsernames")->getCommitSignal()->connect(boost::bind(&handleNameTagOptionChanged, _2)); gSavedSettings.getControl("NameTagShowFriends")->getCommitSignal()->connect(boost::bind(&handleNameTagOptionChanged, _2)); gSavedSettings.getControl("UseDisplayNames")->getCommitSignal()->connect(boost::bind(&handleDisplayNamesOptionChanged, _2)); + + mFavoritesFileMayExist = gSavedSettings.getBOOL("ShowFavoritesOnLogin"); } BOOL LLFloaterPreference::postBuild() @@ -489,6 +491,13 @@ updateDoubleClickSettings(); mDoubleClickActionDirty = false; } + + if (mFavoritesFileMayExist && !gSavedSettings.getBOOL("ShowFavoritesOnLogin")) + { + mFavoritesFileMayExist = false; + std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml"); + LLFile::remove(filename); + } } void LLFloaterPreference::cancel() @@ -1491,6 +1500,10 @@ { getChild("voice_call_friends_only_check")->setCommitCallback(boost::bind(&showFriendsOnlyWarning, _1, _2)); } + if (hasChild("favorites_on_login_check")) + { + getChild("favorites_on_login_check")->setCommitCallback(boost::bind(&showFavoritesOnLoginWarning, _1, _2)); + } // Panel Advanced if (hasChild("modifier_combo")) @@ -1558,6 +1571,14 @@ } } +void LLPanelPreference::showFavoritesOnLoginWarning(LLUICtrl* checkbox, const LLSD& value) +{ + if (checkbox && checkbox->getValue()) + { + LLNotificationsUtil::add("FavoritesOnLogin"); + } +} + void LLPanelPreference::cancel() { for (control_values_map_t::iterator iter = mSavedValues.begin(); diff -r e843e274fa58 indra/newview/llpanellogin.h --- a/indra/newview/llpanellogin.h Sun Dec 05 06:34:17 2010 -0800 +++ b/indra/newview/llpanellogin.h Mon Dec 06 17:56:38 2010 +0200 @@ -85,6 +85,8 @@ private: friend class LLPanelLoginListener; void reshapeBrowser(); + // adds favorites of last logged in user from file to "Start at" combobox. + void addFavoritesToStartLocation(); static void onClickConnect(void*); static void onClickNewAccount(void*); // static bool newAccountAlertCallback(const LLSD& notification, const LLSD& response); diff -r e843e274fa58 indra/newview/llpanellogin.cpp --- a/indra/newview/llpanellogin.cpp Sun Dec 05 06:34:17 2010 -0800 +++ b/indra/newview/llpanellogin.cpp Mon Dec 06 17:56:38 2010 +0200 @@ -262,11 +262,45 @@ gResponsePtr = LLIamHereLogin::build( this ); LLHTTPClient::head( LLGridManager::getInstance()->getLoginPage(), gResponsePtr ); - + + // Show last logged in user favorites in "Start at" combo if corresponding option is enabled. + if (gSavedSettings.getBOOL("ShowFavoritesOnLogin")) + { + addFavoritesToStartLocation(); + } + updateLocationCombo(false); } +void LLPanelLogin::addFavoritesToStartLocation() +{ + std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml"); + LLSD fav_llsd; + llifstream file; + file.open(filename); + if (!file.is_open()) return; + LLComboBox* combo = getChild("start_location_combo"); + combo->addSeparator(); + LLSDSerialize::fromXML(fav_llsd, file); + for (LLSD::map_const_iterator iter = fav_llsd.beginMap(); + iter != fav_llsd.endMap(); ++iter) + { + LLSD user_llsd = iter->second; + for (LLSD::array_const_iterator iter1 = user_llsd.beginArray(); + iter1 != user_llsd.endArray(); ++iter1) + { + std::string label = (*iter1)["name"].asString(); + std::string value = (*iter1)["slurl"].asString(); + if(label != "" && value != "") + { + combo->add(label, value); + } + } + + } +} + // force the size to be correct (XML doesn't seem to be sufficient to do this) // (with some padding so the other login screen doesn't show through) void LLPanelLogin::reshapeBrowser() diff -r e843e274fa58 indra/newview/llviewerinventory.cpp --- a/indra/newview/llviewerinventory.cpp Sun Dec 05 06:34:17 2010 -0800 +++ b/indra/newview/llviewerinventory.cpp Mon Dec 06 17:56:38 2010 +0200 @@ -48,6 +48,7 @@ #include "llinventorybridge.h" #include "llinventorypanel.h" #include "llfloaterinventory.h" +#include "lllandmarkactions.h" #include "llviewerassettype.h" #include "llviewerregion.h" @@ -59,6 +60,8 @@ #include "llcommandhandler.h" #include "llviewermessage.h" #include "llsidepanelappearance.h" +#include "llavatarnamecache.h" +#include "lllogininstance.h" ///---------------------------------------------------------------------------- /// Helper class to store special inventory item names and their localized values. @@ -1414,6 +1417,8 @@ S32 getSortIndex(const LLUUID& inv_item_id); void removeSortIndex(const LLUUID& inv_item_id); + void getSLURL(const LLUUID& asset_id); + /** * Implementation of LLDestroyClass. Calls cleanup() instance method. * @@ -1440,9 +1445,17 @@ void load(); void save(); + void saveFavoritesSLURLs(); + + void onLandmarkLoaded(const LLUUID& asset_id, LLLandmark* landmark); + void storeFavoriteSLURL(const LLUUID& asset_id, std::string& slurl); + typedef std::map sort_index_map_t; sort_index_map_t mSortIndexes; + typedef std::map slurls_map_t; + slurls_map_t mSLURLs; + bool mIsDirty; struct IsNotInFavorites @@ -1497,10 +1510,27 @@ mIsDirty = true; } +void LLFavoritesOrderStorage::getSLURL(const LLUUID& asset_id) +{ + slurls_map_t::iterator slurl_iter = mSLURLs.find(asset_id); + if (slurl_iter != mSLURLs.end()) return; // SLURL for current landmark is already cached + + LLLandmark* lm = gLandmarkList.getAsset(asset_id, + boost::bind(&LLFavoritesOrderStorage::onLandmarkLoaded, this, asset_id, _1)); + if (lm) + { + onLandmarkLoaded(asset_id, lm); + } +} + // static void LLFavoritesOrderStorage::destroyClass() { LLFavoritesOrderStorage::instance().cleanup(); + if (gSavedSettings.getBOOL("ShowFavoritesOnLogin")) + { + LLFavoritesOrderStorage::instance().saveFavoritesSLURLs(); + } } void LLFavoritesOrderStorage::load() @@ -1523,6 +1553,77 @@ } } +void LLFavoritesOrderStorage::saveFavoritesSLURLs() +{ + // Do not change the file if we are not logged in yet. + if (!LLLoginInstance::getInstance()->authSuccess()) return; + + std::string user_dir = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, ""); + if (user_dir.empty()) return; + + std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml"); + + const LLUUID fav_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE); + LLInventoryModel::cat_array_t cats; + LLInventoryModel::item_array_t items; + gInventory.collectDescendents(fav_id, cats, items, LLInventoryModel::EXCLUDE_TRASH); + + LLSD user_llsd; + for (LLInventoryModel::item_array_t::iterator it = items.begin(); it != items.end(); it++) + { + LLSD value; + value["name"] = (*it)->getName(); + value["asset_id"] = (*it)->getAssetUUID(); + + slurls_map_t::iterator slurl_iter = mSLURLs.find(value["asset_id"]); + if (slurl_iter != mSLURLs.end()) + { + value["slurl"] = slurl_iter->second; + } + else + { + llwarns << "Fetching SLURLs for \"Favorites\" is not complete!" << llendl; + return; + } + + user_llsd[(*it)->getSortField()] = value; + } + + LLSD fav_llsd; + // this level in LLSD is not needed now and is just a stub, but will be needed later when implementing save of multiple users favorites in one file. + LLAvatarName av_name; + LLAvatarNameCache::get( gAgentID, &av_name ); + fav_llsd[av_name.getLegacyName()] = user_llsd; + + llofstream file; + file.open(filename); + LLSDSerialize::toPrettyXML(fav_llsd, file); +} + +void LLFavoritesOrderStorage::onLandmarkLoaded(const LLUUID& asset_id, LLLandmark* landmark) +{ + if (!landmark) return; + + LLVector3d pos_global; + if (!landmark->getGlobalPos(pos_global)) + { + // If global position was unknown on first getGlobalPos() call + // it should be set for the subsequent calls. + landmark->getGlobalPos(pos_global); + } + + if (!pos_global.isExactlyZero()) + { + LLLandmarkActions::getSLURLfromPosGlobal(pos_global, + boost::bind(&LLFavoritesOrderStorage::storeFavoriteSLURL, this, asset_id, _1)); + } +} + +void LLFavoritesOrderStorage::storeFavoriteSLURL(const LLUUID& asset_id, std::string& slurl) +{ + mSLURLs[asset_id] = slurl; +} + void LLFavoritesOrderStorage::save() { // nothing to save if clean @@ -1579,6 +1680,7 @@ void LLViewerInventoryItem::setSortField(S32 sortField) { LLFavoritesOrderStorage::instance().setSortIndex(mUUID, sortField); + LLFavoritesOrderStorage::instance().getSLURL(mAssetUUID); } const LLPermissions& LLViewerInventoryItem::getPermissions() const diff -r e843e274fa58 indra/newview/skins/default/xui/en/notifications.xml --- a/indra/newview/skins/default/xui/en/notifications.xml Sun Dec 05 06:34:17 2010 -0800 +++ b/indra/newview/skins/default/xui/en/notifications.xml Mon Dec 06 17:56:38 2010 +0200 @@ -253,6 +253,16 @@ + Note: When you turn on this option, anyone who uses this computer can see your list of favorite locations. + + + + Granting modify rights to another Resident allows them to change, delete or take ANY objects you may have in-world. Be VERY careful when handing out this permission. diff -r e843e274fa58 indra/newview/skins/default/xui/en/panel_preferences_privacy.xml --- a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml Sun Dec 05 06:34:17 2010 -0800 +++ b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml Mon Dec 06 17:56:38 2010 +0200 @@ -69,6 +69,15 @@ name="auto_disengage_mic_check" top_pad="10" width="350" /> + Chat Logs: @@ -170,7 +179,7 @@ layout="topleft" left="30" name="block_list" - top_pad="35" + top_pad="28" width="145">