diff options
Diffstat (limited to 'indra/newview')
33 files changed, 457 insertions, 78 deletions
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 2610fcd248..8abb0f7106 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -11084,5 +11084,16 @@ <integer>2048</integer> </map> <!-- End of back compatibility settings --> + <key>teleport_offer_invitation_max_length</key> + <map> + <key>Comment</key> + <string>Maximum length of teleport offer invitation line editor. 254 - max_location_url_length(76) = 178</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>178</integer> + </map> </map> </llsd> diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 8bcf680876..ddcaeb113d 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -1226,7 +1226,10 @@ void LLAgent::startAutoPilotGlobal(const LLVector3d &target_global, const std::s if ( distance > 1.f && heightDelta > (sqrtf(mAutoPilotStopDistance) + 1.f)) { setFlying(TRUE); - mAutoPilotFlyOnStop = TRUE; + // Do not force flying for "Sit" behavior to prevent flying after pressing "Stand" + // from an object. See EXT-1655. + if ("Sit" != mAutoPilotBehaviorName) + mAutoPilotFlyOnStop = TRUE; } mAutoPilot = TRUE; diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index 466f2d499d..8a880e5ace 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -2031,6 +2031,39 @@ void LLAgentWearables::animateAllWearableParams(F32 delta, BOOL upload_bake) } } +bool LLAgentWearables::moveWearable(const LLViewerInventoryItem* item, bool closer_to_body) +{ + if (!item) return false; + if (!item->isWearableType()) return false; + + wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(item->getWearableType()); + if (wearable_iter == mWearableDatas.end()) return false; + + wearableentry_vec_t& wearable_vec = wearable_iter->second; + if (wearable_vec.empty()) return false; + + const LLUUID& asset_id = item->getAssetUUID(); + + //nowhere to move if the wearable is already on any boundary (closest to the body/furthest from the body) + if (closer_to_body && asset_id == wearable_vec.front()->getAssetID()) return false; + if (!closer_to_body && asset_id == wearable_vec.back()->getAssetID()) return false; + + for (U32 i = 0; i < wearable_vec.size(); ++i) + { + LLWearable* wearable = wearable_vec[i]; + if (!wearable) continue; + if (wearable->getAssetID() != asset_id) continue; + + //swapping wearables + U32 swap_i = closer_to_body ? i-1 : i+1; + wearable_vec[i] = wearable_vec[swap_i]; + wearable_vec[swap_i] = wearable; + return true; + } + + return false; +} + void LLAgentWearables::updateServer() { sendAgentWearablesUpdate(); diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h index 585fd3f8b3..d3b18f68f1 100644 --- a/indra/newview/llagentwearables.h +++ b/indra/newview/llagentwearables.h @@ -82,6 +82,8 @@ public: void animateAllWearableParams(F32 delta, BOOL upload_bake); + bool moveWearable(const LLViewerInventoryItem* item, bool closer_to_body); + //-------------------------------------------------------------------- // Accessors //-------------------------------------------------------------------- diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 9e02886e4f..6aefecc787 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -122,6 +122,38 @@ private: bool mAppend; }; + +//Inventory callback updating "dirty" state when destroyed +class LLUpdateDirtyState: public LLInventoryCallback +{ +public: + LLUpdateDirtyState() {} + virtual ~LLUpdateDirtyState(){ LLAppearanceMgr::getInstance()->updateIsDirty(); } + virtual void fire(const LLUUID&) {} +}; + + +//Inventory collect functor collecting wearables of a specific wearable type +class LLFindClothesOfType : public LLInventoryCollectFunctor +{ +public: + LLFindClothesOfType(EWearableType type) : mWearableType(type) {} + virtual ~LLFindClothesOfType() {} + virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item) + { + if (!item) return false; + if (item->getType() != LLAssetType::AT_CLOTHING) return false; + + LLViewerInventoryItem *vitem = dynamic_cast<LLViewerInventoryItem*>(item); + if (!vitem || vitem->getWearableType() != mWearableType) return false; + + return true; + } + + const EWearableType mWearableType; +}; + + LLUpdateAppearanceOnDestroy::LLUpdateAppearanceOnDestroy(): mFireCount(0) { @@ -1593,8 +1625,11 @@ bool LLAppearanceMgr::updateBaseOutfit() // in a Base Outfit we do not remove items, only links purgeCategory(base_outfit_id, false); + + LLPointer<LLInventoryCallback> dirty_state_updater = new LLUpdateDirtyState(); + //COF contains only links so we copy to the Base Outfit only links - shallowCopyCategoryContents(getCOF(), base_outfit_id, NULL); + shallowCopyCategoryContents(getCOF(), base_outfit_id, dirty_state_updater); return true; } @@ -1802,6 +1837,63 @@ void LLAppearanceMgr::removeItemFromAvatar(const LLUUID& id_to_remove) } } + +bool LLAppearanceMgr::moveWearable(LLViewerInventoryItem* item, bool closer_to_body) +{ + if (!item || !item->isWearableType()) return false; + if (item->getType() != LLAssetType::AT_CLOTHING) return false; + if (!gInventory.isObjectDescendentOf(item->getUUID(), getCOF())) return false; + + LLInventoryModel::cat_array_t cats; + LLInventoryModel::item_array_t items; + LLFindClothesOfType filter_wearables_of_type(item->getWearableType()); + gInventory.collectDescendentsIf(getCOF(), cats, items, true, filter_wearables_of_type); + if (items.empty()) return false; + + //*TODO all items are not guarantied to have valid descriptions (check?) + std::sort(items.begin(), items.end(), WearablesOrderComparator(item->getWearableType())); + + if (closer_to_body && items.front() == item) return false; + if (!closer_to_body && items.back() == item) return false; + + LLInventoryModel::item_array_t::iterator it = std::find(items.begin(), items.end(), item); + if (items.end() == it) return false; + + + //swapping descriptions + closer_to_body ? --it : ++it; + LLViewerInventoryItem* swap_item = *it; + if (!swap_item) return false; + std::string tmp = swap_item->LLInventoryItem::getDescription(); + swap_item->setDescription(item->LLInventoryItem::getDescription()); + item->setDescription(tmp); + + + //items need to be updated on a dataserver + item->setComplete(TRUE); + item->updateServer(FALSE); + gInventory.updateItem(item); + + swap_item->setComplete(TRUE); + swap_item->updateServer(FALSE); + gInventory.updateItem(swap_item); + + //to cause appearance of the agent to be updated + bool result = false; + if (result = gAgentWearables.moveWearable(item, closer_to_body)) + { + gAgentAvatarp->wearableUpdated(item->getWearableType(), TRUE); + } + + setOutfitDirty(true); + + //*TODO do we need to notify observers here in such a way? + gInventory.notifyObservers(); + + return result; +} + + //#define DUMP_CAT_VERBOSE void LLAppearanceMgr::dumpCat(const LLUUID& cat_id, const std::string& msg) diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index efb5274c5b..a308a3efa9 100644 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -141,6 +141,8 @@ public: LLUUID makeNewOutfitLinks(const std::string& new_folder_name); + bool moveWearable(LLViewerInventoryItem* item, bool closer_to_body); + protected: LLAppearanceMgr(); ~LLAppearanceMgr(); diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp index 80d9b14345..44ef39fb7d 100644 --- a/indra/newview/llappviewermacosx.cpp +++ b/indra/newview/llappviewermacosx.cpp @@ -291,6 +291,7 @@ static OSStatus CarbonEventHandler(EventHandlerCallRef inHandlerCallRef, if(os_result >= 0 && matching_psn) { sCrashReporterIsRunning = false; + QuitApplicationEventLoop(); } } return noErr; @@ -326,7 +327,7 @@ void LLAppViewerMacOSX::handleCrashReporting(bool reportFreeze) // *NOTE:Mani A better way - make a copy of the data that the crash reporter will send // and let SL go about its business. This way makes the mac work like windows and linux // and is the smallest patch for the issue. - sCrashReporterIsRunning = true; + sCrashReporterIsRunning = false; ProcessSerialNumber o_psn; static EventHandlerRef sCarbonEventsRef = NULL; @@ -356,15 +357,13 @@ void LLAppViewerMacOSX::handleCrashReporting(bool reportFreeze) if(os_result >= 0) { - EventRecord evt; - while(sCrashReporterIsRunning) - { - while(WaitNextEvent(osMask, &evt, 0, NULL)) - { - // null op!?! - } - } - } + sCrashReporterIsRunning = true; + } + + while(sCrashReporterIsRunning) + { + RunApplicationEventLoop(); + } // Re-install the apps quit handler. AEInstallEventHandler(kCoreEventClass, @@ -453,16 +452,17 @@ std::string LLAppViewerMacOSX::generateSerialNumber() static AudioDeviceID get_default_audio_output_device(void) { AudioDeviceID device = 0; - UInt32 size; - OSStatus err; - - size = sizeof(device); - err = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &size, &device); + UInt32 size = sizeof(device); + AudioObjectPropertyAddress device_address = { kAudioHardwarePropertyDefaultOutputDevice, + kAudioObjectPropertyScopeGlobal, + kAudioObjectPropertyElementMaster }; + + OSStatus err = AudioObjectGetPropertyData(kAudioObjectSystemObject, &device_address, 0, NULL, &size, &device); if(err != noErr) { LL_DEBUGS("SystemMute") << "Couldn't get default audio output device (0x" << std::hex << err << ")" << LL_ENDL; } - + return device; } @@ -470,11 +470,15 @@ static AudioDeviceID get_default_audio_output_device(void) void LLAppViewerMacOSX::setMasterSystemAudioMute(bool new_mute) { AudioDeviceID device = get_default_audio_output_device(); - + if(device != 0) { UInt32 mute = new_mute; - OSStatus err = AudioDeviceSetProperty(device, NULL, 0, false, kAudioDevicePropertyMute, sizeof(mute), &mute); + AudioObjectPropertyAddress device_address = { kAudioDevicePropertyMute, + kAudioDevicePropertyScopeOutput, + kAudioObjectPropertyElementMaster }; + + OSStatus err = AudioObjectSetPropertyData(device, &device_address, 0, NULL, sizeof(mute), &mute); if(err != noErr) { LL_INFOS("SystemMute") << "Couldn't set audio mute property (0x" << std::hex << err << ")" << LL_ENDL; @@ -487,13 +491,17 @@ bool LLAppViewerMacOSX::getMasterSystemAudioMute() { // Assume the system isn't muted UInt32 mute = 0; - + AudioDeviceID device = get_default_audio_output_device(); - + if(device != 0) { UInt32 size = sizeof(mute); - OSStatus err = AudioDeviceGetProperty(device, 0, false, kAudioDevicePropertyMute, &size, &mute); + AudioObjectPropertyAddress device_address = { kAudioDevicePropertyMute, + kAudioDevicePropertyScopeOutput, + kAudioObjectPropertyElementMaster }; + + OSStatus err = AudioObjectGetPropertyData(device, &device_address, 0, NULL, &size, &mute); if(err != noErr) { LL_DEBUGS("SystemMute") << "Couldn't get audio mute property (0x" << std::hex << err << ")" << LL_ENDL; diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 909878207c..f03026715d 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -1767,6 +1767,8 @@ void LLOutgoingCallDialog::show(const LLSD& key) getChild<LLTextBox>("leaving")->setVisible(true); } break; + // STATE_READY is here to show appropriate text for ad-hoc and group calls when floater is shown(EXT-6893) + case LLVoiceChannel::STATE_READY : case LLVoiceChannel::STATE_RINGING : if(show_oldchannel) { diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp index e11df06d86..0341f2c693 100644 --- a/indra/newview/llnavigationbar.cpp +++ b/indra/newview/llnavigationbar.cpp @@ -375,7 +375,6 @@ void LLNavigationBar::draw() if(mPurgeTPHistoryItems) { LLTeleportHistory::getInstance()->purgeItems(); - onTeleportHistoryChanged(); mPurgeTPHistoryItems = false; } diff --git a/indra/newview/llnetmap.h b/indra/newview/llnetmap.h index 3d7f3233ac..eb53d295b2 100644 --- a/indra/newview/llnetmap.h +++ b/indra/newview/llnetmap.h @@ -46,10 +46,6 @@ class LLImageRaw; class LLTextBox; class LLViewerTexture; -const F32 MAP_SCALE_MIN = 64.f; -const F32 MAP_SCALE_MID = 172.f; -const F32 MAP_SCALE_MAX = 512.f; - class LLNetMap : public LLUICtrl { public: diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index ad42d80467..cce4f94028 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -168,26 +168,21 @@ void LLOutfitsList::refreshList(const LLUUID& category_id) std::string name = cat->getName(); - // *TODO: create accordion tabs and lists from XML. - LLAccordionCtrlTab::Params params; - params.name(name); - params.title(name); - params.rect(LLRect(0, 0, 315, 20)); - params.display_children(false); - LLAccordionCtrlTab* tab = LLUICtrlFactory::create<LLAccordionCtrlTab>(params); + static LLXMLNodePtr accordionXmlNode = getAccordionTabXMLNode(); - mAccordion->addCollapsibleCtrl(tab); - - LLFlatListView::Params list_params; - LLWearableItemsList* list = LLUICtrlFactory::create<LLWearableItemsList>(list_params); + accordionXmlNode->setAttributeString("name", name); + accordionXmlNode->setAttributeString("title", name); + LLAccordionCtrlTab* tab = LLUICtrlFactory::defaultBuilder<LLAccordionCtrlTab>(accordionXmlNode, NULL, NULL); - tab->addChild(list, 0); - tab->setDisplayChildren(false); + // *TODO: LLUICtrlFactory::defaultBuilder does not use "display_children" from xml. Should be investigated. + tab->setDisplayChildren(false); + mAccordion->addCollapsibleCtrl(tab); // Map the new tab with outfit category UUID. mOutfitsMap.insert(LLOutfitsList::outfits_map_value_t(cat_id, tab)); // Start observing the new outfit category. + LLWearableItemsList* list = tab->getChild<LLWearableItemsList>("wearable_items_list"); mCategoriesObserver->addCategory(cat_id, boost::bind(&LLWearableItemsList::updateList, list, cat_id)); // Fetch the new outfit contents. @@ -262,4 +257,21 @@ void LLOutfitsList::setFilterSubString(const std::string& string) mFilterSubString = string; } + +////////////////////////////////////////////////////////////////////////// +// Private methods +////////////////////////////////////////////////////////////////////////// +LLXMLNodePtr LLOutfitsList::getAccordionTabXMLNode() +{ + LLXMLNodePtr xmlNode = NULL; + bool success = LLUICtrlFactory::getLayeredXMLNode("outfit_accordion_tab.xml", xmlNode); + if (!success) + { + llwarns << "Failed to read xml of Outfit's Accordion Tab from outfit_accordion_tab.xml" << llendl; + return NULL; + } + + return xmlNode; +} + // EOF diff --git a/indra/newview/lloutfitslist.h b/indra/newview/lloutfitslist.h index 892e0a862a..f1756ce873 100644 --- a/indra/newview/lloutfitslist.h +++ b/indra/newview/lloutfitslist.h @@ -59,6 +59,14 @@ public: void setFilterSubString(const std::string& string); private: + /** + * Reads xml with accordion tab and Flat list from xml file. + * + * @return LLPointer to XMLNode with accordion tab and flat list. + */ + LLXMLNodePtr getAccordionTabXMLNode(); + + LLInventoryCategoriesObserver* mCategoriesObserver; LLAccordionCtrl* mAccordion; diff --git a/indra/newview/llpanelgroupnotices.cpp b/indra/newview/llpanelgroupnotices.cpp index e9cde59985..c0891ae749 100644 --- a/indra/newview/llpanelgroupnotices.cpp +++ b/indra/newview/llpanelgroupnotices.cpp @@ -657,6 +657,9 @@ void LLPanelGroupNotices::setGroupID(const LLUUID& id) if(mViewMessage) mViewMessage->clear(); + + if(mViewInventoryName) + mViewInventoryName->clear(); activate(); } diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp index e139cb31d6..ae181e2819 100644 --- a/indra/newview/llpaneloutfitedit.cpp +++ b/indra/newview/llpaneloutfitedit.cpp @@ -73,6 +73,9 @@ const U64 WEARABLE_MASK = (1LL << LLInventoryType::IT_WEARABLE); const U64 ATTACHMENT_MASK = (1LL << LLInventoryType::IT_ATTACHMENT) | (1LL << LLInventoryType::IT_OBJECT); const U64 ALL_ITEMS_MASK = WEARABLE_MASK | ATTACHMENT_MASK; +static const std::string SAVE_BTN("save_btn"); +static const std::string REVERT_BTN("revert_btn"); + class LLInventoryLookObserver : public LLInventoryObserver { public: @@ -221,10 +224,9 @@ BOOL LLPanelOutfitEdit::postBuild() mEditWearableBtn->setVisible(FALSE); mEditWearableBtn->setCommitCallback(boost::bind(&LLPanelOutfitEdit::onEditWearableClicked, this)); - childSetAction("revert_btn", boost::bind(&LLAppearanceMgr::wearBaseOutfit, LLAppearanceMgr::getInstance())); + childSetAction(REVERT_BTN, boost::bind(&LLAppearanceMgr::wearBaseOutfit, LLAppearanceMgr::getInstance())); - childSetAction("save_btn", boost::bind(&LLPanelOutfitEdit::saveOutfit, this, false)); - childSetAction("save_as_btn", boost::bind(&LLPanelOutfitEdit::saveOutfit, this, true)); + childSetAction(SAVE_BTN, boost::bind(&LLPanelOutfitEdit::saveOutfit, this, false)); childSetAction("save_flyout_btn", boost::bind(&LLPanelOutfitEdit::showSaveMenu, this)); LLUICtrl::CommitCallbackRegistry::ScopedRegistrar save_registar; @@ -234,10 +236,22 @@ BOOL LLPanelOutfitEdit::postBuild() mWearableListManager = new LLFilteredWearableListManager( getChild<LLInventoryItemsList>("filtered_wearables_list"), ALL_ITEMS_MASK); + + childSetAction("move_closer_btn", boost::bind(&LLPanelOutfitEdit::moveWearable, this, true)); + childSetAction("move_further_btn", boost::bind(&LLPanelOutfitEdit::moveWearable, this, false)); return TRUE; } +void LLPanelOutfitEdit::moveWearable(bool closer_to_body) +{ + LLViewerInventoryItem* wearable_to_move = gInventory.getItem(mLookContents->getSelectionInterface()->getCurrentID()); + LLAppearanceMgr::getInstance()->moveWearable(wearable_to_move, closer_to_body); + + //*TODO why not to listen to inventory? + updateLookInfo(); +} + void LLPanelOutfitEdit::showAddWearablesPanel() { childSetVisible("add_wearables_panel", childGetValue("add_btn")); @@ -267,6 +281,8 @@ void LLPanelOutfitEdit::saveOutfit(bool as_new) { panel_outfits_inventory->onSave(); } + + //*TODO how to get to know when base outfit is updated or new outfit is created? } void LLPanelOutfitEdit::showSaveMenu() @@ -542,10 +558,12 @@ void LLPanelOutfitEdit::lookFetched(void) columns[0]["value"] = item->getName(); columns[1]["column"] = "look_item_sort"; columns[1]["type"] = "text"; // TODO: multi-wearable sort "type" should go here. - columns[1]["value"] = "BAR"; // TODO: Multi-wearable sort index should go here + columns[1]["value"] = item->LLInventoryItem::getDescription(); mLookContents->addElement(row); } + + updateVerbs(); } void LLPanelOutfitEdit::updateLookInfo() @@ -589,4 +607,15 @@ void LLPanelOutfitEdit::displayCurrentOutfit() updateLookInfo(); } +//private +void LLPanelOutfitEdit::updateVerbs() +{ + bool outfit_is_dirty = LLAppearanceMgr::getInstance()->isOutfitDirty(); + + childSetEnabled(SAVE_BTN, outfit_is_dirty); + childSetEnabled(REVERT_BTN, outfit_is_dirty); + + mSaveMenu->setItemEnabled("save_outfit", outfit_is_dirty); +} + // EOF diff --git a/indra/newview/llpaneloutfitedit.h b/indra/newview/llpaneloutfitedit.h index 308ee23115..b6f121d484 100644 --- a/indra/newview/llpaneloutfitedit.h +++ b/indra/newview/llpaneloutfitedit.h @@ -87,6 +87,8 @@ public: // Sends a request for data about the given parcel, which will // only update the location if there is none already available. + void moveWearable(bool closer_to_body); + void showAddWearablesPanel(); void showWearablesFilter(); void showFilteredWearablesPanel(); @@ -110,6 +112,8 @@ public: private: + void updateVerbs(); + //*TODO got rid of mCurrentOutfitID LLUUID mCurrentOutfitID; diff --git a/indra/newview/llteleporthistory.cpp b/indra/newview/llteleporthistory.cpp index dcc85392f7..15684337f4 100644 --- a/indra/newview/llteleporthistory.cpp +++ b/indra/newview/llteleporthistory.cpp @@ -136,6 +136,7 @@ void LLTeleportHistory::updateCurrentLocation(const LLVector3d& new_pos) if (mCurrentItem < 0 || mCurrentItem >= (int) mItems.size()) // sanity check { llwarns << "Invalid current item. (this should not happen)" << llendl; + llassert(!"Invalid current teleport histiry item"); return; } LLVector3 new_pos_local = gAgent.getPosAgentFromGlobal(new_pos); @@ -166,6 +167,17 @@ void LLTeleportHistory::onHistoryChanged() void LLTeleportHistory::purgeItems() { + if (mItems.size() == 0) // no entries yet (we're called before login) + { + // If we don't return here the history will get into inconsistent state, hence: + // 1) updateCurrentLocation() will malfunction, + // so further teleports will not properly update the history; + // 2) mHistoryChangedSignal subscribers will be notified + // of such an invalid change. (EXT-6798) + // Both should not happen. + return; + } + if (mItems.size() > 0) { mItems.erase(mItems.begin(), mItems.end()-1); diff --git a/indra/newview/llteleporthistorystorage.cpp b/indra/newview/llteleporthistorystorage.cpp index c635f91423..430d62e15e 100644 --- a/indra/newview/llteleporthistorystorage.cpp +++ b/indra/newview/llteleporthistorystorage.cpp @@ -89,6 +89,13 @@ void LLTeleportHistoryStorage::onTeleportHistoryChange() if (!th) return; + // Hacky sanity check. (EXT-6798) + if (th->getItems().size() == 0) + { + llassert(!"Inconsistent teleport history state"); + return; + } + const LLTeleportHistoryItem &item = th->getItems()[th->getCurrentItemIndex()]; addItem(item.mTitle, item.mGlobalPos); diff --git a/indra/newview/lltoastalertpanel.cpp b/indra/newview/lltoastalertpanel.cpp index 986ccdf19b..2b529a4e50 100644 --- a/indra/newview/lltoastalertpanel.cpp +++ b/indra/newview/lltoastalertpanel.cpp @@ -50,6 +50,7 @@ #include "llnotifications.h" #include "llfunctorregistry.h" #include "llrootview.h" +#include "llviewercontrol.h" // for gSavedSettings const S32 MAX_ALLOWED_MSG_WIDTH = 400; const F32 DEFAULT_BUTTON_DELAY = 0.5f; @@ -279,7 +280,18 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal mLineEditor->reshape(leditor_rect.getWidth(), leditor_rect.getHeight()); mLineEditor->setRect(leditor_rect); mLineEditor->setText(edit_text_contents); - mLineEditor->setMaxTextLength(STD_STRING_STR_LEN - 1); + + // decrease limit of line editor of teleport offer dialog to avoid truncation of + // location URL in invitation message, see EXT-6891 + if ("OfferTeleport" == mNotification->getName()) + { + mLineEditor->setMaxTextLength(gSavedSettings.getS32( + "teleport_offer_invitation_max_length")); + } + else + { + mLineEditor->setMaxTextLength(STD_STRING_STR_LEN - 1); + } LLToastPanel::addChild(mLineEditor); diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index f434d15843..a23e42ea9e 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -67,6 +67,40 @@ #include "llviewermessage.h" ///---------------------------------------------------------------------------- +/// Helper class to store special inventory item names +///---------------------------------------------------------------------------- +class LLLocalizedInventoryItemsDictionary : public LLSingleton<LLLocalizedInventoryItemsDictionary> +{ +public: + std::map<std::string, std::string> mInventoryItemsDict; + + LLLocalizedInventoryItemsDictionary() + { + mInventoryItemsDict["New Shape"] = LLTrans::getString("New Shape"); + mInventoryItemsDict["New Skin"] = LLTrans::getString("New Skin"); + mInventoryItemsDict["New Hair"] = LLTrans::getString("New Hair"); + mInventoryItemsDict["New Eyes"] = LLTrans::getString("New Eyes"); + mInventoryItemsDict["New Shirt"] = LLTrans::getString("New Shirt"); + mInventoryItemsDict["New Pants"] = LLTrans::getString("New Pants"); + mInventoryItemsDict["New Shoes"] = LLTrans::getString("New Shoes"); + mInventoryItemsDict["New Socks"] = LLTrans::getString("New Socks"); + mInventoryItemsDict["New Jacket"] = LLTrans::getString("New Jacket"); + mInventoryItemsDict["New Gloves"] = LLTrans::getString("New Gloves"); + mInventoryItemsDict["New Undershirt"] = LLTrans::getString("New Undershirt"); + mInventoryItemsDict["New Undershirt"] = LLTrans::getString("New Undershirt"); + mInventoryItemsDict["New Skirt"] = LLTrans::getString("New Skirt"); + mInventoryItemsDict["New Alpha"] = LLTrans::getString("New Alpha"); + mInventoryItemsDict["New Tattoo"] = LLTrans::getString("New Tattoo"); + mInventoryItemsDict["Invalid Wearable"] = LLTrans::getString("Invalid Wearable"); + + mInventoryItemsDict["New Script"] = LLTrans::getString("New Script"); + mInventoryItemsDict["New Folder"] = LLTrans::getString("New Folder"); + mInventoryItemsDict["Contents"] = LLTrans::getString("Contents"); + } +}; + + +///---------------------------------------------------------------------------- /// Local function declarations, constants, enums, and typedefs ///---------------------------------------------------------------------------- @@ -316,6 +350,18 @@ BOOL LLViewerInventoryItem::unpackMessage(LLSD item) BOOL LLViewerInventoryItem::unpackMessage(LLMessageSystem* msg, const char* block, S32 block_num) { BOOL rv = LLInventoryItem::unpackMessage(msg, block, block_num); + + std::string localized_str; + + std::map<std::string, std::string>::const_iterator dictionary_iter; + + dictionary_iter = LLLocalizedInventoryItemsDictionary::getInstance()->mInventoryItemsDict.find(mName); + + if(dictionary_iter != LLLocalizedInventoryItemsDictionary::getInstance()->mInventoryItemsDict.end()) + { + mName = dictionary_iter->second; + } + mIsComplete = TRUE; return rv; } @@ -867,6 +913,25 @@ void create_inventory_item(const LLUUID& agent_id, const LLUUID& session_id, U32 next_owner_perm, LLPointer<LLInventoryCallback> cb) { + //check if name is equal to one of special inventory items names + //EXT-5839 + std::string server_name = name; + + { + std::map<std::string, std::string>::const_iterator dictionary_iter; + + for (dictionary_iter = LLLocalizedInventoryItemsDictionary::getInstance()->mInventoryItemsDict.begin(); + dictionary_iter != LLLocalizedInventoryItemsDictionary::getInstance()->mInventoryItemsDict.end(); + dictionary_iter++) + { + const std::string& localized_name = dictionary_iter->second; + if(localized_name == name) + { + server_name = dictionary_iter->first; + } + } + } + LLMessageSystem* msg = gMessageSystem; msg->newMessageFast(_PREHASH_CreateInventoryItem); msg->nextBlock(_PREHASH_AgentData); @@ -880,7 +945,7 @@ void create_inventory_item(const LLUUID& agent_id, const LLUUID& session_id, msg->addS8Fast(_PREHASH_Type, (S8)asset_type); msg->addS8Fast(_PREHASH_InvType, (S8)inv_type); msg->addU8Fast(_PREHASH_WearableType, (U8)wtype); - msg->addStringFast(_PREHASH_Name, name); + msg->addStringFast(_PREHASH_Name, server_name); msg->addStringFast(_PREHASH_Description, desc); gAgent.sendReliableMessage(); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 76d0b11535..579653319d 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -1933,7 +1933,7 @@ protected: } }; -static void parse_lure_bucket(const std::string& bucket, +static bool parse_lure_bucket(const std::string& bucket, U64& region_handle, LLVector3& pos, LLVector3& look_at, @@ -1945,15 +1945,25 @@ static void parse_lure_bucket(const std::string& bucket, tokenizer tokens(bucket, sep); tokenizer::iterator iter = tokens.begin(); - S32 gx = boost::lexical_cast<S32>((*(iter)).c_str()); - S32 gy = boost::lexical_cast<S32>((*(++iter)).c_str()); - S32 rx = boost::lexical_cast<S32>((*(++iter)).c_str()); - S32 ry = boost::lexical_cast<S32>((*(++iter)).c_str()); - S32 rz = boost::lexical_cast<S32>((*(++iter)).c_str()); - S32 lx = boost::lexical_cast<S32>((*(++iter)).c_str()); - S32 ly = boost::lexical_cast<S32>((*(++iter)).c_str()); - S32 lz = boost::lexical_cast<S32>((*(++iter)).c_str()); - + S32 gx,gy,rx,ry,rz,lx,ly,lz; + try + { + gx = boost::lexical_cast<S32>((*(iter)).c_str()); + gy = boost::lexical_cast<S32>((*(++iter)).c_str()); + rx = boost::lexical_cast<S32>((*(++iter)).c_str()); + ry = boost::lexical_cast<S32>((*(++iter)).c_str()); + rz = boost::lexical_cast<S32>((*(++iter)).c_str()); + lx = boost::lexical_cast<S32>((*(++iter)).c_str()); + ly = boost::lexical_cast<S32>((*(++iter)).c_str()); + lz = boost::lexical_cast<S32>((*(++iter)).c_str()); + } + catch( boost::bad_lexical_cast& ) + { + LL_WARNS("parse_lure_bucket") + << "Couldn't parse lure bucket." + << LL_ENDL; + return false; + } // Grab region access region_access = SIM_ACCESS_MIN; if (++iter != tokens.end()) @@ -1978,6 +1988,7 @@ static void parse_lure_bucket(const std::string& bucket, look_at.setVec((F32)lx, (F32)ly, (F32)lz); region_handle = to_region_handle(gx, gy); + return true; } void process_improved_im(LLMessageSystem *msg, void **user_data) @@ -2615,15 +2626,21 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) U64 region_handle; U8 region_access; std::string region_info = ll_safe_string((char*)binary_bucket, binary_bucket_size); - parse_lure_bucket(region_info, region_handle, pos, look_at, region_access); + std::string region_access_str = LLStringUtil::null; + std::string region_access_icn = LLStringUtil::null; - std::string region_access_str = LLViewerRegion::accessToString(region_access); + if (parse_lure_bucket(region_info, region_handle, pos, look_at, region_access)) + { + region_access_str = LLViewerRegion::accessToString(region_access); + region_access_icn = LLViewerRegion::getAccessIcon(region_access); + } LLSD args; // *TODO: Translate -> [FIRST] [LAST] (maybe) args["NAME_SLURL"] = LLSLURL::buildCommand("agent", from_id, "about"); args["MESSAGE"] = message; - args["MATURITY"] = region_access_str; + args["MATURITY_STR"] = region_access_str; + args["MATURITY_ICON"] = region_access_icn; LLSD payload; payload["from_id"] = from_id; payload["lure_id"] = session_id; diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 53ca32d1b0..4fdabd7ff0 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -627,6 +627,26 @@ std::string LLViewerRegion::accessToString(U8 sim_access) } // static +std::string LLViewerRegion::getAccessIcon(U8 sim_access) +{ + switch(sim_access) + { + case SIM_ACCESS_MATURE: + return "Parcel_M_Dark"; + + case SIM_ACCESS_ADULT: + return "Parcel_R_Light"; + + case SIM_ACCESS_PG: + return "Parcel_PG_Light"; + + case SIM_ACCESS_MIN: + default: + return ""; + } +} + +// static std::string LLViewerRegion::accessToShortString(U8 sim_access) { switch(sim_access) /* Flawfinder: ignore */ diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index 49d0900f2a..5c4d5a61fd 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -203,6 +203,9 @@ public: // Returns "M", "PG", "A" etc. static std::string accessToShortString(U8 sim_access); + + // Return access icon name + static std::string getAccessIcon(U8 sim_access); // helper function which just makes sure all interested parties // can process the message. diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 7473adda1f..63f060b58a 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -2238,7 +2238,6 @@ LLGLuint LLVOAvatarSelf::getScratchTexName( LLGLenum format, S32& components, U3 { case GL_LUMINANCE: components = 1; internal_format = GL_LUMINANCE8; break; case GL_ALPHA: components = 1; internal_format = GL_ALPHA8; break; - case GL_COLOR_INDEX: components = 1; internal_format = GL_COLOR_INDEX8_EXT; break; case GL_LUMINANCE_ALPHA: components = 2; internal_format = GL_LUMINANCE8_ALPHA8; break; case GL_RGB: components = 3; internal_format = GL_RGB8; break; case GL_RGBA: components = 4; internal_format = GL_RGBA8; break; diff --git a/indra/newview/llwearablelist.cpp b/indra/newview/llwearablelist.cpp index b2de31218b..20266706da 100644 --- a/indra/newview/llwearablelist.cpp +++ b/indra/newview/llwearablelist.cpp @@ -235,9 +235,7 @@ LLWearable* LLWearableList::createNewWearable( EWearableType type ) LLWearable *wearable = generateNewWearable(); wearable->setType( type ); - LLSD item_name = LLSD().with("[WEARABLE_ITEM]", wearable->getTypeLabel()); - std::string name = LLTrans::getString("NewWearable"); - LLStringUtil::format(name, item_name); + std::string name = LLTrans::getString( LLWearableDictionary::getTypeDefaultNewName(wearable->getType()) ); wearable->setName( name ); LLPermissions perm; diff --git a/indra/newview/skins/default/xui/en/floater_outgoing_call.xml b/indra/newview/skins/default/xui/en/floater_outgoing_call.xml index 5ea207675b..9db6568ee3 100644 --- a/indra/newview/skins/default/xui/en/floater_outgoing_call.xml +++ b/indra/newview/skins/default/xui/en/floater_outgoing_call.xml @@ -119,7 +119,7 @@ No Answer. Please try again later. layout="topleft" left="77" name="leaving" - top="52" + top="62" width="315" word_wrap="true"> Leaving [CURRENT_CHAT]. diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 59b43eeb00..c959a4f55a 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -5168,7 +5168,7 @@ An object named [OBJECTFROMNAME] owned by (an unknown Resident) has given you th type="offer"> [NAME_SLURL] has offered to teleport you to their location: -[MESSAGE], ([MATURITY]) +[MESSAGE] - [MATURITY_STR] <icon>[MATURITY_ICON]</icon> <form name="form"> <button index="0" diff --git a/indra/newview/skins/default/xui/en/outfit_accordion_tab.xml b/indra/newview/skins/default/xui/en/outfit_accordion_tab.xml new file mode 100644 index 0000000000..d00b1bfb7b --- /dev/null +++ b/indra/newview/skins/default/xui/en/outfit_accordion_tab.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<!-- *NOTE: mantipov: this xml is intended to be used inside panel_outfits_list.xml for each outfit folder--> +<!-- All accordion tabs in the My Appearance/My Outfits panel will be created from this one at runtume--> +<accordion_tab + display_children="false" + follows="all" + height="40" + layout="topleft" + name="Mockup Tab" + title="Mockup Tab" + width="0"> + <wearable_items_list + allow_select="true" + follows="all" + keep_one_selected="true" + name="wearable_items_list" + /> +</accordion_tab> diff --git a/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml index 184ea54fcb..5dbd8bfe6a 100644 --- a/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml +++ b/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml @@ -17,7 +17,7 @@ layout="topleft" left_delta="3" left="0" - max_length="512" + max_length="1024" name="chat_box" text_pad_left="5" text_pad_right="25" diff --git a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml index b1f0ff15cb..314d2389ae 100644 --- a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml +++ b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml @@ -222,6 +222,30 @@ top="1" width="31" /> <button + follows="bottom|left" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="Movement_Forward_On" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + layout="topleft" + left_pad="1" + name="move_closer_btn" + top="1" + width="31" /> + <button + follows="bottom|left" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="Movement_Backward_On" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + layout="topleft" + left_pad="1" + name="move_further_btn" + top="1" + width="31" /> + <button follows="bottom|right" height="25" image_hover_unselected="Toolbar_Middle_Over" diff --git a/indra/newview/skins/default/xui/fr/menu_group_plus.xml b/indra/newview/skins/default/xui/fr/menu_group_plus.xml index f5882261b0..0db5afedc7 100644 --- a/indra/newview/skins/default/xui/fr/menu_group_plus.xml +++ b/indra/newview/skins/default/xui/fr/menu_group_plus.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <menu name="menu_group_plus"> - <menu_item_call label="Rejoignez des groupes..." name="item_join"/> + <menu_item_call label="Rejoindre des groupes..." name="item_join"/> <menu_item_call label="Nouveau groupe..." name="item_new"/> </menu> diff --git a/indra/newview/skins/default/xui/fr/menu_inventory_gear_default.xml b/indra/newview/skins/default/xui/fr/menu_inventory_gear_default.xml index 91bccfd699..4cfdfd2614 100644 --- a/indra/newview/skins/default/xui/fr/menu_inventory_gear_default.xml +++ b/indra/newview/skins/default/xui/fr/menu_inventory_gear_default.xml @@ -7,7 +7,7 @@ <menu_item_call label="Réinitialiser les filtres" name="reset_filters"/> <menu_item_call label="Fermer tous les dossiers" name="close_folders"/> <menu_item_call label="Vider la corbeille" name="empty_trash"/> - <menu_item_call label="Vider les Objets trouvés" name="empty_lostnfound"/> + <menu_item_call label="Vider les objets trouvés" name="empty_lostnfound"/> <menu_item_call label="Enregistrer la texture sous" name="Save Texture As"/> <menu_item_call label="Trouver l'original" name="Find Original"/> <menu_item_call label="Trouver tous les liens" name="Find All Links"/> diff --git a/indra/newview/skins/default/xui/fr/panel_main_inventory.xml b/indra/newview/skins/default/xui/fr/panel_main_inventory.xml index 1a4450cccc..6cd9db2a5e 100644 --- a/indra/newview/skins/default/xui/fr/panel_main_inventory.xml +++ b/indra/newview/skins/default/xui/fr/panel_main_inventory.xml @@ -23,7 +23,7 @@ <menu_item_call label="Réinitialiser les filtres" name="Reset Current"/> <menu_item_call label="Fermer tous les dossiers" name="Close All Folders"/> <menu_item_call label="Vider la corbeille" name="Empty Trash"/> - <menu_item_call label="Vider les Objets trouvés" name="Empty Lost And Found"/> + <menu_item_call label="Vider les objets trouvés" name="Empty Lost And Found"/> </menu> <menu label="Créer" name="Create"> <menu_item_call label="Nouveau dossier" name="New Folder"/> diff --git a/indra/newview/skins/default/xui/fr/strings.xml b/indra/newview/skins/default/xui/fr/strings.xml index 61659d386b..6d81df5cdb 100644 --- a/indra/newview/skins/default/xui/fr/strings.xml +++ b/indra/newview/skins/default/xui/fr/strings.xml @@ -2085,7 +2085,7 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE]. Large </string> <string name="Brow Size"> - Taille + Taille du front </string> <string name="Bug Eyes"> Yeux globuleux @@ -2235,7 +2235,7 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE]. Extrémités </string> <string name="Egg Head"> - Forme de la tête + Proéminence </string> <string name="Eye Bags"> Cernes @@ -2559,7 +2559,7 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE]. Fente labiale </string> <string name="Lip Cleft Depth"> - Fente labiale + Prof. fente labiale </string> <string name="Lip Fullness"> Volume des lèvres @@ -2643,7 +2643,7 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE]. Abaisser </string> <string name="Lower Bridge"> - Arête plus basse + Arête inférieure </string> <string name="Lower Cheeks"> Joue inférieure @@ -2817,10 +2817,10 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE]. Épaisseur du nez </string> <string name="Nose Tip Angle"> - Bout du nez + Angle bout du nez </string> <string name="Nose Tip Shape"> - Bout du nez + Forme bout du nez </string> <string name="Nose Width"> Largeur du nez @@ -2946,7 +2946,7 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE]. Plus </string> <string name="Puffy Eyelids"> - Cernes + Paup. gonflées </string> <string name="Rainbow Color"> Couleur arc en ciel @@ -3237,7 +3237,7 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE]. Arête supérieure </string> <string name="Upper Cheeks"> - Pommette + Joue supérieure </string> <string name="Upper Chin Cleft"> Menton supérieur |