summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/llcharacter/llheadrotmotion.cpp1
-rw-r--r--indra/llcommon/llerror.cpp50
-rw-r--r--indra/llcommon/llerror.h3
-rw-r--r--indra/llcommon/llprocessor.cpp2
-rw-r--r--indra/llinventory/llnotecard.cpp6
-rw-r--r--indra/llinventory/llsaleinfo.cpp4
-rw-r--r--indra/llinventory/lluserrelations.h2
-rw-r--r--indra/llmath/llvolume.cpp83
-rw-r--r--indra/llmessage/llcurl.cpp11
-rw-r--r--indra/llmessage/llcurl.h1
-rw-r--r--indra/llmessage/llmessageconfig.cpp5
-rw-r--r--indra/llmessage/message.cpp9
-rw-r--r--indra/llrender/llvertexbuffer.cpp8
-rw-r--r--indra/llrender/llvertexbuffer.h8
-rw-r--r--indra/llui/lllineeditor.cpp81
-rw-r--r--indra/llui/lllineeditor.h10
-rw-r--r--indra/llui/lltexteditor.cpp25
-rw-r--r--indra/llui/lltexteditor.h1
-rw-r--r--indra/llui/llview.cpp3
-rw-r--r--indra/llwindow/llwindowmacosx.cpp8
-rw-r--r--indra/llwindow/llwindowmesaheadless.h1
-rw-r--r--indra/llwindow/llwindowsdl.cpp49
-rw-r--r--indra/mac_updater/mac_updater.cpp194
-rw-r--r--indra/newview/licenses-linux.txt33
-rw-r--r--indra/newview/llagent.cpp2
-rw-r--r--indra/newview/llcallingcard.cpp1
-rw-r--r--indra/newview/llchatbar.cpp4
-rw-r--r--indra/newview/llflexibleobject.cpp12
-rw-r--r--indra/newview/llfloaterbuy.cpp2
-rw-r--r--indra/newview/llfloaterbuycontents.cpp2
-rw-r--r--indra/newview/llfloaterinspect.cpp8
-rw-r--r--indra/newview/llfloaterpreference.cpp1
-rw-r--r--indra/newview/llfolderview.cpp2
-rw-r--r--indra/newview/llgroupmgr.cpp30
-rw-r--r--indra/newview/llimpanel.cpp14
-rw-r--r--indra/newview/llinventorybridge.cpp65
-rw-r--r--indra/newview/llmutelist.cpp7
-rw-r--r--indra/newview/llpanelavatar.cpp39
-rw-r--r--indra/newview/llpanelavatar.h8
-rw-r--r--indra/newview/llpanelclassified.cpp64
-rw-r--r--indra/newview/llpanelclassified.h11
-rw-r--r--indra/newview/llpreview.cpp7
-rw-r--r--indra/newview/llpreview.h5
-rw-r--r--indra/newview/llpreviewnotecard.cpp6
-rw-r--r--indra/newview/llpreviewnotecard.h3
-rw-r--r--indra/newview/lltexturefetch.cpp2
-rw-r--r--indra/newview/lltoolcomp.cpp9
-rw-r--r--indra/newview/lltoolmgr.cpp3
-rw-r--r--indra/newview/llviewermenu.cpp24
-rw-r--r--indra/newview/llviewermessage.cpp67
-rw-r--r--indra/newview/llviewerobject.cpp6
-rw-r--r--indra/newview/llviewerpartsim.cpp2
-rw-r--r--indra/newview/llviewerpartsource.cpp3
-rw-r--r--indra/newview/llviewertexteditor.cpp92
-rw-r--r--indra/newview/llviewertexteditor.h4
-rw-r--r--indra/newview/llviewerwindow.cpp13
-rw-r--r--indra/newview/llvoavatar.cpp2
-rwxr-xr-xindra/newview/viewer_manifest.py2
-rw-r--r--indra/win_updater/updater.cpp2
59 files changed, 824 insertions, 298 deletions
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);