diff options
Diffstat (limited to 'indra/newview')
51 files changed, 456 insertions, 136 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 766dc5226c..2c52b400e4 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1881,12 +1881,12 @@ if (WINDOWS) # sets the 'working directory' for debugging from visual studio. # Condition for version can be moved to requirements once build agents will be updated (see TOOL-3865) - if ((NOT UNATTENDED) AND (${CMAKE_VERSION} VERSION_GREATER "3.7.2")) + if (NOT UNATTENDED) set_property( TARGET ${VIEWER_BINARY_NAME} PROPERTY VS_DEBUGGER_WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" ) - endif ((NOT UNATTENDED) AND (${CMAKE_VERSION} VERSION_GREATER "3.7.2")) + endif (NOT UNATTENDED) if (PACKAGE) add_custom_command( diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index ba250fa471..4bd3ca9157 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -742,7 +742,7 @@ BOOL LLAgent::getFlying() const //----------------------------------------------------------------------------- // setFlying() //----------------------------------------------------------------------------- -void LLAgent::setFlying(BOOL fly) +void LLAgent::setFlying(BOOL fly, BOOL fail_sound) { if (isAgentAvatarValid()) { @@ -771,7 +771,10 @@ void LLAgent::setFlying(BOOL fly) // parcel doesn't let you start fly // gods can always fly // and it's OK if you're already flying - make_ui_sound("UISndBadKeystroke"); + if (fail_sound) + { + make_ui_sound("UISndBadKeystroke"); + } return; } if( !was_flying ) diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index b1b39b637e..ea6f68c482 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -337,7 +337,7 @@ private: //-------------------------------------------------------------------- public: BOOL getFlying() const; - void setFlying(BOOL fly); + void setFlying(BOOL fly, BOOL fail_sound = FALSE); static void toggleFlying(); static bool enableFlying(); BOOL canFly(); // Does this parcel allow you to fly? diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 08daeb0f59..22bcbad7da 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -1865,7 +1865,6 @@ bool LLAppearanceMgr::getCanRemoveOutfit(const LLUUID& outfit_cat_id) LLFindNonRemovableObjects filter_non_removable; LLInventoryModel::cat_array_t cats; LLInventoryModel::item_array_t items; - LLInventoryModel::item_array_t::const_iterator it; gInventory.collectDescendentsIf(outfit_cat_id, cats, items, false, filter_non_removable); if (!cats.empty() || !items.empty()) { diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 577082f01f..6202a382b1 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1167,11 +1167,14 @@ bool LLAppViewer::init() // ForceAddressSize updater.args.add(stringize(gSavedSettings.getU32("ForceAddressSize"))); +#if !LL_RELEASE_FOR_DOWNLOAD && !LL_SEND_CRASH_REPORTS + // This is neither a release package, nor crash-reporting enabled test build + // Note: pointless to launch on Windows - it shouldn't expect secondlife-bin.exe + LL_WARNS("LLLeap") << "Launching without version checker" << LL_ENDL; +#else // Run the updater. An exception from launching the updater should bother us. - if (!beingDebugged()) - { - LLLeap::create(updater, true); - } + LLLeap::create(updater, true); +#endif // Iterate over --leap command-line options. But this is a bit tricky: if // there's only one, it won't be an array at all. @@ -3173,6 +3176,10 @@ LLSD LLAppViewer::getViewerInfo() const substitution["datetime"] = (S32)(gVFS ? gVFS->creationTime() : 0); info["VFS_TIME"] = LLTrans::getString("AboutTime", substitution); +#if LL_DARWIN + info["HIDPI"] = gHiDPISupport; +#endif + // Libraries info["J2C_VERSION"] = LLImageJ2C::getEngineInfo(); @@ -3315,6 +3322,9 @@ std::string LLAppViewer::getViewerInfoString(bool default_string) const } support << "\n" << LLTrans::getString("AboutOGL", args, default_string); support << "\n\n" << LLTrans::getString("AboutSettings", args, default_string); +#if LL_DARWIN + support << "\n" << LLTrans::getString("AboutOSXHiDPI", args, default_string); +#endif support << "\n\n" << LLTrans::getString("AboutLibs", args, default_string); if (info.has("COMPILER")) { diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp index f68e63cb96..98687282ed 100644 --- a/indra/newview/llfasttimerview.cpp +++ b/indra/newview/llfasttimerview.cpp @@ -43,6 +43,7 @@ #include "llsdserialize.h" #include "lltooltip.h" #include "llbutton.h" +#include "llscrollbar.h" #include "llappviewer.h" #include "llviewertexturelist.h" @@ -128,7 +129,8 @@ void LLFastTimerView::setPauseState(bool pause_state) BOOL LLFastTimerView::postBuild() { LLButton& pause_btn = getChildRef<LLButton>("pause_btn"); - + mScrollBar = getChild<LLScrollbar>("scroll_vert"); + pause_btn.setCommitCallback(boost::bind(&LLFastTimerView::onPause, this)); return TRUE; } @@ -183,7 +185,7 @@ BOOL LLFastTimerView::handleDoubleClick(S32 x, S32 y, MASK mask) BOOL LLFastTimerView::handleMouseDown(S32 x, S32 y, MASK mask) { - if (x < mBarRect.mLeft) + if (x < mScrollBar->getRect().mLeft) { BlockTimerStatHandle* idp = getLegendID(y); if (idp) @@ -284,7 +286,7 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask) } } } - else if (x < mBarRect.mLeft) + else if (x < mScrollBar->getRect().mLeft) { BlockTimerStatHandle* timer_id = getLegendID(y); if (timer_id) @@ -335,7 +337,7 @@ BOOL LLFastTimerView::handleToolTip(S32 x, S32 y, MASK mask) else { // tooltips for timer legend - if (x < mBarRect.mLeft) + if (x < mScrollBar->getRect().mLeft) { BlockTimerStatHandle* idp = getLegendID(y); if (idp) @@ -1197,6 +1199,7 @@ void LLFastTimerView::drawLegend() { LLLocalClipRect clip(mLegendRect); S32 cur_line = 0; + S32 scroll_offset = 0; // element's y offset from top of the inner scroll's rect ft_display_idx.clear(); std::map<BlockTimerStatHandle*, S32> display_line; for (block_timer_tree_df_iterator_t it = LLTrace::begin_block_timer_tree_df(FTM_FRAME); @@ -1204,10 +1207,24 @@ void LLFastTimerView::drawLegend() ++it) { BlockTimerStatHandle* idp = (*it); + // Needed to figure out offsets and parenting display_line[idp] = cur_line; - ft_display_idx.push_back(idp); cur_line++; + if (scroll_offset < mScrollBar->getDocPos()) + { + // only offset for visible items + scroll_offset += TEXT_HEIGHT + 2; + if (idp->getTreeNode().mCollapsed) + { + it.skipDescendants(); + } + continue; + } + + // used for mouse clicks + ft_display_idx.push_back(idp); + // Actual draw, first bar (square), then text x = MARGIN; LLRect bar_rect(x, y, x + TEXT_HEIGHT, y - TEXT_HEIGHT); @@ -1281,11 +1298,14 @@ void LLFastTimerView::drawLegend() y -= (TEXT_HEIGHT + 2); + scroll_offset += TEXT_HEIGHT + 2; if (idp->getTreeNode().mCollapsed) { it.skipDescendants(); } } + // Recalculate scroll size + mScrollBar->setDocSize(scroll_offset - mLegendRect.getHeight()); } } diff --git a/indra/newview/llfasttimerview.h b/indra/newview/llfasttimerview.h index 3e30bd86ba..ff65f8da07 100644 --- a/indra/newview/llfasttimerview.h +++ b/indra/newview/llfasttimerview.h @@ -33,6 +33,8 @@ #include "lltracerecording.h" #include <deque> +class LLScrollbar; + class LLFastTimerView : public LLFloater { public: @@ -142,6 +144,8 @@ private: mLegendRect; LLFrameTimer mHighlightTimer; LLTrace::PeriodicRecording mRecording; + + LLScrollbar* mScrollBar; }; #endif diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp index ee4fdbe9a5..c2c15ee12b 100644 --- a/indra/newview/llfloatertools.cpp +++ b/indra/newview/llfloatertools.cpp @@ -514,11 +514,6 @@ void LLFloaterTools::refresh() selection_info << getString("status_selectcount", selection_args); getChild<LLTextBox>("selection_count")->setText(selection_info.str()); - - bool have_selection = !LLSelectMgr::getInstance()->getSelection()->isEmpty(); - childSetVisible("selection_count", have_selection); - childSetVisible("remaining_capacity", have_selection); - childSetVisible("selection_empty", !have_selection); } diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp index 152d0eddcd..088d052533 100644 --- a/indra/newview/llgroupmgr.cpp +++ b/indra/newview/llgroupmgr.cpp @@ -2137,6 +2137,7 @@ void LLGroupMgr::sendCapGroupMembersRequest(const LLUUID& group_id) static U32 lastGroupMemberRequestFrame = 0; // Have we requested the information already this frame? + // Todo: make this per group, we can invite to one group and simultaneously be checking another one if ((lastGroupMemberRequestFrame == gFrameCount) || (mMemberRequestInFlight)) return; @@ -2166,6 +2167,9 @@ void LLGroupMgr::sendCapGroupMembersRequest(const LLUUID& group_id) return; } + LLGroupMgrGroupData* group_datap = createGroupData(group_id); //make sure group exists + group_datap->mMemberRequestID.generate(); // mark as pending + lastGroupMemberRequestFrame = gFrameCount; LLCoros::instance().launch("LLGroupMgr::groupMembersRequestCoro", diff --git a/indra/newview/llgroupmgr.h b/indra/newview/llgroupmgr.h index 940ef6eea1..cf9735e38a 100644 --- a/indra/newview/llgroupmgr.h +++ b/indra/newview/llgroupmgr.h @@ -258,6 +258,11 @@ public: bool isRoleMemberDataComplete() { return mRoleMemberDataComplete; } bool isGroupPropertiesDataComplete() { return mGroupPropertiesDataComplete; } + bool isMemberDataPending() { return mMemberRequestID.notNull(); } + bool isRoleDataPending() { return mRoleDataRequestID.notNull(); } + bool isRoleMemberDataPending() { return (mRoleMembersRequestID.notNull() || mPendingRoleMemberRequest); } + bool isGroupTitlePending() { return mTitlesRequestID.notNull(); } + bool isSingleMemberNotOwner(); F32 getAccessTime() const { return mAccessTime; } diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 00b7732ee9..e13f8343a0 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -2101,7 +2101,9 @@ BOOL LLItemBridge::isItemCopyable() const LLViewerInventoryItem* item = getItem(); if (item) { - // Can't copy worn objects. DEV-15183 + // Can't copy worn objects. + // Worn objects are tied to their inworld conterparts + // Copy of modified worn object will return object with obsolete asset and inventory if(get_is_item_worn(mUUID)) { return FALSE; @@ -7358,8 +7360,7 @@ bool LLFolderViewGroupedItemBridge::canWearSelected(uuid_vec_t item_ids) for (uuid_vec_t::const_iterator it = item_ids.begin(); it != item_ids.end(); ++it) { LLViewerInventoryItem* item = gInventory.getItem(*it); - LLAssetType::EType asset_type = item->getType(); - if (!item || (asset_type >= LLAssetType::AT_COUNT) || (asset_type <= LLAssetType::AT_NONE)) + if (!item || (item->getType() >= LLAssetType::AT_COUNT) || (item->getType() <= LLAssetType::AT_NONE)) { return false; } diff --git a/indra/newview/llmachineid.cpp b/indra/newview/llmachineid.cpp index b0ee8e7fcb..2001359e50 100644 --- a/indra/newview/llmachineid.cpp +++ b/indra/newview/llmachineid.cpp @@ -65,11 +65,11 @@ public: S32 LLMachineID::init() { - memset(static_unique_id,0,sizeof(static_unique_id)); + size_t len = sizeof(static_unique_id); + memset(static_unique_id, 0, len); S32 ret_code = 0; #if LL_WINDOWS # pragma comment(lib, "wbemuuid.lib") - size_t len = sizeof(static_unique_id); // algorithm to detect BIOS serial number found at: // http://msdn.microsoft.com/en-us/library/aa394077%28VS.85%29.aspx @@ -218,16 +218,19 @@ S32 LLMachineID::init() // Get the value of the Name property hr = pclsObj->Get(L"SerialNumber", 0, &vtProp, 0, 0); LL_INFOS("AppInit") << " Serial Number : " << vtProp.bstrVal << LL_ENDL; + // use characters in the returned Serial Number to create a byte array of size len BSTR serialNumber ( vtProp.bstrVal); + unsigned int serial_size = SysStringLen(serialNumber); unsigned int j = 0; - while( vtProp.bstrVal[j] != 0) + + while (j < serial_size) { for (unsigned int i = 0; i < len; i++) { - if (vtProp.bstrVal[j] == 0) + if (j >= serial_size) break; - + static_unique_id[i] = (unsigned int)(static_unique_id[i] + serialNumber[j]); j++; } @@ -254,16 +257,8 @@ S32 LLMachineID::init() ret_code = LLUUID::getNodeID(staticPtr); #endif has_static_unique_id = true; - return ret_code; -} - -S32 LLMachineID::getUniqueID(unsigned char *unique_id, size_t len) -{ - if (has_static_unique_id) - { - memcpy ( unique_id, &static_unique_id, len); - LL_INFOS_ONCE("AppInit") << "UniqueID: 0x"; + LL_INFOS("AppInit") << "UniqueID: 0x"; // Code between here and LL_ENDL is not executed unless the LL_DEBUGS // actually produces output for (size_t i = 0; i < len; ++i) @@ -271,11 +266,21 @@ S32 LLMachineID::getUniqueID(unsigned char *unique_id, size_t len) // Copy each char to unsigned int to hexify. Sending an unsigned // char to a std::ostream tries to represent it as a char, not // what we want here. - unsigned byte = unique_id[i]; + unsigned byte = static_unique_id[i]; LL_CONT << std::hex << std::setw(2) << std::setfill('0') << byte; } // Reset default output formatting to avoid nasty surprises! LL_CONT << std::dec << std::setw(0) << std::setfill(' ') << LL_ENDL; + + return ret_code; +} + + +S32 LLMachineID::getUniqueID(unsigned char *unique_id, size_t len) +{ + if (has_static_unique_id) + { + memcpy ( unique_id, &static_unique_id, len); return 1; } return 0; diff --git a/indra/newview/llpanelgroupinvite.cpp b/indra/newview/llpanelgroupinvite.cpp index 82ea8377de..d6b66ee622 100644 --- a/indra/newview/llpanelgroupinvite.cpp +++ b/indra/newview/llpanelgroupinvite.cpp @@ -606,11 +606,30 @@ void LLPanelGroupInvite::updateLists() { if (!mPendingUpdate) { + // Note: this will partially fail if some requests are already in progress LLGroupMgr::getInstance()->sendGroupPropertiesRequest(mImplementation->mGroupID); LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mImplementation->mGroupID); LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(mImplementation->mGroupID); LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mImplementation->mGroupID); } + else if (gdatap) + { + // restart requests that were interrupted/dropped/failed to start + if (!gdatap->isRoleDataPending() && !gdatap->isRoleDataComplete()) + { + LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mImplementation->mGroupID); + } + if (!gdatap->isRoleMemberDataPending() && !gdatap->isRoleMemberDataComplete()) + { + LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(mImplementation->mGroupID); + } + // sendCapGroupMembersRequest has a per frame send limitation that could have + // interrupted previous request + if (!gdatap->isMemberDataPending() && !gdatap->isMemberDataComplete()) + { + LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mImplementation->mGroupID); + } + } mPendingUpdate = TRUE; } else diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index 142dea83e2..0637010b0b 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -748,7 +748,10 @@ void LLPanelLogin::closePanel() { if (sInstance) { - LLPanelLogin::sInstance->getParent()->removeChild( LLPanelLogin::sInstance ); + if (LLPanelLogin::sInstance->getParent()) + { + LLPanelLogin::sInstance->getParent()->removeChild(LLPanelLogin::sInstance); + } delete sInstance; sInstance = NULL; diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index cd1875e995..5aa80651c4 100644 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -1498,7 +1498,14 @@ void LLPanelObjectInventory::updateInventory() mIsInventoryEmpty = TRUE; } - mHaveInventory = TRUE; + mHaveInventory = !mIsInventoryEmpty || !objectp->isInventoryDirty(); + if (objectp->isInventoryDirty()) + { + // Inventory is dirty, yet we received inventoryChanged() callback. + // User changed something during ongoing request. + // Rerequest. It will clear dirty flag and won't create dupplicate requests. + objectp->requestInventory(); + } } else { @@ -1768,7 +1775,7 @@ void LLPanelObjectInventory::deleteAllChildren() BOOL LLPanelObjectInventory::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, std::string& tooltip_msg) { - if (mFolders && mHaveInventory) + if (mFolders) { LLFolderViewItem* folderp = mFolders->getNextFromChild(NULL); if (!folderp) diff --git a/indra/newview/llpanelobjectinventory.h b/indra/newview/llpanelobjectinventory.h index d700c8f4cf..7b9ecfb8f3 100644 --- a/indra/newview/llpanelobjectinventory.h +++ b/indra/newview/llpanelobjectinventory.h @@ -106,9 +106,9 @@ private: LLUUID mTaskUUID; LLUUID mAttachmentUUID; - BOOL mHaveInventory; - BOOL mIsInventoryEmpty; - BOOL mInventoryNeedsUpdate; + BOOL mHaveInventory; // 'Loading' label and used for initial request + BOOL mIsInventoryEmpty; // 'Empty' label + BOOL mInventoryNeedsUpdate; // for idle, set on changed callback LLFolderViewModelInventory mInventoryViewModel; }; diff --git a/indra/newview/llpanelplaceprofile.cpp b/indra/newview/llpanelplaceprofile.cpp index 610b3a6396..104316e253 100644 --- a/indra/newview/llpanelplaceprofile.cpp +++ b/indra/newview/llpanelplaceprofile.cpp @@ -563,11 +563,8 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel, mSaleToText->setText(getString("anyone")); } - const U8* sign = (U8*)getString("price_text").c_str(); - const U8* sqm = (U8*)getString("area_text").c_str(); - - mSalesPriceText->setText(llformat("%s%d ", sign, parcel->getSalePrice())); - mAreaText->setText(llformat("%d %s", area, sqm)); + mSalesPriceText->setText(llformat("%s%d ", getString("price_text").c_str(), parcel->getSalePrice())); + mAreaText->setText(llformat("%d %s", area, getString("area_text").c_str())); mTrafficText->setText(llformat("%.0f", dwell)); // Can't have more than region max tasks, regardless of parcel @@ -575,10 +572,7 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel, S32 primitives = llmin(ll_round(parcel->getMaxPrimCapacity() * parcel->getParcelPrimBonus()), (S32)region->getMaxTasks()); - const U8* available = (U8*)getString("available").c_str(); - const U8* allocated = (U8*)getString("allocated").c_str(); - - mPrimitivesText->setText(llformat("%d %s, %d %s", primitives, available, parcel->getPrimCount(), allocated)); + mPrimitivesText->setText(llformat("%d %s, %d %s", primitives, getString("available").c_str(), parcel->getPrimCount(), getString("allocated").c_str())); if (parcel->getAllowOtherScripts()) { diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp index d4a8bbdf45..f012d99adf 100644 --- a/indra/newview/llpreviewnotecard.cpp +++ b/indra/newview/llpreviewnotecard.cpp @@ -32,6 +32,7 @@ #include "llagent.h" #include "lldraghandle.h" +#include "llexternaleditor.h" #include "llviewerwindow.h" #include "llbutton.h" #include "llfloaterreg.h" @@ -63,7 +64,8 @@ // Default constructor LLPreviewNotecard::LLPreviewNotecard(const LLSD& key) //const LLUUID& item_id, - : LLPreview( key ) + : LLPreview( key ), + mLiveFile(NULL) { const LLInventoryItem *item = getItem(); if (item) @@ -74,13 +76,14 @@ LLPreviewNotecard::LLPreviewNotecard(const LLSD& key) //const LLUUID& item_id, LLPreviewNotecard::~LLPreviewNotecard() { + delete mLiveFile; } BOOL LLPreviewNotecard::postBuild() { - LLViewerTextEditor *ed = getChild<LLViewerTextEditor>("Notecard Editor"); - ed->setNotecardInfo(mItemUUID, mObjectID, getKey()); - ed->makePristine(); + mEditor = getChild<LLViewerTextEditor>("Notecard Editor"); + mEditor->setNotecardInfo(mItemUUID, mObjectID, getKey()); + mEditor->makePristine(); childSetAction("Save", onClickSave, this); getChildView("lock")->setVisible( FALSE); @@ -88,6 +91,8 @@ BOOL LLPreviewNotecard::postBuild() childSetAction("Delete", onClickDelete, this); getChildView("Delete")->setEnabled(false); + childSetAction("Edit", onClickEdit, this); + const LLInventoryItem* item = getItem(); childSetCommitCallback("desc", LLPreview::onText, this); @@ -408,6 +413,16 @@ void LLPreviewNotecard::onClickDelete(void* user_data) } } +// static +void LLPreviewNotecard::onClickEdit(void* user_data) +{ + LLPreviewNotecard* preview = (LLPreviewNotecard*)user_data; + if (preview) + { + preview->openInExternalEditor(); + } +} + struct LLSaveNotecardInfo { LLPreviewNotecard* mSelf; @@ -468,7 +483,7 @@ void LLPreviewNotecard::finishTaskUpload(LLUUID itemId, LLUUID newAssetId, LLUUI } } -bool LLPreviewNotecard::saveIfNeeded(LLInventoryItem* copyitem) +bool LLPreviewNotecard::saveIfNeeded(LLInventoryItem* copyitem, bool sync) { LLViewerTextEditor* editor = getChild<LLViewerTextEditor>("Notecard Editor"); @@ -487,7 +502,10 @@ bool LLPreviewNotecard::saveIfNeeded(LLInventoryItem* copyitem) } editor->makePristine(); - + if (sync) + { + syncExternal(); + } const LLInventoryItem* item = getItem(); // save it out to database if (item) @@ -566,6 +584,18 @@ bool LLPreviewNotecard::saveIfNeeded(LLInventoryItem* copyitem) return true; } +void LLPreviewNotecard::syncExternal() +{ + // Sync with external editor. + std::string tmp_file = getTmpFileName(); + llstat s; + if (LLFile::stat(tmp_file, &s) == 0) // file exists + { + if (mLiveFile) mLiveFile->ignoreNextUpdate(); + writeToFile(tmp_file); + } +} + void LLPreviewNotecard::deleteNotecard() { LLNotificationsUtil::add("DeleteNotecard", LLSD(), LLSD(), boost::bind(&LLPreviewNotecard::handleConfirmDeleteDialog,this, _1, _2)); @@ -714,4 +744,128 @@ bool LLPreviewNotecard::handleConfirmDeleteDialog(const LLSD& notification, cons return false; } +void LLPreviewNotecard::openInExternalEditor() +{ + delete mLiveFile; // deletes file + + // Save the notecard to a temporary file. + std::string filename = getTmpFileName(); + writeToFile(filename); + + // Start watching file changes. + mLiveFile = new LLLiveLSLFile(filename, boost::bind(&LLPreviewNotecard::onExternalChange, this, _1)); + mLiveFile->addToEventTimer(); + + // Open it in external editor. + { + LLExternalEditor ed; + LLExternalEditor::EErrorCode status; + std::string msg; + + status = ed.setCommand("LL_SCRIPT_EDITOR"); + if (status != LLExternalEditor::EC_SUCCESS) + { + if (status == LLExternalEditor::EC_NOT_SPECIFIED) // Use custom message for this error. + { + msg = getString("external_editor_not_set"); + } + else + { + msg = LLExternalEditor::getErrorMessage(status); + } + + LLNotificationsUtil::add("GenericAlert", LLSD().with("MESSAGE", msg)); + return; + } + + status = ed.run(filename); + if (status != LLExternalEditor::EC_SUCCESS) + { + msg = LLExternalEditor::getErrorMessage(status); + LLNotificationsUtil::add("GenericAlert", LLSD().with("MESSAGE", msg)); + } + } +} + +bool LLPreviewNotecard::onExternalChange(const std::string& filename) +{ + if (!loadNotecardText(filename)) + { + return false; + } + + // Disable sync to avoid recursive load->save->load calls. + saveIfNeeded(NULL, false); + return true; +} + +bool LLPreviewNotecard::loadNotecardText(const std::string& filename) +{ + if (filename.empty()) + { + LL_WARNS() << "Empty file name" << LL_ENDL; + return false; + } + + LLFILE* file = LLFile::fopen(filename, "rb"); /*Flawfinder: ignore*/ + if (!file) + { + LL_WARNS() << "Error opening " << filename << LL_ENDL; + return false; + } + + // read in the whole file + fseek(file, 0L, SEEK_END); + size_t file_length = (size_t)ftell(file); + fseek(file, 0L, SEEK_SET); + char* buffer = new char[file_length + 1]; + size_t nread = fread(buffer, 1, file_length, file); + if (nread < file_length) + { + LL_WARNS() << "Short read" << LL_ENDL; + } + buffer[nread] = '\0'; + fclose(file); + + mEditor->setText(LLStringExplicit(buffer)); + delete[] buffer; + + return true; +} + +bool LLPreviewNotecard::writeToFile(const std::string& filename) +{ + LLFILE* fp = LLFile::fopen(filename, "wb"); + if (!fp) + { + LL_WARNS() << "Unable to write to " << filename << LL_ENDL; + return false; + } + + std::string utf8text = mEditor->getText(); + + if (utf8text.size() == 0) + { + utf8text = " "; + } + + fputs(utf8text.c_str(), fp); + fclose(fp); + return true; +} + + +std::string LLPreviewNotecard::getTmpFileName() +{ + std::string notecard_id = mObjectID.asString() + "_" + mItemUUID.asString(); + + // Use MD5 sum to make the file name shorter and not exceed maximum path length. + char notecard_id_hash_str[33]; /* Flawfinder: ignore */ + LLMD5 notecard_id_hash((const U8 *)notecard_id.c_str()); + notecard_id_hash.hex_digest(notecard_id_hash_str); + + return std::string(LLFile::tmpdir()) + "sl_notecard_" + notecard_id_hash_str + ".txt"; +} + + // EOF diff --git a/indra/newview/llpreviewnotecard.h b/indra/newview/llpreviewnotecard.h index 46a6d0ef50..d9c14815c1 100644 --- a/indra/newview/llpreviewnotecard.h +++ b/indra/newview/llpreviewnotecard.h @@ -29,6 +29,7 @@ #include "llpreview.h" #include "llassetstorage.h" +#include "llpreviewscript.h" #include "lliconctrl.h" //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -47,18 +48,18 @@ public: virtual ~LLPreviewNotecard(); bool saveItem(); - void setObjectID(const LLUUID& object_id); + void setObjectID(const LLUUID& object_id) override; // llview - virtual void draw(); - virtual BOOL handleKeyHere(KEY key, MASK mask); - virtual void setEnabled( BOOL enabled ); + void draw() override; + BOOL handleKeyHere(KEY key, MASK mask) override; + void setEnabled( BOOL enabled ) override; // llfloater - virtual BOOL canClose(); + BOOL canClose() override; // llpanel - virtual BOOL postBuild(); + BOOL postBuild() override; // reach into the text editor, and grab the drag item const LLInventoryItem* getDragItem(); @@ -72,11 +73,13 @@ public: // asset system. :( void refreshFromInventory(const LLUUID& item_id = LLUUID::null); + void syncExternal(); + protected: - void updateTitleButtons(); - virtual void loadAsset(); - bool saveIfNeeded(LLInventoryItem* copyitem = NULL); + void updateTitleButtons() override; + void loadAsset() override; + bool saveIfNeeded(LLInventoryItem* copyitem = NULL, bool sync = true); void deleteNotecard(); @@ -89,6 +92,8 @@ protected: static void onClickDelete(void* data); + static void onClickEdit(void* data); + static void onSaveComplete(const LLUUID& asset_uuid, void* user_data, S32 status, LLExtStat ext_status); @@ -99,6 +104,12 @@ protected: static void finishInventoryUpload(LLUUID itemId, LLUUID newAssetId, LLUUID newItemId); static void finishTaskUpload(LLUUID itemId, LLUUID newAssetId, LLUUID taskId); + void openInExternalEditor(); + bool onExternalChange(const std::string& filename); + bool loadNotecardText(const std::string& filename); + bool writeToFile(const std::string& filename); + std::string getTmpFileName(); + protected: LLViewerTextEditor* mEditor; LLButton* mSaveBtn; @@ -106,6 +117,8 @@ protected: LLUUID mAssetID; LLUUID mObjectID; + + LLLiveLSLFile* mLiveFile; }; diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index 9431914ba3..76a21077ba 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -41,7 +41,6 @@ #include "llinventorymodel.h" #include "llkeyboard.h" #include "lllineeditor.h" -#include "lllivefile.h" #include "llhelp.h" #include "llnotificationsutil.h" #include "llresmgr.h" @@ -120,22 +119,6 @@ static bool have_script_upload_cap(LLUUID& object_id) /// --------------------------------------------------------------------------- /// LLLiveLSLFile /// --------------------------------------------------------------------------- -class LLLiveLSLFile : public LLLiveFile -{ -public: - typedef boost::function<bool (const std::string& filename)> change_callback_t; - - LLLiveLSLFile(std::string file_path, change_callback_t change_cb); - ~LLLiveLSLFile(); - - void ignoreNextUpdate() { mIgnoreNextUpdate = true; } - -protected: - /*virtual*/ bool loadFile(); - - change_callback_t mOnChangeCallback; - bool mIgnoreNextUpdate; -}; LLLiveLSLFile::LLLiveLSLFile(std::string file_path, change_callback_t change_cb) : mOnChangeCallback(change_cb) diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h index 69cf9d9158..74e4c00d43 100644 --- a/indra/newview/llpreviewscript.h +++ b/indra/newview/llpreviewscript.h @@ -34,6 +34,7 @@ #include "lliconctrl.h" #include "llframetimer.h" #include "llfloatergotoline.h" +#include "lllivefile.h" #include "llsyntaxid.h" class LLLiveLSLFile; @@ -53,6 +54,23 @@ class LLScriptEdContainer; class LLFloaterGotoLine; class LLFloaterExperienceProfile; +class LLLiveLSLFile : public LLLiveFile +{ +public: + typedef boost::function<bool(const std::string& filename)> change_callback_t; + + LLLiveLSLFile(std::string file_path, change_callback_t change_cb); + ~LLLiveLSLFile(); + + void ignoreNextUpdate() { mIgnoreNextUpdate = true; } + +protected: + /*virtual*/ bool loadFile(); + + change_callback_t mOnChangeCallback; + bool mIgnoreNextUpdate; +}; + // Inner, implementation class. LLPreviewScript and LLLiveLSLEditor each own one of these. class LLScriptEdCore : public LLPanel { diff --git a/indra/newview/llsearchableui.cpp b/indra/newview/llsearchableui.cpp index de90896548..93143eb33f 100644 --- a/indra/newview/llsearchableui.cpp +++ b/indra/newview/llsearchableui.cpp @@ -125,17 +125,13 @@ void ll::statusbar::SearchableItem::setNotHighlighted( ) } } -bool ll::statusbar::SearchableItem::hightlightAndHide( LLWString const &aFilter ) +bool ll::statusbar::SearchableItem::hightlightAndHide(LLWString const &aFilter, bool hide) { - if( mMenu && !mMenu->getVisible() && !mWasHiddenBySearch ) + if ((mMenu && !mMenu->getVisible() && !mWasHiddenBySearch) || dynamic_cast<LLMenuItemTearOffGL*>(mMenu)) return false; setNotHighlighted( ); - bool bVisible(false); - for( tSearchableItemList::iterator itr = mChildren.begin(); itr != mChildren.end(); ++itr ) - bVisible |= (*itr)->hightlightAndHide( aFilter ); - if( aFilter.empty() ) { if( mCtrl ) @@ -143,17 +139,22 @@ bool ll::statusbar::SearchableItem::hightlightAndHide( LLWString const &aFilter return true; } + bool bHighlighted(!hide); if( mLabel.find( aFilter ) != LLWString::npos ) { if( mCtrl ) mCtrl->setHighlighted( true ); - return true; + bHighlighted = true; } - if( mCtrl && !bVisible ) + bool bVisible(false); + for (tSearchableItemList::iterator itr = mChildren.begin(); itr != mChildren.end(); ++itr) + bVisible |= (*itr)->hightlightAndHide(aFilter, !bHighlighted); + + if (mCtrl && !bVisible && !bHighlighted) { mWasHiddenBySearch = true; mMenu->setVisible(FALSE); } - return bVisible; + return bVisible || bHighlighted; } diff --git a/indra/newview/llsearchableui.h b/indra/newview/llsearchableui.h index 42b2866fb6..9741557e49 100644 --- a/indra/newview/llsearchableui.h +++ b/indra/newview/llsearchableui.h @@ -107,7 +107,7 @@ namespace ll SearchableItem(); void setNotHighlighted( ); - bool hightlightAndHide( LLWString const &aFilter ); + bool hightlightAndHide( LLWString const &aFilter, bool hide = true ); }; struct SearchData diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index b36df244f8..97c547e524 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -3861,6 +3861,14 @@ BOOL LLSelectMgr::selectGetAggregateTexturePermissions(LLAggregatePermissions& r return TRUE; } +BOOL LLSelectMgr::isSelfAvatarSelected() +{ + if (mAllowSelectAvatar) + { + return (getSelection()->getObjectCount() == 1) && (getSelection()->getFirstRootObject() == gAgentAvatarp); + } + return FALSE; +} //-------------------------------------------------------------------- // Duplicate objects @@ -6686,8 +6694,28 @@ void LLSelectMgr::pauseAssociatedAvatars() mSelectedObjects->mSelectType = getSelectTypeForObject(object); + bool is_attached = false; if (mSelectedObjects->mSelectType == SELECT_TYPE_ATTACHMENT && - isAgentAvatarValid() && object->getParent() != NULL) + isAgentAvatarValid()) + { + // Selection can be obsolete, confirm that this is an attachment + LLViewerObject* parent = (LLViewerObject*)object->getParent(); + while (parent != NULL) + { + if (parent->isAvatar()) + { + is_attached = true; + break; + } + else + { + parent = (LLViewerObject*)parent->getParent(); + } + } + } + + + if (is_attached) { if (object->isAnimatedObject()) { @@ -6705,14 +6733,12 @@ void LLSelectMgr::pauseAssociatedAvatars() mPauseRequests.push_back(gAgentAvatarp->requestPause()); } } - else + else if (object && object->isAnimatedObject() && object->getControlAvatar()) { - if (object && object->isAnimatedObject() && object->getControlAvatar()) - { - // Is a non-attached animated object. Pause the control avatar. - mPauseRequests.push_back(object->getControlAvatar()->requestPause()); - } + // Is a non-attached animated object. Pause the control avatar. + mPauseRequests.push_back(object->getControlAvatar()->requestPause()); } + } } diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index ce0fee8803..3e8bfdb00e 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -714,6 +714,8 @@ public: LLPermissions* findObjectPermissions(const LLViewerObject* object); + BOOL isSelfAvatarSelected(); + void selectDelete(); // Delete on simulator void selectForceDelete(); // just delete, no into trash void selectDuplicate(const LLVector3& offset, BOOL select_copy); // Duplicate on simulator diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp index 689734e36a..ea7e649792 100644 --- a/indra/newview/llsidepanelinventory.cpp +++ b/indra/newview/llsidepanelinventory.cpp @@ -564,6 +564,7 @@ void LLSidepanelInventory::updateVerbs() mWearBtn->setEnabled(FALSE); mPlayBtn->setVisible(FALSE); mPlayBtn->setEnabled(FALSE); + mPlayBtn->setToolTip(std::string("")); mTeleportBtn->setVisible(FALSE); mTeleportBtn->setEnabled(FALSE); mShopBtn->setVisible(TRUE); @@ -588,11 +589,23 @@ void LLSidepanelInventory::updateVerbs() mShopBtn->setVisible(FALSE); break; case LLInventoryType::IT_SOUND: + mPlayBtn->setVisible(TRUE); + mPlayBtn->setEnabled(TRUE); + mPlayBtn->setToolTip(LLTrans::getString("InventoryPlaySoundTooltip")); + mShopBtn->setVisible(FALSE); + break; case LLInventoryType::IT_GESTURE: + mPlayBtn->setVisible(TRUE); + mPlayBtn->setEnabled(TRUE); + mPlayBtn->setToolTip(LLTrans::getString("InventoryPlayGestureTooltip")); + mShopBtn->setVisible(FALSE); + break; case LLInventoryType::IT_ANIMATION: mPlayBtn->setVisible(TRUE); mPlayBtn->setEnabled(TRUE); - mShopBtn->setVisible(FALSE); + mPlayBtn->setEnabled(TRUE); + mPlayBtn->setToolTip(LLTrans::getString("InventoryPlayAnimationTooltip")); + mShopBtn->setVisible(FALSE); break; case LLInventoryType::IT_LANDMARK: mTeleportBtn->setVisible(TRUE); diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp index d28a7cc048..f6cf714db4 100644 --- a/indra/newview/llsurfacepatch.cpp +++ b/indra/newview/llsurfacepatch.cpp @@ -99,7 +99,7 @@ void LLSurfacePatch::dirty() } else { - LL_WARNS() << "No viewer object for this surface patch!" << LL_ENDL; + LL_WARNS("Terrain") << "No viewer object for this surface patch!" << LL_ENDL; } mDirtyZStats = TRUE; diff --git a/indra/newview/lltoolcomp.cpp b/indra/newview/lltoolcomp.cpp index 392c103d7c..f9c327b46e 100644 --- a/indra/newview/lltoolcomp.cpp +++ b/indra/newview/lltoolcomp.cpp @@ -267,7 +267,7 @@ BOOL LLToolCompTranslate::handleHover(S32 x, S32 y, MASK mask) BOOL LLToolCompTranslate::handleMouseDown(S32 x, S32 y, MASK mask) { mMouseDown = TRUE; - gViewerWindow->pickAsync(x, y, mask, pickCallback, /*BOOL pick_transparent*/ TRUE); + gViewerWindow->pickAsync(x, y, mask, pickCallback, /*BOOL pick_transparent*/ TRUE, LLFloaterReg::instanceVisible("build")); return TRUE; } diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp index b89e1497a1..e930eb20d3 100644 --- a/indra/newview/llviewerkeyboard.cpp +++ b/indra/newview/llviewerkeyboard.cpp @@ -64,7 +64,12 @@ LLViewerKeyboard gViewerKeyboard; void agent_jump( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + static BOOL first_fly_attempt(TRUE); + if (KEYSTATE_UP == s) + { + first_fly_attempt = TRUE; + return; + } F32 time = gKeyboard->getCurKeyElapsedTime(); S32 frame_count = ll_round(gKeyboard->getCurKeyElapsedFrameCount()); @@ -77,7 +82,8 @@ void agent_jump( EKeystate s ) } else { - gAgent.setFlying(TRUE); + gAgent.setFlying(TRUE, first_fly_attempt); + first_fly_attempt = FALSE; gAgent.moveUp(1); } } diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index d8745b1eca..9f02c4b17c 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -1901,21 +1901,8 @@ void LLViewerMediaImpl::loadURI() // trim whitespace from front and back of URL - fixes EXT-5363 LLStringUtil::trim( mMediaURL ); - // *HACK: we don't know if the URI coming in is properly escaped - // (the contract doesn't specify whether it is escaped or not. - // but LLQtWebKit expects it to be, so we do our best to encode - // special characters) - // The strings below were taken right from http://www.ietf.org/rfc/rfc1738.txt - // Note especially that '%' and '/' are there. - std::string uri = LLURI::escape(mMediaURL, - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" - "0123456789" - "$-_.+" - "!*'()," - "{}|\\^~[]`" - "<>#%" - ";/?:@&=", - false); + // URI often comes unescaped + std::string uri = LLURI::escapePathAndData(mMediaURL); { // Do not log the query parts LLURI u(uri); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index ba68ce4cf4..aa6d75f5fb 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -4066,10 +4066,8 @@ void near_sit_down_point(BOOL success, void *) if (success) { gAgent.setFlying(FALSE); + gAgent.clearControlFlags(AGENT_CONTROL_STAND_UP); // might have been set by autopilot gAgent.setControlFlags(AGENT_CONTROL_SIT_ON_GROUND); - - // Might be first sit - //LLFirstUse::useSit(); } } diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 4308405c64..06524847d1 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -512,7 +512,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id, if (boost_priority != LLViewerTexture::BOOST_ALM && imagep->getBoostLevel() == LLViewerTexture::BOOST_ALM) { // Workaround: we need BOOST_ALM texture for something, 'rise' to NONE - imagep->setDecodePriority(LLViewerTexture::BOOST_NONE); + imagep->setBoostLevel(LLViewerTexture::BOOST_NONE); } LLViewerFetchedTexture *texture = imagep.get(); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 5b764f97fb..6d351f0639 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -3819,7 +3819,7 @@ void LLViewerWindow::renderSelections( BOOL for_gl_pick, BOOL pick_parcel_walls, BOOL draw_handles = TRUE; - if (tool == LLToolCompTranslate::getInstance() && !all_selected_objects_move) + if (tool == LLToolCompTranslate::getInstance() && !all_selected_objects_move && !LLSelectMgr::getInstance()->isSelfAvatarSelected()) { draw_handles = FALSE; } diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index c4430f4308..c63c5f6b23 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -99,6 +99,8 @@ void LLVLComposition::setDetailTextureID(S32 corner, const LLUUID& id) { return; } + // This is terrain texture, but we are not setting it as BOOST_TERRAIN + // since we will be manipulating it later as needed. mDetailTextures[corner] = LLViewerTextureManager::getFetchedTexture(id); mDetailTextures[corner]->setNoDelete() ; mRawImages[corner] = NULL; @@ -241,6 +243,7 @@ BOOL LLVLComposition::generateComposition() } mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail mDetailTextures[i]->setMinDiscardLevel(ddiscard); + mDetailTextures[i]->addTextureStats(BASE_SIZE*BASE_SIZE); // priority return FALSE; } } @@ -287,7 +290,7 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, { mDetailTextures[i]->destroyRawImage() ; } - LL_DEBUGS() << "cached raw data for terrain detail texture is not ready yet: " << mDetailTextures[i]->getID() << LL_ENDL; + LL_DEBUGS("Terrain") << "cached raw data for terrain detail texture is not ready yet: " << mDetailTextures[i]->getID() << " Discard: " << ddiscard << LL_ENDL; return FALSE; } @@ -323,12 +326,12 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, if (x_end > mWidth) { - LL_WARNS() << "x end > width" << LL_ENDL; + LL_WARNS("Terrain") << "x end > width" << LL_ENDL; x_end = mWidth; } if (y_end > mWidth) { - LL_WARNS() << "y end > width" << LL_ENDL; + LL_WARNS("Terrain") << "y end > width" << LL_ENDL; y_end = mWidth; } @@ -358,7 +361,7 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, if (tex_comps != st_comps) { - LL_WARNS() << "Base texture comps != input texture comps" << LL_ENDL; + LL_WARNS("Terrain") << "Base texture comps != input texture comps" << LL_ENDL; return FALSE; } diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index cf40058c34..2231bda33e 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -770,12 +770,16 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon() { #ifndef VIVOXDAEMON_REMOTEHOST // Launch the voice daemon - std::string exe_path = gDirUtilp->getAppRODataDir(); #if LL_WINDOWS + // On windows use exe (not work or RO) directory + std::string exe_path = gDirUtilp->getExecutableDir(); gDirUtilp->append(exe_path, "SLVoice.exe"); #elif LL_DARWIN + // On MAC use resource directory + std::string exe_path = gDirUtilp->getAppRODataDir(); gDirUtilp->append(exe_path, "SLVoice"); #else + std::string exe_path = gDirUtilp->getExecutableDir(); gDirUtilp->append(exe_path, "SLVoice"); #endif // See if the vivox executable exists 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 d04e738b22..51f455b1e3 100644 --- a/indra/newview/skins/default/xui/en/floater_about_land.xml +++ b/indra/newview/skins/default/xui/en/floater_about_land.xml @@ -163,6 +163,7 @@ layout="topleft" left_pad="2" name="Description" + spellcheck="true" top_delta="0" width="365" word_wrap="true" /> diff --git a/indra/newview/skins/default/xui/en/floater_experienceprofile.xml b/indra/newview/skins/default/xui/en/floater_experienceprofile.xml index 2dfba1ac44..f275fec066 100644 --- a/indra/newview/skins/default/xui/en/floater_experienceprofile.xml +++ b/indra/newview/skins/default/xui/en/floater_experienceprofile.xml @@ -493,6 +493,7 @@ layout="topleft" left="11" name="edit_experience_description" + spellcheck="true" max_length="2048" text_color="black" right="-11" diff --git a/indra/newview/skins/default/xui/en/floater_fast_timers.xml b/indra/newview/skins/default/xui/en/floater_fast_timers.xml index fa7147d9ca..645003cc14 100644 --- a/indra/newview/skins/default/xui/en/floater_fast_timers.xml +++ b/indra/newview/skins/default/xui/en/floater_fast_timers.xml @@ -60,10 +60,21 @@ min_width="100"> <panel top="0" left="0" - width="220" + width="204" height="440" name="legend" follows="all"/> + <scroll_bar + top ="0" + right="-1" + height="440" + width="15" + follows="top|right|bottom" + name="scroll_vert" + orientation="vertical" + step_size="16" + doc_size="3000" + /> </layout_panel> <layout_panel name="timers_panel" auto_resize="true" diff --git a/indra/newview/skins/default/xui/en/floater_gesture.xml b/indra/newview/skins/default/xui/en/floater_gesture.xml index 200e9b9537..9f051d9f8d 100644 --- a/indra/newview/skins/default/xui/en/floater_gesture.xml +++ b/indra/newview/skins/default/xui/en/floater_gesture.xml @@ -119,6 +119,7 @@ follows="left|bottom" height="23" label="Edit" + tool_tip="Open window for editing selected gesture." layout="topleft" left="6" name="edit_btn" @@ -128,6 +129,7 @@ follows="left|bottom" height="23" label="Play" + tool_tip="Execute selected gesture in-world." layout="topleft" left_pad="6" name="play_btn" diff --git a/indra/newview/skins/default/xui/en/floater_preview_notecard.xml b/indra/newview/skins/default/xui/en/floater_preview_notecard.xml index 2e1c8ce670..dcbdfa8794 100644 --- a/indra/newview/skins/default/xui/en/floater_preview_notecard.xml +++ b/indra/newview/skins/default/xui/en/floater_preview_notecard.xml @@ -6,7 +6,7 @@ height="361" layout="topleft" min_height="243" - min_width="234" + min_width="330" name="preview notecard" help_topic="preview_notecard" title="NOTECARD:" @@ -77,6 +77,16 @@ word_wrap="true"> Loading... </text_editor> + <button + follows="left|bottom" + height="22" + label="Edit..." + label_selected="Edit" + layout="topleft" + left="4" + name="Edit" + top="332" + width="100" /> <button follows="right|bottom" height="22" diff --git a/indra/newview/skins/default/xui/en/fonts.xml b/indra/newview/skins/default/xui/en/fonts.xml index 8b1d50e58f..87c39b1024 100644 --- a/indra/newview/skins/default/xui/en/fonts.xml +++ b/indra/newview/skins/default/xui/en/fonts.xml @@ -10,6 +10,7 @@ <file>simhei.ttf</file> <file>ArialUni.ttf</file> <file>msyh.ttc</file> + <file load_collection="true">Cambria.ttc</file> </os> <os name="Mac"> <file>ヒラギノ角ゴシック W3.ttc</file> @@ -21,6 +22,7 @@ <file>AppleSDGothicNeo-Regular.otf</file> <file>华文细黑.ttf</file> <file>PingFang.ttc</file> + <file>STIXGeneral.otf</file> </os> </font> diff --git a/indra/newview/skins/default/xui/en/panel_facebook_photo.xml b/indra/newview/skins/default/xui/en/panel_facebook_photo.xml index 22e6598352..97355f4689 100644 --- a/indra/newview/skins/default/xui/en/panel_facebook_photo.xml +++ b/indra/newview/skins/default/xui/en/panel_facebook_photo.xml @@ -138,6 +138,7 @@ length="1" max_length="700" name="photo_caption" + spellcheck="true" type="string" word_wrap="true"> </text_editor> diff --git a/indra/newview/skins/default/xui/en/panel_flickr_photo.xml b/indra/newview/skins/default/xui/en/panel_flickr_photo.xml index 6074ab9ef6..7fb2291423 100644 --- a/indra/newview/skins/default/xui/en/panel_flickr_photo.xml +++ b/indra/newview/skins/default/xui/en/panel_flickr_photo.xml @@ -158,6 +158,7 @@ length="1" max_length="700" name="photo_description" + spellcheck="true" type="string" word_wrap="true"> </text_editor> diff --git a/indra/newview/skins/default/xui/en/panel_group_general.xml b/indra/newview/skins/default/xui/en/panel_group_general.xml index 26f54bacbc..e34335a2af 100644 --- a/indra/newview/skins/default/xui/en/panel_group_general.xml +++ b/indra/newview/skins/default/xui/en/panel_group_general.xml @@ -214,7 +214,7 @@ Hover your mouse over the options for more help. layout="topleft" left="10" name="group_mature_check" - tool_tip="Sets whether your group contains information rated as Moderate" + tool_tip="Maturity ratings designate the type of content and behavior allowed in a group" top_pad="4" width="190"> <combo_item name="select_mature" value="Select"> 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 fd6e96b9a7..13986c4030 100644 --- a/indra/newview/skins/default/xui/en/panel_landmark_info.xml +++ b/indra/newview/skins/default/xui/en/panel_landmark_info.xml @@ -277,6 +277,7 @@ max_length="127" name="notes_editor" read_only="true" + spellcheck="true" text_readonly_color="white" text_type="ascii_with_newline" top_pad="5" diff --git a/indra/newview/skins/default/xui/en/panel_postcard_message.xml b/indra/newview/skins/default/xui/en/panel_postcard_message.xml index 331a08b4bb..63c7259878 100644 --- a/indra/newview/skins/default/xui/en/panel_postcard_message.xml +++ b/indra/newview/skins/default/xui/en/panel_postcard_message.xml @@ -80,6 +80,7 @@ left="5" max_length="700" name="msg_form" + spellcheck="true" right="-4" top_pad="5" word_wrap="true"> diff --git a/indra/newview/skins/default/xui/en/panel_region_terrain.xml b/indra/newview/skins/default/xui/en/panel_region_terrain.xml index 5d060c0a0d..8243c2715d 100644 --- a/indra/newview/skins/default/xui/en/panel_region_terrain.xml +++ b/indra/newview/skins/default/xui/en/panel_region_terrain.xml @@ -94,6 +94,7 @@ layout="topleft" left_delta="0" name="texture_detail_0" + default_image_id="0bc58228-74a0-7e83-89bc-5c23464bcec5" top_delta="20" width="100" /> <texture_picker @@ -102,6 +103,7 @@ layout="topleft" left_pad="10" name="texture_detail_1" + default_image_id="63338ede-0037-c4fd-855b-015d77112fc8" top_delta="0" width="100" /> <texture_picker @@ -110,6 +112,7 @@ layout="topleft" left_pad="10" name="texture_detail_2" + default_image_id="303cd381-8560-7579-23f1-f0a880799740" top_delta="0" width="100" /> <texture_picker @@ -118,6 +121,7 @@ layout="topleft" left_pad="10" name="texture_detail_3" + default_image_id="53a2f406-4895-1d13-d541-d2e3b86bc19c" top_delta="0" width="100" /> <text diff --git a/indra/newview/skins/default/xui/en/panel_snapshot_profile.xml b/indra/newview/skins/default/xui/en/panel_snapshot_profile.xml index d86cb92981..2fdbee49f0 100644 --- a/indra/newview/skins/default/xui/en/panel_snapshot_profile.xml +++ b/indra/newview/skins/default/xui/en/panel_snapshot_profile.xml @@ -126,6 +126,7 @@ length="1" max_length="700" name="caption" + spellcheck="true" width="200" top_pad="2" type="string" diff --git a/indra/newview/skins/default/xui/en/panel_twitter_photo.xml b/indra/newview/skins/default/xui/en/panel_twitter_photo.xml index 9a460ceead..8774d09a03 100644 --- a/indra/newview/skins/default/xui/en/panel_twitter_photo.xml +++ b/indra/newview/skins/default/xui/en/panel_twitter_photo.xml @@ -39,6 +39,7 @@ length="1" max_length="140" name="photo_status" + spellcheck="true" type="string" word_wrap="true"> </text_editor> diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 4dbafd27e0..e567e410bc 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -58,6 +58,9 @@ Advanced Lighting Model: [GPU_SHADERS] Texture memory: [TEXTURE_MEMORY]MB VFS (cache) creation time: [VFS_TIME] </string> + <string name="AboutOSXHiDPI"> +HiDPI display mode: [HIDPI] + </string> <string name="AboutLibs"> J2C Decoder Version: [J2C_VERSION] Audio Driver Version: [AUDIO_DRIVER_VERSION] @@ -2299,6 +2302,9 @@ For AI Character: Get the closest navigable point to the point provided. <string name="MarketplaceURL_Dashboard">https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/dashboard</string> <string name="MarketplaceURL_Imports">https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/imports</string> <string name="MarketplaceURL_LearnMore">https://marketplace.[MARKETPLACE_DOMAIN_NAME]/learn_more</string> + <string name="InventoryPlayAnimationTooltip">Open window with Play options.</string> + <string name="InventoryPlayGestureTooltip">Execute selected gesture in-world.</string> + <string name="InventoryPlaySoundTooltip">Open window with Play options.</string> <string name="InventoryOutboxNotMerchantTitle">Anyone can sell items on the Marketplace.</string> <string name="InventoryOutboxNotMerchantTooltip"></string> <string name="InventoryOutboxNotMerchant"> diff --git a/indra/newview/skins/default/xui/fr/notifications.xml b/indra/newview/skins/default/xui/fr/notifications.xml index 3ac2cfb69b..4239c949fd 100644 --- a/indra/newview/skins/default/xui/fr/notifications.xml +++ b/indra/newview/skins/default/xui/fr/notifications.xml @@ -2987,7 +2987,7 @@ Si vous restez dans cette région, vous serez déconnecté(e). Si vous restez dans cette région, vous serez déconnecté(e). </notification> <notification name="LoadWebPage"> - Charger la page Web [URL] ? +Charger la page Web [URL] ? [MESSAGE] |