diff options
60 files changed, 830 insertions, 300 deletions
diff --git a/doc/contributions.txt b/doc/contributions.txt index dbb18f28bf..1f7ab9e056 100644 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -5,11 +5,12 @@ received from them. To see more about these contributions, visit http://jira.secondlife.com/ and enter the issue identifier. Alissa Sabre - VWR-81, VWR-83, VWR-414, VWR-415 +Blakar Ogre - VWR-881 blino Nakamura - VWR-17 bushing Spatula - VWR-424 -Drewan Keats - VWR-28 +Drewan Keats - VWR-28, VWR-412 Dylan Haskell - VWR-72 -Dzonatas Sol - VWR-198 +Dzonatas Sol - VWR-198, VWR-878 Eddy Stryker - VWR-15, VWR-23 Gigs Taggart - VWR-71, VWR-326 Ginko Bayliss - VWR-4 @@ -19,11 +20,14 @@ Jacek Antonelli - VWR-165, VWR-188 Joghert LeSabre - VWR-64 Kage Pixel - VWR-11 Kunnis Basiat - VWR-82 +Nicholaz Beresford - VWR-793, VWR-794, VWR-802, VWR-803, VWR-804, VWR-805, VWR-808, VWR-809, VWR-810, VWR-823, VWR-870 Paul Churchill - VWR-20 Paula Innis - VWR-30 Peekay Semyorka - VWR-7, VWR-19, VWR-49 SignpostMarv Martin - VWR-154, VWR-155 +Simon Nolan - VWR-409 SpacedOut Frye - VWR-57, VWR-94, VWR-121, VWR-123 Strife Onizuka - SVC-9, VWR-74, VWR-85, VWR-148 +Zi Ree - VWR-671, VWR-682 Zipherius Turas - VWR-76, VWR-77 diff --git a/indra/llcharacter/llheadrotmotion.cpp b/indra/llcharacter/llheadrotmotion.cpp index 4d4f7ce738..66b675e34d 100644 --- a/indra/llcharacter/llheadrotmotion.cpp +++ b/indra/llcharacter/llheadrotmotion.cpp @@ -411,6 +411,7 @@ BOOL LLEyeMotion::onUpdate(F32 time, U8* joint_mask) LLVector3 up; eye_look_at = *targetPos; + has_eye_target = TRUE; F32 lookAtDistance = eye_look_at.normVec(); left.setVec(skyward % eye_look_at); diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index 3d4deac673..5964993928 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -227,7 +227,7 @@ namespace LOG_CLASS(LogControlFile); public: - static LogControlFile& fromDirectory(const std::string& dir); + static LogControlFile *fromDirectory(const std::string& dir); virtual void loadFile(); @@ -237,7 +237,7 @@ namespace { } }; - LogControlFile& LogControlFile::fromDirectory(const std::string& dir) + LogControlFile *LogControlFile::fromDirectory(const std::string& dir) { std::string dirBase = dir + "/"; // NB: We have no abstraction in llcommon for the "proper" @@ -253,8 +253,7 @@ namespace file = dirBase + "logcontrol.xml"; } - return * new LogControlFile(file); - // NB: This instance is never freed + return new LogControlFile(file); } void LogControlFile::loadFile() @@ -298,8 +297,11 @@ namespace static Globals& get(); // return the one instance of the globals + static void Globals::cleanup(); + private: CallSiteVector callSites; + static Globals *sGlobals; Globals() : messageStreamInUse(false) @@ -307,6 +309,8 @@ namespace }; + Globals *Globals::sGlobals; + void Globals::addCallSite(LLError::CallSite& site) { callSites.push_back(&site); @@ -332,8 +336,16 @@ namespace is. See C++ FAQ Lite, sections 10.12 through 10.14 */ - static Globals* globals = new Globals; - return *globals; + if (sGlobals == NULL) { + sGlobals = new Globals; + } + + return *sGlobals; + } + + void Globals::cleanup() + { + delete sGlobals; } } @@ -361,6 +373,7 @@ namespace LLError int shouldLogCallCounter; static Settings& get(); + static void cleanup(); static void reset(); static Settings* saveAndReset(); @@ -391,6 +404,16 @@ namespace LLError return *p; } + void Settings::cleanup() + { + Settings*& ptr = getPtr(); + if (ptr) + { + delete ptr; + ptr = NULL; + } + } + void Settings::reset() { Globals::get().invalidateCallSites(); @@ -469,6 +492,8 @@ namespace } + static LogControlFile *gLogControlFile; + void commonInit(const std::string& dir) { LLError::Settings::reset(); @@ -486,8 +511,8 @@ namespace LLError::addRecorder(new RecordToWinDebug); #endif - LogControlFile& e = LogControlFile::fromDirectory(dir); - e.addToEventTimer(); + gLogControlFile = LogControlFile::fromDirectory(dir); + gLogControlFile->addToEventTimer(); } } @@ -511,6 +536,15 @@ namespace LLError commonInit(dir); } + void cleanupLogging(void) + { + delete gLogControlFile; + gLogControlFile = NULL; + + Settings::cleanup(); + Globals::cleanup(); + } + void setPrintLocation(bool print) { Settings& s = Settings::get(); diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h index 84ac0fa7f0..d32469d0c2 100644 --- a/indra/llcommon/llerror.h +++ b/indra/llcommon/llerror.h @@ -152,6 +152,9 @@ namespace LLError class NoClassInfo { }; // used to indicate no class info known for logging + + void cleanupLogging(); + // after this is called, no more logging is allowed } diff --git a/indra/llcommon/llprocessor.cpp b/indra/llcommon/llprocessor.cpp index 0e469e6341..a6b859ad41 100644 --- a/indra/llcommon/llprocessor.cpp +++ b/indra/llcommon/llprocessor.cpp @@ -257,7 +257,7 @@ bool CProcessor::AnalyzeIntelProcessor() // Only override the brand if we have it in the lookup table. We should // already have a string here from GetCPUInfo(). JC - if (CPUInfo.uiBrandID < sizeof(INTEL_BRAND)) + if (CPUInfo.uiBrandID < (sizeof(INTEL_BRAND)/sizeof(INTEL_BRAND[0]))) { strcpy(CPUInfo.strBrandID, INTEL_BRAND[CPUInfo.uiBrandID]); diff --git a/indra/llinventory/llnotecard.cpp b/indra/llinventory/llnotecard.cpp index 96ee7ff800..325cb2a1f7 100644 --- a/indra/llinventory/llnotecard.cpp +++ b/indra/llinventory/llnotecard.cpp @@ -84,12 +84,6 @@ bool LLNotecard::importEmbeddedItemsStream(std::istream& str) goto import_file_failed; } - if( (index < 0) ) - { - llwarns << "Invalid LLEmbeddedItems file format: invalid ext char index: " << index << llendl; - goto import_file_failed; - } - str >> std::ws >> "inv_item\t0\n"; if(str.fail()) { diff --git a/indra/llinventory/llsaleinfo.cpp b/indra/llinventory/llsaleinfo.cpp index c469eae33c..32ba4aaaec 100644 --- a/indra/llinventory/llsaleinfo.cpp +++ b/indra/llinventory/llsaleinfo.cpp @@ -155,7 +155,7 @@ BOOL LLSaleInfo::importFile(FILE* fp, BOOL& has_perm_mask, U32& perm_mask) buffer, " %254s %254s", keyword, valuestr); - if(!keyword) + if(!keyword[0]) { continue; } @@ -211,7 +211,7 @@ BOOL LLSaleInfo::importLegacyStream(std::istream& input_stream, BOOL& has_perm_m buffer, " %254s %254s", keyword, valuestr); - if(!keyword) + if(!keyword[0]) { continue; } diff --git a/indra/llinventory/lluserrelations.h b/indra/llinventory/lluserrelations.h index 7c24254339..ddf6767b23 100644 --- a/indra/llinventory/lluserrelations.h +++ b/indra/llinventory/lluserrelations.h @@ -18,7 +18,7 @@ * @class LLRelationship * * This class represents a relationship between two agents, where the - * related agent is stored and the other agent is the relationship is + * related agent is stored and the other agent in the relationship is * implicit by container ownership. * This is merely a cache of this information used by the sim * and viewer. diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index c779a8b714..0d95c0492c 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -1809,13 +1809,16 @@ void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, U32 x = (U32) ((F32)s/(sizeS-1) * (F32) sculpt_width); U32 y = (U32) ((F32)t/(sizeT-1) * (F32) sculpt_height); - if (y == sculpt_height) // clamp to bottom row + if (y == sculpt_height) // stitch bottom + { y = sculpt_height - 1; + x = sculpt_width / 2; + } if (x == sculpt_width) // stitch sides x = 0; - if ((y == 0) || (y == sculpt_height-1)) // stitch top and bottom + if (y == 0) // stitch top x = sculpt_width / 2; U32 index = (x + y * sculpt_width) * sculpt_components; @@ -1827,63 +1830,69 @@ void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, last_index = index; } + if ((F32)vertex_change / sizeS / sizeT < 0.05) // less than 5% + data_is_empty = TRUE; } - - if ((F32)vertex_change / sizeS / sizeT < 0.05) // less than 5% - data_is_empty = TRUE; - - //generate vertex positions - // Run along the path. - S32 s = 0, t = 0; - S32 line = 0; - while (s < sizeS) + if (data_is_empty) // if empty, make a sphere { - t = 0; - // Run along the profile. - while (t < sizeT) - { - S32 i = t + line; - Point& pt = mMesh[i]; - - U32 x = (U32) ((F32)t/(sizeT-1) * (F32) sculpt_width); - U32 y = (U32) ((F32)s/(sizeS-1) * (F32) sculpt_height); + S32 line = 0; - if (y == sculpt_height) // clamp to bottom row - y = sculpt_height - 1; - - if (x == sculpt_width) // stitch sides - x = 0; + for (S32 s = 0; s < sizeS; s++) + { + for (S32 t = 0; t < sizeT; t++) + { + S32 i = t + line; + Point& pt = mMesh[i]; - if ((y == 0) || (y == sculpt_height-1)) // stitch top and bottom - x = sculpt_width / 2; - - if (data_is_empty) // if empty, make a sphere - { F32 u = (F32)s/(sizeS-1); F32 v = (F32)t/(sizeT-1); const F32 RADIUS = (F32) 0.3; - + pt.mPos.mV[0] = (F32)(sin(F_PI * v) * cos(2.0 * F_PI * u) * RADIUS); pt.mPos.mV[1] = (F32)(sin(F_PI * v) * sin(2.0 * F_PI * u) * RADIUS); pt.mPos.mV[2] = (F32)(cos(F_PI * v) * RADIUS); + } - - else + line += sizeT; + } + } + else + { + S32 line = 0; + for (S32 s = 0; s < sizeS; s++) + { + // Run along the profile. + for (S32 t = 0; t < sizeT; t++) { + S32 i = t + line; + Point& pt = mMesh[i]; + + U32 x = (U32) ((F32)t/(sizeT-1) * (F32) sculpt_width); + U32 y = (U32) ((F32)s/(sizeS-1) * (F32) sculpt_height); + + if (y == sculpt_height) // stitch bottom row + { + y = sculpt_height - 1; + x = sculpt_width / 2; + } + + if (x == sculpt_width) // stitch sides + x = 0; + + if (y == 0) // stitch top row + x = sculpt_width / 2; + U32 index = (x + y * sculpt_width) * sculpt_components; pt.mPos.mV[0] = sculpt_data[index ] / 256.f - 0.5f; pt.mPos.mV[1] = sculpt_data[index+1] / 256.f - 0.5f; pt.mPos.mV[2] = sculpt_data[index+2] / 256.f - 0.5f; } - - t++; + line += sizeT; } - line += sizeT; - s++; } for (S32 i = 0; i < (S32)mProfilep->mFaces.size(); i++) diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index 3c8ebaeba1..ffc15d45f7 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -322,6 +322,12 @@ namespace } return sMainMulti; } + + void freeMulti() + { + delete sMainMulti; + sMainMulti = NULL; + } } void @@ -342,3 +348,8 @@ LLCurl::process() mainMulti()->process(); } +void LLCurl::cleanup() +{ + freeMulti(); + curl_global_cleanup(); +} diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h index 4e45864cae..5335906b47 100644 --- a/indra/llmessage/llcurl.h +++ b/indra/llmessage/llcurl.h @@ -108,6 +108,7 @@ public: static void getByteRange(const std::string& url, S32 offset, S32 length, ResponderPtr responder); static void process(); + static void cleanup(); }; namespace boost diff --git a/indra/llmessage/llmessageconfig.cpp b/indra/llmessage/llmessageconfig.cpp index a2b0bc5efa..3cc17d67df 100644 --- a/indra/llmessage/llmessageconfig.cpp +++ b/indra/llmessage/llmessageconfig.cpp @@ -92,9 +92,10 @@ void LLMessageConfigFile::loadServerDefaults(const LLSD& data) void LLMessageConfigFile::loadMessages(const LLSD& data) { - mMessages = data["messages"]; + LLPointer<LLSDXMLFormatter> formatter = new LLSDXMLFormatter; std::ostringstream out; - LLSDXMLFormatter *formatter = new LLSDXMLFormatter; + + mMessages = data["messages"]; formatter->format(mMessages, out); lldebugs << "loading ... " << out.str() << " LLMessageConfigFile::loadMessages loaded " diff --git a/indra/llmessage/message.cpp b/indra/llmessage/message.cpp index dfc18e0b2e..a305797fd2 100644 --- a/indra/llmessage/message.cpp +++ b/indra/llmessage/message.cpp @@ -1324,12 +1324,17 @@ LLMessageSystem::~LLMessageSystem() end_net(); } - delete mMessageReader; + delete mTemplateMessageReader; + mTemplateMessageReader = NULL; mMessageReader = NULL; - delete mMessageBuilder; + delete mTemplateMessageBuilder; + mTemplateMessageBuilder = NULL; mMessageBuilder = NULL; + delete mLLSDMessageReader; + mLLSDMessageReader = NULL; + delete mPollInfop; mPollInfop = NULL; diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index b94f593d7f..6d0c57812d 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -1,3 +1,11 @@ +/** + * @file llvertexbuffer.cpp + * @brief LLVertexBuffer implementation + * + * Copyright (c) 2003-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + #include "linden_common.h" #include "llvertexbuffer.h" diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index b221d35ee3..a064081f28 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -1,3 +1,11 @@ +/** + * @file llvertexbuffer.h + * @brief LLVertexBuffer wrapper for OpengGL vertex buffer objects + * + * Copyright (c) 2003-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + #ifndef LL_LLVERTEXBUFFER_H #define LL_LLVERTEXBUFFER_H diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index 43ea584aa1..7e7999c9f9 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -137,6 +137,14 @@ LLLineEditor::LLLineEditor(const LLString& name, const LLRect& rect, { llassert( max_length_bytes > 0 ); + // line history support: + // - initialize line history list + mLineHistory.insert( mLineHistory.end(), "" ); + // - disable line history by default + mHaveHistory = FALSE; + // - reset current history line pointer + mCurrentHistoryLine = 0; + if (font) { mGLFont = font; @@ -209,10 +217,33 @@ void LLLineEditor::onFocusLost() void LLLineEditor::onCommit() { + // put current line into the line history + updateHistory(); + LLUICtrl::onCommit(); selectAll(); } +// line history support +void LLLineEditor::updateHistory() +{ + // On history enabled line editors, remember committed line and + // reset current history line number. + // Be sure only to remember lines that are not empty and that are + // different from the last on the list. + if( mHaveHistory && mText.length() && ( mLineHistory.empty() || getText() != mLineHistory.back() ) ) + { + // discard possible empty line at the end of the history + // inserted by setText() + if( !mLineHistory.back().length() ) + { + mLineHistory.pop_back(); + } + mLineHistory.insert( mLineHistory.end(), getText() ); + mCurrentHistoryLine = mLineHistory.size() - 1; + } +} + void LLLineEditor::reshape(S32 width, S32 height, BOOL called_from_parent) { LLUICtrl::reshape(width, height, called_from_parent ); @@ -220,6 +251,10 @@ void LLLineEditor::reshape(S32 width, S32 height, BOOL called_from_parent) mMaxHPixels = mRect.getWidth() - 2 * (mBorderThickness + UI_LINEEDITOR_H_PAD) + 1 - mBorderRight; } +void LLLineEditor::setEnableLineHistory( BOOL enabled ) +{ + mHaveHistory = enabled; +} void LLLineEditor::setEnabled(BOOL enabled) { @@ -280,6 +315,13 @@ void LLLineEditor::setText(const LLString &new_text) deselect(); } setCursor(llmin((S32)mText.length(), getCursor())); + + // Newly set text goes always in the last line of history. + // Possible empty strings (as with chat line) will be deleted later. + mLineHistory.insert( mLineHistory.end(), new_text ); + // Set current history line to end of history. + mCurrentHistoryLine = mLineHistory.size() - 1; + mPrevText = mText; } @@ -1066,6 +1108,45 @@ BOOL LLLineEditor::handleSpecialKey(KEY key, MASK mask) } break; + // handle ctrl-uparrow if we have a history enabled line editor. + case KEY_UP: + if( mHaveHistory && ( MASK_CONTROL & mask ) ) + { + if( mCurrentHistoryLine > 0 ) + { + mText.assign( mLineHistory[ --mCurrentHistoryLine ] ); + setCursor(llmin((S32)mText.length(), getCursor())); + } + else + { + reportBadKeystroke(); + } + handled = TRUE; + } + break; + + // handle ctrl-downarrow if we have a history enabled line editor + case KEY_DOWN: + if( mHaveHistory && ( MASK_CONTROL & mask ) ) + { + if( !mLineHistory.empty() && mCurrentHistoryLine < mLineHistory.size() - 1 ) + { + mText.assign( mLineHistory[ ++mCurrentHistoryLine ] ); + setCursor(llmin((S32)mText.length(), getCursor())); + } + else + { + reportBadKeystroke(); + } + handled = TRUE; + } + break; + + case KEY_RETURN: + // store sent line in history + updateHistory(); + break; + case KEY_ESCAPE: if (mRevertOnEsc && mText.getString() != mPrevText) { diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h index 27ae351d1f..b3eff3c8e2 100644 --- a/indra/llui/lllineeditor.h +++ b/indra/llui/lllineeditor.h @@ -16,6 +16,7 @@ // Clipboard (cut, copy, and paste) // Horizontal scrolling to allow strings longer than widget size allows // Pre-validation (limit which keys can be used) +// Optional line history so previous entries can be recalled by CTRL UP/DOWN #ifndef LL_LLLINEEDITOR_H @@ -186,6 +187,10 @@ public: static BOOL postvalidateFloat(const LLString &str); + // line history support: + void setEnableLineHistory( BOOL enabled ); // switches line history on or off + void updateHistory(); // stores current line in history + protected: void removeChar(); void addChar(const llwchar c); @@ -204,6 +209,11 @@ protected: LLString mPrevText; // Saved string for 'ESC' revert LLUIString mLabel; // text label that is visible when no user text provided + // line history support: + BOOL mHaveHistory; // flag for enabled line history + std::vector<LLString> mLineHistory; // line history storage + U32 mCurrentHistoryLine; // currently browsed history line + LLViewBorder* mBorder; const LLFontGL* mGLFont; S32 mMaxLengthChars; // Max number of characters diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index 2b588cacce..9363415dc2 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -289,6 +289,9 @@ LLTextEditor::LLTextEditor( { mSourceID.generate(); + // reset desired x cursor position + mDesiredXPixel = -1; + if (font) { mGLFont = font; @@ -894,6 +897,8 @@ void LLTextEditor::setCursorPos(S32 offset) { mCursorPos = llclamp(offset, 0, (S32)getLength()); updateScrollFromCursor(); + // reset desired x cursor position + mDesiredXPixel = -1; } @@ -3078,6 +3083,9 @@ void LLTextEditor::changePage( S32 delta ) S32 line, offset; getLineAndOffset( mCursorPos, &line, &offset ); + // get desired x position to remember previous position + S32 desired_x_pixel = mDesiredXPixel; + // allow one line overlap S32 page_size = mScrollbar->getPageSize() - 1; if( delta == -1 ) @@ -3092,6 +3100,10 @@ void LLTextEditor::changePage( S32 delta ) setCursorPos(getPos( line + page_size, offset )); mScrollbar->setDocPos( mScrollbar->getDocPos() + page_size ); } + + // put desired position into remember-buffer after setCursorPos() + mDesiredXPixel = desired_x_pixel; + if (mOnScrollEndCallback && mOnScrollEndData && (mScrollbar->getDocPos() == mScrollbar->getDocPosMax())) { mOnScrollEndCallback(mOnScrollEndData); @@ -3107,9 +3119,13 @@ void LLTextEditor::changeLine( S32 delta ) S32 line_start = getLineStart(line); - S32 desired_x_pixel; - - desired_x_pixel = mGLFont->getWidth(mWText.c_str(), line_start, offset, mAllowEmbeddedItems ); + // set desired x position to remembered previous position + S32 desired_x_pixel = mDesiredXPixel; + // if remembered position was reset (thus -1), calculate new one here + if( desired_x_pixel == -1 ) + { + desired_x_pixel = mGLFont->getWidth(mWText.c_str(), line_start, offset, mAllowEmbeddedItems ); + } S32 new_line = 0; if( (delta < 0) && (line > 0 ) ) @@ -3145,6 +3161,9 @@ void LLTextEditor::changeLine( S32 delta ) mAllowEmbeddedItems); setCursorPos (getPos( new_line, new_offset )); + + // put desired position into remember-buffer after setCursorPos() + mDesiredXPixel = desired_x_pixel; unbindEmbeddedChars( mGLFont ); } diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h index d95230f0dc..7454b192fd 100644 --- a/indra/llui/lltexteditor.h +++ b/indra/llui/lltexteditor.h @@ -339,6 +339,7 @@ protected: undo_stack_t mUndoStack; S32 mCursorPos; // I-beam is just after the mCursorPos-th character. + S32 mDesiredXPixel; // X pixel position where the user wants the cursor to be LLRect mTextRect; // The rect in which text is drawn. Excludes borders. // List of offsets and segment index of the start of each line. Always has at least one node (0). struct line_info diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index da5c77fc94..05c2247a35 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -176,6 +176,9 @@ LLView::~LLView() (*itor).second->clearDispatchers(); delete (*itor).second; } + + std::for_each(mFloaterControls.begin(), mFloaterControls.end(), + DeletePairedPointer()); } // virtual diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index bc02ebfb63..4152de51c5 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -2211,7 +2211,13 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e case kEventClassWindow: switch(evtKind) - { + { + case kEventWindowActivated: + mCallbacks->handleFocus(this); + break; + case kEventWindowDeactivated: + mCallbacks->handleFocusLost(this); + break; case kEventWindowBoundsChanging: { Rect currentBounds; diff --git a/indra/llwindow/llwindowmesaheadless.h b/indra/llwindow/llwindowmesaheadless.h index 550a61d37a..12a687d713 100644 --- a/indra/llwindow/llwindowmesaheadless.h +++ b/indra/llwindow/llwindowmesaheadless.h @@ -12,6 +12,7 @@ #if LL_MESA_HEADLESS #include "llwindow.h" +#include "GL/glu.h" #include "GL/osmesa.h" class LLWindowMesaHeadless : public LLWindow diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp index 6b25eabfd1..71c766db8e 100644 --- a/indra/llwindow/llwindowsdl.cpp +++ b/indra/llwindow/llwindowsdl.cpp @@ -276,9 +276,9 @@ static SDL_Surface *Load_BMP_Resource(const char *basename) #if LL_X11 // This is an XFree86/XOrg-specific hack for detecting the amount of Video RAM // on this machine. It works by searching /var/log/var/log/Xorg.?.log or -// /var/log/XFree86.?.log for a ': VideoRAM: (%d+) kB' regex, where '?' is -// the X11 display number derived from $DISPLAY -static int x11_detect_VRAM_kb_fp(FILE *fp) +// /var/log/XFree86.?.log for a ': (VideoRAM|Memory): (%d+) kB' regex, where +// '?' is the X11 display number derived from $DISPLAY +static int x11_detect_VRAM_kb_fp(FILE *fp, const char *prefix_str) { const int line_buf_size = 1000; char line_buf[line_buf_size]; @@ -290,7 +290,7 @@ static int x11_detect_VRAM_kb_fp(FILE *fp) // favourite regex implementation - libboost_regex - is // quite a heavy and troublesome dependency for the client, so // it seems a shame to introduce it for such a simple task. - const char part1_template[] = ": VideoRAM: "; + const char *part1_template = prefix_str; const char part2_template[] = " kB"; char *part1 = strstr(line_buf, part1_template); if (part1) // found start of matching line @@ -305,7 +305,6 @@ static int x11_detect_VRAM_kb_fp(FILE *fp) int rtn = 0; for (; part1 < part2; ++part1) { - //lldebugs << "kB" << *part1 << llendl; if (*part1 < '0' || *part1 > '9') { // unexpected char, abort parse @@ -325,6 +324,7 @@ static int x11_detect_VRAM_kb_fp(FILE *fp) } return 0; // 'could not detect' } + static int x11_detect_VRAM_kb() { std::string x_log_location("/var/log/"); @@ -343,7 +343,7 @@ static int x11_detect_VRAM_kb() // *TODO: we could be smarter and see which of Xorg/XFree86 has the // freshest time-stamp. - // Try XOrg log first + // Try Xorg log first fname = x_log_location; fname += "Xorg."; fname += ('0' + display_num); @@ -351,12 +351,25 @@ static int x11_detect_VRAM_kb() fp = fopen(fname.c_str(), "r"); if (fp) { - rtn = x11_detect_VRAM_kb_fp(fp); + llinfos << "Looking in " << fname + << " for VRAM info..." << llendl; + rtn = x11_detect_VRAM_kb_fp(fp, ": VideoRAM: "); fclose(fp); + if (0 == rtn) + { + fp = fopen(fname.c_str(), "r"); + if (fp) + { + rtn = x11_detect_VRAM_kb_fp(fp, ": Memory: "); + fclose(fp); + } + } } - // Try old XFree86 log otherwise - if (rtn == 0) + else { + llinfos << "Could not open " << fname + << " - skipped." << llendl; + // Try old XFree86 log otherwise fname = x_log_location; fname += "XFree86."; fname += ('0' + display_num); @@ -364,8 +377,24 @@ static int x11_detect_VRAM_kb() fp = fopen(fname.c_str(), "r"); if (fp) { - rtn = x11_detect_VRAM_kb_fp(fp); + llinfos << "Looking in " << fname + << " for VRAM info..." << llendl; + rtn = x11_detect_VRAM_kb_fp(fp, ": VideoRAM: "); fclose(fp); + if (0 == rtn) + { + fp = fopen(fname.c_str(), "r"); + if (fp) + { + rtn = x11_detect_VRAM_kb_fp(fp, ": Memory: "); + fclose(fp); + } + } + } + else + { + llinfos << "Could not open " << fname + << " - skipped." << llendl; } } return rtn; diff --git a/indra/mac_updater/mac_updater.cpp b/indra/mac_updater/mac_updater.cpp index 4b56148f10..91bf24ec11 100644 --- a/indra/mac_updater/mac_updater.cpp +++ b/indra/mac_updater/mac_updater.cpp @@ -517,8 +517,7 @@ bool isDirWritable(FSRef &dir) static void utf8str_to_HFSUniStr255(HFSUniStr255 *dest, const char* src) { - LLWString wstr = utf8str_to_wstring(src); - llutf16string utf16str = wstring_to_utf16str(wstr); + llutf16string utf16str = utf8str_to_utf16str(src); dest->length = utf16str.size(); if(dest->length > 255) @@ -530,6 +529,13 @@ static void utf8str_to_HFSUniStr255(HFSUniStr255 *dest, const char* src) memcpy(dest->unicode, utf16str.data(), sizeof(UniChar)* dest->length); /* Flawfinder: ignore */ } +static std::string HFSUniStr255_to_utf8str(const HFSUniStr255* src) +{ + llutf16string string16((U16*)&(src->unicode), src->length); + std::string result = utf16str_to_utf8str(string16); + return result; +} + int restoreObject(const char* aside, const char* target, const char* path, const char* object) { char source[PATH_MAX]; /* Flawfinder: ignore */ @@ -578,6 +584,123 @@ void filterFile(const char* filename) system(temp); /* Flawfinder: ignore */ } +static bool isFSRefViewerBundle(FSRef *targetRef) +{ + bool result = false; + CFURLRef targetURL = NULL; + CFBundleRef targetBundle = NULL; + CFStringRef targetBundleID = NULL; + + targetURL = CFURLCreateFromFSRef(NULL, targetRef); + + if(targetURL == NULL) + { + llinfos << "Error creating target URL." << llendl; + } + else + { + targetBundle = CFBundleCreate(NULL, targetURL); + } + + if(targetBundle == NULL) + { + llinfos << "Failed to create target bundle." << llendl; + } + else + { + targetBundleID = CFBundleGetIdentifier(targetBundle); + } + + if(targetBundleID == NULL) + { + llinfos << "Couldn't retrieve target bundle ID." << llendl; + } + else + { + if(CFStringCompare(targetBundleID, CFSTR("com.secondlife.indra.viewer"), 0) == kCFCompareEqualTo) + { + // This is the bundle we're looking for. + result = true; + } + else + { + llinfos << "Target bundle ID mismatch." << llendl; + } + } + + // Don't release targetBundleID -- since we don't retain it, it's released when targetBundle is released. + if(targetURL != NULL) + CFRelease(targetURL); + if(targetBundle != NULL) + CFRelease(targetBundle); + + return result; +} + +// Search through the directory specified by 'parent' for an item that appears to be a Second Life viewer. +static OSErr findAppBundleOnDiskImage(FSRef *parent, FSRef *app) +{ + FSIterator iterator; + bool found = false; + + OSErr err = FSOpenIterator( parent, kFSIterateFlat, &iterator ); + if(!err) + { + do + { + ItemCount actualObjects = 0; + Boolean containerChanged = false; + FSCatalogInfo info; + FSRef ref; + HFSUniStr255 unicodeName; + err = FSGetCatalogInfoBulk( + iterator, + 1, + &actualObjects, + &containerChanged, + kFSCatInfoNodeFlags, + &info, + &ref, + NULL, + &unicodeName ); + + if(actualObjects == 0) + break; + + if(!err) + { + // Call succeeded and not done with the iteration. + std::string name = HFSUniStr255_to_utf8str(&unicodeName); + + llinfos << "Considering \"" << name << "\"" << llendl; + + if(info.nodeFlags & kFSNodeIsDirectoryMask) + { + // This is a directory. See if it's a .app + if(name.find(".app") != std::string::npos) + { + // Looks promising. Check to see if it has the right bundle identifier. + if(isFSRefViewerBundle(&ref)) + { + // This is the one. Return it. + *app = ref; + found = true; + } + } + } + } + } + while(!err && !found); + + FSCloseIterator(iterator); + } + + if(!err && !found) + err = fnfErr; + + return err; +} + void *updatethreadproc(void*) { char tempDir[PATH_MAX] = ""; /* Flawfinder: ignore */ @@ -650,57 +773,15 @@ void *updatethreadproc(void*) // Sanity check: make sure the target is a bundle with the right identifier if(err == noErr) { - CFURLRef targetURL = NULL; - CFBundleRef targetBundle = NULL; - CFStringRef targetBundleID = NULL; - // Assume the worst... err = -1; - - targetURL = CFURLCreateFromFSRef(NULL, &targetRef); - if(targetURL == NULL) - { - llinfos << "Error creating target URL." << llendl; - } - else + if(isFSRefViewerBundle(&targetRef)) { - targetBundle = CFBundleCreate(NULL, targetURL); - } - - if(targetBundle == NULL) - { - llinfos << "Failed to create target bundle." << llendl; - } - else - { - targetBundleID = CFBundleGetIdentifier(targetBundle); - } - - if(targetBundleID == NULL) - { - llinfos << "Couldn't retrieve target bundle ID." << llendl; - } - else - { - if(CFStringCompare(targetBundleID, CFSTR("com.secondlife.indra.viewer"), 0) == kCFCompareEqualTo) - { - // This is the bundle we're looking for. - err = noErr; - replacingTarget = true; - } - else - { - llinfos << "Target bundle ID mismatch." << llendl; - } + // This is the bundle we're looking for. + err = noErr; + replacingTarget = true; } - - // Don't release targetBundleID -- since we don't retain it, it's released when targetBundle is released. - if(targetURL != NULL) - CFRelease(targetURL); - if(targetBundle != NULL) - CFRelease(targetBundle); - } // Make sure the target's parent directory is writable. @@ -923,13 +1004,24 @@ void *updatethreadproc(void*) // Get an FSRef to the new application on the disk image FSRef sourceRef; - snprintf(temp, sizeof(temp), "%s/mnt/Second Life.app", tempDir); + FSRef mountRef; + snprintf(temp, sizeof(temp), "%s/mnt", tempDir); - llinfos << "Source application is: " << temp << llendl; + llinfos << "Disk image mount point is: " << temp << llendl; - err = FSPathMakeRef((UInt8 *)temp, &sourceRef, NULL); + err = FSPathMakeRef((UInt8 *)temp, &mountRef, NULL); if(err != noErr) + { + llinfos << "Couldn't make FSRef to disk image mount point." << llendl; throw 0; + } + + err = findAppBundleOnDiskImage(&mountRef, &sourceRef); + if(err != noErr) + { + llinfos << "Couldn't find application bundle on mounted disk image." << llendl; + throw 0; + } FSRef asideRef; char aside[MAX_PATH]; /* Flawfinder: ignore */ diff --git a/indra/newview/licenses-linux.txt b/indra/newview/licenses-linux.txt index a0dc048825..1892b810f1 100644 --- a/indra/newview/licenses-linux.txt +++ b/indra/newview/licenses-linux.txt @@ -514,3 +514,36 @@ jloup@gzip.org Mark Adler madler@alumni.caltech.edu + +================================= +tcmalloc/Google perftools license +================================= + +Copyright (c) 2005, Google Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index c6155197f6..eb00692157 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -4963,7 +4963,7 @@ BOOL LLAgent::allowOperation(PermissionBit op, const LLPermissions& perm, U64 group_proxy_power, U8 god_minimum) -{ + { // Check god level. if (getGodLevel() >= god_minimum) return TRUE; diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp index 19992c201a..e93ce8bdff 100644 --- a/indra/newview/llcallingcard.cpp +++ b/indra/newview/llcallingcard.cpp @@ -110,6 +110,7 @@ LLAvatarTracker::~LLAvatarTracker() { deleteTrackingData(); std::for_each(mObservers.begin(), mObservers.end(), DeletePointer()); + std::for_each(mBuddyInfo.begin(), mBuddyInfo.end(), DeletePairedPointer()); } void LLAvatarTracker::track(const LLUUID& avatar_id, const std::string& name) diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp index c5e7eaa1e9..4beea0d112 100644 --- a/indra/newview/llchatbar.cpp +++ b/indra/newview/llchatbar.cpp @@ -98,8 +98,8 @@ LLChatBar::LLChatBar(const std::string& name, const LLRect& rect) mInputEditor->setRevertOnEsc( FALSE ); mInputEditor->setIgnoreTab(TRUE); mInputEditor->setPassDelete(TRUE); - mInputEditor->setMaxTextLength(1023); + mInputEditor->setEnableLineHistory(TRUE); } // Build the list of gestures @@ -426,6 +426,8 @@ void LLChatBar::sendChat( EChatType type ) if (!text.empty()) { + // store sent line in history, duplicates will get filtered + mInputEditor->updateHistory(); // Check if this is destined for another channel S32 channel = 0; stripChannelNumber(text, &channel); diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp index 2b11653da0..5a7a12c38d 100644 --- a/indra/newview/llflexibleobject.cpp +++ b/indra/newview/llflexibleobject.cpp @@ -42,6 +42,7 @@ LLVolumeImplFlexible::LLVolumeImplFlexible(LLViewerObject* vo, LLFlexibleObjectD mInitializedRes = -1; mSimulateRes = 0; mFrameNum = 0; + mRenderRes = 1; }//----------------------------------------------- LLVector3 LLVolumeImplFlexible::getFramePosition() const @@ -233,7 +234,7 @@ BOOL LLVolumeImplFlexible::doIdleUpdate(LLAgent &agent, LLWorld &world, const F6 { if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FLEXIBLE)) { - return TRUE; + return FALSE; // (we are not initialized or updated) } LLFastTimer ftm(LLFastTimer::FTM_FLEXIBLE_UPDATE); @@ -241,7 +242,7 @@ BOOL LLVolumeImplFlexible::doIdleUpdate(LLAgent &agent, LLWorld &world, const F6 if (mVO->mDrawable.isNull()) { // Don't do anything until we have a drawable - return TRUE; + return FALSE; // (we are not initialized or updated) } //flexible objects never go static @@ -326,8 +327,13 @@ void LLVolumeImplFlexible::doFlexibleUpdate() if (mSimulateRes == 0) { mVO->markForUpdate(TRUE); - doIdleUpdate(gAgent, *gWorldp, 0.0); + if (!doIdleUpdate(gAgent, *gWorldp, 0.0)) + { + return; // we did not get updated or initialized, proceeding without can be dangerous + } } + + llassert_always(mInitialized); S32 num_sections = 1 << mSimulateRes; diff --git a/indra/newview/llfloaterbuy.cpp b/indra/newview/llfloaterbuy.cpp index 622af2b473..a838948a1c 100644 --- a/indra/newview/llfloaterbuy.cpp +++ b/indra/newview/llfloaterbuy.cpp @@ -39,7 +39,7 @@ LLFloaterBuy::LLFloaterBuy() childSetAction("cancel_btn", onClickCancel, this); childSetAction("buy_btn", onClickBuy, this); - setDefaultBtn("buy_btn"); + setDefaultBtn("cancel_btn"); // to avoid accidental buy (SL-43130) } LLFloaterBuy::~LLFloaterBuy() diff --git a/indra/newview/llfloaterbuycontents.cpp b/indra/newview/llfloaterbuycontents.cpp index 3745de6552..8c85a6fe5a 100644 --- a/indra/newview/llfloaterbuycontents.cpp +++ b/indra/newview/llfloaterbuycontents.cpp @@ -44,7 +44,7 @@ LLFloaterBuyContents::LLFloaterBuyContents() childDisable("buy_btn"); childDisable("wear_check"); - setDefaultBtn("buy_btn"); + setDefaultBtn("cancel_btn"); // to avoid accidental buy (SL-43130) } LLFloaterBuyContents::~LLFloaterBuyContents() diff --git a/indra/newview/llfloaterinspect.cpp b/indra/newview/llfloaterinspect.cpp index 80da7b63ed..233357453d 100644 --- a/indra/newview/llfloaterinspect.cpp +++ b/indra/newview/llfloaterinspect.cpp @@ -1,3 +1,11 @@ +/** + * @file llfloaterinspect.cpp + * @brief Floater for object inspection tool + * + * Copyright (c) 2002-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + #include "llviewerprecompiledheaders.h" #include "llfloateravatarinfo.h" #include "llfloaterinspect.h" diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index d7717dffc3..588fb1dac0 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -129,7 +129,6 @@ LLPreferenceCore::LLPreferenceCore(LLTabContainerCommon* tab_container, LLButton mPrefsIM->getPanel()->setDefaultBtn(default_btn); mMsgPanel = new LLPanelMsgs(); - gUICtrlFactory->buildPanel(mMsgPanel, "panel_settings_msgbox.xml"); mTabContainer->addTabPanel(mMsgPanel, mMsgPanel->getLabel(), FALSE, onTabChanged, mTabContainer); mMsgPanel->setDefaultBtn(default_btn); diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp index 21b2bbb02e..14a4d7dc00 100644 --- a/indra/newview/llfolderview.cpp +++ b/indra/newview/llfolderview.cpp @@ -1901,7 +1901,7 @@ void LLFolderViewFolder::requestArrange(BOOL include_descendants) { mLastArrangeGeneration = -1; // flag all items up to root - if (mParentFolder && !mParentFolder->needsArrange()) + if (mParentFolder) { mParentFolder->requestArrange(); } diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp index 00108650ef..18993e56fa 100644 --- a/indra/newview/llgroupmgr.cpp +++ b/indra/newview/llgroupmgr.cpp @@ -29,6 +29,7 @@ #include "llviewerwindow.h" #include "llfloaterdirectory.h" #include "llfloatergroupinfo.h" +#include "lluictrlfactory.h" LLGroupMgr sGroupMgr; // use local instance so that it gets cleaned up on application exit LLGroupMgr* gGroupMgr = &sGroupMgr; @@ -1709,21 +1710,28 @@ void LLGroupMgr::cancelGroupRoleChanges(const LLUUID& group_id) //static bool LLGroupMgr::parseRoleActions(const LLString& xml_filename) { - LLXmlTree xml_tree; - LLString xml_file = LLUI::locateSkin(xml_filename); - BOOL success = xml_tree.parseFile(xml_file, TRUE ); - LLXmlTreeNode* root = xml_tree.getRoot(); + LLXMLNodePtr root; + + BOOL success = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root); + if (!success || !root || !root->hasName( "role_actions" )) { llerrs << "Problem reading UI role_actions file: " << xml_filename << llendl; return false; } - for (LLXmlTreeNode* action_set = root->getChildByName("action_set"); - action_set != NULL; action_set = root->getNextNamedChild()) + LLXMLNodeList role_list; + LLXMLNodeList::iterator role_iter; + + root->getChildren("action_set", role_list, false); + + for (role_iter = role_list.begin(); role_iter != role_list.end(); ++role_iter) { + LLXMLNodePtr action_set = role_iter->second; + LLRoleActionSet* role_action_set = new LLRoleActionSet(); LLRoleAction* role_action_data = new LLRoleAction(); + // name= LLString action_set_name; if (action_set->getAttributeString("name", action_set_name)) @@ -1754,9 +1762,15 @@ bool LLGroupMgr::parseRoleActions(const LLString& xml_filename) // power mask= U64 set_power_mask = 0; - for (LLXmlTreeNode* action = action_set->getChildByName("action"); - action != NULL; action = action_set->getNextNamedChild()) + LLXMLNodeList action_list; + LLXMLNodeList::iterator action_iter; + + action_set->getChildren("action", action_list, false); + + for (action_iter = action_list.begin(); action_iter != action_list.end(); ++action_iter) { + LLXMLNodePtr action = action_iter->second; + LLRoleAction* role_action = new LLRoleAction(); // name= diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp index 7c03500f85..0484027455 100644 --- a/indra/newview/llimpanel.cpp +++ b/indra/newview/llimpanel.cpp @@ -199,19 +199,21 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& name, void LLFloaterIMPanel::init(const LLString& session_label) { gUICtrlFactory->buildFloater(this, - "floater_instant_message.xml", - NULL, - FALSE); - + "floater_instant_message.xml", + NULL, + FALSE); + setLabel(session_label); setTitle(session_label); mInputEditor->setMaxTextLength(1023); + // enable line history support for instant message bar + mInputEditor->setEnableLineHistory(TRUE); if ( gSavedPerAccountSettings.getBOOL("LogShowHistory") ) { LLLogChat::loadHistory(session_label, - &chatFromLogFile, - (void *)this); + &chatFromLogFile, + (void *)this); } if(IM_SESSION_911_START == mDialog) diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 13d13031b6..badab645b9 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -802,7 +802,7 @@ LLString LLItemBridge::getLabelSuffix() const if(item) { // it's a bit confusing to put nocopy/nomod/etc on calling cards. - if(LLAssetType::AT_CALLINGCARD != item->getType() + if( LLAssetType::AT_CALLINGCARD != item->getType() && item->getPermissions().getOwner() == gAgent.getID()) { BOOL copy = item->getPermissions().allowCopyBy(gAgent.getID()); @@ -814,14 +814,32 @@ LLString LLItemBridge::getLabelSuffix() const const char* NO_MOD = " (no modify)"; const char* NO_XFER = " (no transfer)"; const char* scopy; - if(copy) scopy = EMPTY; - else scopy = NO_COPY; + if(copy) + { + scopy = EMPTY; + } + else + { + scopy = NO_COPY; + }; const char* smod; - if(mod) smod = EMPTY; - else smod = NO_MOD; + if(mod) + { + smod = EMPTY; + } + else + { + smod = NO_MOD; + }; const char* sxfer; - if(xfer) sxfer = EMPTY; - else sxfer = NO_XFER; + if(xfer) + { + sxfer = EMPTY; + } + else + { + sxfer = NO_XFER; + }; char buffer[MAX_STRING]; /*Flawfinder: ignore*/ snprintf( /* Flawfinder: ignore */ buffer, @@ -2490,14 +2508,14 @@ void LLLandmarkBridge::performAction(LLFolderView* folder, LLInventoryModel* mod else LLItemBridge::performAction(folder, model, action); } -void open_landmark(const LLUUID& item_id, +void open_landmark(LLViewerInventoryItem* inv_item, const LLString& title, BOOL show_keep_discard, const LLUUID& source_id, BOOL take_focus) { // See if we can bring an exiting preview to the front - if( !LLPreview::show( item_id, take_focus ) ) + if( !LLPreview::show( inv_item->getUUID(), take_focus ) ) { // There isn't one, so make a new preview S32 left, top; @@ -2505,11 +2523,12 @@ void open_landmark(const LLUUID& item_id, LLRect rect = gSavedSettings.getRect("PreviewLandmarkRect"); rect.translate( left - rect.mLeft, top - rect.mTop ); - LLPreviewLandmark* preview = new LLPreviewLandmark("preview landmark", + LLPreviewLandmark* preview = new LLPreviewLandmark(title, rect, title, - item_id, - show_keep_discard); + inv_item->getUUID(), + show_keep_discard, + inv_item); preview->setSourceID(source_id); if(take_focus) preview->setFocus(TRUE); // keep onscreen @@ -2522,7 +2541,7 @@ void LLLandmarkBridge::openItem() LLViewerInventoryItem* item = getItem(); if( item ) { - open_landmark(mUUID, LLString(" ") + getPrefix() + item->getName(), FALSE); + open_landmark(item, LLString(" ") + getPrefix() + item->getName(), FALSE); } } @@ -2749,14 +2768,15 @@ LLViewerImage* LLNotecardBridge::getIcon() const return get_item_icon(LLAssetType::AT_NOTECARD, LLInventoryType::IT_NOTECARD, 0, FALSE); } -void open_notecard(const LLUUID& item_id, +void open_notecard(LLViewerInventoryItem* inv_item, const LLString& title, + const LLUUID& object_id, BOOL show_keep_discard, const LLUUID& source_id, BOOL take_focus) { // See if we can bring an existing preview to the front - if(!LLPreview::show(item_id, take_focus)) + if(!LLPreview::show(inv_item->getUUID(), take_focus)) { // There isn't one, so make a new preview S32 left, top; @@ -2764,13 +2784,9 @@ void open_notecard(const LLUUID& item_id, LLRect rect = gSavedSettings.getRect("NotecardEditorRect"); rect.translate(left - rect.mLeft, top - rect.mTop); LLPreviewNotecard* preview; - preview = new LLPreviewNotecard("preview notecard", - rect, - title, - item_id, - LLUUID::null, - LLUUID::null, - show_keep_discard); + preview = new LLPreviewNotecard("preview notecard", rect, title, + inv_item->getUUID(), object_id, inv_item->getAssetUUID(), + show_keep_discard, inv_item); preview->setSourceID(source_id); if(take_focus) preview->setFocus(TRUE); // Force to be entirely onscreen. @@ -2789,23 +2805,22 @@ void open_notecard(const LLUUID& item_id, // { // // create new multipreview if it doesn't exist // LLMultiPreview* preview_hostp = new LLMultiPreview(existing_preview->getRect()); - // preview_hostp->addFloater(existing_preview); // } // // add this preview to existing host // preview_hostp->addFloater(preview); // } //} - } } + void LLNotecardBridge::openItem() { LLViewerInventoryItem* item = getItem(); if (item) { - open_notecard(mUUID, getPrefix() + item->getName(), FALSE); + open_notecard(item, getPrefix() + item->getName(), LLUUID::null, FALSE); } } diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp index 7ba0ccad3a..75be1be4a6 100644 --- a/indra/newview/llmutelist.cpp +++ b/indra/newview/llmutelist.cpp @@ -165,12 +165,7 @@ BOOL LLMuteList::isLinden(const LLString& name) const if (token_iter == tokens.end()) return FALSE; LLString last_name = *token_iter; - - if (last_name == "Linden") - { - return TRUE; - } - return FALSE; + return last_name == "Linden"; } diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index b2fc91f536..daea084759 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -845,14 +845,44 @@ void LLPanelAvatarClassified::refresh() bool allow_delete = (tab_count > 0); bool show_help = (tab_count == 0); - childSetEnabled("New...",self && allow_new); - childSetEnabled("Delete...",self && allow_delete); + // *HACK: Don't allow making new classifieds from inside the directory. + // The logic for save/don't save when closing is too hairy, and the + // directory is conceptually read-only. JC + bool in_directory = false; + LLView* view = this; + while (view) + { + if (view->getName() == "directory") + { + in_directory = true; + break; + } + view = view->getParent(); + } + childSetEnabled("New...", self && !in_directory && allow_new); + childSetVisible("New...", !in_directory); + childSetEnabled("Delete...", self && !in_directory && allow_delete); + childSetVisible("Delete...", !in_directory); childSetVisible("classified tab",!show_help); sendAvatarProfileRequestIfNeeded("avatarclassifiedsrequest"); } +BOOL LLPanelAvatarClassified::canClose() +{ + LLTabContainerCommon* tabs = LLViewerUICtrlFactory::getTabContainerByName(this, "classified tab"); + for (S32 i = 0; i < tabs->getTabCount(); i++) + { + LLPanelClassified* panel = (LLPanelClassified*)tabs->getPanelByIndex(i); + if (!panel->canClose()) + { + return FALSE; + } + } + return TRUE; +} + BOOL LLPanelAvatarClassified::titleIsValid() { LLTabContainerCommon* tabs = LLViewerUICtrlFactory::getTabContainerByName(this, "classified tab"); @@ -1280,6 +1310,11 @@ LLPanelAvatar::~LLPanelAvatar() } +BOOL LLPanelAvatar::canClose() +{ + return mPanelClassified && mPanelClassified->canClose(); +} + void LLPanelAvatar::setAvatar(LLViewerObject *avatarp) { // find the avatar and grab the name diff --git a/indra/newview/llpanelavatar.h b/indra/newview/llpanelavatar.h index f54da2538f..cbc4c55b52 100644 --- a/indra/newview/llpanelavatar.h +++ b/indra/newview/llpanelavatar.h @@ -194,6 +194,10 @@ public: /*virtual*/ void refresh(); + // If can close, return TRUE. If cannot close, pop save/discard dialog + // and return FALSE. + BOOL canClose(); + void apply(); BOOL titleIsValid(); @@ -247,6 +251,10 @@ public: /*virtual*/ BOOL postBuild(void); + // If can close, return TRUE. If cannot close, pop save/discard dialog + // and return FALSE. + BOOL canClose(); + void setAvatar(LLViewerObject *avatarp); // Fill in the avatar ID and handle some field fill-in, as well as diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp index 95ed517794..b9b9cda4e8 100644 --- a/indra/newview/llpanelclassified.cpp +++ b/indra/newview/llpanelclassified.cpp @@ -40,6 +40,7 @@ #include "llfloaterworldmap.h" #include "llviewergenericmessage.h" // send_generic_message #include "llviewerwindow.h" // for window width, height +#include "viewer.h" // app_abort_quit() const S32 MINIMUM_PRICE_FOR_LISTING = 50; // L$ @@ -77,11 +78,12 @@ std::list<LLPanelClassified*> LLPanelClassified::sAllPanels; LLPanelClassified::LLPanelClassified(BOOL in_finder) : LLPanel("Classified Panel"), mInFinder(in_finder), + mDirty(false), + mForceClose(false), mClassifiedID(), mCreatorID(), mPriceForListing(0), mDataRequested(FALSE), - mEnableCommit(FALSE), mPaidFor(FALSE), mPosGlobal(), mSnapshotCtrl(NULL), @@ -132,7 +134,7 @@ void LLPanelClassified::reset() // Don't request data, this isn't valid mDataRequested = TRUE; - mEnableCommit = FALSE; + mDirty = false; mPaidFor = FALSE; mPosGlobal.clearVec(); @@ -215,7 +217,6 @@ BOOL LLPanelClassified::postBuild() mUpdateBtn = LLUICtrlFactory::getButtonByName(this, "classified_update_btn"); mUpdateBtn->setClickedCallback(onClickUpdate); mUpdateBtn->setCallbackUserData(this); - mEnableCommit = TRUE; if (!mInFinder) { @@ -248,12 +249,58 @@ void LLPanelClassified::apply() { // Apply is used for automatically saving results, so only // do that if there is a difference, and this is a save not create. - if (mEnableCommit && mPaidFor) + if (mDirty && mPaidFor) { sendClassifiedInfoUpdate(); } } + +// static +void LLPanelClassified::saveCallback(S32 option, void* data) +{ + LLPanelClassified* self = (LLPanelClassified*)data; + switch(option) + { + case 0: // Save + self->sendClassifiedInfoUpdate(); + // fall through to close + + case 1: // Don't Save + { + self->mForceClose = true; + // Close containing floater + LLView* view = self; + while (view) + { + if (view->getWidgetType() == WIDGET_TYPE_FLOATER) + { + LLFloater* f = (LLFloater*)view; + f->close(); + break; + } + view = view->getParent(); + } + } + break; + + case 2: // Cancel + default: + app_abort_quit(); + break; + } +} + +BOOL LLPanelClassified::canClose() +{ + if (mForceClose || !mDirty) return TRUE; + + LLString::format_map_t args; + args["[NAME]"] = mNameEditor->getText(); + LLAlertDialog::showXml("ClassifiedSave", args, saveCallback, this); + return FALSE; +} + // Fill in some reasonable defaults for a new classified. void LLPanelClassified::initNewClassified() { @@ -396,6 +443,8 @@ void LLPanelClassified::sendClassifiedInfoUpdate() msg->addU8Fast(_PREHASH_ClassifiedFlags, flags); msg->addS32("PriceForListing", mPriceForListing); gAgent.sendReliableMessage(); + + mDirty = false; } @@ -607,7 +656,7 @@ void LLPanelClassified::refresh() mSetBtn->setVisible(is_self); mSetBtn->setEnabled(is_self); - mUpdateBtn->setEnabled(is_self && mEnableCommit); + mUpdateBtn->setEnabled(is_self && mDirty); mUpdateBtn->setVisible(is_self); } } @@ -690,7 +739,6 @@ void LLPanelClassified::callbackConfirmPublish(S32 option, void* data) LLTabContainerVertical* tab = (LLTabContainerVertical*)self->getParent(); tab->setCurrentTabName(self->mNameEditor->getText()); } - self->mEnableCommit = FALSE; } // static @@ -769,14 +817,14 @@ void LLPanelClassified::onCommitAny(LLUICtrl* ctrl, void* data) LLPanelClassified* self = (LLPanelClassified*)data; if (self) { - self->mEnableCommit = TRUE; + self->mDirty = true; } } // static void LLPanelClassified::onFocusReceived(LLUICtrl* ctrl, void* data) { - // first, allow the data to be saved + // allow the data to be saved onCommitAny(ctrl, data); } diff --git a/indra/newview/llpanelclassified.h b/indra/newview/llpanelclassified.h index c959c0f82f..ca6a05eb31 100644 --- a/indra/newview/llpanelclassified.h +++ b/indra/newview/llpanelclassified.h @@ -43,10 +43,14 @@ public: /*virtual*/ void draw(); - void refresh(); + /*virtual*/ void refresh(); void apply(); + // If can close, return TRUE. If cannot close, pop save/discard dialog + // and return FALSE. + BOOL canClose(); + // Setup a new classified, including creating an id, giving a sane // initial position, etc. void initNewClassified(); @@ -74,6 +78,8 @@ public: static void callbackConfirmPublish(S32 option, void* data); protected: + static void saveCallback(S32 option, void* data); + static void onClickUpdate(void* data); static void onClickTeleport(void* data); static void onClickMap(void* data); @@ -87,6 +93,8 @@ protected: protected: BOOL mInFinder; + bool mDirty; + bool mForceClose; LLUUID mClassifiedID; LLUUID mRequestedID; LLUUID mCreatorID; @@ -95,7 +103,6 @@ protected: // Data will be requested on first draw BOOL mDataRequested; - BOOL mEnableCommit; // For avatar panel classifieds only, has the user been charged // yet for this classified? That is, have they saved once? diff --git a/indra/newview/llpreview.cpp b/indra/newview/llpreview.cpp index 7c00742122..562e4c37c1 100644 --- a/indra/newview/llpreview.cpp +++ b/indra/newview/llpreview.cpp @@ -50,7 +50,7 @@ LLPreview::LLPreview(const std::string& name) : mAutoFocus = FALSE; } -LLPreview::LLPreview(const std::string& name, const LLRect& rect, const std::string& title, const LLUUID& item_uuid, const LLUUID& object_uuid, BOOL allow_resize, S32 min_width, S32 min_height ) +LLPreview::LLPreview(const std::string& name, const LLRect& rect, const std::string& title, const LLUUID& item_uuid, const LLUUID& object_uuid, BOOL allow_resize, S32 min_width, S32 min_height, LLViewerInventoryItem* inv_item ) : LLFloater(name, rect, title, allow_resize, min_width, min_height ), mItemUUID(item_uuid), mSourceID(LLUUID::null), @@ -59,7 +59,8 @@ LLPreview::LLPreview(const std::string& name, const LLRect& rect, const std::str mForceClose( FALSE ), mUserResized(FALSE), mCloseAfterSave(FALSE), - mAssetStatus(PREVIEW_ASSET_UNLOADED) + mAssetStatus(PREVIEW_ASSET_UNLOADED), + mItem(inv_item) { mAuxItem = new LLInventoryItem; // don't necessarily steal focus on creation -- sometimes these guys pop up without user action @@ -136,6 +137,8 @@ void LLPreview::setSourceID(const LLUUID& source_id) LLViewerInventoryItem* LLPreview::getItem() const { + if(mItem != NULL) + return mItem; LLViewerInventoryItem* item = NULL; if(mObjectUUID.isNull()) { diff --git a/indra/newview/llpreview.h b/indra/newview/llpreview.h index 5c7d6f30d0..1b7c0fd9c8 100644 --- a/indra/newview/llpreview.h +++ b/indra/newview/llpreview.h @@ -51,13 +51,13 @@ public: public: // Used for XML-based construction. LLPreview(const std::string& name); - LLPreview(const std::string& name, const LLRect& rect, const std::string& title, const LLUUID& item_uuid, const LLUUID& object_uuid, BOOL allow_resize = FALSE, S32 min_width = 0, S32 min_height = 0 ); + LLPreview(const std::string& name, const LLRect& rect, const std::string& title, const LLUUID& item_uuid, const LLUUID& object_uuid, BOOL allow_resize = FALSE, S32 min_width = 0, S32 min_height = 0, LLViewerInventoryItem* inv_item = NULL ); virtual ~LLPreview(); void setItemID(const LLUUID& item_id); void setObjectID(const LLUUID& object_id); void setSourceID(const LLUUID& source_id); - LLViewerInventoryItem* getItem() const; + LLViewerInventoryItem* getItem() const; // searches if not constructed with it static LLPreview* find(const LLUUID& item_uuid); static LLPreview* show(const LLUUID& item_uuid, BOOL take_focus = TRUE ); @@ -134,6 +134,7 @@ protected: static preview_map_t sInstances; LLUUID mNotecardInventoryID; LLUUID mObjectID; + LLViewerInventoryItem* mItem; }; diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp index 1cba69b566..e5dfb9ae76 100644 --- a/indra/newview/llpreviewnotecard.cpp +++ b/indra/newview/llpreviewnotecard.cpp @@ -61,10 +61,12 @@ LLPreviewNotecard::LLPreviewNotecard(const std::string& name, const LLUUID& item_id, const LLUUID& object_id, const LLUUID& asset_id, - BOOL show_keep_discard) : + BOOL show_keep_discard, + LLViewerInventoryItem* inv_item) : LLPreview(name, rect, title, item_id, object_id, TRUE, PREVIEW_MIN_WIDTH, - PREVIEW_MIN_HEIGHT), + PREVIEW_MIN_HEIGHT, + inv_item), mAssetID( asset_id ), mNotecardItemID(item_id), mObjectID(object_id) diff --git a/indra/newview/llpreviewnotecard.h b/indra/newview/llpreviewnotecard.h index 730c56833a..908d4da98c 100644 --- a/indra/newview/llpreviewnotecard.h +++ b/indra/newview/llpreviewnotecard.h @@ -29,7 +29,8 @@ public: const LLUUID& item_id, const LLUUID& object_id = LLUUID::null, const LLUUID& asset_id = LLUUID::null, - BOOL show_keep_discard = FALSE); + BOOL show_keep_discard = FALSE, + LLViewerInventoryItem* inv_item = NULL); // llpreview virtual bool saveItem(LLPointer<LLInventoryItem>* itemptr); diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index e8dc281c6f..ce5649e06e 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -1237,6 +1237,8 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, bool threaded) : LLWorkerThread("TextureFetch", threaded), mDebugCount(0), mDebugPause(FALSE), + mPacketCount(0), + mBadPacketCount(0), mQueueMutex(getAPRPool()), mTextureCache(cache) { diff --git a/indra/newview/lltoolcomp.cpp b/indra/newview/lltoolcomp.cpp index a1c51cfe44..f3b253a4e5 100644 --- a/indra/newview/lltoolcomp.cpp +++ b/indra/newview/lltoolcomp.cpp @@ -226,7 +226,14 @@ void LLToolCompTranslate::pickCallback(S32 x, S32 y, MASK mask) { gEditMenuHandler = gSelectMgr; } - if( LLManip::LL_NO_PART != gToolTranslate->mManip->getHighlightedPart() ) + + BOOL can_move = gToolTranslate->mManip->getSelection()->getObjectCount() != 0; + for (LLViewerObject* objectp = gToolTranslate->mManip->getSelection()->getFirstObject(); objectp; objectp = gToolTranslate->mManip->getSelection()->getNextObject()) + { + can_move = can_move && objectp->permMove() && (objectp->permModify() || gSavedSettings.getBOOL("SelectLinkedSet")); + } + + if( LLManip::LL_NO_PART != gToolTranslate->mManip->getHighlightedPart() && can_move) { gToolTranslate->setCurrentTool( gToolTranslate->mManip ); gToolTranslate->mManip->handleMouseDownOnPart( x, y, mask ); diff --git a/indra/newview/lltoolmgr.cpp b/indra/newview/lltoolmgr.cpp index 7c9cd1b199..40e8a3e1fa 100644 --- a/indra/newview/lltoolmgr.cpp +++ b/indra/newview/lltoolmgr.cpp @@ -186,6 +186,9 @@ LLToolMgr::~LLToolMgr() delete gToolPie; gToolPie = NULL; + delete gToolInspect; + gToolInspect = NULL; + delete gToolGun; gToolGun = NULL; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 5a6ff851c4..c8b62146d6 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -1415,6 +1415,30 @@ void cleanup_menus() { delete gMenuParcelObserver; gMenuParcelObserver = NULL; + + delete gPieSelf; + gPieSelf = NULL; + + delete gPieAvatar; + gPieAvatar = NULL; + + delete gPieObject; + gPieObject = NULL; + + delete gPieAttachment; + gPieAttachment = NULL; + + delete gPieLand; + gPieLand = NULL; + + delete gMenuBarView; + gMenuBarView = NULL; + + delete gPopupMenuView; + gPopupMenuView = NULL; + + delete gMenuHolder; + gMenuHolder = NULL; } //----------------------------------------------------------------------------- diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index a43bb4bb5b..18f5e54154 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -772,10 +772,10 @@ void open_offer(const std::vector<LLUUID>& items, const std::string& from_name) switch(item->getType()) { case LLAssetType::AT_NOTECARD: - open_notecard(*it, LLString("Note: ") + item->getName(), show_keep_discard, LLUUID::null, FALSE); + open_notecard((LLViewerInventoryItem*)item, LLString("Note: ") + item->getName(), LLUUID::null, show_keep_discard, LLUUID::null, FALSE); break; case LLAssetType::AT_LANDMARK: - open_landmark(*it, LLString("Landmark: ") + item->getName(), show_keep_discard, LLUUID::null, FALSE); + open_landmark((LLViewerInventoryItem*)item, LLString("Landmark: ") + item->getName(), show_keep_discard, LLUUID::null, FALSE); break; case LLAssetType::AT_TEXTURE: open_texture(*it, LLString("Texture: ") + item->getName(), show_keep_discard, LLUUID::null, FALSE); @@ -830,7 +830,7 @@ void inventory_offer_mute_callback(const LLUUID& blocked_id, const char* first_name, const char* last_name, BOOL is_group, - void*) + void* user_data) { LLString from_name; LLMute::EType type; @@ -854,10 +854,35 @@ void inventory_offer_mute_callback(const LLUUID& blocked_id, gFloaterMute->show(); gFloaterMute->selectMute(blocked_id); } + + // purge the offer queue of any previously queued inventory offers from the same source. + LLView::child_list_t notification_queue(*(gNotifyBoxView->getChildList())); + for(LLView::child_list_iter_t iter = notification_queue.begin(); + iter != notification_queue.end(); + iter++) + { + LLNotifyBox* notification = (LLNotifyBox*)*iter; + // scan for other inventory offers (i.e. ignore other types of notifications). + // we can tell by looking for the associated callback they were created with. + if(notification->getNotifyCallback() == inventory_offer_callback) + { + // found one. + // safe to downcast user data because we know it's associated with offer callback. + LLOfferInfo* offer_data = (LLOfferInfo*)notification->getUserData(); + if(offer_data == user_data) + { + continue; // don't remove the msg triggering us. it will be dequeued normally. + } + if(offer_data->mFromID == blocked_id) + { + gNotifyBoxView->removeChild(notification); + } + } + } } -void inventory_offer_callback(S32 option, void* user_data) -{ +void inventory_offer_callback(S32 button, void* user_data) + { LLChat chat; LLString log_message; @@ -869,9 +894,9 @@ void inventory_offer_callback(S32 option, void* user_data) // * callback may be called immediately, // * adding the mute sends a message, // * we can't build two messages at once. JC - if (option == 2) + if (2 == button) { - gCacheName->get(info->mFromID, info->mFromGroup, inventory_offer_mute_callback, NULL); + gCacheName->get(info->mFromID, info->mFromGroup, inventory_offer_mute_callback, user_data); } LLMessageSystem* msg = gMessageSystem; @@ -902,7 +927,8 @@ void inventory_offer_callback(S32 option, void* user_data) } // XUI:translate - LLString from_string; + LLString from_string; // Used in the pop-up. + LLString chatHistory_string; // Used in chat history. if (info->mFromObject == TRUE) { if (info->mFromGroup) @@ -911,10 +937,12 @@ void inventory_offer_callback(S32 option, void* user_data) if (gCacheName->getGroupName(info->mFromID, group_name)) { from_string = LLString("An object named '") + info->mFromName + "' owned by the group '" + group_name + "'"; + chatHistory_string = info->mFromName + " owned by the group '" + group_name + "'"; } else { from_string = LLString("An object named '") + info->mFromName + "' owned by an unknown group"; + chatHistory_string = info->mFromName + " owned by an unknown group"; } } else @@ -924,21 +952,23 @@ void inventory_offer_callback(S32 option, void* user_data) if (gCacheName->getName(info->mFromID, first_name, last_name)) { from_string = LLString("An object named '") + info->mFromName + "' owned by " + first_name + " " + last_name; + chatHistory_string = info->mFromName + " owned by " + first_name + " " + last_name; } else { from_string = LLString("An object named '") + info->mFromName + "' owned by an unknown user"; + chatHistory_string = info->mFromName + " owned by an unknown user"; } } } else { - from_string = info->mFromName; + from_string = chatHistory_string = info->mFromName; } bool busy=FALSE; - switch(option) + switch(button) { case IOR_ACCEPT: // ACCEPT. The math for the dialog works, because the accept @@ -955,7 +985,7 @@ void inventory_offer_callback(S32 option, void* user_data) //don't spam them if they are getting flooded if (check_offer_throttle(info->mFromName, true)) { - log_message = info->mFromName + " gave you " + info->mDesc + "."; + log_message = chatHistory_string + " gave you " + info->mDesc + "."; chat.mText = log_message; LLFloaterChat::addChatHistory(chat); } @@ -997,7 +1027,7 @@ void inventory_offer_callback(S32 option, void* user_data) default: llwarns << "inventory_offer_callback: unknown offer type" << llendl; break; - } + } // end switch (info->mIM) break; case IOR_BUSY: @@ -1020,6 +1050,10 @@ void inventory_offer_callback(S32 option, void* user_data) log_message = "You decline " + info->mDesc + " from " + info->mFromName + "."; chat.mText = log_message; + if( gMuteListp->isMuted(info->mFromID ) && ! gMuteListp->isLinden(info->mFromName) ) // muting for SL-42269 + { + chat.mMuted = TRUE; + } LLFloaterChat::addChatHistory(chat); // If it's from an agent, we have to fetch the item to throw @@ -1066,7 +1100,6 @@ void inventory_offer_callback(S32 option, void* user_data) void inventory_offer_handler(LLOfferInfo* info, BOOL from_task) { - //Until throttling is implmented, busy mode should reject inventory instead of silently //accepting it. SEE SL-39554 if (gAgent.getBusy()) @@ -1081,15 +1114,15 @@ void inventory_offer_handler(LLOfferInfo* info, BOOL from_task) inventory_offer_callback(IOR_MUTE, info); return; } - - if (gSavedSettings.getBOOL("ShowNewInventory") + + // Avoid the Accept/Discard dialog if the user so desires. JC + if (gSavedSettings.getBOOL("AutoAcceptNewInventory") && (info->mType == LLAssetType::AT_NOTECARD || info->mType == LLAssetType::AT_LANDMARK || info->mType == LLAssetType::AT_TEXTURE)) { // For certain types, just accept the items into the inventory, - // and we'll automatically open them on receipt. - // 0 = accept button + // and possibly open them on receipt depending upon "ShowNewInventory". inventory_offer_callback(IOR_ACCEPT, info); return; } diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 279dfe2923..e15f5da537 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -208,6 +208,12 @@ LLViewerObject::~LLViewerObject() mJointInfo = NULL; } + if (mPartSourcep) + { + mPartSourcep->setDead(); + mPartSourcep = NULL; + } + // Delete memory associated with extra parameters. std::map<U16, ExtraParameter*>::iterator iter; for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter) diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp index cb0df92386..6d4e8bfeff 100644 --- a/indra/newview/llviewerpartsim.cpp +++ b/indra/newview/llviewerpartsim.cpp @@ -501,6 +501,7 @@ LLViewerPartGroup *LLViewerPartSim::put(LLViewerPart* part) llwarns << "LLViewerPartSim::put - Particle didn't go into its box!" << llendl; llinfos << groupp->getCenterAgent() << llendl; llinfos << part->mPosAgent << llendl; + delete groupp; return NULL; } return groupp; @@ -673,6 +674,7 @@ void LLViewerPartSim::cleanupRegion(LLViewerRegion *regionp) if ((*iter)->getRegion() == regionp) { + delete *iter; i = mViewerPartGroups.erase(iter); } } diff --git a/indra/newview/llviewerpartsource.cpp b/indra/newview/llviewerpartsource.cpp index b14a82e3f1..6a92ba5087 100644 --- a/indra/newview/llviewerpartsource.cpp +++ b/indra/newview/llviewerpartsource.cpp @@ -302,6 +302,7 @@ LLViewerPartSourceScript *LLViewerPartSourceScript::unpackPSS(LLViewerObject *so LLViewerPartSourceScript *new_pssp = new LLViewerPartSourceScript(source_objp); if (!new_pssp->mPartSysData.unpackBlock(block_num)) { + delete new_pssp; return NULL; } if (new_pssp->mPartSysData.mTargetUUID.notNull()) @@ -340,6 +341,7 @@ LLViewerPartSourceScript *LLViewerPartSourceScript::unpackPSS(LLViewerObject *so LLViewerPartSourceScript *new_pssp = new LLViewerPartSourceScript(source_objp); if (!new_pssp->mPartSysData.unpack(dp)) { + delete new_pssp; return NULL; } if (new_pssp->mPartSysData.mTargetUUID.notNull()) @@ -747,3 +749,4 @@ void LLViewerPartSourceChat::setColor(const LLColor4 &color) mColor = color; } + diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp index d81454fa8d..cc0345b79a 100644 --- a/indra/newview/llviewertexteditor.cpp +++ b/indra/newview/llviewertexteditor.cpp @@ -1199,7 +1199,7 @@ BOOL LLViewerTextEditor::openEmbeddedItem(LLInventoryItem* item, BOOL saved) return TRUE; case LLAssetType::AT_LANDMARK: - showLandmarkDialog( item ); + openEmbeddedLandmark( item ); return TRUE; case LLAssetType::AT_LSL_TEXT: @@ -1253,35 +1253,28 @@ void LLViewerTextEditor::openEmbeddedSound( LLInventoryItem* item ) showCopyToInvDialog( item ); } -/* + void LLViewerTextEditor::openEmbeddedLandmark( LLInventoryItem* item ) { - // See if we can bring an existing preview to the front - if( !LLPreview::show( item->getUUID() ) ) - { - // There isn't one, so make a new preview - S32 left, top; - gFloaterView->getNewFloaterPosition(&left, &top); - LLRect rect = gSavedSettings.getRect("PreviewLandmarkRect"); - rect.translate( left - rect.mLeft, top - rect.mTop ); - - LLPreviewLandmark* preview = new LLPreviewLandmark( - "preview landmark", - rect, - item->getName(), - item->getUUID()); - preview->setAuxItem( item ); - preview->addCopyToInvButton(); - preview->open(); - } -}*/ + open_landmark((LLViewerInventoryItem*)item, " preview landmark", FALSE, item->getUUID(), TRUE); +} + void LLViewerTextEditor::openEmbeddedNotecard( LLInventoryItem* item, BOOL saved ) { if (saved) { - // Copy to inventory - copyInventory(item); + // Pop-up the notecard floater. + // Note: Previously would copy to inventory and rely on autodisplay to view. + // Now that autodisplay can be turned off, we need to make this case display always. + // besides, there's no point adding to inventory -MG + open_notecard( + (LLViewerInventoryItem*)item, + LLString("Embedded Note: ") + item->getName(), // title + mObjectID, + FALSE, // show_keep_discard + LLUUID::null, // source_id + TRUE); // take_focus } else { @@ -1304,59 +1297,6 @@ void LLViewerTextEditor::onNotecardDialog( S32 option, void* userdata ) } -void LLViewerTextEditor::showLandmarkDialog( LLInventoryItem* item ) -{ - LLNotecardCopyInfo *info = new LLNotecardCopyInfo(this, item); - gViewerWindow->alertXml("ConfirmLandmarkCopy", - LLViewerTextEditor::onLandmarkDialog, (void*)info); -} - -// static -void LLViewerTextEditor::onLandmarkDialog( S32 option, void* userdata ) -{ - LLNotecardCopyInfo *info = (LLNotecardCopyInfo *)userdata; - if( option == 0 ) - { - // Copy to inventory - info->mTextEd->copyInventory(info->mItem); - /* - * XXXPAM - * - * Yes, this is broken. We don't show the map yet. - * - LLInventoryItem* orig_item = (LLInventoryItem*)userdata; - - // Copy to inventory - LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem; - cloneInventoryItemToViewer(orig_item, new_item); - U32 flags = new_item->getFlags(); - flags &= ~LLInventoryItem::II_FLAGS_LANDMARK_VISITED; - new_item->setFlags(flags); - new_item->updateServer(TRUE); - gInventory.updateItem(new_item); - gInventory.notifyObservers(); - - LLInventoryView* view = LLInventoryView::getActiveInventory(); - if(view) - { - view->getPanel()->setSelection(new_item->getUUID(), TAKE_FOCUS_NO); - } - - if( (0 == option) && gFloaterWorldMap ) - { - // Note: there's a minor race condition here. - // If the user immediately tries to teleport to the landmark, the dataserver may - // not yet know that the user has the landmark in his inventory and so may - // disallow the teleport. However, the user will need to be pretty fast to make - // this happen, and, if it does, they haven't lost anything. Once the dataserver - // knows about the new item, the user will be able to teleport to it successfully. - gFloaterWorldMap->trackLandmark(new_item->getUUID()); - LLFloaterWorldMap::show(NULL, TRUE); - }*/ - } - delete info; -} - void LLViewerTextEditor::showCopyToInvDialog( LLInventoryItem* item ) { diff --git a/indra/newview/llviewertexteditor.h b/indra/newview/llviewertexteditor.h index de57b68e7d..a57b3fec7e 100644 --- a/indra/newview/llviewertexteditor.h +++ b/indra/newview/llviewertexteditor.h @@ -89,14 +89,12 @@ protected: void openEmbeddedTexture( LLInventoryItem* item ); void openEmbeddedSound( LLInventoryItem* item ); - //void openEmbeddedLandmark( LLInventoryItem* item ); + void openEmbeddedLandmark( LLInventoryItem* item ); void openEmbeddedNotecard( LLInventoryItem* item, BOOL saved ); void showCopyToInvDialog( LLInventoryItem* item ); - void showLandmarkDialog( LLInventoryItem* item ); static void onCopyToInvDialog( S32 option, void* userdata ); static void onNotecardDialog( S32 option, void* userdata ); - static void onLandmarkDialog( S32 option, void* userdata ); protected: LLPointer<LLInventoryItem> mDragItem; diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index a9ed98e9db..682490440c 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1559,8 +1559,6 @@ LLViewerWindow::LLViewerWindow( // Can't have spaces in settings.ini strings, so use underscores instead and convert them. LLString::replaceChar(mOverlayTitle, '_', ' '); - gAwayTimer.stop(); - LLAlertDialog::setDisplayCallback(alertCallback); // call this before calling any modal dialogs // sync the keyboard's setting with the saved setting @@ -1857,6 +1855,7 @@ void LLViewerWindow::initWorldUI() gIMView = new LLIMView("gIMView", LLRect() ); gIMView->setFollowsAll(); + mRootView->addChild(gIMView); LLRect morph_view_rect = full_window; morph_view_rect.stretch( -STATUS_BAR_HEIGHT ); @@ -2380,7 +2379,17 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask) case KEY_LEFT: case KEY_RIGHT: case KEY_UP: + // let CTRL UP through for chat line history + if( MASK_CONTROL & mask ) + { + break; + } case KEY_DOWN: + // let CTRL DOWN through for chat line history + if( MASK_CONTROL & mask ) + { + break; + } case KEY_PAGE_UP: case KEY_PAGE_DOWN: case KEY_HOME: diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 1f1145624b..0236abf127 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -8013,7 +8013,7 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) } else { - llwarns << "AvatarAppearance msg received without any parameters" << llendl; + llwarns << "AvatarAppearance msg received without any parameters, object: " << getID() << llendl; } setCompositeUpdatesEnabled( TRUE ); diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index a708b735db..c03ec75081 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -412,6 +412,8 @@ class Linux_i686Manifest(LinuxManifest): self.path("libelfio.so") self.path("libuuid.so", "libuuid.so.1") self.path("libSDL-1.2.so.0") + self.path("libtcmalloc.so.0") + self.path("libstacktrace.so.0") self.path("libllkdu.so", "../bin/libllkdu.so") # llkdu goes in bin for some reason self.end_prefix("lib") diff --git a/indra/win_updater/updater.cpp b/indra/win_updater/updater.cpp index c139d2f55c..92e2cb066a 100644 --- a/indra/win_updater/updater.cpp +++ b/indra/win_updater/updater.cpp @@ -148,7 +148,7 @@ int WINAPI get_url_into_file(WCHAR *uri, char *path, int *cancelled) } #endif - if (!data) + if (!data[0]) { #if _DEBUG fprintf(logfile,"InternetReadFile Returned NULL data, bytes_read = %d.\n",bytes_read); |