diff options
58 files changed, 568 insertions, 152 deletions
diff --git a/indra/llcommon/llkeybind.cpp b/indra/llcommon/llkeybind.cpp index ecfc289cb3..38696c2258 100644 --- a/indra/llcommon/llkeybind.cpp +++ b/indra/llcommon/llkeybind.cpp @@ -144,7 +144,7 @@ bool LLKeyData::canHandle(const LLKeyData& data) const { if (data.mKey == mKey && data.mMouse == mMouse - && ((mIgnoreMasks && (data.mMask & mMask) == data.mMask) || data.mMask == mMask)) + && ((mIgnoreMasks && (data.mMask & mMask) == mMask) || data.mMask == mMask)) { return true; } @@ -155,7 +155,7 @@ bool LLKeyData::canHandle(EMouseClickType mouse, KEY key, MASK mask) const { if (mouse == mMouse && key == mKey - && ((mIgnoreMasks && (mask & mMask) == mask) || mask == mMask)) + && ((mIgnoreMasks && (mask & mMask) == mMask) || mask == mMask)) { return true; } diff --git a/indra/llcommon/llkeybind.h b/indra/llcommon/llkeybind.h index ad0ebec67c..7dc2aff4cb 100644 --- a/indra/llcommon/llkeybind.h +++ b/indra/llcommon/llkeybind.h @@ -53,7 +53,7 @@ public: EMouseClickType mMouse; KEY mKey; MASK mMask; - // Either to expect exact match or ignore not expected masks + // Either to expect exact match or to make sure mMask is inclused and ignore not expected masks bool mIgnoreMasks; }; diff --git a/indra/llui/llaccordionctrl.cpp b/indra/llui/llaccordionctrl.cpp index 623f570cef..779508df49 100644 --- a/indra/llui/llaccordionctrl.cpp +++ b/indra/llui/llaccordionctrl.cpp @@ -655,6 +655,37 @@ void LLAccordionCtrl::onScrollPosChangeCallback(S32, LLScrollbar*) { updateLayout(getRect().getWidth(),getRect().getHeight()); } + +// virtual +void LLAccordionCtrl::onChildGotFocus(const LLUICtrl *cntrl) +{ + if (mScrollbar && mScrollbar->getVisible()) + { + // same as scrollToShowRect + LLRect rect; + cntrl->localRectToOtherView(cntrl->getLocalRect(), &rect, this); + + // Translate to parent coordinatess to check if we are in visible rectangle + rect.translate(getRect().mLeft, getRect().mBottom); + + if (!getRect().contains(rect)) + { + // for accordition's scroll, height is in pixels + // Back to local coords and calculate position for scroller + S32 bottom = mScrollbar->getDocPos() - rect.mBottom + getRect().mBottom; + S32 top = mScrollbar->getDocPos() - rect.mTop + getRect().mTop; + + S32 scroll_pos = llclamp(mScrollbar->getDocPos(), + bottom, // min vertical scroll + top); // max vertical scroll + + mScrollbar->setDocPos(scroll_pos); + } + } + + LLUICtrl::onChildGotFocus(cntrl); +} + void LLAccordionCtrl::onOpen (const LLSD& key) { for(size_t i=0;i<mAccordionTabs.size();++i) diff --git a/indra/llui/llaccordionctrl.h b/indra/llui/llaccordionctrl.h index 1fe64c472e..3e30677429 100644 --- a/indra/llui/llaccordionctrl.h +++ b/indra/llui/llaccordionctrl.h @@ -111,6 +111,7 @@ public: void draw(); void onScrollPosChangeCallback(S32, LLScrollbar*); + virtual void onChildGotFocus(const LLUICtrl * cntrl); void onOpen (const LLSD& key); S32 notifyParent(const LLSD& info); diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp index 1034a21905..d5c4ad961c 100644 --- a/indra/llui/llaccordionctrltab.cpp +++ b/indra/llui/llaccordionctrltab.cpp @@ -452,6 +452,35 @@ void LLAccordionCtrlTab::onVisibilityChange(BOOL new_visibility) notifyParent(LLSD().with("child_visibility_change", new_visibility)); } +// virtual +void LLAccordionCtrlTab::onChildGotFocus(const LLUICtrl *cntrl) +{ + if (mScrollbar && mScrollbar->getVisible()) + { + LLRect rect; + cntrl->localRectToOtherView(cntrl->getLocalRect(), &rect, this); + + // Translate to parent coordinatess to check if we are in visible rectangle + rect.translate(getRect().mLeft, getRect().mBottom); + + if (!getRect().contains(rect)) + { + // for accordition's scroll, height is in pixels + // Back to local coords and calculate position for scroller + S32 bottom = mScrollbar->getDocPos() - rect.mBottom + getRect().mBottom; + S32 top = mScrollbar->getDocPos() - rect.mTop + getRect().mTop; + + S32 scroll_pos = llclamp(mScrollbar->getDocPos(), + bottom, // min vertical scroll + top); // max vertical scroll + + mScrollbar->setDocPos(scroll_pos); + } + } + + LLUICtrl::onChildGotFocus(cntrl); +} + BOOL LLAccordionCtrlTab::handleMouseDown(S32 x, S32 y, MASK mask) { if(mCollapsible && mHeaderVisible && mCanOpenClose) diff --git a/indra/llui/llaccordionctrltab.h b/indra/llui/llaccordionctrltab.h index 0263bce4be..53546ad5a1 100644 --- a/indra/llui/llaccordionctrltab.h +++ b/indra/llui/llaccordionctrltab.h @@ -159,6 +159,7 @@ public: * Raises notifyParent event with "child_visibility_change" = new_visibility */ void onVisibilityChange(BOOL new_visibility); + virtual void onChildGotFocus(const LLUICtrl * cntrl); // Changes expand/collapse state and triggers expand/collapse callbacks virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); diff --git a/indra/llui/llfolderview.h b/indra/llui/llfolderview.h index 2926e160d0..f70e9aa488 100644 --- a/indra/llui/llfolderview.h +++ b/indra/llui/llfolderview.h @@ -238,6 +238,8 @@ public: void dumpSelectionInformation(); virtual S32 notify(const LLSD& info) ; + + void setShowEmptyMessage(bool show_msg) { mShowEmptyMessage = show_msg; } bool useLabelSuffix() { return mUseLabelSuffix; } virtual void updateMenu(); diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp index c98da0d410..e1d275c351 100644 --- a/indra/llui/lluictrl.cpp +++ b/indra/llui/lluictrl.cpp @@ -679,6 +679,7 @@ void LLUICtrl::setFocus(BOOL b) if (!hasFocus()) { gFocusMgr.setKeyboardFocus( this ); + onChildGotFocus(this); } } else diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index 593c8b12fc..9d5cc70580 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -641,6 +641,16 @@ void LLView::onVisibilityChange ( BOOL new_visibility ) } // virtual +void LLView::onChildGotFocus(const LLUICtrl * cntrl) +{ + LLView* parent_view = getParent(); + if (parent_view) + { + parent_view->onChildGotFocus(cntrl); + } +} + +// virtual void LLView::translate(S32 x, S32 y) { mRect.translate(x, y); diff --git a/indra/llui/llview.h b/indra/llui/llview.h index db81900aaf..643436eb8c 100644 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -301,6 +301,7 @@ public: virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text ); virtual void onVisibilityChange ( BOOL new_visibility ); + virtual void onChildGotFocus(const LLUICtrl * cntrl); void pushVisible(BOOL visible) { mLastVisible = mVisible; setVisible(visible); } void popVisible() { setVisible(mLastVisible); } diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml index 8f4ca6c633..5eecf1b9f5 100644 --- a/indra/newview/app_settings/settings_per_account.xml +++ b/indra/newview/app_settings/settings_per_account.xml @@ -392,6 +392,17 @@ <key>Value</key> <string></string> </map> + <key>FavoritesFolder</key> + <map> + <key>Comment</key> + <string>User's chosen folder which will be shown in the Favorites tab (UUID)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>String</string> + <key>Value</key> + <string></string> + </map> <key>SnapshotBaseDir</key> <map> <key>Comment</key> diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 7206e43321..c94ec70766 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -3983,6 +3983,7 @@ static LLNotificationFunctorRegistration finish_quit_reg("ConfirmQuit", finish_q void LLAppViewer::userQuit() { + LL_INFOS() << "User requested quit" << LL_ENDL; if (gDisconnected || !gViewerWindow || !gViewerWindow->getProgressView() diff --git a/indra/newview/llappviewerlistener.cpp b/indra/newview/llappviewerlistener.cpp index 94250f1fc2..2380a8ebf0 100644 --- a/indra/newview/llappviewerlistener.cpp +++ b/indra/newview/llappviewerlistener.cpp @@ -52,10 +52,12 @@ LLAppViewerListener::LLAppViewerListener(const LLAppViewerGetter& getter): void LLAppViewerListener::requestQuit(const LLSD& event) { + LL_INFOS() << "Listener requested quit" << LL_ENDL; mAppViewerGetter()->requestQuit(); } void LLAppViewerListener::forceQuit(const LLSD& event) { + LL_INFOS() << "Listener requested force quit" << LL_ENDL; mAppViewerGetter()->forceQuit(); } diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp index 5539fa75dd..9430bb3ca3 100644 --- a/indra/newview/llconversationlog.cpp +++ b/indra/newview/llconversationlog.cpp @@ -482,6 +482,10 @@ bool LLConversationLog::saveToFile(const std::string& filename) conv_it->getSessionID().toString(conversation_id); conv_it->getParticipantID().toString(participant_id); + bool is_adhoc = (conv_it->getConversationType() == LLIMModel::LLIMSession::ADHOC_SESSION); + std::string conv_name = is_adhoc ? conv_it->getConversationName() : LLURI::escape(conv_it->getConversationName()); + std::string file_name = is_adhoc ? conv_it->getHistoryFileName() : LLURI::escape(conv_it->getHistoryFileName()); + // examples of two file entries // [1343221177] 0 1 0 John Doe| 7e4ec5be-783f-49f5-71dz-16c58c64c145 4ec62a74-c246-0d25-2af6-846beac2aa55 john.doe| // [1343222639] 2 0 0 Ad-hoc Conference| c3g67c89-c479-4c97-b21d-32869bcfe8rc 68f1c33e-4135-3e3e-a897-8c9b23115c09 Ad-hoc Conference hash597394a0-9982-766d-27b8-c75560213b9a| @@ -490,10 +494,10 @@ bool LLConversationLog::saveToFile(const std::string& filename) (S32)conv_it->getConversationType(), (S32)0, (S32)conv_it->hasOfflineMessages(), - LLURI::escape(conv_it->getConversationName()).c_str(), + conv_name.c_str(), participant_id.c_str(), conversation_id.c_str(), - LLURI::escape(conv_it->getHistoryFileName()).c_str()); + file_name.c_str()); } fclose(fp); return true; @@ -541,14 +545,18 @@ bool LLConversationLog::loadFromFile(const std::string& filename) conv_id_buffer, history_file_name); + bool is_adhoc = ((SessionType)stype == LLIMModel::LLIMSession::ADHOC_SESSION); + std::string conv_name = is_adhoc ? conv_name_buffer : LLURI::unescape(conv_name_buffer); + std::string file_name = is_adhoc ? history_file_name : LLURI::unescape(history_file_name); + ConversationParams params; params.time(LLUnits::Seconds::fromValue(time)) .conversation_type((SessionType)stype) .has_offline_ims(has_offline_ims) - .conversation_name(LLURI::unescape(conv_name_buffer)) + .conversation_name(conv_name) .participant_id(LLUUID(part_id_buffer)) .session_id(LLUUID(conv_id_buffer)) - .history_filename(LLURI::unescape(history_file_name)); + .history_filename(file_name); LLConversation conversation(params); diff --git a/indra/newview/llfloaterloadprefpreset.cpp b/indra/newview/llfloaterloadprefpreset.cpp index 403db35cc0..36fae0391c 100644 --- a/indra/newview/llfloaterloadprefpreset.cpp +++ b/indra/newview/llfloaterloadprefpreset.cpp @@ -65,6 +65,11 @@ void LLFloaterLoadPrefPreset::onOpen(const LLSD& key) EDefaultOptions option = DEFAULT_TOP; LLPresetsManager::getInstance()->setPresetNamesInComboBox(mSubdirectory, combo, option); + std::string preset_graphic_active = gSavedSettings.getString("PresetGraphicActive"); + if (!preset_graphic_active.empty()) + { + combo->setSimple(preset_graphic_active); + } } void LLFloaterLoadPrefPreset::onPresetsListChange() @@ -73,6 +78,11 @@ void LLFloaterLoadPrefPreset::onPresetsListChange() EDefaultOptions option = DEFAULT_TOP; LLPresetsManager::getInstance()->setPresetNamesInComboBox(mSubdirectory, combo, option); + std::string preset_graphic_active = gSavedSettings.getString("PresetGraphicActive"); + if (!preset_graphic_active.empty()) + { + combo->setSimple(preset_graphic_active); + } } void LLFloaterLoadPrefPreset::onBtnCancel() diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index c9c563a054..105f728508 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -1868,6 +1868,14 @@ void LLFloaterPreference::updateMaxComplexity() LLAvatarComplexityControls::updateMax( getChild<LLSliderCtrl>("IndirectMaxComplexity"), getChild<LLTextBox>("IndirectMaxComplexityText")); + + LLFloaterPreferenceGraphicsAdvanced* floater_graphics_advanced = LLFloaterReg::findTypedInstance<LLFloaterPreferenceGraphicsAdvanced>("prefs_graphics_advanced"); + if (floater_graphics_advanced) + { + LLAvatarComplexityControls::updateMax( + floater_graphics_advanced->getChild<LLSliderCtrl>("IndirectMaxComplexity"), + floater_graphics_advanced->getChild<LLTextBox>("IndirectMaxComplexityText")); + } } bool LLFloaterPreference::loadFromFilename(const std::string& filename, std::map<std::string, std::string> &label_map) @@ -1915,6 +1923,14 @@ void LLFloaterPreferenceGraphicsAdvanced::updateMaxComplexity() LLAvatarComplexityControls::updateMax( getChild<LLSliderCtrl>("IndirectMaxComplexity"), getChild<LLTextBox>("IndirectMaxComplexityText")); + + LLFloaterPreference* floater_preferences = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences"); + if (floater_preferences) + { + LLAvatarComplexityControls::updateMax( + floater_preferences->getChild<LLSliderCtrl>("IndirectMaxComplexity"), + floater_preferences->getChild<LLTextBox>("IndirectMaxComplexityText")); + } } void LLFloaterPreference::onChangeMaturity() diff --git a/indra/newview/llfloatersaveprefpreset.cpp b/indra/newview/llfloatersaveprefpreset.cpp index 684778c93a..8eb3510881 100644 --- a/indra/newview/llfloatersaveprefpreset.cpp +++ b/indra/newview/llfloatersaveprefpreset.cpp @@ -87,7 +87,10 @@ void LLFloaterSavePrefPreset::onBtnSave() { std::string name = mPresetCombo->getSimple(); - if ((name == LLTrans::getString(PRESETS_DEFAULT)) || (name == PRESETS_DEFAULT)) + std::string upper_name(name); + LLStringUtil::toUpper(upper_name); + + if ((name == LLTrans::getString(PRESETS_DEFAULT)) || (upper_name == PRESETS_DEFAULT_UPPER)) { LLNotificationsUtil::add("DefaultPresetNotSaved"); } diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index d460aa1452..d214946398 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -134,6 +134,35 @@ bool isMarketplaceSendAction(const std::string& action) return ("send_to_marketplace" == action); } +bool isPanelActive(const std::string& panel_name) +{ + LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE); + return (active_panel && (active_panel->getName() == panel_name)); +} + +bool isParentSystemFolder(const LLInventoryModel* model, const LLUUID& folder_id) +{ + if (!model || folder_id.isNull()) return false; + + LLViewerInventoryCategory* cat = model->getCategory(folder_id); + if (cat) + { + if (cat->getPreferredType() == LLFolderType::FT_ROOT_INVENTORY) + { + return false; + } + if (LLFolderType::lookupIsProtectedType(cat->getPreferredType())) + { + return true; + } + else + { + return isParentSystemFolder(model, cat->getParentUUID()); + } + } + return false; +} + // Used by LLFolderBridge as callback for directory fetching recursion class LLRightClickInventoryFetchDescendentsObserver : public LLInventoryFetchDescendentsObserver { @@ -884,8 +913,7 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, disabled_items.push_back(std::string("Properties")); } - LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE); - if (active_panel && (active_panel->getName() != "All Items")) + if (!isPanelActive("All Items")) { items.push_back(std::string("Show in Main Panel")); } @@ -976,7 +1004,7 @@ void LLInvFVBridge::addDeleteContextMenuOptions(menuentry_vec_t &items, items.push_back(std::string("Delete")); - if (!isItemRemovable()) + if (!isItemRemovable() || isPanelActive("Favorite Items")) { disabled_items.push_back(std::string("Delete")); } @@ -3997,6 +4025,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items disabled_items.push_back(std::string("New Clothes")); disabled_items.push_back(std::string("New Body Parts")); disabled_items.push_back(std::string("upload_def")); + disabled_items.push_back(std::string("Set Favorites folder")); } if (favorites == mUUID) { @@ -4024,6 +4053,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items disabled_items.push_back(std::string("New Clothes")); disabled_items.push_back(std::string("New Body Parts")); disabled_items.push_back(std::string("upload_def")); + disabled_items.push_back(std::string("Set Favorites folder")); } if (marketplace_listings_id == mUUID) { @@ -4032,14 +4062,14 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items disabled_items.push_back(std::string("Cut")); disabled_items.push_back(std::string("Delete")); } + + if (isPanelActive("Favorite Items")) + { + disabled_items.push_back(std::string("Delete")); + } if(trash_id == mUUID) { - bool is_recent_panel = false; - LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE); - if (active_panel && (active_panel->getName() == "Recent Items")) - { - is_recent_panel = true; - } + bool is_recent_panel = isPanelActive("Recent Items"); // This is the trash. items.push_back(std::string("Empty Trash")); @@ -4087,6 +4117,11 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items items.push_back(std::string("New Clothes")); items.push_back(std::string("New Body Parts")); items.push_back(std::string("upload_def")); + + if (!LLFolderType::lookupIsProtectedType(getPreferredType()) && !isParentSystemFolder(model, mUUID)) + { + items.push_back(std::string("Set Favorites folder")); + } } } getClipboardEntries(false, items, disabled_items, flags); diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp index e8bc915f22..e200b5bc9e 100644 --- a/indra/newview/llinventoryfilter.cpp +++ b/indra/newview/llinventoryfilter.cpp @@ -286,21 +286,34 @@ bool LLInventoryFilter::checkAgainstFilterType(const LLFolderViewModelItemInvent // Pass if this item's type is of the correct filter type if (filterTypes & FILTERTYPE_OBJECT) { - - // If it has no type, pass it, unless it's a link. - if (object_type == LLInventoryType::IT_NONE) - { - if (object && object->getIsLinkType()) - { - return FALSE; - } - } - else if ((1LL << object_type & mFilterOps.mFilterObjectTypes) == U64(0)) - { - return FALSE; - } + switch (object_type) + { + case LLInventoryType::IT_NONE: + // If it has no type, pass it, unless it's a link. + if (object && object->getIsLinkType()) + { + return FALSE; + } + break; + case LLInventoryType::IT_UNKNOWN: + { + // Unknows are only shown when we show every type. + // Unknows are 255 and won't fit in 64 bits. + if (mFilterOps.mFilterObjectTypes != 0xffffffffffffffffULL) + { + return FALSE; + } + break; + } + default: + if ((1LL << object_type & mFilterOps.mFilterObjectTypes) == U64(0)) + { + return FALSE; + } + break; + } } - + if(filterTypes & FILTERTYPE_WORN) { if (!get_is_item_worn(object_id)) @@ -411,18 +424,32 @@ bool LLInventoryFilter::checkAgainstFilterType(const LLInventoryItem* item) cons // Pass if this item's type is of the correct filter type if (filterTypes & FILTERTYPE_OBJECT) { - // If it has no type, pass it, unless it's a link. - if (object_type == LLInventoryType::IT_NONE) - { - if (item && item->getIsLinkType()) - { - return false; - } - } - else if ((1LL << object_type & mFilterOps.mFilterObjectTypes) == U64(0)) - { - return false; - } + switch (object_type) + { + case LLInventoryType::IT_NONE: + // If it has no type, pass it, unless it's a link. + if (item && item->getIsLinkType()) + { + return FALSE; + } + break; + case LLInventoryType::IT_UNKNOWN: + { + // Unknows are only shown when we show every type. + // Unknows are 255 and won't fit in 64 bits. + if (mFilterOps.mFilterObjectTypes != 0xffffffffffffffffULL) + { + return FALSE; + } + break; + } + default: + if ((1LL << object_type & mFilterOps.mFilterObjectTypes) == U64(0)) + { + return FALSE; + } + break; + } } //////////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index c49d61df31..3cd38a5122 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -542,6 +542,11 @@ const LLUUID LLInventoryModel::findUserDefinedCategoryUUIDForType(LLFolderType:: cat_id = LLUUID(gSavedPerAccountSettings.getString("AnimationUploadFolder")); break; } + case LLFolderType::FT_FAVORITE: + { + cat_id = LLUUID(gSavedPerAccountSettings.getString("FavoritesFolder")); + break; + } default: break; } diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index 6f461673ee..d7598bae91 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -169,6 +169,7 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) : mCommitCallbackRegistrar.add("Inventory.BeginIMSession", boost::bind(&LLInventoryPanel::beginIMSession, this)); mCommitCallbackRegistrar.add("Inventory.Share", boost::bind(&LLAvatarActions::shareWithAvatars, this)); mCommitCallbackRegistrar.add("Inventory.FileUploadLocation", boost::bind(&LLInventoryPanel::fileUploadLocation, this, _2)); + mCommitCallbackRegistrar.add("Inventory.SetFavoritesFolder", boost::bind(&LLInventoryPanel::setFavoritesFolder, this, _2)); } LLFolderView * LLInventoryPanel::createFolderRoot(LLUUID root_id ) @@ -1344,6 +1345,11 @@ void LLInventoryPanel::fileUploadLocation(const LLSD& userdata) } } +void LLInventoryPanel::setFavoritesFolder(const LLSD& userdata) +{ + gSavedPerAccountSettings.setString("FavoritesFolder", LLFolderBridge::sSelf.get()->getUUID().asString()); +} + void LLInventoryPanel::purgeSelectedItems() { if (!mFolderRoot.get()) return; @@ -1729,6 +1735,95 @@ LLInventoryRecentItemsPanel::LLInventoryRecentItemsPanel( const Params& params) mInvFVBridgeBuilder = &RECENT_ITEMS_BUILDER; } +static LLDefaultChildRegistry::Register<LLInventoryFavoriteItemsPanel> t_favorites_inventory_panel("favorites_inventory_panel"); + +LLInventoryFavoriteItemsPanel::LLInventoryFavoriteItemsPanel(const Params& params) + : LLInventoryPanel(params) +{ + std::string ctrl_name = "FavoritesFolder"; + if (gSavedPerAccountSettings.controlExists(ctrl_name)) + { + LLPointer<LLControlVariable> cntrl_ptr = gSavedPerAccountSettings.getControl(ctrl_name); + if (cntrl_ptr.notNull()) + { + mFolderChangedSignal = cntrl_ptr->getCommitSignal()->connect(boost::bind(&LLInventoryFavoriteItemsPanel::updateFavoritesRootFolder, this)); + } + } +} + +void LLInventoryFavoriteItemsPanel::setSelectCallback(const boost::function<void(const std::deque<LLFolderViewItem*>& items, BOOL user_action)>& cb) +{ + if (mFolderRoot.get()) + { + mFolderRoot.get()->setSelectCallback(cb); + mSelectionCallback = cb; + } +} + +void LLInventoryFavoriteItemsPanel::initFromParams(const Params& p) +{ + Params fav_params(p); + fav_params.start_folder.id = gInventory.findUserDefinedCategoryUUIDForType(LLFolderType::FT_FAVORITE); + LLInventoryPanel::initFromParams(fav_params); + updateFavoritesRootFolder(); +} + +void LLInventoryFavoriteItemsPanel::updateFavoritesRootFolder() +{ + const LLUUID& folder_id = gInventory.findUserDefinedCategoryUUIDForType(LLFolderType::FT_FAVORITE); + + bool is_favorites_set = (folder_id != gInventory.findCategoryUUIDForTypeInRoot(LLFolderType::FT_FAVORITE, true, gInventory.getRootFolderID())); + + if (!is_favorites_set || folder_id != getRootFolderID()) + { + LLUUID root_id = folder_id; + if (mFolderRoot.get()) + { + removeItemID(getRootFolderID()); + mFolderRoot.get()->destroyView(); + } + + mCommitCallbackRegistrar.pushScope(); + { + LLFolderView* folder_view = createFolderRoot(root_id); + mFolderRoot = folder_view->getHandle(); + + addItemID(root_id, mFolderRoot.get()); + + + LLRect scroller_view_rect = getRect(); + scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom); + LLScrollContainer::Params scroller_params(mParams.scroll()); + scroller_params.rect(scroller_view_rect); + + if (mScroller) + { + removeChild(mScroller); + delete mScroller; + mScroller = NULL; + } + mScroller = LLUICtrlFactory::create<LLFolderViewScrollContainer>(scroller_params); + addChild(mScroller); + mScroller->addChild(mFolderRoot.get()); + mFolderRoot.get()->setScrollContainer(mScroller); + mFolderRoot.get()->setFollowsAll(); + mFolderRoot.get()->addChild(mFolderRoot.get()->mStatusTextBox); + + if (!mSelectionCallback.empty()) + { + mFolderRoot.get()->setSelectCallback(mSelectionCallback); + } + } + mCommitCallbackRegistrar.popScope(); + mFolderRoot.get()->setCallbackRegistrar(&mCommitCallbackRegistrar); + + if (is_favorites_set) + { + buildNewViews(folder_id); + } + mFolderRoot.get()->setShowEmptyMessage(!is_favorites_set); + } +} namespace LLInitParam { void TypeValues<LLFolderType::EType>::declareValues() diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h index 12001f5a2b..cdbbe2bf35 100644 --- a/indra/newview/llinventorypanel.h +++ b/indra/newview/llinventorypanel.h @@ -205,6 +205,7 @@ public: void doCreate(const LLSD& userdata); bool beginIMSession(); void fileUploadLocation(const LLSD& userdata); + void setFavoritesFolder(const LLSD& userdata); void purgeSelectedItems(); bool attachObject(const LLSD& userdata); static void idle(void* user_data); @@ -322,4 +323,24 @@ private: bool mViewsInitialized; // Views have been generated }; + +class LLInventoryFavoriteItemsPanel : public LLInventoryPanel +{ +public: + struct Params : public LLInitParam::Block<Params, LLInventoryPanel::Params> + {}; + + void initFromParams(const Params& p); + bool isSelectionRemovable() { return false; } + void setSelectCallback(const boost::function<void(const std::deque<LLFolderViewItem*>& items, BOOL user_action)>& cb); + +protected: + LLInventoryFavoriteItemsPanel(const Params& params); + ~LLInventoryFavoriteItemsPanel() { mFolderChangedSignal.disconnect(); } + void updateFavoritesRootFolder(); + + boost::signals2::connection mFolderChangedSignal; + boost::function<void(const std::deque<LLFolderViewItem*>& items, BOOL user_action)> mSelectionCallback; + friend class LLUICtrlFactory; +}; #endif // LL_LLINVENTORYPANEL_H diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index ce41e2bd35..c9c3dffc5a 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -1554,7 +1554,7 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id) if (!zero) { //attempt to parse - if (physicsShapeReceived(mesh_id, buffer, size)) + if (physicsShapeReceived(mesh_id, buffer, size) == MESH_OK) { delete[] buffer; return true; @@ -1648,7 +1648,7 @@ bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params, bool c LLMeshRepository::sCacheBytesRead += bytes; ++LLMeshRepository::sCacheReads; file.read(buffer, bytes); - if (headerReceived(mesh_params, buffer, bytes)) + if (headerReceived(mesh_params, buffer, bytes) == MESH_OK) { // Found mesh in VFS cache return true; @@ -1795,7 +1795,7 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, return retval; } -bool LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* data, S32 data_size) +EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* data, S32 data_size) { const LLUUID mesh_id = mesh_params.getSculptID(); LLSD header; @@ -1803,30 +1803,39 @@ bool LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* dat U32 header_size = 0; if (data_size > 0) { - std::string res_str((char*) data, data_size); + std::istringstream stream; + try + { + std::string res_str((char*)data, data_size); - std::string deprecated_header("<? LLSD/Binary ?>"); + std::string deprecated_header("<? LLSD/Binary ?>"); - if (res_str.substr(0, deprecated_header.size()) == deprecated_header) - { - res_str = res_str.substr(deprecated_header.size()+1, data_size); - header_size = deprecated_header.size()+1; - } - data_size = res_str.size(); + if (res_str.substr(0, deprecated_header.size()) == deprecated_header) + { + res_str = res_str.substr(deprecated_header.size() + 1, data_size); + header_size = deprecated_header.size() + 1; + } + data_size = res_str.size(); - std::istringstream stream(res_str); + stream.str(res_str); + } + catch (std::bad_alloc&) + { + // out of memory, we won't be able to process this mesh + return MESH_OUT_OF_MEMORY; + } if (!LLSDSerialize::fromBinary(header, stream, data_size)) { LL_WARNS(LOG_MESH) << "Mesh header parse error. Not a valid mesh asset! ID: " << mesh_id << LL_ENDL; - return false; + return MESH_PARSE_FAILURE; } if (!header.isMap()) { LL_WARNS(LOG_MESH) << "Mesh header is invalid for ID: " << mesh_id << LL_ENDL; - return false; + return MESH_INVALID; } if (header.has("version") && header["version"].asInteger() > MAX_MESH_VERSION) @@ -1872,7 +1881,7 @@ bool LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* dat } } - return true; + return MESH_OK; } EMeshProcessingResult LLMeshRepoThread::lodReceived(const LLVolumeParams& mesh_params, S32 lod, U8* data, S32 data_size) @@ -1917,18 +1926,25 @@ bool LLMeshRepoThread::skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 dat if (data_size > 0) { - std::string res_str((char*) data, data_size); - - std::istringstream stream(res_str); + try + { + std::string res_str((char*)data, data_size); + std::istringstream stream(res_str); - U32 uzip_result = LLUZipHelper::unzip_llsd(skin, stream, data_size); - if (uzip_result != LLUZipHelper::ZR_OK) - { - LL_WARNS(LOG_MESH) << "Mesh skin info parse error. Not a valid mesh asset! ID: " << mesh_id - << " uzip result" << uzip_result - << LL_ENDL; - return false; - } + U32 uzip_result = LLUZipHelper::unzip_llsd(skin, stream, data_size); + if (uzip_result != LLUZipHelper::ZR_OK) + { + LL_WARNS(LOG_MESH) << "Mesh skin info parse error. Not a valid mesh asset! ID: " << mesh_id + << " uzip result" << uzip_result + << LL_ENDL; + return false; + } + } + catch (std::bad_alloc&) + { + LL_WARNS(LOG_MESH) << "Out of memory for mesh ID " << mesh_id << " of size: " << data_size << LL_ENDL; + return false; + } } { @@ -1950,19 +1966,26 @@ bool LLMeshRepoThread::decompositionReceived(const LLUUID& mesh_id, U8* data, S3 LLSD decomp; if (data_size > 0) - { - std::string res_str((char*) data, data_size); - - std::istringstream stream(res_str); + { + try + { + std::string res_str((char*)data, data_size); + std::istringstream stream(res_str); - U32 uzip_result = LLUZipHelper::unzip_llsd(decomp, stream, data_size); - if (uzip_result != LLUZipHelper::ZR_OK) - { - LL_WARNS(LOG_MESH) << "Mesh decomposition parse error. Not a valid mesh asset! ID: " << mesh_id - << " uzip result: " << uzip_result - << LL_ENDL; - return false; - } + U32 uzip_result = LLUZipHelper::unzip_llsd(decomp, stream, data_size); + if (uzip_result != LLUZipHelper::ZR_OK) + { + LL_WARNS(LOG_MESH) << "Mesh decomposition parse error. Not a valid mesh asset! ID: " << mesh_id + << " uzip result: " << uzip_result + << LL_ENDL; + return false; + } + } + catch (std::bad_alloc&) + { + LL_WARNS(LOG_MESH) << "Out of memory for mesh ID " << mesh_id << " of size: " << data_size << LL_ENDL; + return false; + } } { @@ -1977,7 +2000,7 @@ bool LLMeshRepoThread::decompositionReceived(const LLUUID& mesh_id, U8* data, S3 return true; } -bool LLMeshRepoThread::physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 data_size) +EMeshProcessingResult LLMeshRepoThread::physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 data_size) { LLSD physics_shape; @@ -1994,8 +2017,19 @@ bool LLMeshRepoThread::physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE); volume_params.setSculptID(mesh_id, LL_SCULPT_TYPE_MESH); LLPointer<LLVolume> volume = new LLVolume(volume_params,0); - std::string mesh_string((char*) data, data_size); - std::istringstream stream(mesh_string); + + std::istringstream stream; + try + { + std::string mesh_string((char*)data, data_size); + stream.str(mesh_string); + } + catch (std::bad_alloc&) + { + // out of memory, we won't be able to process this mesh + delete d; + return MESH_OUT_OF_MEMORY; + } if (volume->unpackVolumeFaces(stream, data_size)) { @@ -2034,7 +2068,7 @@ bool LLMeshRepoThread::physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 LLMutexLock lock(mMutex); mDecompositionQ.push_back(d); } - return true; + return MESH_OK; } LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list& data, LLVector3& scale, bool upload_textures, @@ -3143,15 +3177,21 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b U8 * data, S32 data_size) { LLUUID mesh_id = mMeshParams.getSculptID(); - bool success = (! MESH_HEADER_PROCESS_FAILED) - && ((data != NULL) == (data_size > 0)) // if we have data but no size or have size but no data, something is wrong - && gMeshRepo.mThread->headerReceived(mMeshParams, data, data_size); + bool success = (!MESH_HEADER_PROCESS_FAILED) + && ((data != NULL) == (data_size > 0)); // if we have data but no size or have size but no data, something is wrong; llassert(success); + EMeshProcessingResult res = MESH_UNKNOWN; + if (success) + { + res = gMeshRepo.mThread->headerReceived(mMeshParams, data, data_size); + success = (res == MESH_OK); + } if (! success) { // *TODO: Get real reason for parse failure here. Might we want to retry? LL_WARNS(LOG_MESH) << "Unable to parse mesh header. ID: " << mesh_id - << ", Unknown reason. Not retrying." + << ", Size: " << data_size + << ", Reason: " << res << " Not retrying." << LL_ENDL; // Can't get the header so none of the LODs will be available @@ -3431,7 +3471,7 @@ void LLMeshPhysicsShapeHandler::processData(LLCore::BufferArray * /* body */, S3 { if ((!MESH_PHYS_SHAPE_PROCESS_FAILED) && ((data != NULL) == (data_size > 0)) // if we have data but no size or have size but no data, something is wrong - && gMeshRepo.mThread->physicsShapeReceived(mMeshID, data, data_size)) + && gMeshRepo.mThread->physicsShapeReceived(mMeshID, data, data_size) == MESH_OK) { // good fetch from sim, write to VFS for caching LLVFile file(gVFS, mMeshID, LLAssetType::AT_MESH, LLVFile::WRITE); diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index bba0c9f2cb..9a627dabcb 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -57,6 +57,8 @@ typedef enum e_mesh_processing_result_enum MESH_NO_DATA = 1, MESH_OUT_OF_MEMORY, MESH_HTTP_REQUEST_FAILED, + MESH_PARSE_FAILURE, + MESH_INVALID, MESH_UNKNOWN } EMeshProcessingResult; @@ -336,11 +338,11 @@ public: bool fetchMeshHeader(const LLVolumeParams& mesh_params, bool can_retry = true); bool fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, bool can_retry = true); - bool headerReceived(const LLVolumeParams& mesh_params, U8* data, S32 data_size); + EMeshProcessingResult headerReceived(const LLVolumeParams& mesh_params, U8* data, S32 data_size); EMeshProcessingResult lodReceived(const LLVolumeParams& mesh_params, S32 lod, U8* data, S32 data_size); bool skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 data_size); bool decompositionReceived(const LLUUID& mesh_id, U8* data, S32 data_size); - bool physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 data_size); + EMeshProcessingResult physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 data_size); LLSD& getMeshHeader(const LLUUID& mesh_id); void notifyLoadedMeshes(); diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp index 12b46e9bb2..1a28c49141 100644 --- a/indra/newview/lloutfitgallery.cpp +++ b/indra/newview/lloutfitgallery.cpp @@ -1046,6 +1046,7 @@ void LLOutfitGallery::updateSnapshotFolderObserver() void LLOutfitGallery::refreshOutfit(const LLUUID& category_id) { LLViewerInventoryCategory* category = gInventory.getCategory(category_id); + if (category) { bool photo_loaded = false; LLInventoryModel::cat_array_t sub_cat_array; diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 5742b5ad1a..f127325ced 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -1109,6 +1109,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) bool enabled = (editable && isIdenticalPlanarTexgen()); childSetValue("checkbox planar align", align_planar && enabled); + childSetVisible("checkbox planar align", enabled); childSetEnabled("checkbox planar align", enabled); childSetEnabled("button align textures", enabled && LLSelectMgr::getInstance()->getSelection()->getObjectCount() > 1); diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index f63e604927..0eb9ed0ed9 100644 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -184,6 +184,16 @@ BOOL LLPanelMainInventory::postBuild() worn_filter.markDefault(); mWornItemsPanel->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, mWornItemsPanel, _1, _2)); } + + mFavoriteItemsPanel = getChild<LLInventoryFavoriteItemsPanel>("Favorite Items"); + if (mFavoriteItemsPanel) + { + LLInventoryFilter& recent_filter = mFavoriteItemsPanel->getFilter(); + recent_filter.setEmptyLookupMessage("InventoryFavoritItemsNotSelected"); + recent_filter.markDefault(); + mFavoriteItemsPanel->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, mFavoriteItemsPanel, _1, _2)); + } + mSearchTypeCombo = getChild<LLComboBox>("search_type"); if(mSearchTypeCombo) { @@ -1390,7 +1400,7 @@ BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata) } if (command_name == "delete") { - return getActivePanel()->isSelectionRemovable(); + return getActivePanel()->isSelectionRemovable() && (getActivePanel() != mFavoriteItemsPanel); } if (command_name == "save_texture") { diff --git a/indra/newview/llpanelmaininventory.h b/indra/newview/llpanelmaininventory.h index 732a3b04e3..bcb4f6737f 100644 --- a/indra/newview/llpanelmaininventory.h +++ b/indra/newview/llpanelmaininventory.h @@ -37,6 +37,7 @@ class LLComboBox; class LLFolderViewItem; class LLInventoryPanel; +class LLInventoryFavoriteItemsPanel; class LLSaveFolderState; class LLFilterEditor; class LLTabContainer; @@ -136,6 +137,7 @@ private: LLHandle<LLFloater> mFinderHandle; LLInventoryPanel* mActivePanel; LLInventoryPanel* mWornItemsPanel; + LLInventoryFavoriteItemsPanel* mFavoriteItemsPanel; bool mResortActivePanel; LLSaveFolderState* mSavedFolderState; std::string mFilterText; diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp index 8019335f97..8fff52ca4e 100644 --- a/indra/newview/llpaneloutfitsinventory.cpp +++ b/indra/newview/llpaneloutfitsinventory.cpp @@ -55,6 +55,7 @@ LLPanelOutfitsInventory::LLPanelOutfitsInventory() : mMyOutfitsPanel(NULL), mCurrentOutfitPanel(NULL), mActivePanel(NULL), + mAppearanceTabs(NULL), mInitialized(false) { gAgentWearables.addLoadedCallback(boost::bind(&LLPanelOutfitsInventory::onWearablesLoaded, this)); @@ -312,6 +313,7 @@ void LLPanelOutfitsInventory::initTabPanels() void LLPanelOutfitsInventory::onTabChange() { + if (!mAppearanceTabs) return; mActivePanel = dynamic_cast<LLPanelAppearanceTab*>(mAppearanceTabs->getCurrentPanel()); if (!mActivePanel) return; diff --git a/indra/newview/llpresetsmanager.h b/indra/newview/llpresetsmanager.h index 0014e32267..488a61290b 100644 --- a/indra/newview/llpresetsmanager.h +++ b/indra/newview/llpresetsmanager.h @@ -33,6 +33,7 @@ #include <map> static const std::string PRESETS_DEFAULT = "Default"; +static const std::string PRESETS_DEFAULT_UPPER = "DEFAULT"; static const std::string PRESETS_DIR = "presets"; static const std::string PRESETS_GRAPHIC = "graphic"; static const std::string PRESETS_CAMERA = "camera"; diff --git a/indra/newview/llprogressview.cpp b/indra/newview/llprogressview.cpp index 083a913ef8..b34bf515d6 100644 --- a/indra/newview/llprogressview.cpp +++ b/indra/newview/llprogressview.cpp @@ -325,6 +325,7 @@ void LLProgressView::onCancelButtonClicked(void*) // cancel is pressed while teleporting inside region (EXT-4911) if (LLStartUp::getStartupState() < STATE_STARTED) { + LL_INFOS() << "User requesting quit during login" << LL_ENDL; LLAppViewer::instance()->requestQuit(); } else diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index f8745fe85d..38c201d340 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -1117,6 +1117,8 @@ bool idle_startup() // Its either downloading or declined. // If optional was skipped this case shouldn't // be reached. + + LL_INFOS() << "Forcing a quit due to update." << LL_ENDL; LLLoginInstance::getInstance()->disconnect(); LLAppViewer::instance()->forceQuit(); } diff --git a/indra/newview/lltoolgrab.cpp b/indra/newview/lltoolgrab.cpp index a4806ceaf6..f01b374db1 100644 --- a/indra/newview/lltoolgrab.cpp +++ b/indra/newview/lltoolgrab.cpp @@ -142,8 +142,9 @@ BOOL LLToolGrabBase::handleMouseDown(S32 x, S32 y, MASK mask) // call the base class to propogate info to sim LLTool::handleMouseDown(x, y, mask); - - if (!gAgent.leftButtonGrabbed()) + + // leftButtonGrabbed() checks if controls are reserved by scripts, but does not take masks into account + if (!gAgent.leftButtonGrabbed() || ((mask & DEFAULT_GRAB_MASK) != 0 && !gAgentCamera.cameraMouselook())) { // can grab transparent objects (how touch event propagates, scripters rely on this) gViewerWindow->pickAsync(x, y, mask, pickCallback, /*BOOL pick_transparent*/ TRUE); diff --git a/indra/newview/lltoolgrab.h b/indra/newview/lltoolgrab.h index 02ed5c26d7..ce0de0f946 100644 --- a/indra/newview/lltoolgrab.h +++ b/indra/newview/lltoolgrab.h @@ -44,6 +44,7 @@ class LLPickInfo; void send_ObjectGrab_message(LLViewerObject* object, const LLPickInfo & pick, const LLVector3 &grab_offset); void send_ObjectDeGrab_message(LLViewerObject* object, const LLPickInfo & pick); +const MASK DEFAULT_GRAB_MASK = MASK_CONTROL; /** * LLToolGrabBase contains most of the semantics of LLToolGrab. It's just that diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index dd429d4ccf..2476b3f285 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -1390,7 +1390,7 @@ LLTool* LLToolPie::getOverrideTool(MASK mask) { if (gSavedSettings.getBOOL("EnableGrab")) { - if (mask == MASK_CONTROL) + if (mask == DEFAULT_GRAB_MASK) { return LLToolGrab::getInstance(); } diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 9e9c26a20d..f5e0e3eff1 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1378,6 +1378,7 @@ BOOL LLViewerWindow::handleCloseRequest(LLWindow *window) void LLViewerWindow::handleQuit(LLWindow *window) { + LL_INFOS() << "Window forced quit" << LL_ENDL; LLAppViewer::instance()->forceQuit(); } diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 0a1efd564f..0aeccc7399 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -4567,8 +4567,9 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& { U8 mode = mat->getDiffuseAlphaMode(); - if (mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE || - mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE) + if (mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE + || mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE + || (mode == LLMaterial::DIFFUSE_ALPHA_MODE_MASK && mat->getAlphaMaskCutoff() == 0)) { ignore_alpha = true; } diff --git a/indra/newview/skins/default/xui/de/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/de/panel_preferences_graphics1.xml index e0aa9fe4a9..16fdb69509 100644 --- a/indra/newview/skins/default/xui/de/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/de/panel_preferences_graphics1.xml @@ -32,10 +32,10 @@ </text> <check_box initial_value="true" label="Freunde immer darstellen" name="AlwaysRenderFriends"/> <button label="Ausnahmen..." name="RenderExceptionsButton"/> - <button label="Einstellungen als Voreinstellung speichern..." name="PrefSaveButton"/> - <button label="Voreinstellung laden..." name="PrefLoadButton"/> + <button label="Einstellungen als Voreinstellung speichern" name="PrefSaveButton" width="235" left="5"/> + <button label="Voreinstellung laden" name="PrefLoadButton" width="120"/> min_val="0.125" - <button label="Voreinstellung löschen..." name="PrefDeleteButton"/> - <button label="Auf empfohlene Einstellungen zurücksetzen" name="Defaults"/> + <button label="Voreinstellung löschen" name="PrefDeleteButton" width="130"/> + <button label="Auf empfohlene Einstellungen zurücksetzen" name="Defaults" width="248"/> <button label="Erweiterte Einstellungen..." name="AdvancedSettings"/> </panel> diff --git a/indra/newview/skins/default/xui/de/panel_preferences_setup.xml b/indra/newview/skins/default/xui/de/panel_preferences_setup.xml index 1435b7f87d..a8509cabac 100644 --- a/indra/newview/skins/default/xui/de/panel_preferences_setup.xml +++ b/indra/newview/skins/default/xui/de/panel_preferences_setup.xml @@ -35,5 +35,5 @@ <text name="Proxy Settings:"> Proxy-Einstellungen: </text> - <button label="Proxy-Einstellungen ändern" label_selected="Durchsuchen" name="set_proxy"/> + <button label="Proxy-Einstellungen ändern" label_selected="Durchsuchen" name="set_proxy" width="160"/> </panel> diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml index a143adfa06..4a9aebbf09 100644 --- a/indra/newview/skins/default/xui/en/floater_about_land.xml +++ b/indra/newview/skins/default/xui/en/floater_about_land.xml @@ -123,8 +123,8 @@ No parcel selected. </panel.string> <panel.string name="time_stamp_template"> - [wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local] - </panel.string> + [wkday,datetime,slt] [mth,datetime,slt] [day,datetime,slt] [hour,datetime,slt]:[min,datetime,slt]:[second,datetime,slt] [year,datetime,slt] + </panel.string> <text type="string" length="1" diff --git a/indra/newview/skins/default/xui/en/floater_inspect.xml b/indra/newview/skins/default/xui/en/floater_inspect.xml index 63334e2b24..802a6649c8 100644 --- a/indra/newview/skins/default/xui/en/floater_inspect.xml +++ b/indra/newview/skins/default/xui/en/floater_inspect.xml @@ -13,7 +13,7 @@ width="400"> <floater.string name="timeStamp"> - [wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local] + [wkday,datetime,slt] [mth,datetime,slt] [day,datetime,slt] [hour,datetime,slt]:[min,datetime,slt]:[second,datetime,slt] [year,datetime,slt] </floater.string> <scroll_list bottom="268" diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml index 3bdbbb04d7..52fcdc5b58 100644 --- a/indra/newview/skins/default/xui/en/menu_inventory.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory.xml @@ -358,6 +358,13 @@ parameter="model" /> </menu_item_call> </menu> + <menu_item_call + label="Use as Favorites folder" + layout="topleft" + name="Set Favorites folder"> + <menu_item_call.on_click + function="Inventory.SetFavoritesFolder"/> + </menu_item_call> <menu label="Change Type" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 04b5d808ec..bb40aa0b42 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -56,7 +56,8 @@ </menu_item_call> <menu_item_call label="Places..." - name="Places"> + name="Places" + shortcut="control|L"> <menu_item_call.on_click function="Floater.ToggleOrBringToFront" parameter="places" /> @@ -85,11 +86,22 @@ <menu_item_separator/> <menu_item_call label="Camera Controls..." - name="Camera Controls"> + name="Camera Controls" + shortcut="control|K"> <menu_item_call.on_click function="Floater.ToggleOrBringToFront" parameter="camera" /> </menu_item_call> + <menu_item_call + label="Hover Height" + name="HoverHeight" + shortcut="alt|control|H" + visible="false"> + <menu_item_call.on_click + function="HoverHeight"/> + <menu_item_call.on_enable + function="Edit.EnableHoverHeight"/> + </menu_item_call> <menu create_jump_keys="true" label="Movement" @@ -150,7 +162,8 @@ </menu_item_check> <menu_item_call label="Stop Animating Me" - name="Stop Animating My Avatar"> + name="Stop Animating My Avatar" + shortcut="alt|shift|A"> <menu_item_call.on_click function="Tools.StopAllAnimations" /> </menu_item_call> @@ -458,7 +471,8 @@ </menu_item_check> <menu_item_call label="Events" - name="Events"> + name="Events" + shortcut="control|E"> <menu_item_call.on_click function="Advanced.ShowURL" parameter="http://events.secondlife.com"/> @@ -647,7 +661,8 @@ tear_off="true"> <menu_item_check label="Sunrise" - name="Sunrise"> + name="Sunrise" + shortcut="control|shift|O"> <menu_item_check.on_click function="World.EnvSettings" parameter="sunrise" /> @@ -679,7 +694,8 @@ </menu_item_check> <menu_item_check label="Midnight" - name="Midnight"> + name="Midnight" + shortcut="control|shift|Z"> <menu_item_check.on_click function="World.EnvSettings" parameter="midnight" /> @@ -1327,7 +1343,8 @@ <menu_item_call label="Model..." layout="topleft" - name="Upload Model"> + name="Upload Model" + shortcut="alt|control|U"> <menu_item_call.on_click function="File.UploadModel" parameter="" /> diff --git a/indra/newview/skins/default/xui/en/panel_landmark_info.xml b/indra/newview/skins/default/xui/en/panel_landmark_info.xml index 13986c4030..87035e5cd3 100644 --- a/indra/newview/skins/default/xui/en/panel_landmark_info.xml +++ b/indra/newview/skins/default/xui/en/panel_landmark_info.xml @@ -41,7 +41,7 @@ </string> <string name="acquired_date"> - [wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local] + [wkday,datetime,slt] [mth,datetime,slt] [day,datetime,slt] [hour,datetime,slt]:[min,datetime,slt]:[second,datetime,slt] [year,datetime,slt] </string> <!-- Texture names for rating icons --> <string diff --git a/indra/newview/skins/default/xui/en/panel_main_inventory.xml b/indra/newview/skins/default/xui/en/panel_main_inventory.xml index d77fbdec0a..2745b9d302 100644 --- a/indra/newview/skins/default/xui/en/panel_main_inventory.xml +++ b/indra/newview/skins/default/xui/en/panel_main_inventory.xml @@ -117,20 +117,32 @@ name="Recent Items" show_item_link_overlays="true" width="290" /> - <inventory_panel - name="Worn Items" - label="WORN" - show_empty_message="false" - follows="all" - layout="topleft" - width="290" - bg_opaque_color="DkGray2" - bg_alpha_color="DkGray2" - background_visible="true" - border="false" - bevel_style="none" - scroll.reserve_scroll_corner="false"> - </inventory_panel> + <inventory_panel + name="Worn Items" + label="WORN" + show_empty_message="false" + follows="all" + layout="topleft" + width="290" + bg_opaque_color="DkGray2" + bg_alpha_color="DkGray2" + background_visible="true" + border="false" + bevel_style="none" + scroll.reserve_scroll_corner="false"/> + <favorites_inventory_panel + name="Favorite Items" + label="FAVORITES" + show_empty_message="false" + follows="all" + layout="topleft" + width="290" + bg_opaque_color="DkGray2" + bg_alpha_color="DkGray2" + background_visible="true" + border="false" + bevel_style="none" + scroll.reserve_scroll_corner="false"/> </tab_container> <layout_stack animate="false" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml index 74c9b10cff..2ea20570b1 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml @@ -475,12 +475,12 @@ follows="left|top" height="23" is_toggle="true" - label="Input/Output devices" + label="Voice Input/Output devices" layout="topleft" left="20" top_pad="6" name="device_settings_btn" - width="190"> + width="230"> </button> <panel layout="topleft" diff --git a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml index acb6f5b42a..9a68479d05 100644 --- a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml @@ -33,7 +33,7 @@ </panel.string> <panel.string name="acquiredDate"> - [wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local] + [wkday,datetime,slt] [mth,datetime,slt] [day,datetime,slt] [hour,datetime,slt]:[min,datetime,slt]:[second,datetime,slt] [year,datetime,slt] </panel.string> <panel.string name="origin_inventory"> diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index e1554d2a20..5661e7fe96 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -2277,6 +2277,7 @@ For AI Character: Get the closest navigable point to the point provided. <!-- inventory --> <string name="InventoryNoMatchingItems">Didn't find what you're looking for? Try [secondlife:///app/search/all/[SEARCH_TERM] Search].</string> <string name="InventoryNoMatchingRecentItems">Didn't find what you're looking for? Try [secondlife:///app/inventory/filters Show filters].</string> + <string name="InventoryFavoritItemsNotSelected">Click "Use as Favorites folder" on a folder of your choice. You can choose a different folder at any time. System folders cannot be used for Favorites.</string> <string name="PlacesNoMatchingItems">Didn't find what you're looking for? Try [secondlife:///app/search/places/[SEARCH_TERM] Search].</string> <string name="FavoritesNoMatchingItems">Drag a landmark here to add it to your favorites.</string> <string name="MarketplaceNoMatchingItems">No items found. Check the spelling of your search string and try again.</string> diff --git a/indra/newview/skins/default/xui/es/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/es/panel_preferences_advanced.xml index 007101b8fe..0ba676898f 100644 --- a/indra/newview/skins/default/xui/es/panel_preferences_advanced.xml +++ b/indra/newview/skins/default/xui/es/panel_preferences_advanced.xml @@ -28,5 +28,5 @@ <check_box label="Mostrar la selección de cuadrícula al iniciar sesión" name="show_grid_selection_check"/> <check_box label="Mostrar el menú Avanzado" name="show_advanced_menu_check"/> <check_box label="Mostrar el menú Desarrollar" name="show_develop_menu_check"/> - <button label="Permisos de creación predeterminados" name="default_creation_permissions"/> + <button label="Permisos de creación predeterminados" name="default_creation_permissions" width="235"/> </panel> diff --git a/indra/newview/skins/default/xui/es/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/es/panel_preferences_graphics1.xml index 816c698548..47815d0296 100644 --- a/indra/newview/skins/default/xui/es/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/es/panel_preferences_graphics1.xml @@ -32,10 +32,10 @@ </text> <check_box initial_value="true" label="Renderizar siempre los amigos" name="AlwaysRenderFriends"/> <button label="Excepciones..." name="RenderExceptionsButton"/> - <button label="Guardar configuración como valor predefinido..." name="PrefSaveButton"/> - <button label="Cargar predefinido..." name="PrefLoadButton"/> + <button label="Guardar configuración como valor predefinido" name="PrefSaveButton" width="260" left="5"/> + <button label="Cargar predefinido" name="PrefLoadButton" left_pad="7"/> min_val="0.125" - <button label="Eliminar predefinido..." name="PrefDeleteButton"/> - <button label="Restablecer la configuración recomendada" name="Defaults"/> + <button label="Eliminar predefinido" name="PrefDeleteButton" width="117" left_pad="7"/> + <button label="Restablecer la configuración recomendada" name="Defaults" width="248"/> <button label="Configuración avanzada..." name="AdvancedSettings"/> </panel> diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml index 7117ace7e1..46d6305290 100644 --- a/indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml @@ -32,10 +32,10 @@ </text> <check_box initial_value="true" label="Toujours effectuer le rendu des amis" name="AlwaysRenderFriends"/> <button label="Exceptions..." name="RenderExceptionsButton"/> - <button label="Enregistrer les paramètres comme préréglage..." name="PrefSaveButton"/> - <button label="Charger un préréglage..." name="PrefLoadButton"/> + <button label="Enregistrer les paramètres comme préréglage" name="PrefSaveButton" width="260" /> + <button label="Charger un préréglage" name="PrefLoadButton" width="132"/> min_val="0,125" - <button label="Supprimer un préréglage..." name="PrefDeleteButton"/> - <button label="Réinitialiser les paramètres recommandés" name="Defaults"/> + <button label="Supprimer un préréglage" name="PrefDeleteButton" width="148" top_delta="30" left_pad="-220"/> + <button label="Réinitialiser les paramètres recommandés" name="Defaults" width="255" top_delta="35"/> <button label="Paramètres avancés" name="AdvancedSettings"/> </panel> diff --git a/indra/newview/skins/default/xui/it/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/it/panel_preferences_graphics1.xml index f3ca9fafb3..c7739b8472 100644 --- a/indra/newview/skins/default/xui/it/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/it/panel_preferences_graphics1.xml @@ -32,10 +32,10 @@ </text> <check_box initial_value="true" label="Esegui sempre il rendering degli amici" name="AlwaysRenderFriends"/> <button label="Eccezioni..." name="RenderExceptionsButton"/> - <button label="Salva impostazioni come valori predefiniti..." name="PrefSaveButton"/> - <button label="Carica valore predefinito..." name="PrefLoadButton"/> + <button label="Salva impostazioni come valori predefiniti" name="PrefSaveButton" width="240" left="4"/> + <button label="Carica valore predefinito" name="PrefLoadButton" width="145" left_pad="7"/> min_val="0.125" - <button label="Elimina valore predefinito..." name="PrefDeleteButton"/> + <button label="Elimina valore predefinito" name="PrefDeleteButton" width="148" left_pad="7"/> <button label="Ripristina impostazioni consigliate" name="Defaults"/> <button label="Impostazioni avanzate..." name="AdvancedSettings"/> </panel> diff --git a/indra/newview/skins/default/xui/it/panel_preferences_setup.xml b/indra/newview/skins/default/xui/it/panel_preferences_setup.xml index aa3ff53f4a..c9d90539e1 100644 --- a/indra/newview/skins/default/xui/it/panel_preferences_setup.xml +++ b/indra/newview/skins/default/xui/it/panel_preferences_setup.xml @@ -35,5 +35,5 @@ <text name="Proxy Settings:"> Impostazioni proxy: </text> - <button label="Regola impostazioni proxy" label_selected="Sfoglia" name="set_proxy"/> + <button label="Regola impostazioni proxy" label_selected="Sfoglia" name="set_proxy" width="160"/> </panel> diff --git a/indra/newview/skins/default/xui/pt/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/pt/floater_texture_ctrl.xml index ba4ef0afde..5ec005bd1a 100644 --- a/indra/newview/skins/default/xui/pt/floater_texture_ctrl.xml +++ b/indra/newview/skins/default/xui/pt/floater_texture_ctrl.xml @@ -13,8 +13,11 @@ <radio_item label="Inventário" name="inventory" value="0"/> <radio_item label="Local" name="local" value="1"/> </radio_group> + <text name="size_lbl"> + Tamanho: + </text> <text name="unknown"> - Tamanho: [DIMENSÕES] + [DIMENSIONS] </text> <button label="Padrão" label_selected="Padrão" name="Default"/> <button label="Branco" label_selected="Branco" name="Blank"/> diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml index a0f4ea4ed5..d387c4c869 100644 --- a/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml @@ -33,10 +33,10 @@ rápido </text> <check_box initial_value="true" label="Sempre renderizar amigos" name="AlwaysRenderFriends"/> <button label="Exceções..." name="RenderExceptionsButton"/> - <button label="Salvar configurações como predefinição..." name="PrefSaveButton"/> - <button label="Carregar predefinição..." name="PrefLoadButton"/> + <button label="Salvar configurações como predefinição" name="PrefSaveButton" width="235" left="5"/> + <button label="Carregar predefinição" name="PrefLoadButton" width="130" left_pad="8"/> min_val="0.125" - <button label="Excluir predefinição..." name="PrefDeleteButton"/> - <button label="Redefinir para configurações recomendadas" left="110" name="Defaults"/> + <button label="Excluir predefinição" name="PrefDeleteButton" width="122" left_pad="8"/> + <button label="Redefinir para configurações recomendadas" name="Defaults" width="255"/> <button label="Configurações avançadas..." name="AdvancedSettings"/> </panel> diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_setup.xml b/indra/newview/skins/default/xui/pt/panel_preferences_setup.xml index 03536f28c3..56fc225bc0 100644 --- a/indra/newview/skins/default/xui/pt/panel_preferences_setup.xml +++ b/indra/newview/skins/default/xui/pt/panel_preferences_setup.xml @@ -35,5 +35,5 @@ <text name="Proxy Settings:"> Configurações de proxy: </text> - <button label="Ajustar configurações de proxy" label_selected="Procurar" name="set_proxy"/> + <button label="Ajustar configurações de proxy" label_selected="Procurar" name="set_proxy" width="180"/> </panel> diff --git a/indra/newview/skins/default/xui/ru/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/ru/panel_preferences_advanced.xml index dd0cf8e172..79d5cb7960 100644 --- a/indra/newview/skins/default/xui/ru/panel_preferences_advanced.xml +++ b/indra/newview/skins/default/xui/ru/panel_preferences_advanced.xml @@ -28,5 +28,5 @@ <check_box label="Выбор сетки при входе" name="show_grid_selection_check"/> <check_box label="Показывать расширенное меню" name="show_advanced_menu_check"/> <check_box label="Показать меню разработчика" name="show_develop_menu_check"/> - <button label="Стандартные разрешения на создание" name="default_creation_permissions"/> + <button label="Стандартные разрешения на создание" name="default_creation_permissions" width="235"/> </panel> diff --git a/indra/newview/skins/default/xui/ru/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/ru/panel_preferences_graphics1.xml index 4524fb4d43..f392a1f0b7 100644 --- a/indra/newview/skins/default/xui/ru/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/ru/panel_preferences_graphics1.xml @@ -32,7 +32,7 @@ </text> <check_box initial_value="true" label="Всегда рисовать друзей" name="AlwaysRenderFriends"/> <button label="Исключения..." name="RenderExceptionsButton"/> - <button label="Сохранить настройки как пресет..." name="PrefSaveButton"/> + <button label="Сохранить настройки как пресет..." name="PrefSaveButton" width="210"/> <button label="Загрузить пресет..." name="PrefLoadButton"/> min_val="0,125" <button label="Удалить пресет..." name="PrefDeleteButton"/> |