diff options
Diffstat (limited to 'indra/newview')
91 files changed, 1272 insertions, 1418 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 17e340d136..c4886d5b73 100755 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -660,7 +660,6 @@ set(viewer_SOURCE_FILES llwearablelist.cpp llweb.cpp llwebprofile.cpp - llwebsharing.cpp llwind.cpp llwindowlistener.cpp llwlanimator.cpp @@ -1240,7 +1239,6 @@ set(viewer_HEADER_FILES llwearablelist.h llweb.h llwebprofile.h - llwebsharing.h llwind.h llwindowlistener.h llwlanimator.h diff --git a/indra/newview/SecondLife.nib b/indra/newview/SecondLife.nib Binary files differindex 8b99b5a770..c4ddca50dc 100644 --- a/indra/newview/SecondLife.nib +++ b/indra/newview/SecondLife.nib diff --git a/indra/newview/SecondLife.xib b/indra/newview/SecondLife.xib index 370df6bf5f..ef25c648a7 100644 --- a/indra/newview/SecondLife.xib +++ b/indra/newview/SecondLife.xib @@ -120,7 +120,7 @@ </object> <object class="NSMenuItem" id="755159360"> <reference key="NSMenu" ref="110575045"/> - <string key="NSTitle">Hide NewApplication</string> + <string key="NSTitle">Hide Second Life</string> <string key="NSKeyEquiv">h</string> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> diff --git a/indra/newview/app_settings/keys.xml b/indra/newview/app_settings/keys.xml index 6e3673e7d9..a8037fec05 100755 --- a/indra/newview/app_settings/keys.xml +++ b/indra/newview/app_settings/keys.xml @@ -293,11 +293,24 @@ <!--these are for passing controls when sitting on vehicles--> <binding key="A" mask="SHIFT" command="slide_left"/> <binding key="D" mask="SHIFT" command="slide_right"/> + <binding key="W" mask="SHIFT" command="move_forward_sitting"/> + <binding key="S" mask="SHIFT" command="move_backward_sitting"/> + <binding key="E" mask="SHIFT" command="spin_over_sitting"/> + <binding key="C" mask="SHIFT" command="spin_under_sitting"/> + <binding key="LEFT" mask="SHIFT" command="slide_left"/> <binding key="RIGHT" mask="SHIFT" command="slide_right"/> + <binding key="UP" mask="SHIFT" command="move_forward_sitting"/> + <binding key="DOWN" mask="SHIFT" command="move_backward_sitting"/> + <binding key="PGUP" mask="SHIFT" command="spin_over_sitting"/> + <binding key="PGDN" mask="SHIFT" command="spin_under_sitting"/> <binding key="PAD_LEFT" mask="SHIFT" command="slide_left"/> <binding key="PAD_RIGHT" mask="SHIFT" command="slide_right"/> + <binding key="PAD_UP" mask="SHIFT" command="move_forward_sitting"/> + <binding key="PAD_DOWN" mask="SHIFT" command="move_backward_sitting"/> + <binding key="PAD_PGUP" mask="SHIFT" command="spin_over_sitting"/> + <binding key="PAD_PGDN" mask="SHIFT" command="spin_under_sitting"/> <binding key="PAD_ENTER" mask="SHIFT" command="start_chat"/> <binding key="PAD_DIVIDE" mask="SHIFT" command="start_gesture"/> diff --git a/indra/newview/app_settings/keywords.ini b/indra/newview/app_settings/keywords.ini index ad843bca14..17c70ef1c5 100755 --- a/indra/newview/app_settings/keywords.ini +++ b/indra/newview/app_settings/keywords.ini @@ -526,6 +526,7 @@ REGION_FLAG_SANDBOX Used with llGetRegionFlags to find if a region is a sand REGION_FLAG_DISABLE_COLLISIONS Used with llGetRegionFlags to find if a region has disabled collisions REGION_FLAG_DISABLE_PHYSICS Used with llGetRegionFlags to find if a region has disabled physics REGION_FLAG_BLOCK_FLY Used with llGetRegionFlags to find if a region blocks flying +REGION_FLAG_BLOCK_FLYOVER Used with llGetRegionFlags to find if a region enforces higher altitude parcel access rules REGION_FLAG_ALLOW_DIRECT_TELEPORT Used with llGetRegionFlags to find if a region allows direct teleports REGION_FLAG_RESTRICT_PUSHOBJECT Used with llGetRegionFlags to find if a region restricts llPushObject() calls diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index d39bf6c3c2..2a01b81943 100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -11333,28 +11333,6 @@ <key>Value</key> <integer>75</integer> </map> - <key>SnapshotSharingEnabled</key> - <map> - <key>Comment</key> - <string>Enable uploading of snapshots to a web service.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> - <key>SnapshotConfigURL</key> - <map> - <key>Comment</key> - <string>URL to fetch Snapshot Sharing configuration data from.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>String</string> - <key>Value</key> - <string>http://photos.apps.staging.avatarsunited.com/viewer_config</string> - </map> <key>SpeedTest</key> <map> <key>Comment</key> @@ -14958,18 +14936,6 @@ <key>Value</key> <integer>7000</integer> </map> - <key>DisablePrecacheDelayAfterTeleporting</key> - <map> - <key>Comment</key> - <string>Disables the artificial delay in the viewer that precaches some incoming assets</string> - <key>Persist</key> - <integer>0</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> - <key>VersionChannelName</key> <map> <key>Comment</key> diff --git a/indra/newview/gpu_table.txt b/indra/newview/gpu_table.txt index 8efc4ee87d..badbe486b9 100755 --- a/indra/newview/gpu_table.txt +++ b/indra/newview/gpu_table.txt @@ -327,7 +327,8 @@ Intel HD Graphics 4600 .*Intel.*HD Graphics 46.* 3 1 0 4.2 Intel HD Graphics 4000 .*Intel.*HD Graphics 4.* 3 1 1 4.2 Intel Intel Iris Pro Graphics 5200 .*Intel.*Iris Pro Graphics 52.* 4 1 0 4 Intel Intel Iris Graphics 5100 .*Intel.*Iris Graphics 51.* 4 1 0 4 -Intel Intel Iris OpenGL Engine .*Intel.*Iris (Pro )*OpenGL.* 4 1 0 4 +Intel Intel Iris OpenGL Engine .*Intel.*Iris OpenGL.* 4 1 0 4 +Intel Intel Iris Pro OpenGL Engine .*Intel.*Iris Pro OpenGL.* 5 1 0 4 Intel HD Graphics 5000 .*Intel.*HD Graphics 5.* 4 1 0 4 Intel HD Graphics .*Intel.*HD Graphics.* 2 1 1 4 Intel Mobile 4 Series .*Intel.*Mobile.* 4 Series.* 0 1 1 2.1 diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi index c4f503ef4e..4ece83d85a 100755 --- a/indra/newview/installers/windows/installer_template.nsi +++ b/indra/newview/installers/windows/installer_template.nsi @@ -122,24 +122,8 @@ Var DO_UNINSTALL_V2 ; If non-null, path to a previous Viewer 2 installation ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Function .onInstSuccess
Push $R0 # Option value, unused
-
- StrCmp $SKIP_DIALOGS "true" label_launch
-
- ${GetOptions} $COMMANDLINE "/AUTOSTART" $R0
- # If parameter was there (no error) just launch
- # Otherwise ask
- IfErrors label_ask_launch label_launch
-
-label_ask_launch:
- # Don't launch by default when silent
- IfSilent label_no_launch
- MessageBox MB_YESNO $(InstSuccesssQuestion) \
- IDYES label_launch IDNO label_no_launch
-
-label_launch:
# Assumes SetOutPath $INSTDIR
Exec '"$INSTDIR\$INSTEXE" $SHORTCUT_LANG_PARAM'
-label_no_launch:
Pop $R0
FunctionEnd
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index e3c89f1a5f..b7a8194b4d 100755 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -3190,6 +3190,13 @@ bool LLAppViewer::initWindow() LLNotificationsUI::LLNotificationManager::getInstance(); + +#ifdef LL_DARWIN + //Satisfy both MAINT-3135 (OSX 10.6 and earlier) MAINT-3288 (OSX 10.7 and later) + if (getOSInfo().mMajorVer == 10 && getOSInfo().mMinorVer < 7) + gViewerWindow->getWindow()->setOldResize(true); +#endif + if (gSavedSettings.getBOOL("WindowMaximized")) { gViewerWindow->getWindow()->maximize(); diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h index d8cdcdfc97..dc74506c53 100644 --- a/indra/newview/llconversationmodel.h +++ b/indra/newview/llconversationmodel.h @@ -291,6 +291,9 @@ class LLConversationViewModel { public: typedef LLFolderViewModel<LLConversationSort, LLConversationItem, LLConversationItem, LLConversationFilter> base_t; + LLConversationViewModel() + : base_t(new LLConversationSort(), new LLConversationFilter()) + {} void sort(LLFolderViewFolder* folder); bool contentsReady() { return true; } // *TODO : we need to check that participants names are available somewhat diff --git a/indra/newview/lldeferredsounds.cpp b/indra/newview/lldeferredsounds.cpp index 9416e7cd29..e1613e4719 100755 --- a/indra/newview/lldeferredsounds.cpp +++ b/indra/newview/lldeferredsounds.cpp @@ -39,7 +39,10 @@ void LLDeferredSounds::playdeferredSounds() { while(soundVector.size()) { - gAudiop->triggerSound(soundVector.back()); + if (gAudiop) + { + gAudiop->triggerSound(soundVector.back()); + } soundVector.pop_back(); } } diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index 6b4c5cfca1..49ac82e786 100755 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -1232,6 +1232,7 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI //if (iter->second->getWidth() != src->getWidth() || // iter->second->getHeight() != src->getHeight()) // bump not cached yet or has changed resolution + if (src->getData()) { LLPointer<LLImageRaw> dst_image = new LLImageRaw(src->getWidth(), src->getHeight(), 1); U8* dst_data = dst_image->getData(); diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index c3ec234223..d7ecacf2e6 100755 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -88,8 +88,11 @@ LLDrawPoolTerrain::LLDrawPoolTerrain(LLViewerTexture *texturep) : //gGL.getTexUnit(0)->bind(m2DAlphaRampImagep.get()); m2DAlphaRampImagep->setAddressMode(LLTexUnit::TAM_CLAMP); - mTexturep->setBoostLevel(LLGLTexture::BOOST_TERRAIN); - + if (mTexturep) + { + mTexturep->setBoostLevel(LLGLTexture::BOOST_TERRAIN); + } + //gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); } @@ -851,11 +854,18 @@ void LLDrawPoolTerrain::renderSimple() // Pass 1/1 // Stage 0: Base terrain texture pass - mTexturep->addTextureStats(1024.f*1024.f); + if (mTexturep) + { + mTexturep->addTextureStats(1024.f*1024.f); + } gGL.getTexUnit(0)->activate(); gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(0)->bind(mTexturep); + + if (mTexturep) + { + gGL.getTexUnit(0)->bind(mTexturep); + } LLVector3 origin_agent = mDrawFace[0]->getDrawable()->getVObj()->getRegion()->getOriginAgent(); F32 tscale = 1.f/256.f; diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp index 16eacc9392..057acf69b9 100755 --- a/indra/newview/llfilepicker.cpp +++ b/indra/newview/llfilepicker.cpp @@ -570,6 +570,7 @@ std::vector<std::string>* LLFilePicker::navOpenFilterProc(ELoadFilter filter) // allowedv->push_back("lsl"); allowedv->push_back("dic"); allowedv->push_back("xcu"); + allowedv->push_back("gif"); case FFLOAD_IMAGE: allowedv->push_back("jpg"); allowedv->push_back("jpeg"); @@ -661,7 +662,7 @@ bool LLFilePicker::doNavSaveDialog(ESaveFilter filter, const std::string& filena case FFSAVE_TGAPNG: type = "PNG"; creator = "prvw"; - extension = "png"; + extension = "png,tga"; break; case FFSAVE_BMP: type = "BMPf"; @@ -779,7 +780,7 @@ BOOL LLFilePicker::getOpenFile(ELoadFilter filter, bool blocking) if(filter == FFLOAD_ALL) // allow application bundles etc. to be traversed; important for DEV-16869, but generally useful { - mPickOptions &= F_NAV_SUPPORT; + mPickOptions |= F_NAV_SUPPORT; } if (blocking) diff --git a/indra/newview/llfilepicker_mac.mm b/indra/newview/llfilepicker_mac.mm index 13757904e3..1438e4dc0a 100644 --- a/indra/newview/llfilepicker_mac.mm +++ b/indra/newview/llfilepicker_mac.mm @@ -107,7 +107,7 @@ std::string* doSaveDialog(const std::string* file, NSSavePanel *panel = [NSSavePanel savePanel]; NSString *extensionns = [NSString stringWithCString:extension->c_str() encoding:[NSString defaultCStringEncoding]]; - NSArray *fileType = [[NSArray alloc] initWithObjects:extensionns,nil]; + NSArray *fileType = [extensionns componentsSeparatedByString:@","]; //[panel setMessage:@"Save Image File"]; [panel setTreatsFilePackagesAsDirectories: ( flags & F_NAV_SUPPORT ) ]; diff --git a/indra/newview/llfloaterconversationpreview.cpp b/indra/newview/llfloaterconversationpreview.cpp index a303c2c6b3..a358b7c10b 100755 --- a/indra/newview/llfloaterconversationpreview.cpp +++ b/indra/newview/llfloaterconversationpreview.cpp @@ -32,6 +32,7 @@ #include "llfloaterimnearbychat.h" #include "llspinctrl.h" #include "lltrans.h" +#include "llnotificationsutil.h" const std::string LL_FCP_COMPLETE_NAME("complete_name"); const std::string LL_FCP_ACCOUNT_NAME("user_name"); @@ -45,14 +46,20 @@ LLFloaterConversationPreview::LLFloaterConversationPreview(const LLSD& session_i mAccountName(session_id[LL_FCP_ACCOUNT_NAME]), mCompleteName(session_id[LL_FCP_COMPLETE_NAME]), mMutex(NULL), - mShowHistory(false) + mShowHistory(false), + mMessages(NULL), + mHistoryThreadsBusy(false), + mOpened(false) +{ +} + +LLFloaterConversationPreview::~LLFloaterConversationPreview() { } BOOL LLFloaterConversationPreview::postBuild() { mChatHistory = getChild<LLChatHistory>("chat_history"); - LLLoadHistoryThread::setLoadEndSignal(boost::bind(&LLFloaterConversationPreview::setPages, this, _1, _2)); const LLConversation* conv = LLConversationLog::instance().getConversation(mSessionID); std::string name; @@ -79,31 +86,21 @@ BOOL LLFloaterConversationPreview::postBuild() std::string title = getString("Title", args); setTitle(title); - LLSD load_params; - load_params["load_all_history"] = true; - load_params["cut_off_todays_date"] = false; - - - LLSD loading; - loading[LL_IM_TEXT] = LLTrans::getString("loading_chat_logs"); - mMessages.push_back(loading); - mPageSpinner = getChild<LLSpinCtrl>("history_page_spin"); - mPageSpinner->setCommitCallback(boost::bind(&LLFloaterConversationPreview::onMoreHistoryBtnClick, this)); - mPageSpinner->setMinValue(1); - mPageSpinner->set(1); - mPageSpinner->setEnabled(false); - LLLogChat::startChatHistoryThread(file, load_params); return LLFloater::postBuild(); } -void LLFloaterConversationPreview::setPages(std::list<LLSD>& messages,const std::string& file_name) +void LLFloaterConversationPreview::setPages(std::list<LLSD>* messages, const std::string& file_name) { - if(file_name == mChatHistoryFileName) + if(file_name == mChatHistoryFileName && messages) { // additional protection to avoid changes of mMessages in setPages() LLMutexLock lock(&mMutex); + if (mMessages) + { + delete mMessages; // Clean up temporary message list with "Loading..." text + } mMessages = messages; - mCurrentPage = (mMessages.size() ? (mMessages.size() - 1) / mPageSize : 0); + mCurrentPage = (mMessages->size() ? (mMessages->size() - 1) / mPageSize : 0); mPageSpinner->setEnabled(true); mPageSpinner->setMaxValue(mCurrentPage+1); @@ -113,6 +110,11 @@ void LLFloaterConversationPreview::setPages(std::list<LLSD>& messages,const std: getChild<LLTextBox>("page_num_label")->setValue(total_page_num); mShowHistory = true; } + LLLoadHistoryThread* loadThread = LLLogChat::getLoadHistoryThread(mSessionID); + if (loadThread) + { + loadThread->removeLoadEndSignal(boost::bind(&LLFloaterConversationPreview::setPages, this, _1, _2)); + } } void LLFloaterConversationPreview::draw() @@ -127,24 +129,82 @@ void LLFloaterConversationPreview::draw() void LLFloaterConversationPreview::onOpen(const LLSD& key) { + if (mOpened) + { + return; + } + mOpened = true; + if (!LLLogChat::historyThreadsFinished(mSessionID)) + { + LLNotificationsUtil::add("ChatHistoryIsBusyAlert"); + mHistoryThreadsBusy = true; + closeFloater(); + return; + } + LLSD load_params; + load_params["load_all_history"] = true; + load_params["cut_off_todays_date"] = false; + + // The temporary message list with "Loading..." text + // Will be deleted upon loading completion in setPages() method + mMessages = new std::list<LLSD>(); + + + LLSD loading; + loading[LL_IM_TEXT] = LLTrans::getString("loading_chat_logs"); + mMessages->push_back(loading); + mPageSpinner = getChild<LLSpinCtrl>("history_page_spin"); + mPageSpinner->setCommitCallback(boost::bind(&LLFloaterConversationPreview::onMoreHistoryBtnClick, this)); + mPageSpinner->setMinValue(1); + mPageSpinner->set(1); + mPageSpinner->setEnabled(false); + + // The actual message list to load from file + // Will be deleted in a separate thread LLDeleteHistoryThread not to freeze UI + // LLDeleteHistoryThread is started in destructor + std::list<LLSD>* messages = new std::list<LLSD>(); + + LLLogChat::cleanupHistoryThreads(); + + LLLoadHistoryThread* loadThread = new LLLoadHistoryThread(mChatHistoryFileName, messages, load_params); + loadThread->setLoadEndSignal(boost::bind(&LLFloaterConversationPreview::setPages, this, _1, _2)); + loadThread->start(); + LLLogChat::addLoadHistoryThread(mSessionID, loadThread); + + LLDeleteHistoryThread* deleteThread = new LLDeleteHistoryThread(messages, loadThread); + LLLogChat::addDeleteHistoryThread(mSessionID, deleteThread); + mShowHistory = true; } +void LLFloaterConversationPreview::onClose(bool app_quitting) +{ + mOpened = false; + if (!mHistoryThreadsBusy) + { + LLDeleteHistoryThread* deleteThread = LLLogChat::getDeleteHistoryThread(mSessionID); + if (deleteThread) + { + deleteThread->start(); + } + } +} + void LLFloaterConversationPreview::showHistory() { // additional protection to avoid changes of mMessages in setPages LLMutexLock lock(&mMutex); - if (!mMessages.size() || mCurrentPage * mPageSize >= mMessages.size()) + if(mMessages == NULL || !mMessages->size() || mCurrentPage * mPageSize >= mMessages->size()) { return; } mChatHistory->clear(); std::ostringstream message; - std::list<LLSD>::const_iterator iter = mMessages.begin(); + std::list<LLSD>::const_iterator iter = mMessages->begin(); std::advance(iter, mCurrentPage * mPageSize); - for (int msg_num = 0; iter != mMessages.end() && msg_num < mPageSize; ++iter, ++msg_num) + for (int msg_num = 0; iter != mMessages->end() && msg_num < mPageSize; ++iter, ++msg_num) { LLSD msg = *iter; diff --git a/indra/newview/llfloaterconversationpreview.h b/indra/newview/llfloaterconversationpreview.h index b0488f4ff1..a8dbbc9ffe 100755 --- a/indra/newview/llfloaterconversationpreview.h +++ b/indra/newview/llfloaterconversationpreview.h @@ -39,13 +39,14 @@ class LLFloaterConversationPreview : public LLFloater public: LLFloaterConversationPreview(const LLSD& session_id); - virtual ~LLFloaterConversationPreview(){}; + virtual ~LLFloaterConversationPreview(); virtual BOOL postBuild(); - void setPages(std::list<LLSD>& messages,const std::string& file_name); + void setPages(std::list<LLSD>* messages,const std::string& file_name); virtual void draw(); virtual void onOpen(const LLSD& key); + virtual void onClose(bool app_quitting); private: void onMoreHistoryBtnClick(); @@ -58,11 +59,13 @@ private: int mCurrentPage; int mPageSize; - std::list<LLSD> mMessages; + std::list<LLSD>* mMessages; std::string mAccountName; std::string mCompleteName; - std::string mChatHistoryFileName; + std::string mChatHistoryFileName; bool mShowHistory; + bool mHistoryThreadsBusy; + bool mOpened; }; #endif /* LLFLOATERCONVERSATIONPREVIEW_H_ */ diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp index 566f9bc9cc..bb4b9d2d40 100755 --- a/indra/newview/llfloaterimcontainer.cpp +++ b/indra/newview/llfloaterimcontainer.cpp @@ -1318,7 +1318,12 @@ bool LLFloaterIMContainer::enableContextMenuItem(const std::string& item, uuid_v // Extract the single select info bool is_single_select = (uuids.size() == 1); const LLUUID& single_id = uuids.front(); - + + if ("can_chat_history" == item && is_single_select) + { + return LLLogChat::isTranscriptExist(uuids.front(),false); + } + // Handle options that are applicable to all including the user agent if ("can_view_profile" == item) { diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp index 84921849d0..d94dd85bce 100755 --- a/indra/newview/llfloaterimsession.cpp +++ b/indra/newview/llfloaterimsession.cpp @@ -714,7 +714,7 @@ void LLFloaterIMSession::setVisible(BOOL visible) if (visible && isInVisibleChain()) { sIMFloaterShowedSignal(mSessionID); - + updateMessages(); } } diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index b16ef6dd79..d79eee6be3 100755 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -2336,7 +2336,7 @@ BOOL LLPanelLandAccess::postBuild() childSetCommitCallback("public_access", onCommitPublicAccess, this); childSetCommitCallback("limit_payment", onCommitAny, this); childSetCommitCallback("limit_age_verified", onCommitAny, this); - childSetCommitCallback("GroupCheck", onCommitAny, this); + childSetCommitCallback("GroupCheck", onCommitGroupCheck, this); childSetCommitCallback("PassCheck", onCommitAny, this); childSetCommitCallback("pass_combo", onCommitAny, this); childSetCommitCallback("PriceSpin", onCommitAny, this); @@ -2501,11 +2501,11 @@ void LLPanelLandAccess::refresh() } BOOL use_pass = parcel->getParcelFlag(PF_USE_PASS_LIST); - getChild<LLUICtrl>("PassCheck")->setValue(use_pass ); + getChild<LLUICtrl>("PassCheck")->setValue(use_pass); LLCtrlSelectionInterface* passcombo = childGetSelectionInterface("pass_combo"); if (passcombo) { - if (public_access || !use_pass || !use_group) + if (public_access || !use_pass) { passcombo->selectByValue("anyone"); } @@ -2598,12 +2598,11 @@ void LLPanelLandAccess::refresh_ui() getChildView("limit_age_verified")->setEnabled(FALSE); - BOOL group_access = getChild<LLUICtrl>("GroupCheck")->getValue().asBoolean(); BOOL sell_passes = getChild<LLUICtrl>("PassCheck")->getValue().asBoolean(); getChildView("PassCheck")->setEnabled(can_manage_allowed); if (sell_passes) { - getChildView("pass_combo")->setEnabled(group_access && can_manage_allowed); + getChildView("pass_combo")->setEnabled(can_manage_allowed); getChildView("PriceSpin")->setEnabled(can_manage_allowed); getChildView("HoursSpin")->setEnabled(can_manage_allowed); } @@ -2662,6 +2661,32 @@ void LLPanelLandAccess::onCommitPublicAccess(LLUICtrl *ctrl, void *userdata) onCommitAny(ctrl, userdata); } +void LLPanelLandAccess::onCommitGroupCheck(LLUICtrl *ctrl, void *userdata) +{ + LLPanelLandAccess *self = (LLPanelLandAccess *)userdata; + LLParcel* parcel = self->mParcel->getParcel(); + if (!parcel) + { + return; + } + + BOOL use_pass_list = !self->getChild<LLUICtrl>("public_access")->getValue().asBoolean(); + BOOL use_access_group = self->getChild<LLUICtrl>("GroupCheck")->getValue().asBoolean(); + LLCtrlSelectionInterface* passcombo = self->childGetSelectionInterface("pass_combo"); + if (passcombo) + { + if (use_access_group && use_pass_list) + { + if (passcombo->getSelectedValue().asString() == "group") + { + passcombo->selectByValue("anyone"); + } + } + } + + onCommitAny(ctrl, userdata); +} + // static void LLPanelLandAccess::onCommitAny(LLUICtrl *ctrl, void *userdata) { @@ -2699,14 +2724,14 @@ void LLPanelLandAccess::onCommitAny(LLUICtrl *ctrl, void *userdata) { use_access_list = TRUE; use_pass_list = self->getChild<LLUICtrl>("PassCheck")->getValue().asBoolean(); - if (use_access_group && use_pass_list) + LLCtrlSelectionInterface* passcombo = self->childGetSelectionInterface("pass_combo"); + if (passcombo) { - LLCtrlSelectionInterface* passcombo = self->childGetSelectionInterface("pass_combo"); - if (passcombo) + if (use_access_group && use_pass_list) { if (passcombo->getSelectedValue().asString() == "group") { - use_access_list = FALSE; + use_access_group = FALSE; } } } diff --git a/indra/newview/llfloaterland.h b/indra/newview/llfloaterland.h index 4f1c10274a..95612fcb4a 100755 --- a/indra/newview/llfloaterland.h +++ b/indra/newview/llfloaterland.h @@ -366,6 +366,7 @@ public: static void onCommitPublicAccess(LLUICtrl* ctrl, void *userdata); static void onCommitAny(LLUICtrl* ctrl, void *userdata); + static void onCommitGroupCheck(LLUICtrl* ctrl, void *userdata); static void onClickRemoveAccess(void*); static void onClickRemoveBanned(void*); diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 73c0963a1d..cc0f246d1b 100755 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -366,6 +366,7 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg) panel->getChild<LLUICtrl>("block_terraform_check")->setValue((region_flags & REGION_FLAGS_BLOCK_TERRAFORM) ? TRUE : FALSE ); panel->getChild<LLUICtrl>("block_fly_check")->setValue((region_flags & REGION_FLAGS_BLOCK_FLY) ? TRUE : FALSE ); + panel->getChild<LLUICtrl>("block_fly_over_check")->setValue((region_flags & REGION_FLAGS_BLOCK_FLYOVER) ? TRUE : FALSE ); panel->getChild<LLUICtrl>("allow_damage_check")->setValue((region_flags & REGION_FLAGS_ALLOW_DAMAGE) ? TRUE : FALSE ); panel->getChild<LLUICtrl>("restrict_pushobject")->setValue((region_flags & REGION_FLAGS_RESTRICT_PUSHOBJECT) ? TRUE : FALSE ); panel->getChild<LLUICtrl>("allow_land_resell_check")->setValue((region_flags & REGION_FLAGS_BLOCK_LAND_RESELL) ? FALSE : TRUE ); @@ -635,6 +636,7 @@ BOOL LLPanelRegionGeneralInfo::postBuild() // Enable the "Apply" button if something is changed. JC initCtrl("block_terraform_check"); initCtrl("block_fly_check"); + initCtrl("block_fly_over_check"); initCtrl("allow_damage_check"); initCtrl("allow_land_resell_check"); initCtrl("allow_parcel_changes_check"); @@ -816,6 +818,7 @@ BOOL LLPanelRegionGeneralInfo::sendUpdate() { body["block_terraform"] = getChild<LLUICtrl>("block_terraform_check")->getValue(); body["block_fly"] = getChild<LLUICtrl>("block_fly_check")->getValue(); + body["block_fly_over"] = getChild<LLUICtrl>("block_fly_over_check")->getValue(); body["allow_damage"] = getChild<LLUICtrl>("allow_damage_check")->getValue(); body["allow_land_resell"] = getChild<LLUICtrl>("allow_land_resell_check")->getValue(); body["agent_limit"] = getChild<LLUICtrl>("agent_limit_spin")->getValue(); @@ -891,6 +894,7 @@ BOOL LLPanelRegionDebugInfo::postBuild() childSetAction("top_scripts_btn", onClickTopScripts, this); childSetAction("restart_btn", onClickRestart, this); childSetAction("cancel_restart_btn", onClickCancelRestart, this); + childSetAction("region_debug_console_btn", onClickDebugConsole, this); return TRUE; } @@ -912,6 +916,7 @@ bool LLPanelRegionDebugInfo::refreshFromRegion(LLViewerRegion* region) getChildView("top_scripts_btn")->setEnabled(allow_modify); getChildView("restart_btn")->setEnabled(allow_modify); getChildView("cancel_restart_btn")->setEnabled(allow_modify); + getChildView("region_debug_console_btn")->setEnabled(allow_modify); return LLPanelRegionInfo::refreshFromRegion(region); } @@ -1074,6 +1079,11 @@ void LLPanelRegionDebugInfo::onClickCancelRestart(void* data) self->sendEstateOwnerMessage(gMessageSystem, "restart", invoice, strings); } +// static +void LLPanelRegionDebugInfo::onClickDebugConsole(void* data) +{ + LLFloaterReg::showInstance("region_debug_console"); +} BOOL LLPanelRegionTerrainInfo::validateTextureSizes() { diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h index f0499f1903..bf174f3700 100755 --- a/indra/newview/llfloaterregioninfo.h +++ b/indra/newview/llfloaterregioninfo.h @@ -209,6 +209,7 @@ protected: static void onClickRestart(void* data); bool callbackRestart(const LLSD& notification, const LLSD& response); static void onClickCancelRestart(void* data); + static void onClickDebugConsole(void* data); private: LLUUID mTargetAvatar; diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp index ea385d7baf..d9835292a1 100755 --- a/indra/newview/llfloatersnapshot.cpp +++ b/indra/newview/llfloatersnapshot.cpp @@ -44,7 +44,6 @@ #include "lltoolfocus.h" #include "lltoolmgr.h" #include "llwebprofile.h" -#include "llwebsharing.h" ///---------------------------------------------------------------------------- /// Local function declarations, constants, enums, and typedefs @@ -360,10 +359,6 @@ void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater) ESnapshotFormat shot_format = (ESnapshotFormat)gSavedSettings.getS32("SnapshotFormat"); LLViewerWindow::ESnapshotType layer_type = getLayerType(floater); -#if 0 - floater->getChildView("share_to_web")->setVisible( gSavedSettings.getBOOL("SnapshotSharingEnabled")); -#endif - floater->getChild<LLComboBox>("local_format_combo")->selectNthItem(gSavedSettings.getS32("SnapshotFormat")); enableAspectRatioCheckbox(floater, !floater->impl.mAspectRatioCheckOff); setAspectRatioCheckboxValue(floater, gSavedSettings.getBOOL("KeepAspectForSnapshot")); @@ -1032,12 +1027,6 @@ LLFloaterSnapshot::~LLFloaterSnapshot() BOOL LLFloaterSnapshot::postBuild() { - // Kick start Web Sharing, to fetch its config data if it needs to. - if (gSavedSettings.getBOOL("SnapshotSharingEnabled")) - { - LLWebSharing::instance().init(); - } - mRefreshBtn = getChild<LLUICtrl>("new_snapshot_btn"); childSetAction("new_snapshot_btn", Impl::onClickNewSnapshot, this); mRefreshLabel = getChild<LLUICtrl>("refresh_lbl"); @@ -1263,7 +1252,7 @@ S32 LLFloaterSnapshot::notify(const LLSD& info) //static void LLFloaterSnapshot::update() { - LLFloaterSnapshot* inst = LLFloaterReg::findTypedInstance<LLFloaterSnapshot>("snapshot"); + LLFloaterSnapshot* inst = findInstance(); LLFloaterSocial* floater_social = LLFloaterReg::findTypedInstance<LLFloaterSocial>("social"); if (!inst && !floater_social) @@ -1291,12 +1280,18 @@ LLFloaterSnapshot* LLFloaterSnapshot::getInstance() } // static +LLFloaterSnapshot* LLFloaterSnapshot::findInstance() +{ + return LLFloaterReg::findTypedInstance<LLFloaterSnapshot>("snapshot"); +} + +// static void LLFloaterSnapshot::saveTexture() { lldebugs << "saveTexture" << llendl; // FIXME: duplicated code - LLFloaterSnapshot* instance = LLFloaterReg::findTypedInstance<LLFloaterSnapshot>("snapshot"); + LLFloaterSnapshot* instance = findInstance(); if (!instance) { llassert(instance != NULL); @@ -1317,7 +1312,7 @@ BOOL LLFloaterSnapshot::saveLocal() { lldebugs << "saveLocal" << llendl; // FIXME: duplicated code - LLFloaterSnapshot* instance = LLFloaterReg::findTypedInstance<LLFloaterSnapshot>("snapshot"); + LLFloaterSnapshot* instance = findInstance(); if (!instance) { llassert(instance != NULL); @@ -1337,7 +1332,7 @@ BOOL LLFloaterSnapshot::saveLocal() void LLFloaterSnapshot::preUpdate() { // FIXME: duplicated code - LLFloaterSnapshot* instance = LLFloaterReg::findTypedInstance<LLFloaterSnapshot>("snapshot"); + LLFloaterSnapshot* instance = findInstance(); if (instance) { // Disable the send/post/save buttons until snapshot is ready. @@ -1352,7 +1347,7 @@ void LLFloaterSnapshot::preUpdate() void LLFloaterSnapshot::postUpdate() { // FIXME: duplicated code - LLFloaterSnapshot* instance = LLFloaterReg::findTypedInstance<LLFloaterSnapshot>("snapshot"); + LLFloaterSnapshot* instance = findInstance(); if (instance) { // Enable the send/post/save buttons. @@ -1373,7 +1368,7 @@ void LLFloaterSnapshot::postUpdate() // static void LLFloaterSnapshot::postSave() { - LLFloaterSnapshot* instance = LLFloaterReg::findTypedInstance<LLFloaterSnapshot>("snapshot"); + LLFloaterSnapshot* instance = findInstance(); if (!instance) { llassert(instance != NULL); @@ -1399,7 +1394,7 @@ LLPointer<LLImageFormatted> LLFloaterSnapshot::getImageData() { // FIXME: May not work for textures. - LLFloaterSnapshot* instance = LLFloaterReg::findTypedInstance<LLFloaterSnapshot>("snapshot"); + LLFloaterSnapshot* instance = findInstance(); if (!instance) { llassert(instance != NULL); @@ -1426,7 +1421,7 @@ LLPointer<LLImageFormatted> LLFloaterSnapshot::getImageData() // static const LLVector3d& LLFloaterSnapshot::getPosTakenGlobal() { - LLFloaterSnapshot* instance = LLFloaterReg::findTypedInstance<LLFloaterSnapshot>("snapshot"); + LLFloaterSnapshot* instance = findInstance(); if (!instance) { llassert(instance != NULL); @@ -1446,7 +1441,7 @@ const LLVector3d& LLFloaterSnapshot::getPosTakenGlobal() // static void LLFloaterSnapshot::setAgentEmail(const std::string& email) { - LLFloaterSnapshot* instance = LLFloaterReg::findTypedInstance<LLFloaterSnapshot>("snapshot"); + LLFloaterSnapshot* instance = findInstance(); if (instance) { LLSideTrayPanelContainer* panel_container = instance->getChild<LLSideTrayPanelContainer>("panel_container"); diff --git a/indra/newview/llfloatersnapshot.h b/indra/newview/llfloatersnapshot.h index 82af8c7a9d..c757bf21c2 100755 --- a/indra/newview/llfloatersnapshot.h +++ b/indra/newview/llfloatersnapshot.h @@ -56,6 +56,7 @@ public: // TODO: create a snapshot model instead static LLFloaterSnapshot* getInstance(); + static LLFloaterSnapshot* findInstance(); static void saveTexture(); static BOOL saveLocal(); static void preUpdate(); diff --git a/indra/newview/llfolderviewmodelinventory.h b/indra/newview/llfolderviewmodelinventory.h index 9dcfdfa185..8772185ad0 100755 --- a/indra/newview/llfolderviewmodelinventory.h +++ b/indra/newview/llfolderviewmodelinventory.h @@ -105,6 +105,10 @@ class LLFolderViewModelInventory public: typedef LLFolderViewModel<LLInventorySort, LLFolderViewModelItemInventory, LLFolderViewModelItemInventory, LLInventoryFilter> base_t; + LLFolderViewModelInventory(const std::string& name) + : base_t(new LLInventorySort(), new LLInventoryFilter(LLInventoryFilter::Params().name(name))) + {} + void setTaskID(const LLUUID& id) {mTaskID = id;} void sort(LLFolderViewFolder* folder); diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp index b56c34573d..2ae13b1b2f 100755 --- a/indra/newview/llgesturemgr.cpp +++ b/indra/newview/llgesturemgr.cpp @@ -1339,6 +1339,7 @@ BOOL LLGestureMgr::matchPrefix(const std::string& in_str, std::string* out_str) { S32 in_len = in_str.length(); + //return whole trigger, if received text equals to it item_map_t::iterator it; for (it = mActive.begin(); it != mActive.end(); ++it) { @@ -1346,7 +1347,24 @@ BOOL LLGestureMgr::matchPrefix(const std::string& in_str, std::string* out_str) if (gesture) { const std::string& trigger = gesture->getTrigger(); - + if (!LLStringUtil::compareInsensitive(in_str, trigger)) + { + *out_str = trigger; + return TRUE; + } + } + } + + //return common chars, if more than one trigger matches the prefix + std::string rest_of_match = ""; + std::string buf = ""; + for (it = mActive.begin(); it != mActive.end(); ++it) + { + LLMultiGesture* gesture = (*it).second; + if (gesture) + { + const std::string& trigger = gesture->getTrigger(); + if (in_len > (S32)trigger.length()) { // too short, bail out @@ -1357,11 +1375,49 @@ BOOL LLGestureMgr::matchPrefix(const std::string& in_str, std::string* out_str) LLStringUtil::truncate(trigger_trunc, in_len); if (!LLStringUtil::compareInsensitive(in_str, trigger_trunc)) { - *out_str = trigger; - return TRUE; + if (rest_of_match.compare("") == 0) + { + rest_of_match = trigger.substr(in_str.size()); + } + std::string cur_rest_of_match = trigger.substr(in_str.size()); + buf = ""; + S32 i=0; + + while (i<rest_of_match.length() && i<cur_rest_of_match.length()) + { + if (rest_of_match[i]==cur_rest_of_match[i]) + { + buf.push_back(rest_of_match[i]); + } + else + { + if(i==0) + { + rest_of_match = ""; + } + break; + } + i++; + } + if (rest_of_match.compare("") == 0) + { + return FALSE; + } + if (buf.compare("") != 0) + { + rest_of_match = buf; + } + } } } + + if (rest_of_match.compare("") != 0) + { + *out_str = in_str+rest_of_match; + return TRUE; + } + return FALSE; } diff --git a/indra/newview/llgiveinventory.cpp b/indra/newview/llgiveinventory.cpp index 72bea8db10..0dd84b6073 100755 --- a/indra/newview/llgiveinventory.cpp +++ b/indra/newview/llgiveinventory.cpp @@ -139,7 +139,7 @@ bool LLGiveInventory::isInventoryGiveAcceptable(const LLInventoryItem* item) BOOL copyable = false; if (item->getPermissions().allowCopyBy(gAgentID)) copyable = true; - if (!copyable && get_is_item_worn(item->getUUID())) + if (!copyable || get_is_item_worn(item->getUUID())) { acceptable = false; } diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp index c4c1827266..cf550e5eff 100755 --- a/indra/newview/llglsandbox.cpp +++ b/indra/newview/llglsandbox.cpp @@ -624,7 +624,8 @@ void LLViewerParcelMgr::renderCollisionSegments(U8* segments, BOOL use_pass, LLV LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); LLGLDisable cull(GL_CULL_FACE); - if (mCollisionBanned == BA_BANNED) + if (mCollisionBanned == BA_BANNED || + regionp->getRegionFlag(REGION_FLAGS_BLOCK_FLYOVER)) { collision_height = BAN_HEIGHT; } diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp index 7ea08539f9..9c0b486cc5 100755 --- a/indra/newview/llgroupmgr.cpp +++ b/indra/newview/llgroupmgr.cpp @@ -609,6 +609,11 @@ void LLGroupMgrGroupData::recalcAgentPowers(const LLUUID& agent_id) } } +bool LLGroupMgrGroupData::isSingleMemberNotOwner() +{ + return mMembers.size() == 1 && !mMembers.begin()->second->isOwner(); +} + bool packRoleUpdateMessageBlock(LLMessageSystem* msg, const LLUUID& group_id, const LLUUID& role_id, diff --git a/indra/newview/llgroupmgr.h b/indra/newview/llgroupmgr.h index d8c1ab7ef5..1750551395 100755 --- a/indra/newview/llgroupmgr.h +++ b/indra/newview/llgroupmgr.h @@ -232,6 +232,8 @@ public: BOOL isRoleDataComplete() { return mRoleDataComplete; } BOOL isRoleMemberDataComplete() { return mRoleMemberDataComplete; } BOOL isGroupPropertiesDataComplete() { return mGroupPropertiesDataComplete; } + + bool isSingleMemberNotOwner(); F32 getAccessTime() const { return mAccessTime; } void setAccessed(); diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index e5b9e11d48..d27f7d2527 100755 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -146,7 +146,8 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) : mShowItemLinkOverlays(p.show_item_link_overlays), mShowEmptyMessage(p.show_empty_message), mViewsInitialized(false), - mInvFVBridgeBuilder(NULL) + mInvFVBridgeBuilder(NULL), + mInventoryViewModel(p.name) { mInvFVBridgeBuilder = &INVENTORY_BRIDGE_BUILDER; diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp index 90b169ecd3..d0ecf80706 100755 --- a/indra/newview/lllogchat.cpp +++ b/indra/newview/lllogchat.cpp @@ -206,7 +206,11 @@ private: }; LLLogChat::save_history_signal_t * LLLogChat::sSaveHistorySignal = NULL; -LLLoadHistoryThread::load_end_signal_t * LLLoadHistoryThread::mLoadEndSignal = NULL; + +std::map<LLUUID,LLLoadHistoryThread *> LLLogChat::sLoadHistoryThreads; +std::map<LLUUID,LLDeleteHistoryThread *> LLLogChat::sDeleteHistoryThreads; +LLMutex* LLLogChat::sHistoryThreadsMutex = NULL; + //static std::string LLLogChat::makeLogFileName(std::string filename) @@ -337,83 +341,179 @@ void LLLogChat::saveHistory(const std::string& filename, void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& messages, const LLSD& load_params) { if (file_name.empty()) - { - LL_WARNS("LLLogChat::loadChatHistory") << "Session name is Empty!" << LL_ENDL; - return ; - } + { + LL_WARNS("LLLogChat::loadChatHistory") << "Session name is Empty!" << LL_ENDL; + return ; + } - bool load_all_history = load_params.has("load_all_history") ? load_params["load_all_history"].asBoolean() : false; + bool load_all_history = load_params.has("load_all_history") ? load_params["load_all_history"].asBoolean() : false; - LLFILE* fptr = LLFile::fopen(LLLogChat::makeLogFileName(file_name), "r");/*Flawfinder: ignore*/ - if (!fptr) - { - fptr = LLFile::fopen(LLLogChat::oldLogFileName(file_name), "r");/*Flawfinder: ignore*/ - if (!fptr) - { - return; //No previous conversation with this name. - } - } + LLFILE* fptr = LLFile::fopen(LLLogChat::makeLogFileName(file_name), "r");/*Flawfinder: ignore*/ + if (!fptr) + { + fptr = LLFile::fopen(LLLogChat::oldLogFileName(file_name), "r");/*Flawfinder: ignore*/ + if (!fptr) + { + return; //No previous conversation with this name. + } + } - char buffer[LOG_RECALL_SIZE]; /*Flawfinder: ignore*/ - char *bptr; - S32 len; - bool firstline = TRUE; - - if (load_all_history || fseek(fptr, (LOG_RECALL_SIZE - 1) * -1 , SEEK_END)) - { //We need to load the whole historyFile or it's smaller than recall size, so get it all. - firstline = FALSE; - if (fseek(fptr, 0, SEEK_SET)) - { - fclose(fptr); - return; - } - } - while (fgets(buffer, LOG_RECALL_SIZE, fptr) && !feof(fptr)) - { - len = strlen(buffer) - 1; /*Flawfinder: ignore*/ - for (bptr = (buffer + len); (*bptr == '\n' || *bptr == '\r') && bptr>buffer; bptr--) *bptr='\0'; - - if (firstline) - { - firstline = FALSE; - continue; - } - - std::string line(buffer); - - //updated 1.23 plain text log format requires a space added before subsequent lines in a multilined message - if (' ' == line[0]) - { - line.erase(0, MULTI_LINE_PREFIX.length()); - append_to_last_message(messages, '\n' + line); - } - else if (0 == len && ('\n' == line[0] || '\r' == line[0])) - { - //to support old format's multilined messages with new lines used to divide paragraphs - append_to_last_message(messages, line); - } - else - { - LLSD item; - if (!LLChatLogParser::parse(line, item, load_params)) - { - item[LL_IM_TEXT] = line; - } - messages.push_back(item); - } - } - fclose(fptr); + char buffer[LOG_RECALL_SIZE]; /*Flawfinder: ignore*/ + char *bptr; + S32 len; + bool firstline = TRUE; + + if (load_all_history || fseek(fptr, (LOG_RECALL_SIZE - 1) * -1 , SEEK_END)) + { //We need to load the whole historyFile or it's smaller than recall size, so get it all. + firstline = FALSE; + if (fseek(fptr, 0, SEEK_SET)) + { + fclose(fptr); + return; + } + } + while (fgets(buffer, LOG_RECALL_SIZE, fptr) && !feof(fptr)) + { + len = strlen(buffer) - 1; /*Flawfinder: ignore*/ + for (bptr = (buffer + len); (*bptr == '\n' || *bptr == '\r') && bptr>buffer; bptr--) *bptr='\0'; + + if (firstline) + { + firstline = FALSE; + continue; + } + std::string line(buffer); + //updated 1.23 plain text log format requires a space added before subsequent lines in a multilined message + if (' ' == line[0]) + { + line.erase(0, MULTI_LINE_PREFIX.length()); + append_to_last_message(messages, '\n' + line); + } + else if (0 == len && ('\n' == line[0] || '\r' == line[0])) + { + //to support old format's multilined messages with new lines used to divide paragraphs + append_to_last_message(messages, line); + } + else + { + LLSD item; + if (!LLChatLogParser::parse(line, item, load_params)) + { + item[LL_IM_TEXT] = line; + } + messages.push_back(item); + } + } + fclose(fptr); } -void LLLogChat::startChatHistoryThread(const std::string& file_name, const LLSD& load_params) +// static +bool LLLogChat::historyThreadsFinished(LLUUID session_id) { + LLMutexLock lock(historyThreadsMutex()); + bool finished = true; + std::map<LLUUID,LLLoadHistoryThread *>::iterator it = sLoadHistoryThreads.find(session_id); + if (it != sLoadHistoryThreads.end()) + { + finished = it->second->isFinished(); + } + if (!finished) + { + return false; + } + std::map<LLUUID,LLDeleteHistoryThread *>::iterator dit = sDeleteHistoryThreads.find(session_id); + if (dit != sDeleteHistoryThreads.end()) + { + finished = finished && dit->second->isFinished(); + } + return finished; +} - LLLoadHistoryThread* mThread = new LLLoadHistoryThread(); - mThread->start(); - mThread->setHistoryParams(file_name, load_params); +// static +LLLoadHistoryThread* LLLogChat::getLoadHistoryThread(LLUUID session_id) +{ + LLMutexLock lock(historyThreadsMutex()); + std::map<LLUUID,LLLoadHistoryThread *>::iterator it = sLoadHistoryThreads.find(session_id); + if (it != sLoadHistoryThreads.end()) + { + return it->second; + } + return NULL; +} + +// static +LLDeleteHistoryThread* LLLogChat::getDeleteHistoryThread(LLUUID session_id) +{ + LLMutexLock lock(historyThreadsMutex()); + std::map<LLUUID,LLDeleteHistoryThread *>::iterator it = sDeleteHistoryThreads.find(session_id); + if (it != sDeleteHistoryThreads.end()) + { + return it->second; + } + return NULL; +} + +// static +bool LLLogChat::addLoadHistoryThread(LLUUID& session_id, LLLoadHistoryThread* lthread) +{ + LLMutexLock lock(historyThreadsMutex()); + std::map<LLUUID,LLLoadHistoryThread *>::const_iterator it = sLoadHistoryThreads.find(session_id); + if (it != sLoadHistoryThreads.end()) + { + return false; + } + sLoadHistoryThreads[session_id] = lthread; + return true; } + +// static +bool LLLogChat::addDeleteHistoryThread(LLUUID& session_id, LLDeleteHistoryThread* dthread) +{ + LLMutexLock lock(historyThreadsMutex()); + std::map<LLUUID,LLDeleteHistoryThread *>::const_iterator it = sDeleteHistoryThreads.find(session_id); + if (it != sDeleteHistoryThreads.end()) + { + return false; + } + sDeleteHistoryThreads[session_id] = dthread; + return true; +} + +// static +void LLLogChat::cleanupHistoryThreads() +{ + LLMutexLock lock(historyThreadsMutex()); + std::vector<LLUUID> uuids; + std::map<LLUUID,LLLoadHistoryThread *>::iterator lit = sLoadHistoryThreads.begin(); + for (; lit != sLoadHistoryThreads.end(); lit++) + { + if (lit->second->isFinished() && sDeleteHistoryThreads[lit->first]->isFinished()) + { + delete lit->second; + delete sDeleteHistoryThreads[lit->first]; + uuids.push_back(lit->first); + } + } + std::vector<LLUUID>::iterator uuid_it = uuids.begin(); + for ( ;uuid_it != uuids.end(); uuid_it++) + { + sLoadHistoryThreads.erase(*uuid_it); + sDeleteHistoryThreads.erase(*uuid_it); + } +} + +//static +LLMutex* LLLogChat::historyThreadsMutex() +{ + if (sHistoryThreadsMutex == NULL) + { + sHistoryThreadsMutex = new LLMutex(NULL); + } + return sHistoryThreadsMutex; +} + // static std::string LLLogChat::oldLogFileName(std::string filename) { @@ -475,7 +575,7 @@ void LLLogChat::findTranscriptFiles(std::string pattern, std::vector<std::string //Add Nearby chat history to the list of transcriptions list_of_transcriptions.push_back(gDirUtilp->add(dirname, filename)); LLFile::close(filep); - return; + continue; } char buffer[LOG_RECALL_SIZE]; @@ -845,115 +945,188 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im, const LLSD& parse_params return true; //parsed name and message text, maybe have a timestamp too } +LLDeleteHistoryThread::LLDeleteHistoryThread(std::list<LLSD>* messages, LLLoadHistoryThread* loadThread) + : LLActionThread("delete chat history"), + mMessages(messages), + mLoadThread(loadThread) +{ +} +LLDeleteHistoryThread::~LLDeleteHistoryThread() +{ +} - LLLoadHistoryThread::LLLoadHistoryThread() : LLThread("load chat history") - { - mNewLoad = false; +void LLDeleteHistoryThread::run() +{ + if (mLoadThread != NULL) + { + mLoadThread->waitFinished(); } - - void LLLoadHistoryThread::run() + if (NULL != mMessages) { - while (!LLApp::isQuitting()) - { - if(mNewLoad) - { - loadHistory(mFileName,mMessages,mLoadParams); - shutdown(); - } - } + delete mMessages; } - void LLLoadHistoryThread::setHistoryParams(const std::string& file_name, const LLSD& load_params) + mMessages = NULL; + setFinished(); +} + +LLActionThread::LLActionThread(const std::string& name) + : LLThread(name), + mMutex(NULL), + mRunCondition(NULL), + mFinished(false) +{ +} + +LLActionThread::~LLActionThread() +{ +} + +void LLActionThread::waitFinished() +{ + mMutex.lock(); + if (!mFinished) { - mFileName = file_name; - mLoadParams = load_params; - mNewLoad = true; + mMutex.unlock(); + mRunCondition.wait(); } - void LLLoadHistoryThread::loadHistory(const std::string& file_name, std::list<LLSD>& messages, const LLSD& load_params) + else { + mMutex.unlock(); + } +} - if (file_name.empty()) - { - LL_WARNS("LLLogChat::loadHistory") << "Session name is Empty!" << LL_ENDL; - return ; - } +void LLActionThread::setFinished() +{ + mMutex.lock(); + mFinished = true; + mMutex.unlock(); + mRunCondition.signal(); +} - bool load_all_history = load_params.has("load_all_history") ? load_params["load_all_history"].asBoolean() : false; +LLLoadHistoryThread::LLLoadHistoryThread(const std::string& file_name, std::list<LLSD>* messages, const LLSD& load_params) + : LLActionThread("load chat history"), + mMessages(messages), + mFileName(file_name), + mLoadParams(load_params), + mNewLoad(true), + mLoadEndSignal(NULL) +{ +} - LLFILE* fptr = LLFile::fopen(LLLogChat::makeLogFileName(file_name), "r");/*Flawfinder: ignore*/ - if (!fptr) - { - fptr = LLFile::fopen(LLLogChat::oldLogFileName(file_name), "r");/*Flawfinder: ignore*/ - if (!fptr) - { - mNewLoad = false; - (*mLoadEndSignal)(messages, file_name); - return; //No previous conversation with this name. - } - } +LLLoadHistoryThread::~LLLoadHistoryThread() +{ +} - char buffer[LOG_RECALL_SIZE]; /*Flawfinder: ignore*/ - char *bptr; - S32 len; - bool firstline = TRUE; +void LLLoadHistoryThread::run() +{ + if(mNewLoad) + { + loadHistory(mFileName, mMessages, mLoadParams); + int count = mMessages->size(); + llinfos << "mMessages->size(): " << count << llendl; + setFinished(); + } +} - if (load_all_history || fseek(fptr, (LOG_RECALL_SIZE - 1) * -1 , SEEK_END)) - { //We need to load the whole historyFile or it's smaller than recall size, so get it all. - firstline = FALSE; - if (fseek(fptr, 0, SEEK_SET)) - { - fclose(fptr); - mNewLoad = false; - (*mLoadEndSignal)(messages, file_name); - return; - } - } - while (fgets(buffer, LOG_RECALL_SIZE, fptr) && !feof(fptr)) - { - len = strlen(buffer) - 1; /*Flawfinder: ignore*/ - for (bptr = (buffer + len); (*bptr == '\n' || *bptr == '\r') && bptr>buffer; bptr--) *bptr='\0'; +void LLLoadHistoryThread::loadHistory(const std::string& file_name, std::list<LLSD>* messages, const LLSD& load_params) +{ + if (file_name.empty()) + { + LL_WARNS("LLLogChat::loadHistory") << "Session name is Empty!" << LL_ENDL; + return ; + } - if (firstline) - { - firstline = FALSE; - continue; - } + bool load_all_history = load_params.has("load_all_history") ? load_params["load_all_history"].asBoolean() : false; + LLFILE* fptr = LLFile::fopen(LLLogChat::makeLogFileName(file_name), "r");/*Flawfinder: ignore*/ - std::string line(buffer); + if (!fptr) + { + fptr = LLFile::fopen(LLLogChat::oldLogFileName(file_name), "r");/*Flawfinder: ignore*/ + if (!fptr) + { + mNewLoad = false; + (*mLoadEndSignal)(messages, file_name); + return; //No previous conversation with this name. + } + } - //updated 1.23 plaint text log format requires a space added before subsequent lines in a multilined message - if (' ' == line[0]) - { - line.erase(0, MULTI_LINE_PREFIX.length()); - append_to_last_message(messages, '\n' + line); - } - else if (0 == len && ('\n' == line[0] || '\r' == line[0])) - { - //to support old format's multilined messages with new lines used to divide paragraphs - append_to_last_message(messages, line); - } - else - { - LLSD item; - if (!LLChatLogParser::parse(line, item, load_params)) - { - item[LL_IM_TEXT] = line; - } - messages.push_back(item); - } - } + char buffer[LOG_RECALL_SIZE]; /*Flawfinder: ignore*/ + + char *bptr; + S32 len; + bool firstline = TRUE; + + if (load_all_history || fseek(fptr, (LOG_RECALL_SIZE - 1) * -1 , SEEK_END)) + { //We need to load the whole historyFile or it's smaller than recall size, so get it all. + firstline = FALSE; + if (fseek(fptr, 0, SEEK_SET)) + { fclose(fptr); mNewLoad = false; (*mLoadEndSignal)(messages, file_name); + return; + } } - //static - boost::signals2::connection LLLoadHistoryThread::setLoadEndSignal(const load_end_signal_t::slot_type& cb) + + while (fgets(buffer, LOG_RECALL_SIZE, fptr) && !feof(fptr)) { - if (NULL == mLoadEndSignal) + len = strlen(buffer) - 1; /*Flawfinder: ignore*/ + + for (bptr = (buffer + len); (*bptr == '\n' || *bptr == '\r') && bptr>buffer; bptr--) *bptr='\0'; + + + if (firstline) { - mLoadEndSignal = new load_end_signal_t(); + firstline = FALSE; + continue; } + std::string line(buffer); - return mLoadEndSignal->connect(cb); + //updated 1.23 plaint text log format requires a space added before subsequent lines in a multilined message + if (' ' == line[0]) + { + line.erase(0, MULTI_LINE_PREFIX.length()); + append_to_last_message(*messages, '\n' + line); + } + else if (0 == len && ('\n' == line[0] || '\r' == line[0])) + { + //to support old format's multilined messages with new lines used to divide paragraphs + append_to_last_message(*messages, line); + } + else + { + LLSD item; + if (!LLChatLogParser::parse(line, item, load_params)) + { + item[LL_IM_TEXT] = line; + } + messages->push_back(item); + } } + + fclose(fptr); + mNewLoad = false; + (*mLoadEndSignal)(messages, file_name); +} + +boost::signals2::connection LLLoadHistoryThread::setLoadEndSignal(const load_end_signal_t::slot_type& cb) +{ + if (NULL == mLoadEndSignal) + { + mLoadEndSignal = new load_end_signal_t(); + } + + return mLoadEndSignal->connect(cb); +} + +void LLLoadHistoryThread::removeLoadEndSignal(const load_end_signal_t::slot_type& cb) +{ + if (NULL != mLoadEndSignal) + { + mLoadEndSignal->disconnect_all_slots(); + delete mLoadEndSignal; + } + mLoadEndSignal = NULL; +} diff --git a/indra/newview/lllogchat.h b/indra/newview/lllogchat.h index acee99afa2..81f75ef626 100755 --- a/indra/newview/lllogchat.h +++ b/indra/newview/lllogchat.h @@ -28,23 +28,54 @@ #define LL_LLLOGCHAT_H class LLChat; -class LLLoadHistoryThread : public LLThread + +class LLActionThread : public LLThread { +public: + LLActionThread(const std::string& name); + ~LLActionThread(); + + void waitFinished(); + bool isFinished() { return mFinished; } +protected: + void setFinished(); private: - std::string mFileName; - std::list<LLSD> mMessages; + bool mFinished; + LLMutex mMutex; + LLCondition mRunCondition; +}; + +class LLLoadHistoryThread : public LLActionThread +{ +private: + const std::string& mFileName; + std::list<LLSD>* mMessages; LLSD mLoadParams; bool mNewLoad; public: - LLLoadHistoryThread(); - - void setHistoryParams(const std::string& file_name, const LLSD& load_params); - virtual void loadHistory(const std::string& file_name, std::list<LLSD>& messages, const LLSD& load_params); + LLLoadHistoryThread(const std::string& file_name, std::list<LLSD>* messages, const LLSD& load_params); + ~LLLoadHistoryThread(); + //void setHistoryParams(const std::string& file_name, const LLSD& load_params); + virtual void loadHistory(const std::string& file_name, std::list<LLSD>* messages, const LLSD& load_params); virtual void run(); - typedef boost::signals2::signal<void (std::list<LLSD>& messages,const std::string& file_name)> load_end_signal_t; - static load_end_signal_t * mLoadEndSignal; - static boost::signals2::connection setLoadEndSignal(const load_end_signal_t::slot_type& cb); + typedef boost::signals2::signal<void (std::list<LLSD>* messages,const std::string& file_name)> load_end_signal_t; + load_end_signal_t * mLoadEndSignal; + boost::signals2::connection setLoadEndSignal(const load_end_signal_t::slot_type& cb); + void removeLoadEndSignal(const load_end_signal_t::slot_type& cb); +}; + +class LLDeleteHistoryThread : public LLActionThread +{ +private: + std::list<LLSD>* mMessages; + LLLoadHistoryThread* mLoadThread; +public: + LLDeleteHistoryThread(std::list<LLSD>* messages, LLLoadHistoryThread* loadThread); + ~LLDeleteHistoryThread(); + + virtual void run(); + static void deleteHistory(); }; class LLLogChat @@ -73,7 +104,6 @@ public: static void getListOfTranscriptBackupFiles(std::vector<std::string>& list_of_transcriptions); static void loadChatHistory(const std::string& file_name, std::list<LLSD>& messages, const LLSD& load_params = LLSD()); - static void startChatHistoryThread(const std::string& file_name, const LLSD& load_params); typedef boost::signals2::signal<void ()> save_history_signal_t; static boost::signals2::connection setSaveHistorySignal(const save_history_signal_t::slot_type& cb); @@ -90,9 +120,21 @@ public: static bool isTranscriptExist(const LLUUID& avatar_id, bool is_group=false); static bool isNearbyTranscriptExist(); + static bool historyThreadsFinished(LLUUID session_id); + static LLLoadHistoryThread* getLoadHistoryThread(LLUUID session_id); + static LLDeleteHistoryThread* getDeleteHistoryThread(LLUUID session_id); + static bool addLoadHistoryThread(LLUUID& session_id, LLLoadHistoryThread* lthread); + static bool addDeleteHistoryThread(LLUUID& session_id, LLDeleteHistoryThread* dthread); + static void cleanupHistoryThreads(); + private: static std::string cleanFileName(std::string filename); static save_history_signal_t * sSaveHistorySignal; + + static std::map<LLUUID,LLLoadHistoryThread *> sLoadHistoryThreads; + static std::map<LLUUID,LLDeleteHistoryThread *> sDeleteHistoryThreads; + static LLMutex* sHistoryThreadsMutex; + static LLMutex* historyThreadsMutex(); }; /** diff --git a/indra/newview/llmanipscale.cpp b/indra/newview/llmanipscale.cpp index ae0884ac5d..087f617bbb 100755 --- a/indra/newview/llmanipscale.cpp +++ b/indra/newview/llmanipscale.cpp @@ -843,121 +843,85 @@ void LLManipScale::drag( S32 x, S32 y ) // Scale around the void LLManipScale::dragCorner( S32 x, S32 y ) { - LLBBox bbox = LLSelectMgr::getInstance()->getBBoxOfSelection(); - // Suppress scale if mouse hasn't moved. if (x == mLastMouseX && y == mLastMouseY) { - // sendUpdates(TRUE,TRUE,TRUE); return; } - mLastMouseX = x; mLastMouseY = y; - LLVector3d drag_start_point_global = mDragStartPointGlobal; - LLVector3d drag_start_center_global = mDragStartCenterGlobal; - LLVector3 drag_start_point_agent = gAgent.getPosAgentFromGlobal(drag_start_point_global); - LLVector3 drag_start_center_agent = gAgent.getPosAgentFromGlobal(drag_start_center_global); + LLVector3 drag_start_point_agent = gAgent.getPosAgentFromGlobal(mDragStartPointGlobal); + LLVector3 drag_start_center_agent = gAgent.getPosAgentFromGlobal(mDragStartCenterGlobal); LLVector3d drag_start_dir_d; - drag_start_dir_d.setVec(drag_start_point_global - drag_start_center_global); - LLVector3 drag_start_dir_f; - drag_start_dir_f.setVec(drag_start_dir_d); + drag_start_dir_d.setVec(mDragStartPointGlobal - mDragStartCenterGlobal); F32 s = 0; F32 t = 0; - nearestPointOnLineFromMouse(x, y, - drag_start_center_agent, - drag_start_point_agent, - s, t ); - - F32 drag_start_dist = dist_vec(drag_start_point_agent, drag_start_center_agent); + drag_start_center_agent, + drag_start_point_agent, + s, t ); if( s <= 0 ) // we only care about intersections in front of the camera { return; } + mDragPointGlobal = lerp(mDragStartCenterGlobal, mDragStartPointGlobal, t); - LLVector3d drag_point_global = drag_start_center_global + t * drag_start_dir_d; - - F32 scale_factor = t; - - BOOL uniform = LLManipScale::getUniform(); - - if( !uniform ) - { - scale_factor = 0.5f + (scale_factor * 0.5f); - } + LLBBox bbox = LLSelectMgr::getInstance()->getBBoxOfSelection(); + F32 scale_factor = 1.f; + F32 max_scale = partToMaxScale(mManipPart, bbox); + F32 min_scale = partToMinScale(mManipPart, bbox); + BOOL uniform = LLManipScale::getUniform(); // check for snapping - LLVector3 drag_center_agent = gAgent.getPosAgentFromGlobal(drag_point_global); LLVector3 mouse_on_plane1; - getMousePointOnPlaneAgent(mouse_on_plane1, x, y, drag_center_agent, mScalePlaneNormal1); - LLVector3 mouse_on_plane2; - getMousePointOnPlaneAgent(mouse_on_plane2, x, y, drag_center_agent, mScalePlaneNormal2); - LLVector3 mouse_dir_1 = mouse_on_plane1 - mScaleCenter; - LLVector3 mouse_dir_2 = mouse_on_plane2 - mScaleCenter; - LLVector3 mouse_to_scale_line_1 = mouse_dir_1 - projected_vec(mouse_dir_1, mScaleDir); - LLVector3 mouse_to_scale_line_2 = mouse_dir_2 - projected_vec(mouse_dir_2, mScaleDir); - LLVector3 mouse_to_scale_line_dir_1 = mouse_to_scale_line_1; - mouse_to_scale_line_dir_1.normVec(); - if (mouse_to_scale_line_dir_1 * mSnapGuideDir1 < 0.f) - { - // need to keep sign of mouse offset wrt to snap guide direction - mouse_to_scale_line_dir_1 *= -1.f; - } - LLVector3 mouse_to_scale_line_dir_2 = mouse_to_scale_line_2; - mouse_to_scale_line_dir_2.normVec(); - if (mouse_to_scale_line_dir_2 * mSnapGuideDir2 < 0.f) - { - // need to keep sign of mouse offset wrt to snap guide direction - mouse_to_scale_line_dir_2 *= -1.f; - } + getMousePointOnPlaneAgent(mouse_on_plane1, x, y, mScaleCenter, mScalePlaneNormal1); + mouse_on_plane1 -= mScaleCenter; - F32 snap_dir_dot_mouse_offset1 = mSnapGuideDir1 * mouse_to_scale_line_dir_1; - F32 snap_dir_dot_mouse_offset2 = mSnapGuideDir2 * mouse_to_scale_line_dir_2; + LLVector3 mouse_on_plane2; + getMousePointOnPlaneAgent(mouse_on_plane2, x, y, mScaleCenter, mScalePlaneNormal2); + mouse_on_plane2 -= mScaleCenter; - F32 dist_from_scale_line_1 = mouse_to_scale_line_1 * mouse_to_scale_line_dir_1; - F32 dist_from_scale_line_2 = mouse_to_scale_line_2 * mouse_to_scale_line_dir_2; + LLVector3 projected_drag_pos1 = inverse_projected_vec(mScaleDir, orthogonal_component(mouse_on_plane1, mSnapGuideDir1)); + LLVector3 projected_drag_pos2 = inverse_projected_vec(mScaleDir, orthogonal_component(mouse_on_plane2, mSnapGuideDir2)); - F32 max_scale = partToMaxScale(mManipPart, bbox); - F32 min_scale = partToMinScale(mManipPart, bbox); + LLVector3 mouse_offset_from_scale_line_1 = orthogonal_component(mouse_on_plane1, mScaleDir); + LLVector3 mouse_offset_from_scale_line_2 = orthogonal_component(mouse_on_plane2, mScaleDir); BOOL snap_enabled = gSavedSettings.getBOOL("SnapEnabled"); - if (snap_enabled && dist_from_scale_line_1 > mSnapRegimeOffset * snap_dir_dot_mouse_offset1) + if (snap_enabled && (mouse_on_plane1 - projected_drag_pos1) * mSnapGuideDir1 > mSnapRegimeOffset) { - mInSnapRegime = TRUE; - LLVector3 projected_drag_pos = mouse_on_plane1 - (dist_from_scale_line_1 / snap_dir_dot_mouse_offset1) * mSnapGuideDir1; - F32 drag_dist = (projected_drag_pos - mScaleCenter) * mScaleDir; + F32 drag_dist = projected_drag_pos1.length(); - F32 cur_subdivisions = llclamp(getSubdivisionLevel(projected_drag_pos, mScaleDir, mScaleSnapUnit1), sGridMinSubdivisionLevel, sGridMaxSubdivisionLevel); + F32 cur_subdivisions = llclamp(getSubdivisionLevel(projected_drag_pos1, mScaleDir, mScaleSnapUnit1), sGridMinSubdivisionLevel, sGridMaxSubdivisionLevel); F32 snap_dist = mScaleSnapUnit1 / (2.f * cur_subdivisions); F32 relative_snap_dist = fmodf(drag_dist + snap_dist, mScaleSnapUnit1 / cur_subdivisions); mScaleSnapValue = llclamp((drag_dist - (relative_snap_dist - snap_dist)), min_scale, max_scale); - scale_factor = mScaleSnapValue / drag_start_dist; - if( !uniform ) + mInSnapRegime = TRUE; + scale_factor = mScaleSnapValue / dist_vec(drag_start_point_agent, drag_start_center_agent); + if (!uniform) { scale_factor *= 0.5f; } } - else if (snap_enabled && dist_from_scale_line_2 > mSnapRegimeOffset * snap_dir_dot_mouse_offset2) + else if (snap_enabled && (mouse_on_plane2 - projected_drag_pos2) * mSnapGuideDir2 > mSnapRegimeOffset ) { - mInSnapRegime = TRUE; - LLVector3 projected_drag_pos = mouse_on_plane2 - (dist_from_scale_line_2 / snap_dir_dot_mouse_offset2) * mSnapGuideDir2; - F32 drag_dist = (projected_drag_pos - mScaleCenter) * mScaleDir; + F32 drag_dist = projected_drag_pos2.length(); - F32 cur_subdivisions = llclamp(getSubdivisionLevel(projected_drag_pos, mScaleDir, mScaleSnapUnit2), sGridMinSubdivisionLevel, sGridMaxSubdivisionLevel); + F32 cur_subdivisions = llclamp(getSubdivisionLevel(projected_drag_pos2, mScaleDir, mScaleSnapUnit2), sGridMinSubdivisionLevel, sGridMaxSubdivisionLevel); F32 snap_dist = mScaleSnapUnit2 / (2.f * cur_subdivisions); F32 relative_snap_dist = fmodf(drag_dist + snap_dist, mScaleSnapUnit2 / cur_subdivisions); mScaleSnapValue = llclamp((drag_dist - (relative_snap_dist - snap_dist)), min_scale, max_scale); - scale_factor = mScaleSnapValue / drag_start_dist; - if( !uniform ) + mInSnapRegime = TRUE; + scale_factor = mScaleSnapValue / dist_vec(drag_start_point_agent, drag_start_center_agent); + if (!uniform) { scale_factor *= 0.5f; } @@ -965,8 +929,14 @@ void LLManipScale::dragCorner( S32 x, S32 y ) else { mInSnapRegime = FALSE; + scale_factor = t; + if (!uniform) + { + scale_factor = 0.5f + (scale_factor * 0.5f); + } } + F32 max_scale_factor = get_default_max_prim_scale() / MIN_PRIM_SCALE; F32 min_scale_factor = MIN_PRIM_SCALE / get_default_max_prim_scale(); @@ -1069,9 +1039,6 @@ void LLManipScale::dragCorner( S32 x, S32 y ) } } - - - mDragPointGlobal = drag_point_global; } diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index 08b5eaedbb..193e2ea678 100755 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -798,7 +798,10 @@ void LLNetMap::createObjectImage() { mObjectRawImagep = new LLImageRaw(img_size, img_size, 4); U8* data = mObjectRawImagep->getData(); - memset( data, 0, img_size * img_size * 4 ); + if (data) + { + memset( data, 0, img_size * img_size * 4 ); + } mObjectImagep = LLViewerTextureManager::getLocalTexture( mObjectRawImagep.get(), FALSE); } setScale(mScale); diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp index 180c1d6ab5..c872a15af7 100755 --- a/indra/newview/llpanelgroup.cpp +++ b/indra/newview/llpanelgroup.cpp @@ -49,6 +49,7 @@ #include "llpanelgroupnotices.h" #include "llpanelgroupgeneral.h" +#include "llpanelgrouproles.h" #include "llaccordionctrltab.h" #include "llaccordionctrl.h" @@ -275,6 +276,7 @@ void LLPanelGroup::onBtnApply(void* user_data) { LLPanelGroup* self = static_cast<LLPanelGroup*>(user_data); self->apply(); + self->refreshData(); } void LLPanelGroup::onBtnGroupCallClicked(void* user_data) @@ -495,6 +497,22 @@ bool LLPanelGroup::apply(LLPanelGroupTab* tab) { //we skip refreshing group after ew manually apply changes since its very annoying //for those who are editing group + + LLPanelGroupRoles * roles_tab = dynamic_cast<LLPanelGroupRoles*>(tab); + if (roles_tab) + { + LLGroupMgr* gmgrp = LLGroupMgr::getInstance(); + LLGroupMgrGroupData* gdatap = gmgrp->getGroupData(roles_tab->getGroupID()); + + // allow refresh only for one specific case: + // there is only one member in group and it is not owner + // it's a wrong situation and need refresh panels from server + if (gdatap && gdatap->isSingleMemberNotOwner()) + { + return true; + } + } + mSkipRefresh = TRUE; return true; } diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp index 88400e4ef2..a22d9c06fa 100755 --- a/indra/newview/llpanellandmarks.cpp +++ b/indra/newview/llpanellandmarks.cpp @@ -716,6 +716,11 @@ void LLLandmarksPanel::updateListCommands() mListCommands->getChildView(TRASH_BUTTON_NAME)->setEnabled(trash_enabled); } +void LLLandmarksPanel::updateMenuVisibility(LLUICtrl* menu) +{ + onMenuVisibilityChange(menu, LLSD().with("visibility", true)); +} + void LLLandmarksPanel::onActionsButtonClick() { LLToggleableMenu* menu = mGearFolderMenu; diff --git a/indra/newview/llpanellandmarks.h b/indra/newview/llpanellandmarks.h index 8fae0f0b67..80310d1524 100755 --- a/indra/newview/llpanellandmarks.h +++ b/indra/newview/llpanellandmarks.h @@ -80,6 +80,8 @@ public: LLPlacesInventoryPanel* getLibraryInventoryPanel() { return mLibraryInventoryPanel; } + void updateMenuVisibility(LLUICtrl* menu); + protected: /** * @return true - if current selected panel is not null and selected item is a landmark diff --git a/indra/newview/llpanelnearbymedia.cpp b/indra/newview/llpanelnearbymedia.cpp index a50d9074f7..edcf0d0452 100755 --- a/indra/newview/llpanelnearbymedia.cpp +++ b/indra/newview/llpanelnearbymedia.cpp @@ -876,7 +876,10 @@ void LLPanelNearByMedia::onClickParcelAudioPlay() // playing and updated as they cross to other parcels etc. mParcelAudioAutoStart = true; if (!gAudiop) + { + LL_WARNS("AudioEngine") << "LLAudioEngine instance doesn't exist!" << LL_ENDL; return; + } if (LLAudioEngine::AUDIO_PAUSED == gAudiop->isInternetStreamPlaying()) { @@ -896,7 +899,10 @@ void LLPanelNearByMedia::onClickParcelAudioStop() // they explicitly start it again. mParcelAudioAutoStart = false; if (!gAudiop) + { + LL_WARNS("AudioEngine") << "LLAudioEngine instance doesn't exist!" << LL_ENDL; return; + } LLViewerAudio::getInstance()->stopInternetStreamWithAutoFade(); } @@ -904,7 +910,10 @@ void LLPanelNearByMedia::onClickParcelAudioStop() void LLPanelNearByMedia::onClickParcelAudioPause() { if (!gAudiop) + { + LL_WARNS("AudioEngine") << "LLAudioEngine instance doesn't exist!" << LL_ENDL; return; + } // 'true' means pause gAudiop->pauseInternetStream(true); diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index d7130820ab..6c9616511f 100755 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -1491,7 +1491,8 @@ LLPanelObjectInventory::LLPanelObjectInventory(const LLPanelObjectInventory::Par mFolders(NULL), mHaveInventory(FALSE), mIsInventoryEmpty(TRUE), - mInventoryNeedsUpdate(FALSE) + mInventoryNeedsUpdate(FALSE), + mInventoryViewModel(p.name) { // Setup context menu callbacks mCommitCallbackRegistrar.add("Inventory.DoToSelected", boost::bind(&LLPanelObjectInventory::doToSelected, this, _2)); @@ -2010,3 +2011,46 @@ void LLPanelObjectInventory::clearItemIDs() mItemMap.clear(); } +BOOL LLPanelObjectInventory::handleKeyHere( KEY key, MASK mask ) +{ + BOOL handled = FALSE; + switch (key) + { + case KEY_DELETE: + case KEY_BACKSPACE: + // Delete selected items if delete or backspace key hit on the inventory panel + // Note: on Mac laptop keyboards, backspace and delete are one and the same + if (isSelectionRemovable() && mask == MASK_NONE) + { + LLInventoryAction::doToSelected(&gInventory, mFolders, "delete"); + handled = TRUE; + } + break; + } + return handled; +} + +BOOL LLPanelObjectInventory::isSelectionRemovable() +{ + if (!mFolders || !mFolders->getRoot()) + { + return FALSE; + } + std::set<LLFolderViewItem*> selection_set = mFolders->getRoot()->getSelectionList(); + if (selection_set.empty()) + { + return FALSE; + } + for (std::set<LLFolderViewItem*>::iterator iter = selection_set.begin(); + iter != selection_set.end(); + ++iter) + { + LLFolderViewItem *item = *iter; + const LLFolderViewModelItemInventory *listener = dynamic_cast<const LLFolderViewModelItemInventory*>(item->getViewModelItem()); + if (!listener || !listener->isItemRemovable() || listener->isItemInTrash()) + { + return FALSE; + } + } + return TRUE; +} diff --git a/indra/newview/llpanelobjectinventory.h b/indra/newview/llpanelobjectinventory.h index f497c695b3..9559f7e886 100755 --- a/indra/newview/llpanelobjectinventory.h +++ b/indra/newview/llpanelobjectinventory.h @@ -94,6 +94,9 @@ protected: void removeItemID(const LLUUID& id); void clearItemIDs(); + BOOL handleKeyHere( KEY key, MASK mask ); + BOOL isSelectionRemovable(); + private: std::map<LLUUID, LLFolderViewItem*> mItemMap; diff --git a/indra/newview/llplacesfolderview.cpp b/indra/newview/llplacesfolderview.cpp index 3caa93ae71..1cb013adc6 100755 --- a/indra/newview/llplacesfolderview.cpp +++ b/indra/newview/llplacesfolderview.cpp @@ -31,6 +31,7 @@ #include "llplacesinventorypanel.h" #include "llpanellandmarks.h" +#include "llmenugl.h" LLPlacesFolderView::LLPlacesFolderView(const LLFolderView::Params& p) : LLFolderView(p) @@ -67,6 +68,16 @@ BOOL LLPlacesFolderView::handleRightMouseDown(S32 x, S32 y, MASK mask) return LLFolderView::handleRightMouseDown(x, y, mask); } +void LLPlacesFolderView::updateMenu() +{ + LLFolderView::updateMenu(); + LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); + if (menu && menu->getVisible()) + { + mParentLandmarksPanel->updateMenuVisibility(menu); + } +} + void LLPlacesFolderView::setupMenuHandle(LLInventoryType::EType asset_type, LLHandle<LLView> menu_handle) { mMenuHandlesByInventoryType[asset_type] = menu_handle; diff --git a/indra/newview/llplacesfolderview.h b/indra/newview/llplacesfolderview.h index 8c5be39b5e..65fe76007a 100755 --- a/indra/newview/llplacesfolderview.h +++ b/indra/newview/llplacesfolderview.h @@ -51,6 +51,8 @@ public: */ /*virtual*/ BOOL handleRightMouseDown( S32 x, S32 y, MASK mask ); + /*virtual*/ void updateMenu(); + void setupMenuHandle(LLInventoryType::EType asset_type, LLHandle<LLView> menu_handle); void setParentLandmarksPanel(LLLandmarksPanel* panel) diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index e533be7f24..26c46d543c 100755 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -192,11 +192,11 @@ public: private: LLScriptEdCore* mEditorCore; - static LLFloaterScriptSearch* sInstance; protected: LLLineEditor* mSearchBox; + LLLineEditor* mReplaceBox; void onSearchBoxCommit(); }; @@ -205,6 +205,7 @@ LLFloaterScriptSearch* LLFloaterScriptSearch::sInstance = NULL; LLFloaterScriptSearch::LLFloaterScriptSearch(LLScriptEdCore* editor_core) : LLFloater(LLSD()), mSearchBox(NULL), + mReplaceBox(NULL), mEditorCore(editor_core) { buildFromFile("floater_script_search.xml"); @@ -227,6 +228,7 @@ LLFloaterScriptSearch::LLFloaterScriptSearch(LLScriptEdCore* editor_core) BOOL LLFloaterScriptSearch::postBuild() { + mReplaceBox = getChild<LLLineEditor>("replace_text"); mSearchBox = getChild<LLLineEditor>("search_text"); mSearchBox->setCommitCallback(boost::bind(&LLFloaterScriptSearch::onSearchBoxCommit, this)); mSearchBox->setCommitOnFocusLost(FALSE); @@ -242,8 +244,12 @@ BOOL LLFloaterScriptSearch::postBuild() //static void LLFloaterScriptSearch::show(LLScriptEdCore* editor_core) { + LLSD::String search_text; + LLSD::String replace_text; if (sInstance && sInstance->mEditorCore && sInstance->mEditorCore != editor_core) { + search_text=sInstance->mSearchBox->getValue().asString(); + replace_text=sInstance->mReplaceBox->getValue().asString(); sInstance->closeFloater(); delete sInstance; } @@ -252,6 +258,8 @@ void LLFloaterScriptSearch::show(LLScriptEdCore* editor_core) { // sInstance will be assigned in the constructor. new LLFloaterScriptSearch(editor_core); + sInstance->mSearchBox->setValue(search_text); + sInstance->mReplaceBox->setValue(replace_text); } sInstance->openFloater(); @@ -272,7 +280,7 @@ void LLFloaterScriptSearch::onBtnSearch(void *userdata) void LLFloaterScriptSearch::handleBtnSearch() { LLCheckBoxCtrl* caseChk = getChild<LLCheckBoxCtrl>("case_text"); - mEditorCore->mEditor->selectNext(getChild<LLUICtrl>("search_text")->getValue().asString(), caseChk->get()); + mEditorCore->mEditor->selectNext(mSearchBox->getValue().asString(), caseChk->get()); } // static @@ -285,7 +293,7 @@ void LLFloaterScriptSearch::onBtnReplace(void *userdata) void LLFloaterScriptSearch::handleBtnReplace() { LLCheckBoxCtrl* caseChk = getChild<LLCheckBoxCtrl>("case_text"); - mEditorCore->mEditor->replaceText(getChild<LLUICtrl>("search_text")->getValue().asString(), getChild<LLUICtrl>("replace_text")->getValue().asString(), caseChk->get()); + mEditorCore->mEditor->replaceText(mSearchBox->getValue().asString(), mReplaceBox->getValue().asString(), caseChk->get()); } // static @@ -298,7 +306,7 @@ void LLFloaterScriptSearch::onBtnReplaceAll(void *userdata) void LLFloaterScriptSearch::handleBtnReplaceAll() { LLCheckBoxCtrl* caseChk = getChild<LLCheckBoxCtrl>("case_text"); - mEditorCore->mEditor->replaceTextAll(getChild<LLUICtrl>("search_text")->getValue().asString(), getChild<LLUICtrl>("replace_text")->getValue().asString(), caseChk->get()); + mEditorCore->mEditor->replaceTextAll(mSearchBox->getValue().asString(), mReplaceBox->getValue().asString(), caseChk->get()); } bool LLFloaterScriptSearch::hasAccelerators() const @@ -329,7 +337,7 @@ void LLFloaterScriptSearch::onSearchBoxCommit() if (mEditorCore && mEditorCore->mEditor) { LLCheckBoxCtrl* caseChk = getChild<LLCheckBoxCtrl>("case_text"); - mEditorCore->mEditor->selectNext(getChild<LLUICtrl>("search_text")->getValue().asString(), caseChk->get()); + mEditorCore->mEditor->selectNext(mSearchBox->getValue().asString(), caseChk->get()); } } @@ -518,6 +526,10 @@ void LLScriptEdCore::initMenu() menuItem->setClickCallback(boost::bind(&LLTextEditor::selectAll, mEditor)); menuItem->setEnableCallback(boost::bind(&LLTextEditor::canSelectAll, mEditor)); + menuItem = getChild<LLMenuItemCallGL>("Deselect"); + menuItem->setClickCallback(boost::bind(&LLTextEditor::deselect, mEditor)); + menuItem->setEnableCallback(boost::bind(&LLTextEditor::canDeselect, mEditor)); + menuItem = getChild<LLMenuItemCallGL>("Search / Replace..."); menuItem->setClickCallback(boost::bind(&LLFloaterScriptSearch::show, this)); @@ -1867,7 +1879,7 @@ void LLLiveLSLEditor::loadAsset() mIsModifiable = item && gAgent.allowOperation(PERM_MODIFY, item->getPermissions(), GP_OBJECT_MANIPULATE); - + refreshFromItem(); // This is commented out, because we don't completely // handle script exports yet. /* diff --git a/indra/newview/llpreviewsound.cpp b/indra/newview/llpreviewsound.cpp index 33d2d015ad..11b81a58fc 100755 --- a/indra/newview/llpreviewsound.cpp +++ b/indra/newview/llpreviewsound.cpp @@ -55,7 +55,9 @@ BOOL LLPreviewSound::postBuild() { getChild<LLUICtrl>("desc")->setValue(item->getDescription()); if (gAudiop) + { gAudiop->preloadSound(item->getAssetUUID()); // preload the sound + } } childSetAction("Sound play btn",&LLPreviewSound::playSound,this); @@ -94,6 +96,6 @@ void LLPreviewSound::auditionSound( void *userdata ) if(item && gAudiop) { LLVector3d lpos_global = gAgent.getPositionGlobal(); - gAudiop->triggerSound(item->getAssetUUID(), gAgent.getID(), SOUND_GAIN, LLAudioEngine::AUDIO_TYPE_UI, lpos_global); + gAudiop->triggerSound(item->getAssetUUID(), gAgent.getID(), SOUND_GAIN, LLAudioEngine::AUDIO_TYPE_SFX, lpos_global); } } diff --git a/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp index 1ed48a978f..5c41c5ad97 100755 --- a/indra/newview/llpreviewtexture.cpp +++ b/indra/newview/llpreviewtexture.cpp @@ -127,9 +127,28 @@ BOOL LLPreviewTexture::postBuild() getChild<LLLineEditor>("desc")->setPrevalidate(&LLTextValidate::validateASCIIPrintableNoPipe); } } + + // Fill in ratios list with common aspect ratio values + mRatiosList.clear(); + mRatiosList.push_back(LLTrans::getString("Unconstrained")); + mRatiosList.push_back("1:1"); + mRatiosList.push_back("4:3"); + mRatiosList.push_back("10:7"); + mRatiosList.push_back("3:2"); + mRatiosList.push_back("16:10"); + mRatiosList.push_back("16:9"); + mRatiosList.push_back("2:1"); - childSetCommitCallback("combo_aspect_ratio", onAspectRatioCommit, this); + // Now fill combo box with provided list LLComboBox* combo = getChild<LLComboBox>("combo_aspect_ratio"); + combo->removeall(); + + for (std::vector<std::string>::const_iterator it = mRatiosList.begin(); it != mRatiosList.end(); ++it) + { + combo->add(*it); + } + + childSetCommitCallback("combo_aspect_ratio", onAspectRatioCommit, this); combo->setCurrentByIndex(0); return LLPreview::postBuild(); @@ -414,6 +433,13 @@ void LLPreviewTexture::updateDimensions() { return; } + + if (mAssetStatus != PREVIEW_ASSET_LOADED) + { + mAssetStatus = PREVIEW_ASSET_LOADED; + // Asset has been fully loaded, adjust aspect ratio + adjustAspectRatio(); + } // Update the width/height display every time getChild<LLUICtrl>("dimensions")->setTextArg("[WIDTH]", llformat("%d", mImage->getFullWidth())); @@ -501,6 +527,46 @@ LLPreview::EAssetStatus LLPreviewTexture::getAssetStatus() return mAssetStatus; } +void LLPreviewTexture::adjustAspectRatio() +{ + S32 w = mImage->getFullWidth(); + S32 h = mImage->getFullHeight(); + + // Determine aspect ratio of the image + S32 tmp; + while (h != 0) + { + tmp = w % h; + w = h; + h = tmp; + } + S32 divisor = w; + S32 num = mImage->getFullWidth() / divisor; + S32 denom = mImage->getFullHeight() / divisor; + + if (setAspectRatio(num, denom)) + { + // Select corresponding ratio entry in the combo list + LLComboBox* combo = getChild<LLComboBox>("combo_aspect_ratio"); + if (combo) + { + std::ostringstream ratio; + ratio << num << ":" << denom; + std::vector<std::string>::const_iterator found = std::find(mRatiosList.begin(), mRatiosList.end(), ratio.str()); + if (found == mRatiosList.end()) + { + combo->setCurrentByIndex(0); + } + else + { + combo->setCurrentByIndex(found - mRatiosList.begin()); + } + } + } + + mUpdateDimensions = TRUE; +} + void LLPreviewTexture::updateImageID() { const LLViewerInventoryItem *item = static_cast<const LLViewerInventoryItem*>(getItem()); diff --git a/indra/newview/llpreviewtexture.h b/indra/newview/llpreviewtexture.h index cd16bacde2..97e74706cc 100755 --- a/indra/newview/llpreviewtexture.h +++ b/indra/newview/llpreviewtexture.h @@ -70,6 +70,7 @@ protected: /* virtual */ BOOL postBuild(); bool setAspectRatio(const F32 width, const F32 height); static void onAspectRatioCommit(LLUICtrl*,void* userdata); + void adjustAspectRatio(); private: void updateImageID(); // set what image is being uploaded. @@ -95,5 +96,6 @@ private: F32 mAspectRatio; LLLoadedCallbackEntry::source_callback_list_t mCallbackTextureList ; + std::vector<std::string> mRatiosList; }; #endif // LL_LLPREVIEWTEXTURE_H diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp index 2e91ceee2e..1ce691f696 100755 --- a/indra/newview/llsidepanelinventory.cpp +++ b/indra/newview/llsidepanelinventory.cpp @@ -710,13 +710,13 @@ void LLSidepanelInventory::clearSelections(bool clearMain, bool clearInbox) if (inv_panel) { - inv_panel->clearSelection(); + inv_panel->getRootFolder()->clearSelection(); } } if (clearInbox && mInboxEnabled && (mInventoryPanelInbox != NULL)) { - mInventoryPanelInbox->clearSelection(); + mInventoryPanelInbox->getRootFolder()->clearSelection(); } updateVerbs(); diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp index 7532ebfc57..ea8225a3ac 100644 --- a/indra/newview/llsnapshotlivepreview.cpp +++ b/indra/newview/llsnapshotlivepreview.cpp @@ -50,7 +50,6 @@ #include "llviewerstats.h" #include "llvfile.h" #include "llvfs.h" -#include "llwebsharing.h" #include "llwindow.h" #include "llworld.h" @@ -845,30 +844,3 @@ BOOL LLSnapshotLivePreview::saveLocal() } return success; } - -void LLSnapshotLivePreview::saveWeb() -{ - // *FIX: Will break if the window closes because of CloseSnapshotOnKeep! - // Needs to pass on ownership of the image. - LLImageJPEG* jpg = dynamic_cast<LLImageJPEG*>(mFormattedImage.get()); - if(!jpg) - { - llwarns << "Formatted image not a JPEG" << llendl; - return; - } - - LLSD metadata; - metadata["description"] = getChild<LLLineEditor>("description")->getText(); - - LLLandmarkActions::getRegionNameAndCoordsFromPosGlobal(gAgentCamera.getCameraPositionGlobal(), - boost::bind(&LLSnapshotLivePreview::regionNameCallback, this, jpg, metadata, _1, _2, _3, _4)); - - gViewerWindow->playSnapshotAnimAndSound(); -} - -void LLSnapshotLivePreview::regionNameCallback(LLImageJPEG* snapshot, LLSD& metadata, const std::string& name, S32 x, S32 y, S32 z) -{ - metadata["slurl"] = LLSLURL(name, LLVector3d(x, y, z)).getSLURLString(); - - LLWebSharing::instance().shareSnapshot(snapshot, metadata); -} diff --git a/indra/newview/llsnapshotlivepreview.h b/indra/newview/llsnapshotlivepreview.h index fe3d257b02..0f09ef214a 100644 --- a/indra/newview/llsnapshotlivepreview.h +++ b/indra/newview/llsnapshotlivepreview.h @@ -96,7 +96,6 @@ public: void setSnapshotQuality(S32 quality); void setSnapshotBufferType(LLViewerWindow::ESnapshotType type) { mSnapshotBufferType = type; } void updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail = FALSE, F32 delay = 0.f); - void saveWeb(); void saveTexture(); BOOL saveLocal(); @@ -113,9 +112,6 @@ public: // Returns TRUE when snapshot generated, FALSE otherwise. static BOOL onIdle( void* snapshot_preview ); - // callback for region name resolve - void regionNameCallback(LLImageJPEG* snapshot, LLSD& metadata, const std::string& name, S32 x, S32 y, S32 z); - private: LLColor4 mColor; LLPointer<LLViewerTexture> mViewerImage[2]; //used to represent the scene when the frame is frozen. diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index d5f8a1e46e..6361c18c9f 100755 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -624,25 +624,22 @@ bool idle_startup() if (FALSE == gSavedSettings.getBOOL("NoAudio")) { + delete gAudiop; gAudiop = NULL; #ifdef LL_FMODEX - if (!gAudiop #if !LL_WINDOWS - && NULL == getenv("LL_BAD_FMODEX_DRIVER") + if (NULL == getenv("LL_BAD_FMODEX_DRIVER")) #endif // !LL_WINDOWS - ) { gAudiop = (LLAudioEngine *) new LLAudioEngine_FMODEX(gSavedSettings.getBOOL("FMODExProfilerEnable")); } #endif #ifdef LL_OPENAL - if (!gAudiop #if !LL_WINDOWS - && NULL == getenv("LL_BAD_OPENAL_DRIVER") + if (NULL == getenv("LL_BAD_OPENAL_DRIVER")) #endif // !LL_WINDOWS - ) { gAudiop = (LLAudioEngine *) new LLAudioEngine_OpenAL(); } @@ -2687,7 +2684,7 @@ void init_start_screen(S32 location_id) } } - if(gStartTexture.isNull()) + if(gStartTexture && gStartTexture.isNull()) { gStartTexture = LLViewerTexture::sBlackImagep ; gStartImageWidth = gStartTexture->getWidth() ; diff --git a/indra/newview/llsurface.cpp b/indra/newview/llsurface.cpp index 93c7f54101..f1b27279e3 100755 --- a/indra/newview/llsurface.cpp +++ b/indra/newview/llsurface.cpp @@ -233,6 +233,12 @@ void LLSurface::createSTexture() // GL NOT ACTIVE HERE LLPointer<LLImageRaw> raw = new LLImageRaw(sTextureSize, sTextureSize, 3); U8 *default_texture = raw->getData(); + + if (!default_texture) + { + return; + } + for (S32 i = 0; i < sTextureSize; i++) { for (S32 j = 0; j < sTextureSize; j++) @@ -257,6 +263,12 @@ void LLSurface::createWaterTexture() // Create the water texture LLPointer<LLImageRaw> raw = new LLImageRaw(sTextureSize/2, sTextureSize/2, 4); U8 *default_texture = raw->getData(); + + if (!default_texture) + { + return; + } + for (S32 i = 0; i < sTextureSize/2; i++) { for (S32 j = 0; j < sTextureSize/2; j++) diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index 5bc2e971eb..8d9d2421da 100755 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -1937,7 +1937,7 @@ bool LLTextureCache::writeToFastCache(S32 id, LLPointer<LLImageRaw> raw, S32 dis memcpy(mFastCachePadBuffer + sizeof(S32) * 3, &discardlevel, sizeof(S32)); S32 copy_size = w * h * c; - if(copy_size > 0) //valid + if(copy_size > 0 && raw->getData()) //valid { copy_size = llmin(copy_size, TEXTURE_FAST_CACHE_ENTRY_SIZE - TEXTURE_FAST_CACHE_ENTRY_OVERHEAD); memcpy(mFastCachePadBuffer + TEXTURE_FAST_CACHE_ENTRY_OVERHEAD, raw->getData(), copy_size); diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index ea837c9127..99e41cf39a 100755 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -242,7 +242,7 @@ void LLFloaterTexturePicker::setImageID(const LLUUID& image_id) LLUUID item_id = findItemID(mImageAssetID, FALSE); if (item_id.isNull()) { - mInventoryPanel->clearSelection(); + mInventoryPanel->getRootFolder()->clearSelection(); } else { diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index 1a137f7129..7314ab60c1 100755 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -1611,16 +1611,19 @@ static void show_item_sharing_confirmation(const std::string name, llassert(NULL != inv_item); return; } - - LLSD substitutions; - substitutions["RESIDENTS"] = name; - substitutions["ITEMS"] = inv_item->getName(); - LLSD payload; - payload["agent_id"] = dest_agent; - payload["item_id"] = inv_item->getUUID(); - payload["session_id"] = session_id; - payload["d&d_dest"] = dest.asString(); - LLNotificationsUtil::add("ShareItemsConfirmation", substitutions, payload, &give_inventory_cb); + if(gInventory.getItem(inv_item->getUUID()) + && LLGiveInventory::isInventoryGiveAcceptable(inv_item)) + { + LLSD substitutions; + substitutions["RESIDENTS"] = name; + substitutions["ITEMS"] = inv_item->getName(); + LLSD payload; + payload["agent_id"] = dest_agent; + payload["item_id"] = inv_item->getUUID(); + payload["session_id"] = session_id; + payload["d&d_dest"] = dest.asString(); + LLNotificationsUtil::add("ShareItemsConfirmation", substitutions, payload, &give_inventory_cb); + } } static void get_name_cb(const LLUUID& id, diff --git a/indra/newview/llvieweraudio.cpp b/indra/newview/llvieweraudio.cpp index 826d296117..fce42a1587 100755 --- a/indra/newview/llvieweraudio.cpp +++ b/indra/newview/llvieweraudio.cpp @@ -93,7 +93,12 @@ void LLViewerAudio::startInternetStreamWithAutoFade(std::string streamURI) switch (mFadeState) { - case FADE_IDLE: + case FADE_IDLE: + if (!gAudiop) + { + LL_WARNS("AudioEngine") << "LLAudioEngine instance doesn't exist!" << LL_ENDL; + break; + } // If a stream is playing fade it out first if (!gAudiop->getInternetStreamURL().empty()) { @@ -115,18 +120,18 @@ void LLViewerAudio::startInternetStreamWithAutoFade(std::string streamURI) break; } - case FADE_OUT: - startFading(); - registerIdleListener(); - break; + case FADE_OUT: + startFading(); + registerIdleListener(); + break; - case FADE_IN: - registerIdleListener(); - break; + case FADE_IN: + registerIdleListener(); + break; - default: - llwarns << "Unknown fading state: " << mFadeState << llendl; - break; + default: + llwarns << "Unknown fading state: " << mFadeState << llendl; + break; } } @@ -157,19 +162,26 @@ bool LLViewerAudio::onIdleUpdate() // we have finished the current fade operation if (mFadeState == FADE_OUT) { - // Clear URI - gAudiop->startInternetStream(LLStringUtil::null); - gAudiop->stopInternetStream(); + if (gAudiop) + { + // Clear URI + gAudiop->startInternetStream(LLStringUtil::null); + gAudiop->stopInternetStream(); + } if (!mNextStreamURI.empty()) { mFadeState = FADE_IN; - LLStreamingAudioInterface *stream = gAudiop->getStreamingAudioImpl(); - if(stream && stream->supportsAdjustableBufferSizes()) - stream->setBufferSizes(gSavedSettings.getU32("FMODExStreamBufferSize"),gSavedSettings.getU32("FMODExDecodeBufferSize")); + if (gAudiop) + { + LLStreamingAudioInterface *stream = gAudiop->getStreamingAudioImpl(); + if(stream && stream->supportsAdjustableBufferSizes()) + stream->setBufferSizes(gSavedSettings.getU32("FMODExStreamBufferSize"),gSavedSettings.getU32("FMODExDecodeBufferSize")); + + gAudiop->startInternetStream(mNextStreamURI); + } - gAudiop->startInternetStream(mNextStreamURI); startFading(); } else @@ -181,7 +193,7 @@ bool LLViewerAudio::onIdleUpdate() } else if (mFadeState == FADE_IN) { - if (mNextStreamURI != gAudiop->getInternetStreamURL()) + if (gAudiop && mNextStreamURI != gAudiop->getInternetStreamURL()) { mFadeState = FADE_OUT; startFading(); @@ -203,9 +215,12 @@ void LLViewerAudio::stopInternetStreamWithAutoFade() mFadeState = FADE_IDLE; mNextStreamURI = LLStringUtil::null; mDone = true; - - gAudiop->startInternetStream(LLStringUtil::null); - gAudiop->stopInternetStream(); + + if (gAudiop) + { + gAudiop->startInternetStream(LLStringUtil::null); + gAudiop->stopInternetStream(); + } } void LLViewerAudio::startFading() @@ -267,7 +282,7 @@ F32 LLViewerAudio::getFadeVolume() void LLViewerAudio::onTeleportStarted() { - if (!LLViewerAudio::getInstance()->getForcedTeleportFade()) + if (gAudiop && !LLViewerAudio::getInstance()->getForcedTeleportFade()) { // Even though the music was turned off it was starting up (with autoplay disabled) occasionally // after a failed teleport or after an intra-parcel teleport. Also, the music sometimes was not @@ -393,9 +408,10 @@ void audio_update_volume(bool force_update) } F32 mute_volume = mute_audio ? 0.0f : 1.0f; - // Sound Effects if (gAudiop) { + // Sound Effects + gAudiop->setMasterGain ( master_volume ); gAudiop->setDopplerFactor(gSavedSettings.getF32("AudioLevelDoppler")); @@ -425,11 +441,9 @@ void audio_update_volume(bool force_update) gSavedSettings.getBOOL("MuteUI") ? 0.f : gSavedSettings.getF32("AudioLevelUI")); gAudiop->setSecondaryGain(LLAudioEngine::AUDIO_TYPE_AMBIENT, gSavedSettings.getBOOL("MuteAmbient") ? 0.f : gSavedSettings.getF32("AudioLevelAmbient")); - } - // Streaming Music - if (gAudiop) - { + // Streaming Music + if (!progress_view_visible && LLViewerAudio::getInstance()->getForcedTeleportFade()) { LLViewerAudio::getInstance()->setWasPlaying(!gAudiop->getInternetStreamURL().empty()); @@ -527,6 +541,12 @@ void audio_update_wind(bool force_update) volume_delta = 1.f; } + if (!gAudiop) + { + LL_WARNS("AudioEngine") << "LLAudioEngine instance doesn't exist!" << LL_ENDL; + return; + } + // mute wind when not flying if (gAgent.getFlying()) { diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 21fb8d519b..2c132740fe 100755 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -67,7 +67,6 @@ #include "llvoavatarself.h" #include "llvovolume.h" #include "llwebprofile.h" -#include "llwebsharing.h" // For LLWebSharing::setOpenIDCookie(), *TODO: find a better way to do this! #include "llwindow.h" #include "llvieweraudio.h" @@ -1426,9 +1425,6 @@ void LLViewerMedia::setOpenIDCookie() getCookieStore()->setCookiesFromHost(sOpenIDCookie, authority.substr(host_start, host_end - host_start)); - // *HACK: Doing this here is nasty, find a better way. - LLWebSharing::instance().setOpenIDCookie(sOpenIDCookie); - // Do a web profile get so we can store the cookie LLSD headers = LLSD::emptyMap(); headers["Accept"] = "*/*"; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index c7c8da27f3..59e98fc882 100755 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -8235,6 +8235,45 @@ class LLWorldEnvSettings : public view_listener_t } }; +class LLWorldEnableEnvSettings : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + bool result = false; + std::string tod = userdata.asString(); + + if (tod == "region") + { + return LLEnvManagerNew::instance().getUseRegionSettings(); + } + + if (LLEnvManagerNew::instance().getUseFixedSky()) + { + if (tod == "sunrise") + { + result = (LLEnvManagerNew::instance().getSkyPresetName() == "Sunrise"); + } + else if (tod == "noon") + { + result = (LLEnvManagerNew::instance().getSkyPresetName() == "Midday"); + } + else if (tod == "sunset") + { + result = (LLEnvManagerNew::instance().getSkyPresetName() == "Sunset"); + } + else if (tod == "midnight") + { + result = (LLEnvManagerNew::instance().getSkyPresetName() == "Midnight"); + } + else + { + llwarns << "Unknown item" << llendl; + } + } + return result; + } +}; + class LLWorldEnvPreset : public view_listener_t { bool handleEvent(const LLSD& userdata) @@ -8573,6 +8612,7 @@ void initialize_menus() view_listener_t::addMenu(new LLWorldCheckAlwaysRun(), "World.CheckAlwaysRun"); view_listener_t::addMenu(new LLWorldEnvSettings(), "World.EnvSettings"); + view_listener_t::addMenu(new LLWorldEnableEnvSettings(), "World.EnableEnvSettings"); view_listener_t::addMenu(new LLWorldEnvPreset(), "World.EnvPreset"); view_listener_t::addMenu(new LLWorldEnableEnvPreset(), "World.EnableEnvPreset"); view_listener_t::addMenu(new LLWorldPostProcess(), "World.PostProcess"); diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index be78603e2d..4c95dcd6a2 100755 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -494,7 +494,9 @@ class LLFileEnableCloseAllWindows : public view_listener_t { bool handleEvent(const LLSD& userdata) { - bool open_children = gFloaterView->allChildrenClosed() && !LLFloaterSnapshot::getInstance()->isInVisibleChain(); + LLFloaterSnapshot* floater_snapshot = LLFloaterSnapshot::findInstance(); + bool is_floater_snapshot_opened = floater_snapshot && floater_snapshot->isInVisibleChain(); + bool open_children = gFloaterView->allChildrenClosed() && !is_floater_snapshot_opened; return !open_children; } }; diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index df5c7d5c2e..9d12587801 100755 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -3522,6 +3522,12 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) } else { + // make sure that we don't have an empty or all-whitespace name + LLStringUtil::trim(from_name); + if (from_name.empty()) + { + from_name = LLTrans::getString("Unnamed"); + } chat.mFromName = from_name; } @@ -4646,7 +4652,11 @@ void process_time_synch(LLMessageSystem *mesgsys, void **user_data) void process_sound_trigger(LLMessageSystem *msg, void **) { - if (!gAudiop) return; + if (!gAudiop) + { + LL_WARNS("AudioEngine") << "LLAudioEngine instance doesn't exist!" << LL_ENDL; + return; + } U64 region_handle = 0; F32 gain = 0; @@ -4706,6 +4716,7 @@ void process_preload_sound(LLMessageSystem *msg, void **user_data) { if (!gAudiop) { + LL_WARNS("AudioEngine") << "LLAudioEngine instance doesn't exist!" << LL_ENDL; return; } @@ -4736,9 +4747,9 @@ void process_preload_sound(LLMessageSystem *msg, void **user_data) LLVector3d pos_global = objectp->getPositionGlobal(); if (gAgent.canAccessMaturityAtGlobal(pos_global)) { - // Add audioData starts a transfer internally. - sourcep->addAudioData(datap, FALSE); -} + // Add audioData starts a transfer internally. + sourcep->addAudioData(datap, FALSE); + } } void process_attached_sound(LLMessageSystem *msg, void **user_data) diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index e62998db70..c789719291 100755 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -4950,6 +4950,7 @@ void LLViewerObject::setAttachedSound(const LLUUID &audio_uuid, const LLUUID& ow { if (!gAudiop) { + LL_WARNS("AudioEngine") << "LLAudioEngine instance doesn't exist!" << LL_ENDL; return; } @@ -5032,7 +5033,10 @@ LLAudioSource *LLViewerObject::getAudioSource(const LLUUID& owner_id) LLAudioSourceVO *asvop = new LLAudioSourceVO(mID, owner_id, 0.01f, this); mAudioSourcep = asvop; - if(gAudiop) gAudiop->addAudioSource(asvop); + if(gAudiop) + { + gAudiop->addAudioSource(asvop); + } } return mAudioSourcep; @@ -5040,10 +5044,6 @@ LLAudioSource *LLViewerObject::getAudioSource(const LLUUID& owner_id) void LLViewerObject::adjustAudioGain(const F32 gain) { - if (!gAudiop) - { - return; - } if (mAudioSourcep) { mAudioGain = gain; diff --git a/indra/newview/llviewerparceloverlay.cpp b/indra/newview/llviewerparceloverlay.cpp index a1c12c5cd6..fad77bce25 100755 --- a/indra/newview/llviewerparceloverlay.cpp +++ b/indra/newview/llviewerparceloverlay.cpp @@ -76,10 +76,13 @@ LLViewerParcelOverlay::LLViewerParcelOverlay(LLViewerRegion* region, F32 region_ // // Create the base texture. U8 *raw = mImageRaw->getData(); - const S32 COUNT = mParcelGridsPerEdge * mParcelGridsPerEdge * OVERLAY_IMG_COMPONENTS; - for (S32 i = 0; i < COUNT; i++) + if (raw) { - raw[i] = 0; + const S32 COUNT = mParcelGridsPerEdge * mParcelGridsPerEdge * OVERLAY_IMG_COMPONENTS; + for (S32 i = 0; i < COUNT; i++) + { + raw[i] = 0; + } } //mTexture->setSubImage(mImageRaw, 0, 0, mParcelGridsPerEdge, mParcelGridsPerEdge); @@ -380,10 +383,13 @@ void LLViewerParcelOverlay::updateOverlayTexture() break; } - raw[pixel_index + 0] = (U8)r; - raw[pixel_index + 1] = (U8)g; - raw[pixel_index + 2] = (U8)b; - raw[pixel_index + 3] = (U8)a; + if (raw) + { + raw[pixel_index + 0] = (U8)r; + raw[pixel_index + 1] = (U8)g; + raw[pixel_index + 2] = (U8)b; + raw[pixel_index + 3] = (U8)a; + } pixel_index += OVERLAY_IMG_COMPONENTS; } diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index 8f8bfa23c1..a8716985cb 100755 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -115,7 +115,7 @@ public: void setAllowSetHome(BOOL b) { setRegionFlag(REGION_FLAGS_ALLOW_SET_HOME, b); } void setResetHomeOnTeleport(BOOL b) { setRegionFlag(REGION_FLAGS_RESET_HOME_ON_TELEPORT, b); } void setSunFixed(BOOL b) { setRegionFlag(REGION_FLAGS_SUN_FIXED, b); } - void setBlockFly(BOOL b) { setRegionFlag(REGION_FLAGS_BLOCK_FLY, b); } + //void setBlockFly(BOOL b) { setRegionFlag(REGION_FLAGS_BLOCK_FLY, b); } Never used void setAllowDirectTeleport(BOOL b) { setRegionFlag(REGION_FLAGS_ALLOW_DIRECT_TELEPORT, b); } diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 3da6d33d72..6364eee3ec 100755 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -337,6 +337,11 @@ void LLViewerTextureManager::init() const S32 dim = 128; LLPointer<LLImageRaw> image_raw = new LLImageRaw(dim,dim,3); U8* data = image_raw->getData(); + + if (!data) + { + return; + } memset(data, 0, dim * dim * 3) ; LLViewerTexture::sBlackImagep = LLViewerTextureManager::getLocalTexture(image_raw.get(), TRUE) ; @@ -373,8 +378,12 @@ void LLViewerTextureManager::init() #else LLViewerFetchedTexture::sDefaultImagep = LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, TRUE, LLGLTexture::BOOST_UI); #endif - LLViewerFetchedTexture::sDefaultImagep->dontDiscard(); - LLViewerFetchedTexture::sDefaultImagep->setCategory(LLGLTexture::OTHER) ; + + if (LLViewerFetchedTexture::sDefaultImagep) + { + LLViewerFetchedTexture::sDefaultImagep->dontDiscard(); + LLViewerFetchedTexture::sDefaultImagep->setCategory(LLGLTexture::OTHER) ; + } LLViewerFetchedTexture::sSmokeImagep = LLViewerTextureManager::getFetchedTexture(IMG_SMOKE, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); LLViewerFetchedTexture::sSmokeImagep->setNoDelete() ; @@ -690,7 +699,7 @@ bool LLViewerTexture::bindDefaultImage(S32 stage) if (stage < 0) return false; bool res = true; - if (LLViewerFetchedTexture::sDefaultImagep.notNull() && (this != LLViewerFetchedTexture::sDefaultImagep.get())) + if (LLViewerFetchedTexture::sDefaultImagep && LLViewerFetchedTexture::sDefaultImagep.notNull() && (this != LLViewerFetchedTexture::sDefaultImagep.get())) { // use default if we've got it res = gGL.getTexUnit(stage)->bind(LLViewerFetchedTexture::sDefaultImagep); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 3193a2955b..f2b5ef54fd 100755 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -438,10 +438,7 @@ public: } if (gDisplayWindInfo) { - if (gAudiop) - { - audio_text= llformat("Audio for wind: %d", gAudiop->isWindEnabled()); - } + audio_text = llformat("Audio for wind: %d", gAudiop ? gAudiop->isWindEnabled() : -1); addText(xpos, ypos, audio_text); ypos += y_inc; } if (gDisplayFOV) diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 082a85e217..ca004962d5 100755 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -818,7 +818,8 @@ void LLVOAvatarSelf::setLocalTextureTE(U8 te, LLViewerTexture* image, U32 index) return; } - if (getTEImage(te)->getID() == image->getID()) + LLViewerTexture * tx = getTEImage(te); + if (!tx || tx->getID() == image->getID()) { return; } @@ -1698,6 +1699,7 @@ S32 LLVOAvatarSelf::getLocalDiscardLevel(ETextureIndex type, U32 wearable_index) const LLViewerFetchedTexture* image = dynamic_cast<LLViewerFetchedTexture*>( local_tex_obj->getImage() ); if (type >= 0 && local_tex_obj->getID() != IMG_DEFAULT_AVATAR + && image && !image->isMissingAsset()) { return image->getDiscardLevel(); @@ -2036,7 +2038,10 @@ BOOL LLVOAvatarSelf::getIsCloud() const /*static*/ void LLVOAvatarSelf::debugOnTimingLocalTexLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata) { - gAgentAvatarp->debugTimingLocalTexLoaded(success, src_vi, src, aux_src, discard_level, final, userdata); + if (gAgentAvatarp) + { + gAgentAvatarp->debugTimingLocalTexLoaded(success, src_vi, src, aux_src, discard_level, final, userdata); + } } void LLVOAvatarSelf::debugTimingLocalTexLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata) diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp index 93f0e50336..467152881e 100755 --- a/indra/newview/llvosky.cpp +++ b/indra/newview/llvosky.cpp @@ -257,18 +257,21 @@ LLSkyTex::~LLSkyTex() void LLSkyTex::initEmpty(const S32 tex) { U8* data = mImageRaw[tex]->getData(); - for (S32 i = 0; i < sResolution; ++i) + if (data) { - for (S32 j = 0; j < sResolution; ++j) + for (S32 i = 0; i < sResolution; ++i) { - const S32 basic_offset = (i * sResolution + j); - S32 offset = basic_offset * sComponents; - data[offset] = 0; - data[offset+1] = 0; - data[offset+2] = 0; - data[offset+3] = 255; - - mSkyData[basic_offset].setToBlack(); + for (S32 j = 0; j < sResolution; ++j) + { + const S32 basic_offset = (i * sResolution + j); + S32 offset = basic_offset * sComponents; + data[offset] = 0; + data[offset+1] = 0; + data[offset+2] = 0; + data[offset+3] = 255; + + mSkyData[basic_offset].setToBlack(); + } } } @@ -279,17 +282,21 @@ void LLSkyTex::create(const F32 brightness) { /// Brightness ignored for now. U8* data = mImageRaw[sCurrent]->getData(); - for (S32 i = 0; i < sResolution; ++i) + if (data) { - for (S32 j = 0; j < sResolution; ++j) + for (S32 i = 0; i < sResolution; ++i) { - const S32 basic_offset = (i * sResolution + j); - S32 offset = basic_offset * sComponents; - U32* pix = (U32*)(data + offset); - LLColor4U temp = LLColor4U(mSkyData[basic_offset]); - *pix = temp.mAll; + for (S32 j = 0; j < sResolution; ++j) + { + const S32 basic_offset = (i * sResolution + j); + S32 offset = basic_offset * sComponents; + U32* pix = (U32*)(data + offset); + LLColor4U temp = LLColor4U(mSkyData[basic_offset]); + *pix = temp.mAll; + } } } + createGLImage(sCurrent); } diff --git a/indra/newview/llwebsharing.cpp b/indra/newview/llwebsharing.cpp deleted file mode 100755 index 3a80051b9b..0000000000 --- a/indra/newview/llwebsharing.cpp +++ /dev/null @@ -1,603 +0,0 @@ -/** - * @file llwebsharing.cpp - * @author Aimee - * @brief Web Snapshot Sharing - * - * $LicenseInfo:firstyear=2010&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" - -#include "llwebsharing.h" - -#include "llagentui.h" -#include "llbufferstream.h" -#include "llhttpclient.h" -#include "llhttpstatuscodes.h" -#include "llsdserialize.h" -#include "llsdutil.h" -#include "llurl.h" -#include "llviewercontrol.h" - -#include <boost/regex.hpp> -#include <boost/algorithm/string/replace.hpp> - - - -/////////////////////////////////////////////////////////////////////////////// -// -class LLWebSharingConfigResponder : public LLHTTPClient::Responder -{ - LOG_CLASS(LLWebSharingConfigResponder); -public: - /// Overrides the default LLSD parsing behaviour, to allow parsing a JSON response. - virtual void completedRaw(U32 status, const std::string& reason, - const LLChannelDescriptors& channels, - const LLIOPipe::buffer_ptr_t& buffer) - { - LLSD content; - LLBufferStream istr(channels, buffer.get()); - LLPointer<LLSDParser> parser = new LLSDNotationParser(); - - if (parser->parse(istr, content, LLSDSerialize::SIZE_UNLIMITED) == LLSDParser::PARSE_FAILURE) - { - LL_WARNS("WebSharing") << "Failed to deserialize LLSD from JSON response. " << " [" << status << "]: " << reason << LL_ENDL; - } - else - { - completed(status, reason, content); - } - } - - virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content) - { - LL_WARNS("WebSharing") << "Error [status:" << status << "]: " << content << LL_ENDL; - } - - virtual void result(const LLSD& content) - { - LLWebSharing::instance().receiveConfig(content); - } -}; - - - -/////////////////////////////////////////////////////////////////////////////// -// -class LLWebSharingOpenIDAuthResponder : public LLHTTPClient::Responder -{ - LOG_CLASS(LLWebSharingOpenIDAuthResponder); -public: - /* virtual */ void completedHeader(U32 status, const std::string& reason, const LLSD& content) - { - completed(status, reason, content); - } - - /* virtual */ void completedRaw(U32 status, const std::string& reason, - const LLChannelDescriptors& channels, - const LLIOPipe::buffer_ptr_t& buffer) - { - /// Left empty to override the default LLSD parsing behaviour. - } - - virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content) - { - if (HTTP_UNAUTHORIZED == status) - { - LL_WARNS("WebSharing") << "AU account not authenticated." << LL_ENDL; - // *TODO: No account found on AU, so start the account creation process here. - } - else - { - LL_WARNS("WebSharing") << "Error [status:" << status << "]: " << content << LL_ENDL; - LLWebSharing::instance().retryOpenIDAuth(); - } - - } - - virtual void result(const LLSD& content) - { - if (content.has("set-cookie")) - { - // OpenID request succeeded and returned a session cookie. - LLWebSharing::instance().receiveSessionCookie(content["set-cookie"].asString()); - } - } -}; - - - -/////////////////////////////////////////////////////////////////////////////// -// -class LLWebSharingSecurityTokenResponder : public LLHTTPClient::Responder -{ - LOG_CLASS(LLWebSharingSecurityTokenResponder); -public: - /// Overrides the default LLSD parsing behaviour, to allow parsing a JSON response. - virtual void completedRaw(U32 status, const std::string& reason, - const LLChannelDescriptors& channels, - const LLIOPipe::buffer_ptr_t& buffer) - { - LLSD content; - LLBufferStream istr(channels, buffer.get()); - LLPointer<LLSDParser> parser = new LLSDNotationParser(); - - if (parser->parse(istr, content, LLSDSerialize::SIZE_UNLIMITED) == LLSDParser::PARSE_FAILURE) - { - LL_WARNS("WebSharing") << "Failed to deserialize LLSD from JSON response. " << " [" << status << "]: " << reason << LL_ENDL; - LLWebSharing::instance().retryOpenIDAuth(); - } - else - { - completed(status, reason, content); - } - } - - virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content) - { - LL_WARNS("WebSharing") << "Error [status:" << status << "]: " << content << LL_ENDL; - LLWebSharing::instance().retryOpenIDAuth(); - } - - virtual void result(const LLSD& content) - { - if (content[0].has("st") && content[0].has("expires")) - { - const std::string& token = content[0]["st"].asString(); - const std::string& expires = content[0]["expires"].asString(); - if (LLWebSharing::instance().receiveSecurityToken(token, expires)) - { - // Sucessfully received a valid security token. - return; - } - } - else - { - LL_WARNS("WebSharing") << "No security token received." << LL_ENDL; - } - - LLWebSharing::instance().retryOpenIDAuth(); - } -}; - - - -/////////////////////////////////////////////////////////////////////////////// -// -class LLWebSharingUploadResponder : public LLHTTPClient::Responder -{ - LOG_CLASS(LLWebSharingUploadResponder); -public: - /// Overrides the default LLSD parsing behaviour, to allow parsing a JSON response. - virtual void completedRaw(U32 status, const std::string& reason, - const LLChannelDescriptors& channels, - const LLIOPipe::buffer_ptr_t& buffer) - { -/* - // Dump the body, for debugging. - - LLBufferStream istr1(channels, buffer.get()); - std::ostringstream ostr; - std::string body; - - while (istr1.good()) - { - char buf[1024]; - istr1.read(buf, sizeof(buf)); - body.append(buf, istr1.gcount()); - } - LL_DEBUGS("WebSharing") << body << LL_ENDL; -*/ - LLSD content; - LLBufferStream istr(channels, buffer.get()); - LLPointer<LLSDParser> parser = new LLSDNotationParser(); - - if (parser->parse(istr, content, LLSDSerialize::SIZE_UNLIMITED) == LLSDParser::PARSE_FAILURE) - { - LL_WARNS("WebSharing") << "Failed to deserialize LLSD from JSON response. " << " [" << status << "]: " << reason << LL_ENDL; - } - else - { - completed(status, reason, content); - } - } - - virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content) - { - LL_WARNS("WebSharing") << "Error [status:" << status << "]: " << content << LL_ENDL; - } - - virtual void result(const LLSD& content) - { - if (content[0].has("result") && content[0].has("id") && - content[0]["id"].asString() == "newMediaItem") - { - // *TODO: Upload successful, continue from here to post metadata and create AU activity. - } - else - { - LL_WARNS("WebSharing") << "Error [" << content[0]["code"].asString() - << "]: " << content[0]["message"].asString() << LL_ENDL; - } - } -}; - - - -/////////////////////////////////////////////////////////////////////////////// -// -LLWebSharing::LLWebSharing() -: mConfig(), - mSecurityToken(LLSD::emptyMap()), - mEnabled(false), - mRetries(0), - mImage(NULL), - mMetadata(LLSD::emptyMap()) -{ -} - -void LLWebSharing::init() -{ - if (!mEnabled) - { - sendConfigRequest(); - } -} - -bool LLWebSharing::shareSnapshot(LLImageJPEG* snapshot, LLSD& metadata) -{ - LL_INFOS("WebSharing") << metadata << LL_ENDL; - - if (mImage) - { - // *TODO: Handle this possibility properly, queue them up? - LL_WARNS("WebSharing") << "Snapshot upload already in progress." << LL_ENDL; - return false; - } - - mImage = snapshot; - mMetadata = metadata; - - // *TODO: Check whether we have a valid security token already and re-use it. - sendOpenIDAuthRequest(); - return true; -} - -bool LLWebSharing::setOpenIDCookie(const std::string& cookie) -{ - LL_DEBUGS("WebSharing") << "Setting OpenID cookie " << cookie << LL_ENDL; - mOpenIDCookie = cookie; - return validateConfig(); -} - -bool LLWebSharing::receiveConfig(const LLSD& config) -{ - LL_DEBUGS("WebSharing") << "Received config data: " << config << LL_ENDL; - mConfig = config; - return validateConfig(); -} - -bool LLWebSharing::receiveSessionCookie(const std::string& cookie) -{ - LL_DEBUGS("WebSharing") << "Received AU session cookie: " << cookie << LL_ENDL; - mSessionCookie = cookie; - - // Fetch a security token using the new session cookie. - LLWebSharing::instance().sendSecurityTokenRequest(); - - return (!mSessionCookie.empty()); -} - -bool LLWebSharing::receiveSecurityToken(const std::string& token, const std::string& expires) -{ - mSecurityToken["st"] = token; - mSecurityToken["expires"] = LLDate(expires); - - if (!securityTokenIsValid(mSecurityToken)) - { - LL_WARNS("WebSharing") << "Invalid security token received: \"" << token << "\" Expires: " << expires << LL_ENDL; - return false; - } - - LL_DEBUGS("WebSharing") << "Received security token: \"" << token << "\" Expires: " << expires << LL_ENDL; - mRetries = 0; - - // Continue the upload process now that we have a security token. - sendUploadRequest(); - - return true; -} - -void LLWebSharing::sendConfigRequest() -{ - std::string config_url = gSavedSettings.getString("SnapshotConfigURL"); - LL_DEBUGS("WebSharing") << "Requesting Snapshot Sharing config data from: " << config_url << LL_ENDL; - - LLSD headers = LLSD::emptyMap(); - headers["Accept"] = "application/json"; - - LLHTTPClient::get(config_url, new LLWebSharingConfigResponder(), headers); -} - -void LLWebSharing::sendOpenIDAuthRequest() -{ - std::string auth_url = mConfig["openIdAuthUrl"]; - LL_DEBUGS("WebSharing") << "Starting OpenID Auth: " << auth_url << LL_ENDL; - - LLSD headers = LLSD::emptyMap(); - headers["Cookie"] = mOpenIDCookie; - headers["Accept"] = "*/*"; - - // Send request, successful login will trigger fetching a security token. - LLHTTPClient::get(auth_url, new LLWebSharingOpenIDAuthResponder(), headers); -} - -bool LLWebSharing::retryOpenIDAuth() -{ - if (mRetries++ >= MAX_AUTH_RETRIES) - { - LL_WARNS("WebSharing") << "Exceeded maximum number of authorization attempts, aborting." << LL_ENDL; - mRetries = 0; - return false; - } - - LL_WARNS("WebSharing") << "Authorization failed, retrying (" << mRetries << "/" << MAX_AUTH_RETRIES << ")" << LL_ENDL; - sendOpenIDAuthRequest(); - return true; -} - -void LLWebSharing::sendSecurityTokenRequest() -{ - std::string token_url = mConfig["securityTokenUrl"]; - LL_DEBUGS("WebSharing") << "Fetching security token from: " << token_url << LL_ENDL; - - LLSD headers = LLSD::emptyMap(); - headers["Cookie"] = mSessionCookie; - - headers["Accept"] = "application/json"; - headers["Content-Type"] = "application/json"; - - std::ostringstream body; - body << "{ \"gadgets\": [{ \"url\":\"" - << mConfig["gadgetSpecUrl"].asString() - << "\" }] }"; - - // postRaw() takes ownership of the buffer and releases it later. - size_t size = body.str().size(); - U8 *data = new U8[size]; - memcpy(data, body.str().data(), size); - - // Send request, receiving a valid token will trigger snapshot upload. - LLHTTPClient::postRaw(token_url, data, size, new LLWebSharingSecurityTokenResponder(), headers); -} - -void LLWebSharing::sendUploadRequest() -{ - LLUriTemplate upload_template(mConfig["openSocialRpcUrlTemplate"].asString()); - std::string upload_url(upload_template.buildURI(mSecurityToken)); - - LL_DEBUGS("WebSharing") << "Posting upload to: " << upload_url << LL_ENDL; - - static const std::string BOUNDARY("------------abcdef012345xyZ"); - - LLSD headers = LLSD::emptyMap(); - headers["Cookie"] = mSessionCookie; - - headers["Accept"] = "application/json"; - headers["Content-Type"] = "multipart/form-data; boundary=" + BOUNDARY; - - std::ostringstream body; - body << "--" << BOUNDARY << "\r\n" - << "Content-Disposition: form-data; name=\"request\"\r\n\r\n" - << "[{" - << "\"method\":\"mediaItems.create\"," - << "\"params\": {" - << "\"userId\":[\"@me\"]," - << "\"groupId\":\"@self\"," - << "\"mediaItem\": {" - << "\"mimeType\":\"image/jpeg\"," - << "\"type\":\"image\"," - << "\"url\":\"@field:image1\"" - << "}" - << "}," - << "\"id\":\"newMediaItem\"" - << "}]" - << "--" << BOUNDARY << "\r\n" - << "Content-Disposition: form-data; name=\"image1\"\r\n\r\n"; - - // Insert the image data. - // *FIX: Treating this as a string will probably screw it up ... - U8* image_data = mImage->getData(); - for (S32 i = 0; i < mImage->getDataSize(); ++i) - { - body << image_data[i]; - } - - body << "\r\n--" << BOUNDARY << "--\r\n"; - - // postRaw() takes ownership of the buffer and releases it later. - size_t size = body.str().size(); - U8 *data = new U8[size]; - memcpy(data, body.str().data(), size); - - // Send request, successful upload will trigger posting metadata. - LLHTTPClient::postRaw(upload_url, data, size, new LLWebSharingUploadResponder(), headers); -} - -bool LLWebSharing::validateConfig() -{ - // Check the OpenID Cookie has been set. - if (mOpenIDCookie.empty()) - { - mEnabled = false; - return mEnabled; - } - - if (!mConfig.isMap()) - { - mEnabled = false; - return mEnabled; - } - - // Template to match the received config against. - LLSD required(LLSD::emptyMap()); - required["gadgetSpecUrl"] = ""; - required["loginTokenUrl"] = ""; - required["openIdAuthUrl"] = ""; - required["photoPageUrlTemplate"] = ""; - required["openSocialRpcUrlTemplate"] = ""; - required["securityTokenUrl"] = ""; - required["tokenBasedLoginUrlTemplate"] = ""; - required["viewerIdUrl"] = ""; - - std::string mismatch(llsd_matches(required, mConfig)); - if (!mismatch.empty()) - { - LL_WARNS("WebSharing") << "Malformed config data response: " << mismatch << LL_ENDL; - mEnabled = false; - return mEnabled; - } - - mEnabled = true; - return mEnabled; -} - -// static -bool LLWebSharing::securityTokenIsValid(LLSD& token) -{ - return (token.has("st") && - token.has("expires") && - (token["st"].asString() != "") && - (token["expires"].asDate() > LLDate::now())); -} - - - -/////////////////////////////////////////////////////////////////////////////// -// -LLUriTemplate::LLUriTemplate(const std::string& uri_template) - : - mTemplate(uri_template) -{ -} - -std::string LLUriTemplate::buildURI(const LLSD& vars) -{ - // *TODO: Separate parsing the template from building the URI. - // Parsing only needs to happen on construction/assignnment. - - static const std::string VAR_NAME_REGEX("[[:alpha:]][[:alnum:]\\._-]*"); - // Capture var name with and without surrounding {} - static const std::string VAR_REGEX("\\{(" + VAR_NAME_REGEX + ")\\}"); - // Capture delimiter and comma separated list of var names. - static const std::string JOIN_REGEX("\\{-join\\|(&)\\|(" + VAR_NAME_REGEX + "(?:," + VAR_NAME_REGEX + ")*)\\}"); - - std::string uri = mTemplate; - boost::smatch results; - - // Validate and expand join operators : {-join|&|var1,var2,...} - - boost::regex join_regex(JOIN_REGEX); - - while (boost::regex_search(uri, results, join_regex)) - { - // Extract the list of var names from the results. - std::string delim = results[1].str(); - std::string var_list = results[2].str(); - - // Expand the list of vars into a query string with their values - std::string query = expandJoin(delim, var_list, vars); - - // Substitute the query string into the template. - uri = boost::regex_replace(uri, join_regex, query, boost::format_first_only); - } - - // Expand vars : {var1} - - boost::regex var_regex(VAR_REGEX); - - std::set<std::string> var_names; - std::string::const_iterator start = uri.begin(); - std::string::const_iterator end = uri.end(); - - // Extract the var names used. - while (boost::regex_search(start, end, results, var_regex)) - { - var_names.insert(results[1].str()); - start = results[0].second; - } - - // Replace each var with its value. - for (std::set<std::string>::const_iterator it = var_names.begin(); it != var_names.end(); ++it) - { - std::string var = *it; - if (vars.has(var)) - { - boost::replace_all(uri, "{" + var + "}", vars[var].asString()); - } - } - - return uri; -} - -std::string LLUriTemplate::expandJoin(const std::string& delim, const std::string& var_list, const LLSD& vars) -{ - std::ostringstream query; - - typedef boost::tokenizer<boost::char_separator<char> > tokenizer; - boost::char_separator<char> sep(","); - tokenizer var_names(var_list, sep); - tokenizer::const_iterator it = var_names.begin(); - - // First var does not need a delimiter - if (it != var_names.end()) - { - const std::string& name = *it; - if (vars.has(name)) - { - // URL encode the value before appending the name=value pair. - query << name << "=" << escapeURL(vars[name].asString()); - } - } - - for (++it; it != var_names.end(); ++it) - { - const std::string& name = *it; - if (vars.has(name)) - { - // URL encode the value before appending the name=value pair. - query << delim << name << "=" << escapeURL(vars[name].asString()); - } - } - - return query.str(); -} - -// static -std::string LLUriTemplate::escapeURL(const std::string& unescaped) -{ - char* escaped = curl_escape(unescaped.c_str(), unescaped.size()); - std::string result = escaped; - curl_free(escaped); - return result; -} - diff --git a/indra/newview/llwebsharing.h b/indra/newview/llwebsharing.h deleted file mode 100755 index ad9c99c224..0000000000 --- a/indra/newview/llwebsharing.h +++ /dev/null @@ -1,224 +0,0 @@ -/** - * @file llwebsharing.h - * @author Aimee - * @brief Web Snapshot Sharing - * - * $LicenseInfo:firstyear=2010&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#ifndef LL_LLWEBSHARING_H -#define LL_LLWEBSHARING_H - -#include "llimagejpeg.h" -#include "llsingleton.h" - - - -/** - * @class LLWebSharing - * - * Manages authentication to, and interaction with, a web service allowing the - * upload of snapshot images taken within the viewer, using OpenID and the - * OpenSocial APIs. - * http://www.opensocial.org/Technical-Resources/opensocial-spec-v09/RPC-Protocol.html - */ -class LLWebSharing : public LLSingleton<LLWebSharing> -{ - LOG_CLASS(LLWebSharing); -public: - /* - * Performs initial setup, by requesting config data from the web service if - * it has not already been received. - */ - void init(); - - /* - * @return true if both the OpenID cookie and config data have been received. - */ - bool enabled() const { return mEnabled; }; - - /* - * Sets the OpenID cookie to use for login to the web service. - * - * @param cookie a string containing the OpenID cookie. - * - * @return true if both the OpenID cookie and config data have been received. - */ - bool setOpenIDCookie(const std::string& cookie); - - /* - * Receive config data used to connect to the web service. - * - * @param config an LLSD map of URL templates for the web service end-points. - * - * @return true if both the OpenID cookie and config data have been received. - * - * @see sendConfigRequest() - */ - bool receiveConfig(const LLSD& config); - - /* - * Receive the session cookie from the web service, which is the result of - * the OpenID login process. - * - * @see sendOpenIDAuthRequest() - */ - bool receiveSessionCookie(const std::string& cookie); - - /* - * Receive a security token for the upload service. - * - * @see sendSecurityTokenRequest() - */ - bool receiveSecurityToken(const std::string& token, const std::string& expires); - - /* - * Restarts the authentication process if the maximum number of retries has - * not been exceeded. - * - * @return true if retrying, false if LLWebSharing::MAX_AUTH_RETRIES has been exceeded. - */ - bool retryOpenIDAuth(); - - /* - * Post a snapshot to the upload service. - * - * @return true if accepted for upload, false if already uploading another image. - */ - bool shareSnapshot(LLImageJPEG* snapshot, LLSD& metadata); - -private: - static const S32 MAX_AUTH_RETRIES = 4; - - friend class LLSingleton<LLWebSharing>; - - LLWebSharing(); - ~LLWebSharing() {}; - - /* - * Request a map of URLs and URL templates to the web service end-points. - * - * @see receiveConfig() - */ - void sendConfigRequest(); - - /* - * Initiate the OpenID login process. - * - * @see receiveSessionCookie() - */ - void sendOpenIDAuthRequest(); - - /* - * Request a security token for the upload service. - * - * @see receiveSecurityToken() - */ - void sendSecurityTokenRequest(); - - /* - * Request a security token for the upload service. - * - * @see receiveSecurityToken() - */ - void sendUploadRequest(); - - /* - * Checks all necessary config information has been received, and sets mEnabled. - * - * @return true if both the OpenID cookie and config data have been received. - */ - bool validateConfig(); - - /* - * Checks the security token is present and has not expired. - * - * @param token an LLSD map containing the token string and the time it expires. - * - * @return true if the token is not empty and has not expired. - */ - static bool securityTokenIsValid(LLSD& token); - - std::string mOpenIDCookie; - std::string mSessionCookie; - LLSD mSecurityToken; - - LLSD mConfig; - bool mEnabled; - - LLPointer<LLImageJPEG> mImage; - LLSD mMetadata; - - S32 mRetries; -}; - -/** - * @class LLUriTemplate - * - * @brief Builds complete URIs, given URI template and a map of keys and values - * to use for substition. - * Note: This is only a partial implementation of a draft standard required - * by the web API used by LLWebSharing. - * See: http://tools.ietf.org/html/draft-gregorio-uritemplate-03 - * - * @see LLWebSharing - */ -class LLUriTemplate -{ - LOG_CLASS(LLUriTemplate); -public: - LLUriTemplate(const std::string& uri_template); - ~LLUriTemplate() {}; - - /* - * Builds a complete URI from the template. - * - * @param vars an LLSD map of keys and values for substitution. - * - * @return a string containing the complete URI. - */ - std::string buildURI(const LLSD& vars); - -private: - /* - * Builds a URL query string. - * - * @param delim a string containing the separator to use between name=value pairs. - * @param var_list a string containing a comma separated list of variable names. - * @param vars an LLSD map of keys and values for substitution. - * - * @return a URL query string. - */ - std::string expandJoin(const std::string& delim, const std::string& var_list, const LLSD& vars); - - /* - * URL escape the given string. - * LLWeb::escapeURL() only does a partial escape, so this uses curl_escape() instead. - */ - static std::string escapeURL(const std::string& unescaped); - - std::string mTemplate; -}; - - - -#endif // LL_LLWEBSHARING_H diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index 85614f397c..27256af97a 100755 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -101,15 +101,21 @@ LLWorld::LLWorld() : LLPointer<LLImageRaw> raw = new LLImageRaw(1,1,4); U8 *default_texture = raw->getData(); - *(default_texture++) = MAX_WATER_COLOR.mV[0]; - *(default_texture++) = MAX_WATER_COLOR.mV[1]; - *(default_texture++) = MAX_WATER_COLOR.mV[2]; - *(default_texture++) = MAX_WATER_COLOR.mV[3]; - - mDefaultWaterTexturep = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE); - gGL.getTexUnit(0)->bind(mDefaultWaterTexturep); - mDefaultWaterTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); + if (default_texture) + { + *(default_texture++) = MAX_WATER_COLOR.mV[0]; + *(default_texture++) = MAX_WATER_COLOR.mV[1]; + *(default_texture++) = MAX_WATER_COLOR.mV[2]; + *(default_texture++) = MAX_WATER_COLOR.mV[3]; + } + + if (mDefaultWaterTexturep) + { + mDefaultWaterTexturep = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE); + gGL.getTexUnit(0)->bind(mDefaultWaterTexturep); + mDefaultWaterTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); + } } diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 5da8a78b1b..0af1143ae8 100755 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -4410,9 +4410,11 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) sUnderWaterRender = FALSE; } - gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sDefaultImagep); - LLViewerFetchedTexture::sDefaultImagep->setAddressMode(LLTexUnit::TAM_WRAP); - + if (LLViewerFetchedTexture::sDefaultImagep) + { + gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sDefaultImagep); + LLViewerFetchedTexture::sDefaultImagep->setAddressMode(LLTexUnit::TAM_WRAP); + } ////////////////////////////////////////////// // diff --git a/indra/newview/skins/default/xui/da/strings.xml b/indra/newview/skins/default/xui/da/strings.xml index 11d100eeff..74d160dfae 100755 --- a/indra/newview/skins/default/xui/da/strings.xml +++ b/indra/newview/skins/default/xui/da/strings.xml @@ -1172,7 +1172,8 @@ Prøv venligst om lidt igen. <string name="InventoryNoTexture"> Du har ikke en kopi af denne tekstur i din beholdning </string> - <string name="no_transfer" value=" (ikke overdragbar)"/> + <string name="Unconstrained">Ikke låst</string> + <string name="no_transfer" value=" (ikke overdragbar)"/> <string name="no_modify" value=" (ikke redigere)"/> <string name="no_copy" value=" (ikke kopiere)"/> <string name="worn" value=" (båret)"/> diff --git a/indra/newview/skins/default/xui/de/strings.xml b/indra/newview/skins/default/xui/de/strings.xml index 4268b95370..082febd709 100755 --- a/indra/newview/skins/default/xui/de/strings.xml +++ b/indra/newview/skins/default/xui/de/strings.xml @@ -1267,7 +1267,8 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden. <string name="InventoryNoTexture"> Sie haben keine Kopie dieser Textur in Ihrem Inventar. </string> - <string name="InventoryInboxNoItems"> + <string name="Unconstrained">keines</string> + <string name="InventoryInboxNoItems"> Einkäufe aus dem Marktplatz erscheinen hier. Sie können diese dann zur Verwendung in Ihr Inventar ziehen. </string> <string name="MarketplaceURL"> diff --git a/indra/newview/skins/default/xui/en/floater_places.xml b/indra/newview/skins/default/xui/en/floater_places.xml index b241e265a9..31dd6d2c64 100755 --- a/indra/newview/skins/default/xui/en/floater_places.xml +++ b/indra/newview/skins/default/xui/en/floater_places.xml @@ -2,6 +2,7 @@ <floater positioning="cascading" + default_tab_group="1" legacy_header_height="18" can_resize="true" height="588" @@ -16,6 +17,7 @@ width="333"> <panel top="18" + tab_group="1" class="panel_places" name="main_panel" filename="panel_places.xml" diff --git a/indra/newview/skins/default/xui/en/floater_preview_texture.xml b/indra/newview/skins/default/xui/en/floater_preview_texture.xml index 137e278ddc..e1e7e1c8c8 100755 --- a/indra/newview/skins/default/xui/en/floater_preview_texture.xml +++ b/indra/newview/skins/default/xui/en/floater_preview_texture.xml @@ -79,30 +79,6 @@ width="108" name="combo_aspect_ratio" tool_tip="Preview at a fixed aspect ratio"> - <combo_item name="Unconstrained" value="Unconstrained"> - Unconstrained - </combo_item> - <combo_item name="1:1" value="1:1" tool_tip="Group insignia or Real World profile"> - 1:1 - </combo_item> - <combo_item name="4:3" value="4:3" tool_tip="[SECOND_LIFE] profile"> - 4:3 - </combo_item> - <combo_item name="10:7" value="10:7" tool_tip="Classifieds and search listings, landmarks"> - 10:7 - </combo_item> - <combo_item name="3:2" value="3:2" tool_tip="About land"> - 3:2 - </combo_item> - <combo_item name="16:10" value="16:10"> - 16:10 - </combo_item> - <combo_item name="16:9" value="16:9" tool_tip="Profile picks"> - 16:9 - </combo_item> - <combo_item name="2:1" value="2:1"> - 2:1 - </combo_item> </combo_box> <button follows="right|bottom" diff --git a/indra/newview/skins/default/xui/en/menu_login.xml b/indra/newview/skins/default/xui/en/menu_login.xml index 52c4fb1613..e91eea04d1 100755 --- a/indra/newview/skins/default/xui/en/menu_login.xml +++ b/indra/newview/skins/default/xui/en/menu_login.xml @@ -35,14 +35,72 @@ tear_off="true" name="Help"> <menu_item_call - label="[SECOND_LIFE] Help" - name="Second Life Help" + label="How to..." + name="How To" shortcut="F1"> <menu_item_call.on_click - function="ShowHelp" - parameter="f1_help" /> + function="Help.ToggleHowTo" + parameter="" /> </menu_item_call> - <menu_item_separator /> + <menu_item_call + label="Quickstart" + name="Quickstart"> + <menu_item_call.on_click + function="Advanced.ShowURL" + parameter="http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-Quickstart/ta-p/1087919"/> + </menu_item_call> + <menu_item_separator/> + <menu_item_call + label="Knowledge Base" + name="Knowledge Base"> + <menu_item_call.on_click + function="Advanced.ShowURL" + parameter="http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-User-s-Guide/ta-p/1244857"/> + </menu_item_call> + <menu_item_call + label="Wiki" + name="Wiki"> + <menu_item_call.on_click + function="Advanced.ShowURL" + parameter="http://wiki.secondlife.com"/> + </menu_item_call> + <menu_item_call + label="Community Forums" + name="Community Forums"> + <menu_item_call.on_click + function="Advanced.ShowURL" + parameter="http://community.secondlife.com/t5/Forums/ct-p/Forums"/> + </menu_item_call> + <menu_item_call + label="Support portal" + name="Support portal"> + <menu_item_call.on_click + function="Advanced.ShowURL" + parameter="https://support.secondlife.com/"/> + </menu_item_call> + <menu_item_separator/> + <menu_item_call + label="[SECOND_LIFE] News" + name="Second Life News"> + <menu_item_call.on_click + function="Advanced.ShowURL" + parameter="http://community.secondlife.com/t5/Featured-News/bg-p/blog_feature_news"/> + </menu_item_call> + <menu_item_call + label="[SECOND_LIFE] Blogs" + name="Second Life Blogs"> + <menu_item_call.on_click + function="Advanced.ShowURL" + parameter="http://community.secondlife.com/t5/Blogs/ct-p/Blogs"/> + </menu_item_call> + <menu_item_separator/> + <menu_item_call + label="Report Bug" + name="Report Bug"> + <menu_item_call.on_click + function="Advanced.ReportBug"/> + </menu_item_call> + <menu_item_separator/> <menu_item_call label="About [APP_NAME]" name="About Second Life"> diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 7e8d2aaf9a..d91b4243b2 100755 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -606,44 +606,59 @@ label="Sun" name="Sun" tear_off="true"> - <menu_item_call + <menu_item_check label="Sunrise" name="Sunrise"> - <menu_item_call.on_click + <menu_item_check.on_click function="World.EnvSettings" parameter="sunrise" /> - </menu_item_call> - <menu_item_call + <menu_item_check.on_check + function="World.EnableEnvSettings" + parameter="sunrise" /> + </menu_item_check> + <menu_item_check label="Midday" name="Noon" shortcut="control|shift|Y"> - <menu_item_call.on_click + <menu_item_check.on_click function="World.EnvSettings" parameter="noon" /> - </menu_item_call> - <menu_item_call + <menu_item_check.on_check + function="World.EnableEnvSettings" + parameter="noon" /> + </menu_item_check> + <menu_item_check label="Sunset" name="Sunset" shortcut="control|shift|N"> - <menu_item_call.on_click + <menu_item_check.on_click function="World.EnvSettings" parameter="sunset" /> - </menu_item_call> - <menu_item_call + <menu_item_check.on_check + function="World.EnableEnvSettings" + parameter="sunset" /> + </menu_item_check> + <menu_item_check label="Midnight" name="Midnight"> - <menu_item_call.on_click + <menu_item_check.on_click function="World.EnvSettings" parameter="midnight" /> - </menu_item_call> + <menu_item_check.on_check + function="World.EnableEnvSettings" + parameter="midnight" /> + </menu_item_check> <menu_item_separator/> - <menu_item_call + <menu_item_check label="Use Region Settings" name="Use Region Settings"> - <menu_item_call.on_click + <menu_item_check.on_click function="World.EnvSettings" parameter="region" /> - </menu_item_call> + <menu_item_check.on_check + function="World.EnableEnvSettings" + parameter="region" /> + </menu_item_check> </menu> @@ -1542,7 +1557,8 @@ <menu_item_check label="Highlight Transparent" name="Highlight Transparent" - shortcut="control|alt|T"> + shortcut="control|alt|T" + use_mac_ctrl="true"> <menu_item_check.on_check function="View.CheckHighlightTransparent" /> <menu_item_check.on_click @@ -3136,18 +3152,6 @@ <menu_item_call.on_click function="Advanced.PrintAgentInfo" /> </menu_item_call> - <menu_item_check - label="Region Debug Console" - name="Region Debug Console" - shortcut="control|shift|`" - use_mac_ctrl="true"> - <menu_item_check.on_check - function="Floater.Visible" - parameter="region_debug_console" /> - <menu_item_check.on_click - function="Floater.Toggle" - parameter="region_debug_console" /> - </menu_item_check> <menu_item_separator /> <menu_item_check diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index c97af4e9ef..ce34c3f7a1 100755 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -7634,7 +7634,7 @@ Are you sure you want to share the following items: With the following Residents: -[RESIDENTS] +<nolink>[RESIDENTS]</nolink> <tag>confirm</tag> <usetemplate name="okcancelbuttons" @@ -7654,7 +7654,7 @@ Are you sure you want to share the following items: With the following Residents: -[RESIDENTS] +<nolink>[RESIDENTS]</nolink> <tag>confirm</tag> <usetemplate name="okcancelbuttons" @@ -10224,4 +10224,14 @@ Cannot create large prims that intersect other players. Please re-try when othe yestext="OK"/> </notification> + <notification + icon="alert.tga" + name="ChatHistoryIsBusyAlert" + type="alertmodal"> + Chat history file is busy with previous operation. Please try again in a few minutes or choose chat with another person. + <usetemplate + name="okbutton" + yestext="OK"/> + </notification> + </notifications> diff --git a/indra/newview/skins/default/xui/en/panel_places.xml b/indra/newview/skins/default/xui/en/panel_places.xml index f169dbb702..7d171490e8 100755 --- a/indra/newview/skins/default/xui/en/panel_places.xml +++ b/indra/newview/skins/default/xui/en/panel_places.xml @@ -27,6 +27,7 @@ background_visible="true" label="Filter My Places" max_length_chars="300" name="Filter" + tab_group="1" top="3" width="303" /> <tab_container @@ -39,7 +40,7 @@ background_visible="true" tab_min_width="80" tab_max_width="157" tab_height="30" - tab_group="1" + tab_group="2" tab_position="top" top_pad="10" width="315" /> diff --git a/indra/newview/skins/default/xui/en/panel_region_debug.xml b/indra/newview/skins/default/xui/en/panel_region_debug.xml index 81b2281adb..fea5f1b19f 100755 --- a/indra/newview/skins/default/xui/en/panel_region_debug.xml +++ b/indra/newview/skins/default/xui/en/panel_region_debug.xml @@ -201,4 +201,14 @@ tool_tip="Cancel region restart" top_delta="0" width="150" /> + <button + follows="left|top" + height="20" + label="Region Debug Console" + layout="topleft" + left="10" + name="region_debug_console_btn" + tool_tip="Open Region Debug Console" + top_pad="5" + width="150" /> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_region_general.xml b/indra/newview/skins/default/xui/en/panel_region_general.xml index 44c84e69a1..489d286e67 100755 --- a/indra/newview/skins/default/xui/en/panel_region_general.xml +++ b/indra/newview/skins/default/xui/en/panel_region_general.xml @@ -94,11 +94,20 @@ width="80" /> <check_box height="20" + label="Block Parcel Fly Over" + layout="topleft" + left="10" + name="block_fly_over_check" + tool_tip="Extend access checks upwards to prevent flying over a parcel" + top="110" + width="90" /> + <check_box + height="20" label="Allow Damage" layout="topleft" left="10" name="allow_damage_check" - top="110" + top="130" width="80" /> <check_box height="20" @@ -106,7 +115,7 @@ layout="topleft" left="10" name="restrict_pushobject" - top="130" + top="150" width="80" /> <check_box height="20" @@ -114,7 +123,7 @@ layout="topleft" left="10" name="allow_land_resell_check" - top="150" + top="170" width="80" /> <check_box height="20" @@ -122,7 +131,7 @@ layout="topleft" left="10" name="allow_parcel_changes_check" - top="170" + top="190" width="80" /> <check_box height="20" @@ -131,7 +140,7 @@ left="10" name="block_parcel_search_check" tool_tip="Let people see this region and its parcels in search results" - top="190" + top="210" width="80" /> <spinner decimal_digits="0" @@ -145,7 +154,7 @@ max_val="100" min_val="1" name="agent_limit_spin" - top="240" + top="260" width="170" /> <spinner follows="left|top" @@ -158,7 +167,7 @@ max_val="10" min_val="1" name="object_bonus_spin" - top="260" + top="280" width="170" /> <text follows="left|top" @@ -167,7 +176,7 @@ layout="topleft" left="10" name="access_text" - top="290" + top="310" width="100"> Rating: </text> @@ -224,7 +233,7 @@ layout="topleft" left="108" name="apply_btn" - top="320" + top="340" width="100"/> <button follows="left|top" diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 67f75fe1d2..f0ff6d5b88 100755 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -2257,6 +2257,7 @@ Drag folders to this area and click "Send to Marketplace" to list them for sale <string name="Marketplace Error Internal Import">Error: There was a problem with this item. Try again later.</string> <string name="Open landmarks">Open landmarks</string> + <string name="Unconstrained">Unconstrained</string> <!-- use value="" because they have preceding spaces --> <string name="no_transfer" value=" (no transfer)" /> diff --git a/indra/newview/skins/default/xui/es/strings.xml b/indra/newview/skins/default/xui/es/strings.xml index 484511a08b..2b91c542ad 100755 --- a/indra/newview/skins/default/xui/es/strings.xml +++ b/indra/newview/skins/default/xui/es/strings.xml @@ -1252,7 +1252,8 @@ Intenta iniciar sesión de nuevo en unos instantes. <string name="InventoryInboxNoItems"> Aquí aparecerán algunos de los objetos que recibas, como los regalos Premium. Después puedes arrastrarlos a tu inventario. </string> - <string name="MarketplaceURL"> + <string name="Unconstrained">Sin restricciones</string> + <string name="MarketplaceURL"> https://marketplace.[MARKETPLACE_DOMAIN_NAME]/ </string> <string name="MarketplaceURL_CreateStore"> diff --git a/indra/newview/skins/default/xui/fr/strings.xml b/indra/newview/skins/default/xui/fr/strings.xml index 78d846ff4f..b8721420cb 100755 --- a/indra/newview/skins/default/xui/fr/strings.xml +++ b/indra/newview/skins/default/xui/fr/strings.xml @@ -1270,7 +1270,8 @@ Veuillez réessayer de vous connecter dans une minute. <string name="InventoryInboxNoItems"> Les achats que vous avez effectués sur la Place du marché s'affichent ici. Vous pouvez alors les faire glisser vers votre inventaire afin de les utiliser. </string> - <string name="MarketplaceURL"> + <string name="Unconstrained">Sans contraintes</string> + <string name="MarketplaceURL"> https://marketplace.[MARKETPLACE_DOMAIN_NAME]/ </string> <string name="MarketplaceURL_CreateStore"> diff --git a/indra/newview/skins/default/xui/it/strings.xml b/indra/newview/skins/default/xui/it/strings.xml index 60ed2b0929..86d7f75b83 100755 --- a/indra/newview/skins/default/xui/it/strings.xml +++ b/indra/newview/skins/default/xui/it/strings.xml @@ -1261,7 +1261,8 @@ Prova ad accedere nuovamente tra un minuto. <string name="InventoryInboxNoItems"> Gli acquissti dal mercato verranno mostrati qui. Potrai quindi trascinarli nel tuo inventario per usarli. </string> - <string name="MarketplaceURL"> + <string name="Unconstrained">Libero</string> + <string name="MarketplaceURL"> https://marketplace.[MARKETPLACE_DOMAIN_NAME]/ </string> <string name="MarketplaceURL_CreateStore"> diff --git a/indra/newview/skins/default/xui/ja/strings.xml b/indra/newview/skins/default/xui/ja/strings.xml index a0f45e5a55..36966d6825 100755 --- a/indra/newview/skins/default/xui/ja/strings.xml +++ b/indra/newview/skins/default/xui/ja/strings.xml @@ -1270,7 +1270,8 @@ support@secondlife.com にお問い合わせください。 <string name="InventoryInboxNoItems"> マーケットプレイスで購入した商品はここに表示されます。その後、アイテムをインベントリにドラッグすれば、それらのアイテムを使用できます。 </string> - <string name="MarketplaceURL"> + <string name="Unconstrained">非拘束</string> + <string name="MarketplaceURL"> https://marketplace.[MARKETPLACE_DOMAIN_NAME]/ </string> <string name="MarketplaceURL_CreateStore"> diff --git a/indra/newview/skins/default/xui/pl/strings.xml b/indra/newview/skins/default/xui/pl/strings.xml index f6dec8536b..f86e393646 100755 --- a/indra/newview/skins/default/xui/pl/strings.xml +++ b/indra/newview/skins/default/xui/pl/strings.xml @@ -1035,6 +1035,7 @@ <string name="InventoryNoTexture"> Nie posiadasz kopii tej tekstury w Twojej Szafie. </string> + <string name="Unconstrained">Swobodny</string> <string name="no_transfer" value=" (brak oddawania)"/> <string name="no_modify" value=" (brak modyfikowania)"/> <string name="no_copy" value=" (brak kopiowania)"/> diff --git a/indra/newview/skins/default/xui/pt/strings.xml b/indra/newview/skins/default/xui/pt/strings.xml index 2eb4c0a02e..8436452228 100755 --- a/indra/newview/skins/default/xui/pt/strings.xml +++ b/indra/newview/skins/default/xui/pt/strings.xml @@ -1216,7 +1216,8 @@ Pessoas com contas gratuitas não poderão acessar o Second Life no momento para <string name="InventoryInboxNoItems"> Suas compras do Marketplace aparecerão aqui. Depois, você poderá arrastá-las para seu inventário para usá-las. </string> - <string name="MarketplaceURL"> + <string name="Unconstrained">Sem limites</string> + <string name="MarketplaceURL"> https://marketplace.[MARKETPLACE_DOMAIN_NAME]/ </string> <string name="MarketplaceURL_CreateStore"> diff --git a/indra/newview/skins/default/xui/ru/strings.xml b/indra/newview/skins/default/xui/ru/strings.xml index 0f71edcee0..8faf834f8f 100755 --- a/indra/newview/skins/default/xui/ru/strings.xml +++ b/indra/newview/skins/default/xui/ru/strings.xml @@ -1267,7 +1267,8 @@ support@secondlife.com. <string name="InventoryInboxNoItems"> Здесь будут показаны ваши покупки из торгового центра. Их можно будет перетащить в ваш инвентарь для использования. </string> - <string name="MarketplaceURL"> + <string name="Unconstrained">Без ограничения</string> + <string name="MarketplaceURL"> https://marketplace.[MARKETPLACE_DOMAIN_NAME]/ </string> <string name="MarketplaceURL_CreateStore"> diff --git a/indra/newview/skins/default/xui/tr/strings.xml b/indra/newview/skins/default/xui/tr/strings.xml index c4b1530b2b..31c5d2d310 100755 --- a/indra/newview/skins/default/xui/tr/strings.xml +++ b/indra/newview/skins/default/xui/tr/strings.xml @@ -1267,7 +1267,8 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin. <string name="InventoryInboxNoItems"> Pazaryerinda satın aldıklarınız burada görünecektir. Bunları kullanmak için envanterinize sürükleyebilirsiniz. </string> - <string name="MarketplaceURL"> + <string name="Unconstrained">Kısıtsız</string> + <string name="MarketplaceURL"> https://marketplace.[MARKETPLACE_DOMAIN_NAME]/ </string> <string name="MarketplaceURL_CreateStore"> |