summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
authorDon Kjer <don@lindenlab.com>2007-05-02 21:24:47 +0000
committerDon Kjer <don@lindenlab.com>2007-05-02 21:24:47 +0000
commit1c909afe3998778e4cc045c9ab733e8afbf7c25b (patch)
tree75c00a32a8e305280cbec253195d1113d628fc3e /indra/newview
parentbc59c04653bf1404e8148a8169208b146a123b28 (diff)
svn merge -r 60342:61148 svn+ssh://svn/svn/linden/branches/maintenance into release
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/app_settings/keys.ini22
-rwxr-xr-xindra/newview/linux_tools/launch_url.sh2
-rwxr-xr-xindra/newview/linux_tools/wrapper.sh2
-rw-r--r--indra/newview/llassetuploadresponders.cpp2
-rw-r--r--indra/newview/llchatbar.cpp3
-rw-r--r--indra/newview/lldebugmessagebox.cpp22
-rw-r--r--indra/newview/lldrawpoolavatar.cpp11
-rw-r--r--indra/newview/lldriverparam.cpp2
-rw-r--r--indra/newview/llfasttimerview.cpp9
-rw-r--r--indra/newview/llfilepicker.cpp15
-rw-r--r--indra/newview/llfloateranimpreview.cpp8
-rw-r--r--indra/newview/llfloaterfriends.cpp4
-rw-r--r--indra/newview/llfloaterinspect.cpp80
-rw-r--r--indra/newview/llfloaterland.cpp37
-rw-r--r--indra/newview/llfloaternamedesc.cpp9
-rw-r--r--indra/newview/llfloaterpreference.cpp60
-rw-r--r--indra/newview/llfloaterpreference.h1
-rw-r--r--indra/newview/llfloaterregioninfo.cpp19
-rw-r--r--indra/newview/llfloaterreporter.cpp5
-rw-r--r--indra/newview/llfloatersnapshot.cpp2
-rw-r--r--indra/newview/llfloatertools.cpp2
-rw-r--r--indra/newview/llfolderview.cpp674
-rw-r--r--indra/newview/llfolderview.h49
-rw-r--r--indra/newview/llglsandbox.cpp2
-rw-r--r--indra/newview/llhudeffecttrail.cpp8
-rw-r--r--indra/newview/llhudrender.cpp9
-rw-r--r--indra/newview/llinventorybridge.cpp85
-rw-r--r--indra/newview/llinventorymodel.cpp134
-rw-r--r--indra/newview/llinventorymodel.h29
-rw-r--r--indra/newview/llpanelavatar.cpp59
-rw-r--r--indra/newview/llpanelface.cpp35
-rw-r--r--indra/newview/llpanelgroup.cpp2
-rw-r--r--indra/newview/llpanelgroupgeneral.cpp28
-rw-r--r--indra/newview/llpanelgroupnotices.cpp8
-rw-r--r--indra/newview/llpanelgrouproles.cpp23
-rw-r--r--indra/newview/llpanelpermissions.cpp17
-rw-r--r--indra/newview/llpatchvertexarray.cpp10
-rw-r--r--indra/newview/llpolymesh.cpp32
-rw-r--r--indra/newview/llpolymorph.cpp12
-rw-r--r--indra/newview/llpreview.cpp24
-rw-r--r--indra/newview/llpreview.h6
-rw-r--r--indra/newview/llpreviewgesture.cpp7
-rw-r--r--indra/newview/llpreviewnotecard.cpp11
-rw-r--r--indra/newview/llpreviewscript.cpp26
-rw-r--r--indra/newview/llpreviewtexture.cpp63
-rw-r--r--indra/newview/llresourcedata.h24
-rw-r--r--indra/newview/llselectmgr.cpp110
-rw-r--r--indra/newview/llselectmgr.h1
-rw-r--r--indra/newview/llspatialpartition.cpp7
-rw-r--r--indra/newview/llstartup.cpp4
-rw-r--r--indra/newview/llstartup.h1
-rw-r--r--indra/newview/llstatusbar.cpp5
-rw-r--r--indra/newview/llstatusbar.h3
-rw-r--r--indra/newview/lltexlayer.cpp2
-rw-r--r--indra/newview/lltexturectrl.cpp43
-rw-r--r--indra/newview/lltooldraganddrop.cpp18
-rw-r--r--indra/newview/lltoolgrab.cpp8
-rw-r--r--indra/newview/lltoolpie.cpp8
-rw-r--r--indra/newview/llviewerassetstorage.cpp13
-rw-r--r--indra/newview/llviewercontrol.cpp8
-rw-r--r--indra/newview/llviewerdisplay.cpp6
-rw-r--r--indra/newview/llviewerinventory.cpp4
-rw-r--r--indra/newview/llviewerjointmesh.cpp8
-rw-r--r--indra/newview/llviewerkeyboard.cpp13
-rw-r--r--indra/newview/llviewermenu.cpp993
-rw-r--r--indra/newview/llviewermenu.h29
-rw-r--r--indra/newview/llviewermenufile.cpp1002
-rw-r--r--indra/newview/llviewermenufile.h39
-rw-r--r--indra/newview/llviewermessage.cpp523
-rw-r--r--indra/newview/llviewermessage.h9
-rw-r--r--indra/newview/llviewerobject.cpp29
-rw-r--r--indra/newview/llviewerparceloverlay.cpp15
-rw-r--r--indra/newview/llvlcomposition.cpp7
-rw-r--r--indra/newview/llvoavatar.cpp6
-rw-r--r--indra/newview/llvoclouds.cpp12
-rw-r--r--indra/newview/llvopartgroup.cpp13
-rw-r--r--indra/newview/llwindebug.cpp2
-rw-r--r--indra/newview/llworldmap.cpp2
-rw-r--r--indra/newview/pipeline.cpp12
79 files changed, 2634 insertions, 2015 deletions
diff --git a/indra/newview/app_settings/keys.ini b/indra/newview/app_settings/keys.ini
index b7fc6f9286..3a1e9ead36 100644
--- a/indra/newview/app_settings/keys.ini
+++ b/indra/newview/app_settings/keys.ini
@@ -235,6 +235,13 @@ EDIT PAD_PGUP ALT jump
EDIT PAD_PGDN ALT push_down
EDIT PAD_ENTER ALT start_chat
+SITTING A ALT spin_around_cw
+SITTING D ALT spin_around_ccw
+SITTING W ALT move_forward
+SITTING S ALT move_backward
+SITTING E ALT spin_over_sitting
+SITTING C ALT spin_under_sitting
+
SITTING LEFT ALT spin_around_cw
SITTING RIGHT ALT spin_around_ccw
SITTING UP ALT move_forward
@@ -242,6 +249,21 @@ SITTING DOWN ALT move_backward
SITTING PGUP ALT spin_over
SITTING PGDN ALT spin_under
+SITTING A CTL_ALT spin_around_cw
+SITTING D CTL_ALT spin_around_ccw
+SITTING W CTL_ALT spin_over
+SITTING S CTL_ALT spin_under
+SITTING E CTL_ALT spin_over
+SITTING C CTL_ALT spin_under
+
+SITTING LEFT CTL_ALT spin_around_cw
+SITTING RIGHT CTL_ALT spin_around_ccw
+SITTING UP CTL_ALT spin_over
+SITTING DOWN CTL_ALT spin_under
+SITTING PGUP CTL_ALT spin_over
+SITTING PGDN CTL_ALT spin_under
+
+
SITTING A NONE spin_around_cw_sitting
SITTING D NONE spin_around_ccw_sitting
SITTING W NONE move_forward_sitting
diff --git a/indra/newview/linux_tools/launch_url.sh b/indra/newview/linux_tools/launch_url.sh
index 564e834939..a1c6f5dbd9 100755
--- a/indra/newview/linux_tools/launch_url.sh
+++ b/indra/newview/linux_tools/launch_url.sh
@@ -1,5 +1,5 @@
#!/bin/sh
-# bash v1.14+ expected
+# Script tested with: bash 1.14, bash 3.1.17, zsh 4.2.5, ksh 1993-12-28
# This script loads a web page in the 'default' graphical web browser.
# It MUST return immediately (or soon), so the browser should be
diff --git a/indra/newview/linux_tools/wrapper.sh b/indra/newview/linux_tools/wrapper.sh
index cdc36a8375..5f128e8e41 100755
--- a/indra/newview/linux_tools/wrapper.sh
+++ b/indra/newview/linux_tools/wrapper.sh
@@ -1,4 +1,6 @@
#!/bin/sh
+# Script tested with: bash 1.14, bash 3.1.17, zsh 4.2.5, ksh 1993-12-28
+
## Here are some configuration options for Linux Client Alpha Testers.
## These options are for self-assisted troubleshooting during this alpha
## testing phase; you should not usually need to touch them.
diff --git a/indra/newview/llassetuploadresponders.cpp b/indra/newview/llassetuploadresponders.cpp
index 821bb2a69f..26c606fc31 100644
--- a/indra/newview/llassetuploadresponders.cpp
+++ b/indra/newview/llassetuploadresponders.cpp
@@ -21,7 +21,7 @@
#include "lluploaddialog.h"
#include "llviewerobject.h"
#include "llviewerobjectlist.h"
-#include "llviewermenu.h"
+#include "llviewermenufile.h"
#include "llviewerwindow.h"
#include "viewer.h"
diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp
index ddf0b83e73..c5e7eaa1e9 100644
--- a/indra/newview/llchatbar.cpp
+++ b/indra/newview/llchatbar.cpp
@@ -98,9 +98,10 @@ LLChatBar::LLChatBar(const std::string& name, const LLRect& rect)
mInputEditor->setRevertOnEsc( FALSE );
mInputEditor->setIgnoreTab(TRUE);
mInputEditor->setPassDelete(TRUE);
+
+ mInputEditor->setMaxTextLength(1023);
}
- mInputEditor->setMaxTextLength(1023);
// Build the list of gestures
refreshGestures();
diff --git a/indra/newview/lldebugmessagebox.cpp b/indra/newview/lldebugmessagebox.cpp
index 0ce745a373..938a6ebd11 100644
--- a/indra/newview/lldebugmessagebox.cpp
+++ b/indra/newview/lldebugmessagebox.cpp
@@ -205,21 +205,21 @@ void LLDebugVarMessageBox::draw()
if(mAnimate)
{
- F32 animated_val = clamp_rescale(fmodf((F32)LLFrameTimer::getElapsedSeconds() / 5.f, 1.f), 0.f, 1.f, 0.f, mSlider1->getMaxValue());
if (mSlider1)
{
+ F32 animated_val = clamp_rescale(fmodf((F32)LLFrameTimer::getElapsedSeconds() / 5.f, 1.f), 0.f, 1.f, 0.f, mSlider1->getMaxValue());
mSlider1->setValue(animated_val);
slider_changed(mSlider1, this);
- }
- if (mSlider2)
- {
- mSlider2->setValue(animated_val);
- slider_changed(mSlider2, this);
- }
- if (mSlider3)
- {
- mSlider3->setValue(animated_val);
- slider_changed(mSlider3, this);
+ if (mSlider2)
+ {
+ mSlider2->setValue(animated_val);
+ slider_changed(mSlider2, this);
+ }
+ if (mSlider3)
+ {
+ mSlider3->setValue(animated_val);
+ slider_changed(mSlider3, this);
+ }
}
}
LLFloater::draw();
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index d8b923c271..ee0ed22e35 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -82,7 +82,8 @@ BOOL gRenderAvatar = TRUE;
S32 LLDrawPoolAvatar::getVertexShaderLevel() const
{
- return (S32) LLShaderMgr::getVertexShaderLevel(LLShaderMgr::SHADER_AVATAR);
+ return sShaderLevel;
+ //return (S32) LLShaderMgr::getVertexShaderLevel(LLShaderMgr::SHADER_AVATAR);
}
void LLDrawPoolAvatar::prerender()
@@ -177,20 +178,22 @@ void LLDrawPoolAvatar::endFootShadow()
void LLDrawPoolAvatar::beginRigid()
{
- sVertexProgram = &gAvatarEyeballProgram;
+ sVertexProgram = NULL;
+ sShaderLevel = 0;
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- if (sShaderLevel > 0)
+ /*if (sShaderLevel > 0)
{ //eyeballs render with the specular shader
gAvatarEyeballProgram.bind();
gMaterialIndex = gAvatarEyeballProgram.mAttribute[LLShaderMgr::MATERIAL_COLOR];
gSpecularIndex = gAvatarEyeballProgram.mAttribute[LLShaderMgr::SPECULAR_COLOR];
- }
+ }*/
}
void LLDrawPoolAvatar::endRigid()
{
+ sShaderLevel = mVertexShaderLevel;
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
diff --git a/indra/newview/lldriverparam.cpp b/indra/newview/lldriverparam.cpp
index e0d1792e6c..d96ebc3094 100644
--- a/indra/newview/lldriverparam.cpp
+++ b/indra/newview/lldriverparam.cpp
@@ -326,7 +326,7 @@ const LLVector3* LLDriverParam::getNextDistortion(U32 *index, LLPolyMesh **poly_
// We're already in the middle of a param's distortions, so get the next one.
const LLVector3* v = driven->mParam->getNextDistortion( index, poly_mesh );
- if( !v )
+ if( (!v) && (iter != mDriven.end()) )
{
// This param is finished, so start the next param. It might not have any
// distortions, though, so we have to loop to find the next param that does.
diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp
index cbcdfaa55c..f5e6545369 100644
--- a/indra/newview/llfasttimerview.cpp
+++ b/indra/newview/llfasttimerview.cpp
@@ -1088,6 +1088,15 @@ F64 LLFastTimerView::getTime(LLFastTimer::EFastTimerType tidx)
break;
}
}
+
+ if (i == FTV_DISPLAY_NUM)
+ {
+ // walked off the end of ft_display_table without finding
+ // the desired timer type
+ llwarns << "Timer type " << tidx << " not known." << llendl;
+ return F64(0.0);
+ }
+
S32 table_idx = i;
// Add child ticks to parent
diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp
index 4a69286493..6f43460f70 100644
--- a/indra/newview/llfilepicker.cpp
+++ b/indra/newview/llfilepicker.cpp
@@ -431,8 +431,9 @@ void LLFilePicker::reset()
void LLFilePicker::buildFilename( void )
{
- strncpy( mFilename, mFiles, LL_MAX_PATH ); /*Flawfinder: ignore*/
- S32 len = strlen( mFilename ); /*Flawfinder: ignore*/
+ strncpy( mFilename, mFiles, LL_MAX_PATH );
+ mFilename[LL_MAX_PATH-1] = '\0'; // stupid strncpy
+ S32 len = strlen( mFilename );
strncat(mFilename,gDirUtilp->getDirDelimiter().c_str(), sizeof(mFilename)-len+1); /*Flawfinder: ignore*/
len += strlen(gDirUtilp->getDirDelimiter().c_str()); /*Flawfinder: ignore*/
@@ -838,7 +839,10 @@ void LLFilePicker::getFilePath(SInt32 index)
{
mFiles[0] = 0;
if (mFileVector.size())
- strncpy(mFiles, mFileVector[index].c_str(), sizeof(mFiles)); /*Flawfinder: ignore*/
+ {
+ strncpy(mFiles, mFileVector[index].c_str(), sizeof(mFiles));
+ mFiles[sizeof(mFiles)-1] = '\0'; // stupid strncpy
+ }
}
void LLFilePicker::getFileName(SInt32 index)
@@ -848,7 +852,10 @@ void LLFilePicker::getFileName(SInt32 index)
{
char *start = strrchr(mFileVector[index].c_str(), '/');
if (start && ((start + 1 - mFileVector[index].c_str()) < (mFileVector[index].size())))
- strncpy(mFilename, start + 1, sizeof(mFilename)); /*Flawfinder: ignore*/
+ {
+ strncpy(mFilename, start + 1, sizeof(mFilename));
+ mFilename[sizeof(mFilename)-1] = '\0';// stupid strncpy
+ }
}
}
diff --git a/indra/newview/llfloateranimpreview.cpp b/indra/newview/llfloateranimpreview.cpp
index 22617a7fcc..7085407999 100644
--- a/indra/newview/llfloateranimpreview.cpp
+++ b/indra/newview/llfloateranimpreview.cpp
@@ -34,7 +34,7 @@
#include "llviewercamera.h"
#include "llviewerobjectlist.h"
#include "llviewerwindow.h"
-#include "llviewermenu.h"
+#include "llviewermenufile.h" // upload_new_resource()
#include "llvoavatar.h"
#include "pipeline.h"
#include "viewer.h"
@@ -201,7 +201,7 @@ BOOL LLFloaterAnimPreview::postBuild()
}
apr_file_close(fp);
- delete file_buffer;
+ delete[] file_buffer;
}
}
@@ -227,11 +227,11 @@ BOOL LLFloaterAnimPreview::postBuild()
// pass animation data through memory buffer
loaderp->serialize(dp);
dp.reset();
- BOOL success = motionp->deserialize(dp);
+ BOOL success = motionp && motionp->deserialize(dp);
delete []buffer;
- if (motionp && success)
+ if (success)
{
const LLBBoxLocal &pelvis_bbox = motionp->getPelvisBBox();
diff --git a/indra/newview/llfloaterfriends.cpp b/indra/newview/llfloaterfriends.cpp
index 1e65ae5620..4f1da916fc 100644
--- a/indra/newview/llfloaterfriends.cpp
+++ b/indra/newview/llfloaterfriends.cpp
@@ -267,6 +267,7 @@ void LLFloaterFriends::refreshRightsChangeList(U8 state)
bool can_change_online_multiple = true;
bool can_change_map_multiple = true;
LLTextBox* processing_label = LLUICtrlFactory::getTextBoxByName(this, "process_rights_label");
+
if(!mAllowRightsChange)
{
if(processing_label)
@@ -282,9 +283,10 @@ void LLFloaterFriends::refreshRightsChangeList(U8 state)
processing_label->setVisible(false);
}
}
+
if(state == 1)
{
- if(!friend_status->isOnline())
+ if(friend_status && !friend_status->isOnline())
{
childSetEnabled("offer_teleport_btn", false);
}
diff --git a/indra/newview/llfloaterinspect.cpp b/indra/newview/llfloaterinspect.cpp
index 1548c0e5d6..80da7b63ed 100644
--- a/indra/newview/llfloaterinspect.cpp
+++ b/indra/newview/llfloaterinspect.cpp
@@ -64,42 +64,54 @@ void LLFloaterInspect::show(void* ignored)
void LLFloaterInspect::onClickCreatorProfile(void* ctrl)
{
if(sInstance->mObjectList->getAllSelected().size() == 0) return;
- LLSelectNode* obj = sInstance->mObjectSelection->getFirstNode();
- LLUUID obj_id, creator_id;
- obj_id = sInstance->mObjectList->getFirstSelected()->getUUID();
- while(obj)
+ LLScrollListItem* first_selected =
+ sInstance->mObjectList->getFirstSelected();
+
+ if (first_selected)
{
- if(obj_id == obj->getObject()->getID())
+ LLSelectNode* obj= sInstance->mObjectSelection->getFirstNode();
+ LLUUID obj_id, creator_id;
+ obj_id = first_selected->getUUID();
+ while(obj)
{
- creator_id = obj->mPermissions->getCreator();
- break;
+ if(obj_id == obj->getObject()->getID())
+ {
+ creator_id = obj->mPermissions->getCreator();
+ break;
+ }
+ obj = sInstance->mObjectSelection->getNextNode();
+ }
+ if(obj)
+ {
+ LLFloaterAvatarInfo::showFromDirectory(creator_id);
}
- obj = sInstance->mObjectSelection->getNextNode();
- }
- if(obj)
- {
- LLFloaterAvatarInfo::showFromDirectory(creator_id);
}
}
void LLFloaterInspect::onClickOwnerProfile(void* ctrl)
{
if(sInstance->mObjectList->getAllSelected().size() == 0) return;
- LLSelectNode* obj = sInstance->mObjectSelection->getFirstNode();
- LLUUID obj_id, owner_id;
- obj_id = sInstance->mObjectList->getFirstSelected()->getUUID();
- while(obj)
+ LLScrollListItem* first_selected =
+ sInstance->mObjectList->getFirstSelected();
+
+ if (first_selected)
{
- if(obj_id == obj->getObject()->getID())
+ LLSelectNode* obj= sInstance->mObjectSelection->getFirstNode();
+ LLUUID obj_id, owner_id;
+ obj_id = first_selected->getUUID();
+ while(obj)
{
- owner_id = obj->mPermissions->getOwner();
- break;
+ if(obj_id == obj->getObject()->getID())
+ {
+ owner_id = obj->mPermissions->getOwner();
+ break;
+ }
+ obj = sInstance->mObjectSelection->getNextNode();
+ }
+ if(obj)
+ {
+ LLFloaterAvatarInfo::showFromDirectory(owner_id);
}
- obj = sInstance->mObjectSelection->getNextNode();
- }
- if(obj)
- {
- LLFloaterAvatarInfo::showFromDirectory(owner_id);
}
}
@@ -125,7 +137,15 @@ LLUUID LLFloaterInspect::getSelectedUUID()
{
if(sInstance)
{
- if(sInstance->mObjectList->getAllSelected().size() > 0) return sInstance->mObjectList->getFirstSelected()->getUUID();
+ if(sInstance->mObjectList->getAllSelected().size() > 0)
+ {
+ LLScrollListItem* first_selected =
+ sInstance->mObjectList->getFirstSelected();
+ if (first_selected)
+ {
+ return first_selected->getUUID();
+ }
+ }
}
return LLUUID::null;
}
@@ -139,7 +159,15 @@ void LLFloaterInspect::refresh()
childSetEnabled("button creator", false);
LLUUID selected_uuid;
S32 selected_index = mObjectList->getFirstSelectedIndex();
- if(selected_index > -1) selected_uuid = mObjectList->getFirstSelected()->getUUID();
+ if(selected_index > -1)
+ {
+ LLScrollListItem* first_selected =
+ mObjectList->getFirstSelected();
+ if (first_selected)
+ {
+ selected_uuid = first_selected->getUUID();
+ }
+ }
mObjectList->operateOnAll(LLScrollListCtrl::OP_DELETE);
//List all transient objects, then all linked objects
LLSelectNode* obj = mObjectSelection->getFirstNode();
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index 51a1a99d71..9f990d47b7 100644
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -1976,12 +1976,18 @@ BOOL LLPanelLandOptions::postBuild()
mSnapshotCtrl = LLUICtrlFactory::getTexturePickerByName(this, "snapshot_ctrl");
- mSnapshotCtrl->setCommitCallback( onCommitAny );
- mSnapshotCtrl->setCallbackUserData( this );
- mSnapshotCtrl->setAllowNoTexture ( TRUE );
- mSnapshotCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
- mSnapshotCtrl->setNonImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
-
+ if (mSnapshotCtrl)
+ {
+ mSnapshotCtrl->setCommitCallback( onCommitAny );
+ mSnapshotCtrl->setCallbackUserData( this );
+ mSnapshotCtrl->setAllowNoTexture ( TRUE );
+ mSnapshotCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
+ mSnapshotCtrl->setNonImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
+ }
+ else
+ {
+ llwarns << "LLUICtrlFactory::getTexturePickerByName() returned NULL for 'snapshot_ctrl'" << llendl;
+ }
mLocationText = LLUICtrlFactory::getTextBoxByName(this, "Landing Point: (none)");
@@ -2313,12 +2319,19 @@ BOOL LLPanelLandMedia::postBuild()
mMediaTextureCtrl = LLUICtrlFactory::getTexturePickerByName(this, "media texture");
- mMediaTextureCtrl->setCommitCallback( onCommitAny );
- mMediaTextureCtrl->setCallbackUserData( this );
- mMediaTextureCtrl->setAllowNoTexture ( TRUE );
- mMediaTextureCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
- mMediaTextureCtrl->setNonImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
-
+ if (mMediaTextureCtrl)
+ {
+ mMediaTextureCtrl->setCommitCallback( onCommitAny );
+ mMediaTextureCtrl->setCallbackUserData( this );
+ mMediaTextureCtrl->setAllowNoTexture ( TRUE );
+ mMediaTextureCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
+ mMediaTextureCtrl->setNonImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
+ }
+ else
+ {
+ llwarns << "LLUICtrlFactory::getTexturePickerByName() returned NULL for 'media texure'" << llendl;
+ }
+
mMediaAutoScaleCheck = LLUICtrlFactory::getCheckBoxByName(this, "media_auto_scale");
childSetCommitCallback("media_auto_scale", onCommitAny, this);
diff --git a/indra/newview/llfloaternamedesc.cpp b/indra/newview/llfloaternamedesc.cpp
index 6b2562e73c..602a198a03 100644
--- a/indra/newview/llfloaternamedesc.cpp
+++ b/indra/newview/llfloaternamedesc.cpp
@@ -9,6 +9,8 @@
#include "llviewerprecompiledheaders.h"
#include "llfloaternamedesc.h"
+
+// project includes
#include "lllineeditor.h"
#include "llresmgr.h"
#include "lltextbox.h"
@@ -16,13 +18,16 @@
#include "llviewerwindow.h"
#include "llfocusmgr.h"
#include "llradiogroup.h"
-#include "llassetstorage.h"
#include "lldbstrings.h"
#include "lldir.h"
#include "llviewercontrol.h"
-#include "llviewermenu.h"
+#include "llviewermenufile.h" // upload_new_resource()
#include "llvieweruictrlfactory.h"
+// linden includes
+#include "llassetstorage.h"
+#include "llinventorytype.h"
+
const S32 PREVIEW_LINE_HEIGHT = 19;
const S32 PREVIEW_CLOSE_BOX_SIZE = 16;
const S32 PREVIEW_BORDER_WIDTH = 2;
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 3a56eab2e2..5364b7da85 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -155,6 +155,66 @@ LLPreferenceCore::LLPreferenceCore(LLTabContainerCommon* tab_container, LLButton
// addTabPanel(mWebPanel, "Web", FALSE, onTabChanged, this);
}
+LLPreferenceCore::~LLPreferenceCore()
+{
+ if (mGeneralPanel)
+ {
+ delete mGeneralPanel;
+ mGeneralPanel = NULL;
+ }
+ if (mInputPanel)
+ {
+ delete mInputPanel;
+ mInputPanel = NULL;
+ }
+ if (mNetworkPanel)
+ {
+ delete mNetworkPanel;
+ mNetworkPanel = NULL;
+ }
+ if (mDisplayPanel)
+ {
+ delete mDisplayPanel;
+ mDisplayPanel = NULL;
+ }
+ if (mDisplayPanel2)
+ {
+ delete mDisplayPanel2;
+ mDisplayPanel2 = NULL;
+ }
+ if (mDisplayPanel3)
+ {
+ delete mDisplayPanel3;
+ mDisplayPanel3 = NULL;
+ }
+ if (mAudioPanel)
+ {
+ delete mAudioPanel;
+ mAudioPanel = NULL;
+ }
+ if (mPrefsChat)
+ {
+ delete mPrefsChat;
+ mPrefsChat = NULL;
+ }
+ if (mPrefsIM)
+ {
+ delete mPrefsIM;
+ mPrefsIM = NULL;
+ }
+ if (mMsgPanel)
+ {
+ delete mMsgPanel;
+ mMsgPanel = NULL;
+ }
+ //if (mWebPanel)
+ //{
+ // delete mWebPanel;
+ // mWebPanel = NULL;
+ //}
+}
+
+
void LLPreferenceCore::apply()
{
mGeneralPanel->apply();
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index 9988d0c353..8d4078cc9b 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -39,6 +39,7 @@ class LLPreferenceCore
public:
LLPreferenceCore(LLTabContainerCommon* tab_container, LLButton * default_btn);
+ ~LLPreferenceCore();
void apply();
void cancel();
diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index 4cc00b12d1..32923e2f11 100644
--- a/indra/newview/llfloaterregioninfo.cpp
+++ b/indra/newview/llfloaterregioninfo.cpp
@@ -54,7 +54,6 @@
const S32 TERRAIN_TEXTURE_COUNT = 4;
const S32 CORNER_COUNT = 4;
-#define LL_ENABLE_MAINLAND_VISIBLE_CONTROL 0
///----------------------------------------------------------------------------
/// Local class declaration
@@ -1900,9 +1899,6 @@ BOOL LLPanelEstateInfo::postBuild()
{
// set up the callbacks for the generic controls
initCtrl("externally_visible_check");
-#if LL_ENABLE_MAINLAND_VISIBLE_CONTROL
- initCtrl("mainland_visible_check");
-#endif
initCtrl("use_global_time_check");
initCtrl("fixed_sun_check");
initCtrl("allow_direct_teleport");
@@ -1914,9 +1910,6 @@ BOOL LLPanelEstateInfo::postBuild()
initHelpBtn("use_global_time_help", "HelpEstateUseGlobalTime");
initHelpBtn("fixed_sun_help", "HelpEstateFixedSun");
initHelpBtn("externally_visible_help", "HelpEstateExternallyVisible");
-#if LL_ENABLE_MAINLAND_VISIBLE_CONTROL
- initHelpBtn("mainland_visible_help", "HelpEstateMainlandVisible");
-#endif
initHelpBtn("allow_direct_teleport_help", "HelpEstateAllowDirectTeleport");
initHelpBtn("allow_resident_help", "HelpEstateAllowResident");
initHelpBtn("allow_group_help", "HelpEstateAllowGroup");
@@ -2085,9 +2078,6 @@ void LLPanelEstateInfo::commitEstateInfo()
void LLPanelEstateInfo::setEstateFlags(U32 flags)
{
childSetValue("externally_visible_check", LLSD(flags & REGION_FLAGS_EXTERNALLY_VISIBLE ? TRUE : FALSE) );
-#if LL_ENABLE_MAINLAND_VISIBLE_CONTROL
- childSetValue("mainland_visible_check", LLSD(flags & REGION_FLAGS_MAINLAND_VISIBLE ? TRUE : FALSE) );
-#endif
childSetValue("fixed_sun_check", LLSD(flags & REGION_FLAGS_SUN_FIXED ? TRUE : FALSE) );
childSetValue("allow_direct_teleport", LLSD(flags & REGION_FLAGS_ALLOW_DIRECT_TELEPORT ? TRUE : FALSE) );
childSetValue("deny_anonymous", LLSD(flags & REGION_FLAGS_DENY_ANONYMOUS ? TRUE : FALSE) );
@@ -2104,15 +2094,6 @@ U32 LLPanelEstateInfo::computeEstateFlags()
{
flags |= REGION_FLAGS_EXTERNALLY_VISIBLE;
}
-#if LL_ENABLE_MAINLAND_VISIBLE_CONTROL
- // This flag is ignored by everything. 2006-11-17 Phoenix.
- if (childGetValue("mainland_visible_check").asBoolean())
- {
- flags |= REGION_FLAGS_MAINLAND_VISIBLE;
- }
-#else
- flags |= REGION_FLAGS_MAINLAND_VISIBLE;
-#endif
if (childGetValue("allow_direct_teleport").asBoolean())
{
diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp
index 8968da9720..f377fae8af 100644
--- a/indra/newview/llfloaterreporter.cpp
+++ b/indra/newview/llfloaterreporter.cpp
@@ -46,10 +46,9 @@
#include "lluploaddialog.h"
#include "llcallingcard.h"
#include "llviewerobjectlist.h"
-#include "llagent.h"
#include "lltoolobjpicker.h"
#include "lltoolmgr.h"
-#include "llviewermenu.h" // for LLResourceData
+#include "llresourcedata.h" // for LLResourceData
#include "llviewerwindow.h"
#include "llviewerimagelist.h"
#include "llworldmap.h"
@@ -945,8 +944,8 @@ void LLFloaterReporter::uploadDoneCallback(const LLUUID &uuid, void *user_data,
self->mScreenID = uuid;
llinfos << "Got screen shot " << uuid << llendl;
self->sendReportViaLegacy(self->gatherReport());
+ self->close();
}
- self->close();
}
diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp
index 92e005c0bb..b47ec270e3 100644
--- a/indra/newview/llfloatersnapshot.cpp
+++ b/indra/newview/llfloatersnapshot.cpp
@@ -33,7 +33,7 @@
#include "llviewerstats.h"
#include "llviewercamera.h"
#include "llviewerwindow.h"
-#include "llviewermenu.h"
+#include "llviewermenufile.h" // upload_new_resource()
#include "llfloaterpostcard.h"
#include "llcheckboxctrl.h"
#include "llradiogroup.h"
diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp
index 0529507c35..224bd4650f 100644
--- a/indra/newview/llfloatertools.cpp
+++ b/indra/newview/llfloatertools.cpp
@@ -294,8 +294,8 @@ BOOL LLFloaterTools::postBuild()
mTab->setFollows(FOLLOWS_TOP | FOLLOWS_LEFT);
mTab->setVisible( gSavedSettings.getBOOL("ToolboxShowMore") );
mTab->setBorderVisible(FALSE);
+ mTab->selectFirstTab();
}
- mTab->selectFirstTab();
return TRUE;
}
diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp
index 31668b6d80..21b2bbb02e 100644
--- a/indra/newview/llfolderview.cpp
+++ b/indra/newview/llfolderview.cpp
@@ -209,6 +209,16 @@ LLFolderViewItem* LLFolderViewItem::getPreviousOpenNode(BOOL include_children)
return itemp;
}
+// is this item something we think we should be showing?
+// for example, if we haven't gotten around to filtering it yet, then the answer is yes
+// until we find out otherwise
+BOOL LLFolderViewItem::potentiallyVisible()
+{
+ // we haven't been checked against min required filter
+ // or we have and we passed
+ return getLastFilterGeneration() < getRoot()->getFilter()->getMinRequiredGeneration() || getFiltered();
+}
+
BOOL LLFolderViewItem::getFiltered()
{
return mFiltered && mLastFilterGeneration >= mRoot->getFilter()->getMinRequiredGeneration();
@@ -315,8 +325,7 @@ void LLFolderViewItem::setSelectionFromRoot(LLFolderViewItem* selection,
}
// helper function to change the selection from the root.
-void LLFolderViewItem::changeSelectionFromRoot(LLFolderViewItem* selection,
- BOOL selected)
+void LLFolderViewItem::changeSelectionFromRoot(LLFolderViewItem* selection, BOOL selected)
{
getRoot()->changeSelection(selection, selected);
}
@@ -338,6 +347,11 @@ LLString LLFolderViewItem::getWidgetTag() const
return LL_FOLDER_VIEW_ITEM_TAG;
}
+EInventorySortGroup LLFolderViewItem::getSortGroup()
+{
+ return SG_ITEM;
+}
+
// addToFolder() returns TRUE if it succeeds. FALSE otherwise
BOOL LLFolderViewItem::addToFolder(LLFolderViewFolder* folder, LLFolderView* root)
{
@@ -407,8 +421,7 @@ void LLFolderViewItem::dirtyFilter()
// means 'deselect' for a leaf item. Do this optimization after
// multiple selection is implemented to make sure it all plays nice
// together.
-BOOL LLFolderViewItem::setSelection(LLFolderViewItem* selection, BOOL open,
- BOOL take_keyboard_focus)
+BOOL LLFolderViewItem::setSelection(LLFolderViewItem* selection, BOOL open, BOOL take_keyboard_focus)
{
if( selection == this )
{
@@ -425,8 +438,7 @@ BOOL LLFolderViewItem::setSelection(LLFolderViewItem* selection, BOOL open,
return mIsSelected;
}
-BOOL LLFolderViewItem::changeSelection(LLFolderViewItem* selection,
- BOOL selected)
+BOOL LLFolderViewItem::changeSelection(LLFolderViewItem* selection, BOOL selected)
{
if(selection == this && mIsSelected != selected)
{
@@ -768,182 +780,174 @@ BOOL LLFolderViewItem::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
void LLFolderViewItem::draw()
{
- if( getVisible() )
+ bool possibly_has_children = false;
+ bool up_to_date = mListener && mListener->isUpToDate();
+ if((up_to_date && hasVisibleChildren() ) || // we fetched our children and some of them have passed the filter...
+ (!up_to_date && mListener && mListener->hasChildren())) // ...or we know we have children but haven't fetched them (doesn't obey filter)
{
- bool possibly_has_children = false;
- bool up_to_date = mListener && mListener->isUpToDate();
- if((up_to_date && hasVisibleChildren() ) || // we fetched our children and some of them have passed the filter...
- (!up_to_date && mListener && mListener->hasChildren())) // ...or we know we have children but haven't fetched them (doesn't obey filter)
- {
- possibly_has_children = true;
- }
- if(/*mControlLabel[0] != '\0' && */possibly_has_children)
+ possibly_has_children = true;
+ }
+ if(/*mControlLabel[0] != '\0' && */possibly_has_children)
+ {
+ LLGLSTexture gls_texture;
+ if (mArrowImage)
{
- LLGLSTexture gls_texture;
- if (mArrowImage)
- {
- gl_draw_scaled_rotated_image(mIndentation, mRect.getHeight() - ARROW_SIZE - TEXT_PAD,
- ARROW_SIZE, ARROW_SIZE, mControlLabelRotation, mArrowImage, sFgColor);
- }
+ gl_draw_scaled_rotated_image(mIndentation, mRect.getHeight() - ARROW_SIZE - TEXT_PAD,
+ ARROW_SIZE, ARROW_SIZE, mControlLabelRotation, mArrowImage, sFgColor);
}
+ }
- F32 text_left = (F32)(ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + mIndentation);
+ F32 text_left = (F32)(ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + mIndentation);
- // If we have keyboard focus, draw selection filled
- BOOL show_context = getRoot()->getShowSelectionContext();
- BOOL filled = show_context || (gFocusMgr.getKeyboardFocus() == getRoot());
+ // If we have keyboard focus, draw selection filled
+ BOOL show_context = getRoot()->getShowSelectionContext();
+ BOOL filled = show_context || (gFocusMgr.getKeyboardFocus() == getRoot());
- // always render "current" item, only render other selected items if
- // mShowSingleSelection is FALSE
- if( mIsSelected )
+ // always render "current" item, only render other selected items if
+ // mShowSingleSelection is FALSE
+ if( mIsSelected )
+ {
+ LLGLSNoTexture gls_no_texture;
+ LLColor4 bg_color = sHighlightBgColor;
+ //const S32 TRAILING_PAD = 5; // It just looks better with this.
+ if (!mIsCurSelection)
{
- LLGLSNoTexture gls_no_texture;
- LLColor4 bg_color = sHighlightBgColor;
- //const S32 TRAILING_PAD = 5; // It just looks better with this.
- if (!mIsCurSelection)
+ // do time-based fade of extra objects
+ F32 fade_time = getRoot()->getSelectionFadeElapsedTime();
+ if (getRoot()->getShowSingleSelection())
{
- // do time-based fade of extra objects
- F32 fade_time = getRoot()->getSelectionFadeElapsedTime();
- if (getRoot()->getShowSingleSelection())
- {
- // fading out
- bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, bg_color.mV[VALPHA], 0.f);
- }
- else
- {
- // fading in
- bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, 0.f, bg_color.mV[VALPHA]);
- }
+ // fading out
+ bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, bg_color.mV[VALPHA], 0.f);
}
+ else
+ {
+ // fading in
+ bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, 0.f, bg_color.mV[VALPHA]);
+ }
+ }
+ gl_rect_2d(
+ 0,
+ mRect.getHeight(),
+ mRect.getWidth() - 2,
+ llfloor(mRect.getHeight() - sFont->getLineHeight() - ICON_PAD),
+ bg_color, filled);
+ if (mIsCurSelection)
+ {
gl_rect_2d(
0,
mRect.getHeight(),
mRect.getWidth() - 2,
llfloor(mRect.getHeight() - sFont->getLineHeight() - ICON_PAD),
- bg_color, filled);
- if (mIsCurSelection)
- {
- gl_rect_2d(
- 0,
- mRect.getHeight(),
- mRect.getWidth() - 2,
- llfloor(mRect.getHeight() - sFont->getLineHeight() - ICON_PAD),
- sHighlightFgColor, FALSE);
- }
- if (mRect.getHeight() > llround(sFont->getLineHeight()) + ICON_PAD + 2)
- {
- gl_rect_2d(
- 0,
- llfloor(mRect.getHeight() - sFont->getLineHeight() - ICON_PAD) - 2,
- mRect.getWidth() - 2,
- 2,
- sHighlightFgColor, FALSE);
- if (show_context)
- {
- gl_rect_2d(
- 0,
- llfloor(mRect.getHeight() - sFont->getLineHeight() - ICON_PAD) - 2,
- mRect.getWidth() - 2,
- 2,
- sHighlightBgColor, TRUE);
- }
- }
+ sHighlightFgColor, FALSE);
}
- if (mDragAndDropTarget)
+ if (mRect.getHeight() > llround(sFont->getLineHeight()) + ICON_PAD + 2)
{
- LLGLSNoTexture gls_no_texture;
gl_rect_2d(
0,
- mRect.getHeight(),
+ llfloor(mRect.getHeight() - sFont->getLineHeight() - ICON_PAD) - 2,
mRect.getWidth() - 2,
- llfloor(mRect.getHeight() - sFont->getLineHeight() - ICON_PAD),
- sHighlightBgColor, FALSE);
-
- if (mRect.getHeight() > llround(sFont->getLineHeight()) + ICON_PAD + 2)
+ 2,
+ sHighlightFgColor, FALSE);
+ if (show_context)
{
gl_rect_2d(
0,
llfloor(mRect.getHeight() - sFont->getLineHeight() - ICON_PAD) - 2,
mRect.getWidth() - 2,
2,
- sHighlightBgColor, FALSE);
+ sHighlightBgColor, TRUE);
}
- mDragAndDropTarget = FALSE;
}
+ }
+ if (mDragAndDropTarget)
+ {
+ LLGLSNoTexture gls_no_texture;
+ gl_rect_2d(
+ 0,
+ mRect.getHeight(),
+ mRect.getWidth() - 2,
+ llfloor(mRect.getHeight() - sFont->getLineHeight() - ICON_PAD),
+ sHighlightBgColor, FALSE);
-
- if(mIcon)
+ if (mRect.getHeight() > llround(sFont->getLineHeight()) + ICON_PAD + 2)
{
- gl_draw_image(mIndentation + ARROW_SIZE + TEXT_PAD, mRect.getHeight() - mIcon->getHeight(), mIcon);
- mIcon->addTextureStats( (F32)(mIcon->getWidth() * mIcon->getHeight()));
+ gl_rect_2d(
+ 0,
+ llfloor(mRect.getHeight() - sFont->getLineHeight() - ICON_PAD) - 2,
+ mRect.getWidth() - 2,
+ 2,
+ sHighlightBgColor, FALSE);
}
+ mDragAndDropTarget = FALSE;
+ }
- if (!mLabel.empty())
- {
- // highlight filtered text
- BOOL debug_filters = getRoot()->getDebugFilters();
- LLColor4 color = ( (mIsSelected && filled) ? sHighlightFgColor : sFgColor );
- F32 right_x;
- F32 y = (F32)mRect.getHeight() - sFont->getLineHeight() - (F32)TEXT_PAD;
- if (debug_filters)
- {
- if (!getFiltered() && !possibly_has_children)
- {
- color.mV[VALPHA] *= 0.5f;
- }
-
- LLColor4 filter_color = mLastFilterGeneration >= getRoot()->getFilter()->getCurrentGeneration() ? LLColor4(0.5f, 0.8f, 0.5f, 1.f) : LLColor4(0.8f, 0.5f, 0.5f, 1.f);
- sSmallFont->renderUTF8(mStatusText, 0, text_left, y, filter_color,
- LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL,
- S32_MAX, S32_MAX, &right_x, FALSE );
- text_left = right_x;
- }
+ if(mIcon)
+ {
+ gl_draw_image(mIndentation + ARROW_SIZE + TEXT_PAD, mRect.getHeight() - mIcon->getHeight(), mIcon);
+ mIcon->addTextureStats( (F32)(mIcon->getWidth() * mIcon->getHeight()));
+ }
- sFont->renderUTF8( mLabel, 0, text_left, y, color,
- LLFontGL::LEFT, LLFontGL::BOTTOM, mLabelStyle,
- S32_MAX, S32_MAX, &right_x, FALSE );
- if (!mLabelSuffix.empty())
- {
- sFont->renderUTF8( mLabelSuffix, 0, right_x, y, LLColor4(0.75f, 0.85f, 0.85f, 1.f),
- LLFontGL::LEFT, LLFontGL::BOTTOM, mLabelStyle,
- S32_MAX, S32_MAX, &right_x, FALSE );
- }
+ if (!mLabel.empty())
+ {
+ // highlight filtered text
+ BOOL debug_filters = getRoot()->getDebugFilters();
+ LLColor4 color = ( (mIsSelected && filled) ? sHighlightFgColor : sFgColor );
+ F32 right_x;
+ F32 y = (F32)mRect.getHeight() - sFont->getLineHeight() - (F32)TEXT_PAD;
- if (mBoxImage.notNull() && mStringMatchOffset != LLString::npos)
+ if (debug_filters)
+ {
+ if (!getFiltered() && !possibly_has_children)
{
- // don't draw backgrounds for zero-length strings
- S32 filter_string_length = mRoot->getFilterSubString().size();
- if (filter_string_length > 0)
- {
- LLString combined_string = mLabel + mLabelSuffix;
- S32 left = llround(text_left) + sFont->getWidth(combined_string, 0, mStringMatchOffset) - 1;
- S32 right = left + sFont->getWidth(combined_string, mStringMatchOffset, filter_string_length) + 2;
- S32 bottom = llfloor(mRect.getHeight() - sFont->getLineHeight() - 3);
- S32 top = mRect.getHeight();
-
- LLViewerImage::bindTexture(mBoxImage);
- glColor4fv(sFilterBGColor.mV);
- gl_segmented_rect_2d_tex(left, top, right, bottom, mBoxImage->getWidth(), mBoxImage->getHeight(), 16);
- F32 match_string_left = text_left + sFont->getWidthF32(combined_string, 0, mStringMatchOffset);
- F32 y = (F32)mRect.getHeight() - sFont->getLineHeight() - (F32)TEXT_PAD;
- sFont->renderUTF8( combined_string, mStringMatchOffset, match_string_left, y,
- sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, mLabelStyle,
- filter_string_length, S32_MAX, &right_x, FALSE );
- }
+ color.mV[VALPHA] *= 0.5f;
}
+
+ LLColor4 filter_color = mLastFilterGeneration >= getRoot()->getFilter()->getCurrentGeneration() ? LLColor4(0.5f, 0.8f, 0.5f, 1.f) : LLColor4(0.8f, 0.5f, 0.5f, 1.f);
+ sSmallFont->renderUTF8(mStatusText, 0, text_left, y, filter_color,
+ LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL,
+ S32_MAX, S32_MAX, &right_x, FALSE );
+ text_left = right_x;
}
- if( sDebugRects )
+ sFont->renderUTF8( mLabel, 0, text_left, y, color,
+ LLFontGL::LEFT, LLFontGL::BOTTOM, mLabelStyle,
+ S32_MAX, S32_MAX, &right_x, FALSE );
+ if (!mLabelSuffix.empty())
{
- drawDebugRect();
+ sFont->renderUTF8( mLabelSuffix, 0, right_x, y, LLColor4(0.75f, 0.85f, 0.85f, 1.f),
+ LLFontGL::LEFT, LLFontGL::BOTTOM, mLabelStyle,
+ S32_MAX, S32_MAX, &right_x, FALSE );
+ }
+
+ if (mBoxImage.notNull() && mStringMatchOffset != LLString::npos)
+ {
+ // don't draw backgrounds for zero-length strings
+ S32 filter_string_length = mRoot->getFilterSubString().size();
+ if (filter_string_length > 0)
+ {
+ LLString combined_string = mLabel + mLabelSuffix;
+ S32 left = llround(text_left) + sFont->getWidth(combined_string, 0, mStringMatchOffset) - 1;
+ S32 right = left + sFont->getWidth(combined_string, mStringMatchOffset, filter_string_length) + 2;
+ S32 bottom = llfloor(mRect.getHeight() - sFont->getLineHeight() - 3);
+ S32 top = mRect.getHeight();
+
+ LLViewerImage::bindTexture(mBoxImage);
+ glColor4fv(sFilterBGColor.mV);
+ gl_segmented_rect_2d_tex(left, top, right, bottom, mBoxImage->getWidth(), mBoxImage->getHeight(), 16);
+ F32 match_string_left = text_left + sFont->getWidthF32(combined_string, 0, mStringMatchOffset);
+ F32 y = (F32)mRect.getHeight() - sFont->getLineHeight() - (F32)TEXT_PAD;
+ sFont->renderUTF8( combined_string, mStringMatchOffset, match_string_left, y,
+ sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, mLabelStyle,
+ filter_string_length, S32_MAX, &right_x, FALSE );
+ }
}
}
- else if (mStatusText.size())
+
+ if( sDebugRects )
{
- // just draw status text
- sFont->renderUTF8( mStatusText, 0, 0, 1, sFgColor, LLFontGL::LEFT, LLFontGL::BOTTOM, mLabelStyle, S32_MAX, S32_MAX, NULL, FALSE );
+ drawDebugRect();
}
}
@@ -957,7 +961,6 @@ LLFolderViewFolder::LLFolderViewFolder( const LLString& name, LLViewerImage* ico
LLFolderView* root,
LLFolderViewEventListener* listener ):
LLFolderViewItem( name, icon, 0, root, listener ), // 0 = no create time
- mSortFunction(sort_item_name),
mIsOpen(FALSE),
mExpanderHighlighted(FALSE),
mCurHeight(0.f),
@@ -1226,7 +1229,7 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter)
}
// when applying a filter, matching folders get their contents downloaded first
- if (filter.isNotDefault() && getFiltered(filter.getMinRequiredGeneration()) && !gInventory.isCategoryComplete(mListener->getUUID()))
+ if (filter.isNotDefault() && getFiltered(filter.getMinRequiredGeneration()) && (mListener && !gInventory.isCategoryComplete(mListener->getUUID())))
{
gInventory.startBackgroundFetch(mListener->getUUID());
}
@@ -1647,7 +1650,8 @@ BOOL LLFolderViewFolder::removeItem(LLFolderViewItem* item)
{
if(item->remove())
{
- removeView(item);
+ //RN: this seem unneccessary as remove() moves to trash
+ //removeView(item);
return TRUE;
}
return FALSE;
@@ -1657,7 +1661,7 @@ BOOL LLFolderViewFolder::removeItem(LLFolderViewItem* item)
// listeners.
void LLFolderViewFolder::removeView(LLFolderViewItem* item)
{
- if (!item)
+ if (!item || item->getParentFolder() != this)
{
return;
}
@@ -1702,23 +1706,8 @@ void LLFolderViewFolder::extractItem( LLFolderViewItem* item )
// This is only called for renaming an object because it won't work for date
void LLFolderViewFolder::resort(LLFolderViewItem* item)
{
- std::sort(mItems.begin(), mItems.end(), *mSortFunction);
- std::sort(mFolders.begin(), mFolders.end(), *mSortFunction);
- //if(mItems.removeData(item))
- //{
- // mItems.addDataSorted(item);
- //}
- //else
- //{
- // // This is an evil downcast. However, it's only doing
- // // pointer comparison to find if (which it should be ) the
- // // item is in the container, so it's pretty safe.
- // LLFolderViewFolder* f = reinterpret_cast<LLFolderViewFolder*>(item);
- // if(mFolders.removeData(f))
- // {
- // mFolders.addDataSorted(f);
- // }
- //}
+ std::sort(mItems.begin(), mItems.end(), mSortFunction);
+ std::sort(mFolders.begin(), mFolders.end(), mSortFunction);
}
bool LLFolderViewFolder::isTrash()
@@ -1732,65 +1721,22 @@ bool LLFolderViewFolder::isTrash()
void LLFolderViewFolder::sortBy(U32 order)
{
- BOOL sort_order_changed = FALSE;
- if (!(order & LLInventoryFilter::SO_DATE))
- {
- if (mSortFunction != sort_item_name)
- {
- mSortFunction = sort_item_name;
- sort_order_changed = TRUE;
- }
- }
- else
+ if (!mSortFunction.updateSort(order))
{
- if (mSortFunction != sort_item_date)
- {
- mSortFunction = sort_item_date;
- sort_order_changed = TRUE;
- }
+ // No changes.
+ return;
}
+ // Propegate this change to sub folders
for (folders_t::iterator iter = mFolders.begin();
iter != mFolders.end();)
{
folders_t::iterator fit = iter++;
(*fit)->sortBy(order);
}
- if (order & LLInventoryFilter::SO_FOLDERS_BY_NAME)
- {
- // sort folders by name if always by name
- std::sort(mFolders.begin(), mFolders.end(), sort_item_name);
- }
- else
- {
- // sort folders by the default sort ordering
- std::sort(mFolders.begin(), mFolders.end(), *mSortFunction);
- // however, if we are at the root of the inventory and we are sorting by date
- if (mListener->getUUID() == gAgent.getInventoryRootID() && order & LLInventoryFilter::SO_DATE)
- {
- // pull the trash folder and stick it on the end of the list
- LLFolderViewFolder *t = NULL;
- for (folders_t::iterator fit = mFolders.begin();
- fit != mFolders.end(); ++fit)
- {
- if ((*fit)->isTrash())
- {
- t = *fit;
- mFolders.erase(fit);
- break;
- }
- }
- if (t)
- {
- mFolders.push_back(t);
- }
- }
- }
- if (sort_order_changed)
- {
- std::sort(mItems.begin(), mItems.end(), *mSortFunction);
- }
+ std::sort(mFolders.begin(), mFolders.end(), mSortFunction);
+ std::sort(mItems.begin(), mItems.end(), mSortFunction);
if (order & LLInventoryFilter::SO_DATE)
{
@@ -1814,19 +1760,39 @@ void LLFolderViewFolder::sortBy(U32 order)
}
}
-void LLFolderViewFolder::setItemSortFunction(sort_order_f ordering)
+void LLFolderViewFolder::setItemSortOrder(U32 ordering)
{
- mSortFunction = ordering;
+ if (mSortFunction.updateSort(ordering))
+ {
+ for (folders_t::iterator iter = mFolders.begin();
+ iter != mFolders.end();)
+ {
+ folders_t::iterator fit = iter++;
+ (*fit)->setItemSortOrder(ordering);
+ }
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();)
+ std::sort(mFolders.begin(), mFolders.end(), mSortFunction);
+ std::sort(mItems.begin(), mItems.end(), mSortFunction);
+ }
+}
+
+EInventorySortGroup LLFolderViewFolder::getSortGroup()
+{
+ if (isTrash())
{
- folders_t::iterator fit = iter++;
- (*fit)->setItemSortFunction(ordering);
+ return SG_TRASH_FOLDER;
}
- std::sort(mFolders.begin(), mFolders.end(), *mSortFunction);
- std::sort(mItems.begin(), mItems.end(), *mSortFunction);
+ // Folders that can't be moved are 'system' folders.
+ if( mListener )
+ {
+ if( !(mListener->isItemMovable()) )
+ {
+ return SG_SYSTEM_FOLDER;
+ }
+ }
+
+ return SG_NORMAL_FOLDER;
}
BOOL LLFolderViewFolder::isMovable()
@@ -1897,6 +1863,7 @@ BOOL LLFolderViewFolder::isRemovable()
// this is an internal method used for adding items to folders.
BOOL LLFolderViewFolder::addItem(LLFolderViewItem* item)
{
+
items_t::iterator it = std::lower_bound(
mItems.begin(),
mItems.end(),
@@ -1925,18 +1892,29 @@ BOOL LLFolderViewFolder::addFolder(LLFolderViewFolder* folder)
folder->setVisible(FALSE);
addChild( folder );
folder->dirtyFilter();
- requestArrange();
+ // rearrange all descendants too, as our indentation level might have changed
+ folder->requestArrange(TRUE);
return TRUE;
}
-void LLFolderViewFolder::requestArrange()
+void LLFolderViewFolder::requestArrange(BOOL include_descendants)
{
mLastArrangeGeneration = -1;
// flag all items up to root
- if (mParentFolder)
+ if (mParentFolder && !mParentFolder->needsArrange())
{
mParentFolder->requestArrange();
}
+
+ if (include_descendants)
+ {
+ for (folders_t::iterator iter = mFolders.begin();
+ iter != mFolders.end();
+ ++iter)
+ {
+ (*iter)->requestArrange(TRUE);
+ }
+ }
}
void LLFolderViewFolder::toggleOpen()
@@ -1982,11 +1960,11 @@ void LLFolderViewFolder::setOpenArrangeRecursively(BOOL open, ERecurseType recur
}
BOOL LLFolderViewFolder::handleDragAndDropFromChild(MASK mask,
- BOOL drop,
- EDragAndDropType c_type,
- void* cargo_data,
- EAcceptance* accept,
- LLString& tooltip_msg)
+ BOOL drop,
+ EDragAndDropType c_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ LLString& tooltip_msg)
{
BOOL accepted = mListener && mListener->dragOrDrop(mask,drop,c_type,cargo_data);
if (accepted)
@@ -2198,16 +2176,13 @@ void LLFolderViewFolder::draw()
}
LLFolderViewItem::draw();
- if( mIsOpen )
+
+ // draw children if root folder, or any other folder that is open or animating to closed state
+ if( getRoot() == this || (mIsOpen || mCurHeight != mTargetHeight ))
{
LLView::draw();
}
-// if (mExpanderHighlighted)
-// {
-// gl_rect_2d(mIndentation - TEXT_PAD, llfloor(mRect.getHeight() - TEXT_PAD), mIndentation + sFont->getWidth(mControlLabel) + TEXT_PAD, llfloor(mRect.getHeight() - sFont->getLineHeight() - TEXT_PAD), sFgColor, FALSE);
-// //sFont->renderUTF8( mControlLabel, 0, mIndentation, llfloor(mRect.getHeight() - sFont->getLineHeight() - TEXT_PAD), sFgColor, LLFontGL::LEFT, LLFontGL::BOTTOM, mLabelStyle, S32_MAX, S32_MAX, NULL, FALSE );
-// }
mExpanderHighlighted = FALSE;
}
@@ -2217,6 +2192,16 @@ U32 LLFolderViewFolder::getCreationDate() const
}
+BOOL LLFolderViewFolder::potentiallyVisible()
+{
+ // folder should be visible by it's own filter status
+ return LLFolderViewItem::potentiallyVisible()
+ // or one or more of its descendants have passed the minimum filter requirement
+ || hasFilteredDescendants(mRoot->getFilter()->getMinRequiredGeneration())
+ // or not all of its descendants have been checked against minimum filter requirement
+ || getCompletedFilterGeneration() < getRoot()->getFilter()->getMinRequiredGeneration();
+}
+
// this does prefix traversal, as folders are listed above their contents
LLFolderViewItem* LLFolderViewFolder::getNextFromChild( LLFolderViewItem* item, BOOL include_children )
{
@@ -2436,20 +2421,20 @@ LLFolderViewItem* LLFolderViewFolder::getPreviousFromChild( LLFolderViewItem* it
class LLSetItemSortFunction : public LLFolderViewFunctor
{
public:
- LLSetItemSortFunction(sort_order_f ordering)
- : mSortFunction(ordering) {}
+ LLSetItemSortFunction(U32 ordering)
+ : mSortOrder(ordering) {}
virtual ~LLSetItemSortFunction() {}
virtual void doFolder(LLFolderViewFolder* folder);
virtual void doItem(LLFolderViewItem* item);
- sort_order_f mSortFunction;
+ U32 mSortOrder;
};
// Set the sort order.
void LLSetItemSortFunction::doFolder(LLFolderViewFolder* folder)
{
- folder->setItemSortFunction(mSortFunction);
+ folder->setItemSortOrder(mSortOrder);
}
// Do nothing.
@@ -2676,6 +2661,7 @@ BOOL LLFolderView::addFolder( LLFolderViewFolder* folder)
folder->setVisible(FALSE);
addChild( folder );
folder->dirtyFilter();
+ folder->requestArrange();
return TRUE;
}
@@ -2896,8 +2882,8 @@ BOOL LLFolderView::setSelection(LLFolderViewItem* selection, BOOL open, /* Flaw
addToSelectionList(selection);
}
- BOOL rv = LLFolderViewFolder::setSelection(selection, open, take_keyboard_focus); /* Flawfinder: ignore */
- if(open) /* Flawfinder: ignore */
+ BOOL rv = LLFolderViewFolder::setSelection(selection, open, take_keyboard_focus);
+ if(open && selection)
{
selection->getParentFolder()->requestArrange();
}
@@ -2934,11 +2920,6 @@ BOOL LLFolderView::changeSelection(LLFolderViewItem* selection, BOOL selected)
}
BOOL on_list = (item_iter != mSelectedItems.end());
- if (on_list && mSelectedItems.size() == 1)
- {
- // we are trying to select/deselect the only selected item
- return FALSE;
- }
if(selected && !on_list)
{
@@ -2985,48 +2966,46 @@ S32 LLFolderView::extendSelection(LLFolderViewItem* selection, LLFolderViewItem*
void LLFolderView::sanitizeSelection()
{
+ // store off current item in case it is automatically deselected
+ // and we want to preserve context
+ LLFolderViewItem* original_selected_item = getCurSelectedItem();
+
std::vector<LLFolderViewItem*> items_to_remove;
selected_items_t::iterator item_iter;
for (item_iter = mSelectedItems.begin(); item_iter != mSelectedItems.end(); ++item_iter)
{
LLFolderViewItem* item = *item_iter;
- BOOL visible = item->getVisible();
+ // ensure that each ancestor is open and potentially passes filtering
+ BOOL visible = item->potentiallyVisible(); // initialize from filter state for this item
+ // modify with parent open and filters states
LLFolderViewFolder* parent_folder = item->getParentFolder();
- while(visible && parent_folder)
+ while(parent_folder)
{
- visible = visible && parent_folder->isOpen() && parent_folder->getVisible();
+ visible = visible && parent_folder->isOpen() && parent_folder->potentiallyVisible();
parent_folder = parent_folder->getParentFolder();
}
- if (!visible || item->getNumSelectedDescendants() > 0)
+
+ // deselect item if any ancestor is closed or didn't pass filter requirements.
+ if (!visible)
{
- // only deselect self if not visible
- // check to see if item failed the filter but was checked against most recent generation
- if ((!item->getFiltered() && item->getLastFilterGeneration() >= getFilter()->getMinRequiredGeneration())
- || (item->getParentFolder() && !item->getParentFolder()->isOpen()))
- {
- item->recursiveDeselect(TRUE);
- items_to_remove.push_back(item);
- }
- else
- {
- item->recursiveDeselect(FALSE);
- }
+ items_to_remove.push_back(item);
+ }
- selected_items_t::iterator other_item_iter;
- for (other_item_iter = mSelectedItems.begin(); other_item_iter != mSelectedItems.end(); ++other_item_iter)
+ // disallow nested selections (i.e. folder items plus one or more ancestors)
+ // could check cached mum selections count and only iterate if there are any
+ // but that may be a premature optimization.
+ selected_items_t::iterator other_item_iter;
+ for (other_item_iter = mSelectedItems.begin(); other_item_iter != mSelectedItems.end(); ++other_item_iter)
+ {
+ LLFolderViewItem* other_item = *other_item_iter;
+ for(LLFolderViewFolder* parent_folder = other_item->getParentFolder(); parent_folder; parent_folder = parent_folder->getParentFolder())
{
- LLFolderViewItem* other_item = *other_item_iter;
- LLFolderViewFolder* parent_folder = other_item->getParentFolder();
- while (parent_folder)
+ if (parent_folder == item)
{
- if (parent_folder == item)
- {
- // this is a descendent of the current folder, remove from list
- items_to_remove.push_back(other_item);
- break;
- }
- parent_folder = parent_folder->getParentFolder();
+ // this is a descendent of the current folder, remove from list
+ items_to_remove.push_back(other_item);
+ break;
}
}
}
@@ -3035,7 +3014,47 @@ void LLFolderView::sanitizeSelection()
std::vector<LLFolderViewItem*>::iterator item_it;
for (item_it = items_to_remove.begin(); item_it != items_to_remove.end(); ++item_it )
{
- removeFromSelectionList(*item_it);
+ changeSelection(*item_it, FALSE); // toggle selection (also removes from list)
+ }
+
+ // if nothing selected after prior constraints...
+ if (mSelectedItems.empty())
+ {
+ // ...select first available parent of original selection, or "My Inventory" otherwise
+ LLFolderViewItem* new_selection = NULL;
+ if (original_selected_item)
+ {
+ for(LLFolderViewFolder* parent_folder = original_selected_item->getParentFolder();
+ parent_folder;
+ parent_folder = parent_folder->getParentFolder())
+ {
+ if (parent_folder->potentiallyVisible())
+ {
+ // give initial selection to first ancestor folder that potentially passes the filter
+ if (!new_selection)
+ {
+ new_selection = parent_folder;
+ }
+
+ // if any ancestor folder of original item is closed, move the selection up
+ // to the highest closed
+ if (!parent_folder->isOpen())
+ {
+ new_selection = parent_folder;
+ }
+ }
+ }
+ }
+ else
+ {
+ // nothing selected to start with, so pick "My Inventory" as best guess
+ new_selection = getItemByID(gAgent.getInventoryRootID());
+ }
+
+ if (new_selection)
+ {
+ setSelection(new_selection, FALSE, FALSE);
+ }
}
}
@@ -3212,7 +3231,7 @@ void LLFolderView::removeSelectedItems( void )
// create a temporary structure which we will use to remove
// items, since the removal will futz with internal data
// structures.
- LLDynamicArray<LLFolderViewItem*> items;
+ std::vector<LLFolderViewItem*> items;
S32 count = mSelectedItems.size();
if(count == 0) return;
LLFolderViewItem* item = NULL;
@@ -3222,7 +3241,7 @@ void LLFolderView::removeSelectedItems( void )
item = *item_it;
if(item->isRemovable())
{
- items.put(item);
+ items.push_back(item);
}
else
{
@@ -3232,11 +3251,11 @@ void LLFolderView::removeSelectedItems( void )
}
// iterate through the new container.
- count = items.count();
+ count = items.size();
LLUUID new_selection_id;
if(count == 1)
{
- LLFolderViewItem* item_to_delete = items.get(0);
+ LLFolderViewItem* item_to_delete = items[0];
LLFolderViewFolder* parent = item_to_delete->getParentFolder();
LLFolderViewItem* new_selection = item_to_delete->getNextOpenNode(FALSE);
if (!new_selection)
@@ -3264,7 +3283,7 @@ void LLFolderView::removeSelectedItems( void )
{
LLDynamicArray<LLFolderViewEventListener*> listeners;
LLFolderViewEventListener* listener;
- LLFolderViewItem* last_item = items.get(count - 1);
+ LLFolderViewItem* last_item = items[count - 1];
LLFolderViewItem* new_selection = last_item->getNextOpenNode(FALSE);
while(new_selection && new_selection->isSelected())
{
@@ -3289,7 +3308,7 @@ void LLFolderView::removeSelectedItems( void )
for(S32 i = 0; i < count; ++i)
{
- listener = items.get(i)->getListener();
+ listener = items[i]->getListener();
if(listener && (listeners.find(listener) == LLDynamicArray<LLFolderViewEventListener*>::FAIL))
{
listeners.put(listener);
@@ -3600,21 +3619,6 @@ void LLFolderView::setFocus(BOOL focus)
{
if (focus)
{
- // select "My Inventory" if nothing selected
- if (!getCurSelectedItem())
- {
- LLFolderViewItem* itemp = getItemByID(gAgent.getInventoryRootID());
- if (itemp)
- {
- setSelection(itemp, FALSE, FALSE);
- }
- }
-
- if (mRenamer->getVisible())
- {
- //RN: commit rename changes when focus is moved, only revert on ESC
- finishRenamingItem();
- }
if(!hasFocus())
{
gEditMenuHandler = this;
@@ -3934,10 +3938,10 @@ BOOL LLFolderView::search(LLFolderViewItem* first_item, const LLString &search_s
LLString::toUpper(upper_case_string);
// if nothing selected, select first item in folder
- if (!first_item)
+ if (!search_item)
{
// start from first item
- first_item = getNextFromChild(NULL);
+ search_item = getNextFromChild(NULL);
}
// search over all open nodes for first substring match (with wrapping)
@@ -4228,8 +4232,6 @@ void LLFolderView::idle(void* user_data)
// filter to determine visiblity before arranging
self->filterFromRoot();
- self->sanitizeSelection();
-
// automatically show matching items, and select first one
// do this every frame until user puts keyboard focus into the inventory window
// signaling the end of the automatic update
@@ -4249,6 +4251,8 @@ void LLFolderView::idle(void* user_data)
self->scrollToShowSelection();
}
+ self->sanitizeSelection();
+
if( self->needsArrange() && self->isInVisibleChain())
{
self->arrangeFromRoot();
@@ -4287,45 +4291,71 @@ void LLFolderView::dumpSelectionInformation()
///----------------------------------------------------------------------------
/// Local function definitions
///----------------------------------------------------------------------------
-
-bool sort_item_name(LLFolderViewItem* a, LLFolderViewItem* b)
+bool LLInventorySort::updateSort(U32 order)
{
- // Sort 'system' / unmovable folders to the top.
- if (a->isMovable() != b->isMovable())
- {
- return b->isMovable();
- }
-
- S32 compare = LLString::compareDict(a->getLabel(), b->getLabel());
- if (0 == compare)
- {
- return (a->getCreationDate() > b->getCreationDate());
- }
- else
+ if (order != mSortOrder)
{
- return (compare < 0);
+ mSortOrder = order;
+ mByDate = (order & LLInventoryFilter::SO_DATE);
+ mSystemToTop = (order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP);
+ mFoldersByName = (order & LLInventoryFilter::SO_FOLDERS_BY_NAME);
+ return true;
}
+ return false;
}
-// BUG: This is very very slow. The getCreationDate() is log n in number
-// of inventory items.
-bool sort_item_date(LLFolderViewItem* a, LLFolderViewItem* b)
+bool LLInventorySort::operator()(LLFolderViewItem* a, LLFolderViewItem* b)
{
- // Sort 'system' / unmovable folders to the top.
- if (a->isMovable() != b->isMovable())
+ // We sort by name if we aren't sorting by date
+ // OR if these are folders and we are sorting folders by name.
+ bool by_name = (!mByDate
+ || (mFoldersByName
+ && (a->getSortGroup() != SG_ITEM)));
+
+ if (a->getSortGroup() != b->getSortGroup())
{
- return b->isMovable();
+ if (mSystemToTop)
+ {
+ // Group order is System Folders, Trash, Normal Folders, Items
+ return (a->getSortGroup() < b->getSortGroup());
+ }
+ else if (mByDate)
+ {
+ // Trash needs to go to the bottom if we are sorting by date
+ if ( (a->getSortGroup() == SG_TRASH_FOLDER)
+ || (b->getSortGroup() == SG_TRASH_FOLDER))
+ {
+ return (b->getSortGroup() == SG_TRASH_FOLDER);
+ }
+ }
}
- U32 first_create = a->getCreationDate();
- U32 second_create = b->getCreationDate();
- if (first_create == second_create)
+ if (by_name)
{
- return (LLString::compareDict(a->getLabel(), b->getLabel()) < 0);
+ S32 compare = LLString::compareDict(a->getLabel(), b->getLabel());
+ if (0 == compare)
+ {
+ return (a->getCreationDate() > b->getCreationDate());
+ }
+ else
+ {
+ return (compare < 0);
+ }
}
else
{
- return (first_create > second_create);
+ // BUG: This is very very slow. The getCreationDate() is log n in number
+ // of inventory items.
+ U32 first_create = a->getCreationDate();
+ U32 second_create = b->getCreationDate();
+ if (first_create == second_create)
+ {
+ return (LLString::compareDict(a->getLabel(), b->getLabel()) < 0);
+ }
+ else
+ {
+ return (first_create > second_create);
+ }
}
}
diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h
index 76784f1ac9..248118dfdf 100644
--- a/indra/newview/llfolderview.h
+++ b/indra/newview/llfolderview.h
@@ -161,6 +161,7 @@ public:
static const U32 SO_DATE = 1;
static const U32 SO_FOLDERS_BY_NAME = 2;
+ static const U32 SO_SYSTEM_FOLDERS_TO_TOP = 4;
LLInventoryFilter(const LLString& name);
virtual ~LLInventoryFilter();
@@ -245,6 +246,34 @@ private:
LLString mFilterText;
};
+// These are grouping of inventory types.
+// Order matters when sorting system folders to the top.
+enum EInventorySortGroup
+{
+ SG_SYSTEM_FOLDER,
+ SG_TRASH_FOLDER,
+ SG_NORMAL_FOLDER,
+ SG_ITEM
+};
+
+class LLInventorySort
+{
+public:
+ LLInventorySort()
+ : mSortOrder(0) { }
+
+ // Returns true if order has changed
+ bool updateSort(U32 order);
+ U32 getSort() { return mSortOrder; }
+
+ bool operator()(LLFolderViewItem* a, LLFolderViewItem* b);
+private:
+ U32 mSortOrder;
+ bool mByDate;
+ bool mSystemToTop;
+ bool mFoldersByName;
+};
+
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLFolderViewItem
//
@@ -331,6 +360,8 @@ public:
enum { ARRANGE = TRUE, DO_NOT_ARRANGE = FALSE };
virtual BOOL addToFolder(LLFolderViewFolder* folder, LLFolderView* root);
+ virtual EInventorySortGroup getSortGroup();
+
// Finds width and height of this object and it's children. Also
// makes sure that this view and it's children are the right size.
virtual S32 arrange( S32* width, S32* height, S32 filter_generation );
@@ -429,8 +460,10 @@ public:
virtual void setStatusText(const LLString& text) { mStatusText = text; }
- BOOL getFiltered();
- BOOL getFiltered(S32 filter_generation);
+ virtual BOOL potentiallyVisible(); // do we know for a fact that this item has been filtered out?
+
+ virtual BOOL getFiltered();
+ virtual BOOL getFiltered(S32 filter_generation);
virtual void setFiltered(BOOL filtered, S32 filter_generation);
// change the icon
@@ -484,7 +517,7 @@ protected:
typedef std::vector<LLFolderViewFolder*> folders_t;
items_t mItems;
folders_t mFolders;
- sort_order_f mSortFunction;
+ LLInventorySort mSortFunction;
BOOL mIsOpen;
BOOL mExpanderHighlighted;
@@ -514,6 +547,8 @@ public:
virtual EWidgetType getWidgetType() const;
virtual LLString getWidgetTag() const;
+ virtual BOOL potentiallyVisible();
+
LLFolderViewItem* getNextFromChild( LLFolderViewItem*, BOOL include_children = TRUE );
LLFolderViewItem* getPreviousFromChild( LLFolderViewItem*, BOOL include_children = TRUE );
@@ -526,6 +561,9 @@ public:
BOOL needsArrange();
+ // Returns the sort group (system, trash, folder) for this folder.
+ virtual EInventorySortGroup getSortGroup();
+
virtual void setCompletedFilterGeneration(S32 generation, BOOL recurse_up);
virtual S32 getCompletedFilterGeneration() { return mCompletedFilterGeneration; }
@@ -583,7 +621,7 @@ public:
// This function is called by a child that needs to be resorted.
void resort(LLFolderViewItem* item);
- void setItemSortFunction(sort_order_f ordering);
+ void setItemSortOrder(U32 ordering);
void sortBy(U32);
//BOOL (*func)(LLFolderViewItem* a, LLFolderViewItem* b));
@@ -597,7 +635,8 @@ public:
virtual void setOpen(BOOL open = TRUE); /* Flawfinder: ignore */
// Called when a child is refreshed.
- virtual void requestArrange();
+ // don't rearrange child folder contents unless explicitly requested
+ virtual void requestArrange(BOOL include_descendants = FALSE);
// internal method which doesn't update the entire view. This
// method was written because the list iterators destroy the state
diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp
index 7a6b7b1bf3..39601eca25 100644
--- a/indra/newview/llglsandbox.cpp
+++ b/indra/newview/llglsandbox.cpp
@@ -1114,5 +1114,5 @@ void post_show_depth_buffer()
}
glDrawPixels(xsize,ysize,GL_RED,GL_UNSIGNED_BYTE,buf);
- delete buf;
+ delete [] buf;
}
diff --git a/indra/newview/llhudeffecttrail.cpp b/indra/newview/llhudeffecttrail.cpp
index 05da40f214..1ce443fd00 100644
--- a/indra/newview/llhudeffecttrail.cpp
+++ b/indra/newview/llhudeffecttrail.cpp
@@ -92,17 +92,19 @@ void LLHUDEffectSpiral::packData(LLMessageSystem *mesgsys)
void LLHUDEffectSpiral::unpackData(LLMessageSystem *mesgsys, S32 blocknum)
{
- U8 packed_data[56];
+ const size_t EFFECT_SIZE = 56;
+ U8 packed_data[EFFECT_SIZE];
LLHUDEffect::unpackData(mesgsys, blocknum);
LLUUID object_id, target_object_id;
S32 size = mesgsys->getSizeFast(_PREHASH_Effect, blocknum, _PREHASH_TypeData);
- if (size != 56)
+ if (size != EFFECT_SIZE)
{
llwarns << "Spiral effect with bad size " << size << llendl;
return;
}
- mesgsys->getBinaryDataFast(_PREHASH_Effect, _PREHASH_TypeData, packed_data, 56, blocknum);
+ mesgsys->getBinaryDataFast(_PREHASH_Effect, _PREHASH_TypeData,
+ packed_data, EFFECT_SIZE, blocknum, EFFECT_SIZE);
htonmemcpy(object_id.mData, packed_data, MVT_LLUUID, 16);
htonmemcpy(target_object_id.mData, packed_data + 16, MVT_LLUUID, 16);
diff --git a/indra/newview/llhudrender.cpp b/indra/newview/llhudrender.cpp
index 72c114d966..9b74b3963b 100644
--- a/indra/newview/llhudrender.cpp
+++ b/indra/newview/llhudrender.cpp
@@ -77,9 +77,12 @@ void hud_render_text(const LLWString &wstr, const LLVector3 &pos_agent,
LLVector3 render_pos = pos_agent + (floorf(x_offset) * right_axis) + (floorf(y_offset) * up_axis);
//get the render_pos in screen space
- F64* modelview = gGLModelView;
- F64* projection = gGLProjection;
- GLint* viewport = (GLint*) gGLViewport;
+ F64 modelview[16];
+ F64 projection[16];
+ GLint viewport[4];
+ glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
+ glGetDoublev(GL_PROJECTION_MATRIX, projection);
+ glGetIntegerv(GL_VIEWPORT, viewport);
F64 winX, winY, winZ;
gluProject(render_pos.mV[0], render_pos.mV[1], render_pos.mV[2],
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index f90fe340b4..13d13031b6 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -549,10 +549,10 @@ const char* safe_inv_type_lookup(LLInventoryType::EType inv_type)
}
LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type,
- LLInventoryType::EType inv_type,
- LLInventoryPanel* inventory,
- const LLUUID& uuid,
- U32 flags)
+ LLInventoryType::EType inv_type,
+ LLInventoryPanel* inventory,
+ const LLUUID& uuid,
+ U32 flags)
{
LLInvFVBridge* new_listener = NULL;
switch(asset_type)
@@ -657,7 +657,11 @@ LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type,
break;
}
- new_listener->mInvType = inv_type;
+ if (new_listener)
+ {
+ new_listener->mInvType = inv_type;
+ }
+
return new_listener;
}
@@ -887,16 +891,20 @@ BOOL LLItemBridge::removeItem()
if(!model) return FALSE;
LLUUID trash_id = model->findCategoryUUIDForType(LLAssetType::AT_TRASH);
LLViewerInventoryItem* item = getItem();
- if(item)
+
+ // if item is not already in trash
+ if(item && !model->isObjectDescendentOf(mUUID, trash_id))
{
- // restamp on move to trash.
+ // move to trash, and restamp
LLInvFVBridge::changeItemParent(model, item, trash_id, TRUE);
+ // delete was successful
+ return TRUE;
+ }
+ else
+ {
+ // tried to delete already item in trash (should purge?)
+ return FALSE;
}
-
- // return false anyway, so that if it's called from the folder
- // view, it doesn't remove the view - it's just being moved to the
- // trash.
- return FALSE;
}
BOOL LLItemBridge::isItemCopyable() const
@@ -1442,11 +1450,20 @@ void LLInventoryCopyAndWearObserver::changed(U32 mask)
{
LLViewerInventoryCategory* category = gInventory.getCategory(mCatID);
- if (category->getDescendentCount() == mContentsCount)
+ if (NULL == category)
{
- gInventory.removeObserver(this);
- wear_inventory_category(category, FALSE, TRUE);
- delete this;
+ llwarns << "gInventory.getCategory(" << mCatID
+ << ") was NULL" << llendl;
+ }
+ else
+ {
+ if (category->getDescendentCount() ==
+ mContentsCount)
+ {
+ gInventory.removeObserver(this);
+ wear_inventory_category(category, FALSE, TRUE);
+ delete this;
+ }
}
}
@@ -1662,11 +1679,7 @@ BOOL LLFolderBridge::removeItem()
LLInvFVBridge::changeCategoryParent(model, cat, trash_id, TRUE);
}
- // return false anyway, so that if it's called from the folder
- // view, it doesn't remove the view - it's just being moved to the
- // trash.
- return FALSE;
-
+ return TRUE;
}
BOOL LLFolderBridge::isClipboardPasteable() const
@@ -2158,10 +2171,13 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
// everything in the active window so that we don't follow
// the selection to its new location (which is very
// annoying).
- LLInventoryPanel* active_panel = LLInventoryView::getActiveInventory()->getPanel();
- if (mInventoryPanel != active_panel)
+ if (LLInventoryView::getActiveInventory())
{
- active_panel->unSelectAll();
+ LLInventoryPanel* active_panel = LLInventoryView::getActiveInventory()->getPanel();
+ if (active_panel && (mInventoryPanel != active_panel))
+ {
+ active_panel->unSelectAll();
+ }
}
// restamp if the move is into the trash.
@@ -3097,7 +3113,16 @@ void LLObjectBridge::performAction(LLFolderView* folder, LLInventoryModel* model
gMessageSystem->sendReliable( gAgent.getRegion()->getHost() );
}
// this object might have been selected, so let the selection manager know it's gone now
- gSelectMgr->remove(gObjectList.findObject(item->getUUID()));
+ LLViewerObject *found_obj =
+ gObjectList.findObject(item->getUUID());
+ if (found_obj)
+ {
+ gSelectMgr->remove(found_obj);
+ }
+ else
+ {
+ llwarns << "object not found - ignoring" << llendl;
+ }
}
else LLItemBridge::performAction(folder, model, action);
}
@@ -4007,7 +4032,15 @@ void remove_inventory_category_from_avatar_step2( BOOL proceed, void* userdata)
gMessageSystem->sendReliable( gAgent.getRegion()->getHost() );
// this object might have been selected, so let the selection manager know it's gone now
- gSelectMgr->remove(gObjectList.findObject( obj_item_array.get(i)->getUUID()) );
+ LLViewerObject *found_obj = gObjectList.findObject( obj_item_array.get(i)->getUUID());
+ if (found_obj)
+ {
+ gSelectMgr->remove(found_obj);
+ }
+ else
+ {
+ llwarns << "object not found, ignoring" << llendl;
+ }
}
}
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index edc4ba0ca6..8be81c944e 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -7,6 +7,7 @@
*/
#include "llviewerprecompiledheaders.h"
+
#include "llinventorymodel.h"
#include "llassetstorage.h"
@@ -21,6 +22,7 @@
#include "llfocusmgr.h"
#include "llinventoryview.h"
#include "llviewerinventory.h"
+#include "llviewermessage.h"
#include "llviewerwindow.h"
#include "viewer.h"
#include "lldbstrings.h"
@@ -2262,7 +2264,7 @@ void LLInventoryModel::processUseCachedInventory(LLMessageSystem* msg, void**)
void LLInventoryModel::processUpdateCreateInventoryItem(LLMessageSystem* msg, void**)
{
// do accounting and highlight new items if they arrive
- if (gInventory.messageUpdateCore(msg, true, true))
+ if (gInventory.messageUpdateCore(msg, true))
{
U32 callback_id;
LLUUID item_id;
@@ -2278,12 +2280,15 @@ void LLInventoryModel::processUpdateCreateInventoryItem(LLMessageSystem* msg, vo
void LLInventoryModel::processFetchInventoryReply(LLMessageSystem* msg, void**)
{
// no accounting
- gInventory.messageUpdateCore(msg, false, false);
+ gInventory.messageUpdateCore(msg, false);
}
-bool LLInventoryModel::messageUpdateCore(LLMessageSystem* msg, bool account, bool highlight_new)
+bool LLInventoryModel::messageUpdateCore(LLMessageSystem* msg, bool account)
{
+ //make sure our added inventory observer is active -Gigs
+ start_new_inventory_observer();
+
LLUUID agent_id;
msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id);
if(agent_id != gAgent.getID())
@@ -2292,16 +2297,15 @@ bool LLInventoryModel::messageUpdateCore(LLMessageSystem* msg, bool account, boo
<< llendl;
return false;
}
- LLPointer<LLViewerInventoryItem> lastitem; // hack
item_array_t items;
update_map_t update;
S32 count = msg->getNumberOfBlocksFast(_PREHASH_InventoryData);
bool all_one_folder = true;
LLUUID folder_id;
+ // Does this loop ever execute more than once? -Gigs
for(S32 i = 0; i < count; ++i)
{
LLPointer<LLViewerInventoryItem> titem = new LLViewerInventoryItem;
- lastitem = titem;
titem->unpackMessage(msg, _PREHASH_InventoryData, i);
lldebugs << "LLInventoryModel::messageUpdateCore() item id:"
<< titem->getUUID() << llendl;
@@ -2339,6 +2343,7 @@ bool LLInventoryModel::messageUpdateCore(LLMessageSystem* msg, bool account, boo
}
U32 changes = 0x0;
+ //as above, this loop never seems to loop more than once per call
for (item_array_t::iterator it = items.begin(); it != items.end(); ++it)
{
changes |= gInventory.updateItem(*it);
@@ -2346,88 +2351,6 @@ bool LLInventoryModel::messageUpdateCore(LLMessageSystem* msg, bool account, boo
gInventory.notifyObservers();
gViewerWindow->getWindow()->decBusyCount();
- // *HACK: Do the 'show' logic for a new item in the inventory if
- // it is a newly created item.
- if (highlight_new
- && (changes & LLInventoryObserver::ADD) == LLInventoryObserver::ADD)
- {
- LLUUID trash_id;
- trash_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_TRASH);
- if(!gInventory.isObjectDescendentOf(lastitem->getUUID(), trash_id))
- {
- LLMultiPreview* multi_previewp = LLMultiPreview::getAutoOpenInstance(folder_id);
- if (!multi_previewp && all_one_folder && count > 1)
- {
- S32 left, top;
- gFloaterView->getNewFloaterPosition(&left, &top);
-
- multi_previewp = new LLMultiPreview(LLRect(left, top, left + 300, top - 100));
- LLMultiPreview::setAutoOpenInstance(multi_previewp, folder_id);
- }
-
- LLFloater::setFloaterHost(multi_previewp);
-
- bool show_keep_discard = lastitem->getPermissions().getCreator() != gAgent.getID();
- switch(lastitem->getType())
- {
- case LLAssetType::AT_NOTECARD:
- open_notecard(
- lastitem->getUUID(),
- LLString("Note: ") + lastitem->getName(),
- show_keep_discard,
- LLUUID::null,
- FALSE);
- break;
- case LLAssetType::AT_LANDMARK:
- open_landmark(
- lastitem->getUUID(),
- LLString(" ") + lastitem->getName(),
- show_keep_discard,
- LLUUID::null,
- FALSE);
- break;
- case LLAssetType::AT_TEXTURE:
- open_texture(
- lastitem->getUUID(),
- LLString("Texture: ") + lastitem->getName(),
- show_keep_discard,
- LLUUID::null,
- FALSE);
- break;
- default:
- break;
- }
-
- LLFloater::setFloaterHost(NULL);
- if (multi_previewp)
- {
- multi_previewp->open();
- }
-
- LLInventoryView* view = LLInventoryView::getActiveInventory();
- if(view)
- {
- LLUUID lost_and_found_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_LOST_AND_FOUND);
- BOOL inventory_has_focus = gFocusMgr.childHasKeyboardFocus(view);
- BOOL user_is_away = gAwayTimer.getStarted();
-
- // don't select lost and found items if an active user is working in the inventory
- if (!gInventory.isObjectDescendentOf(lastitem->getUUID(), lost_and_found_id) ||
- !inventory_has_focus ||
- user_is_away)
- {
- LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus();
- LLFocusMgr::FocusLostCallback callback = gFocusMgr.getFocusCallback();
- view->getPanel()->setSelection(lastitem->getUUID(), TAKE_FOCUS_NO);
- // HACK to open inventory offers that are
- // accepted. This information really needs to
- // flow through the instant messages and
- // inventory restore keyboard focus
- gFocusMgr.setKeyboardFocus(focus_ctrl, callback);
- }
- }
- }
- }
return true;
}
@@ -3432,6 +3355,43 @@ void LLInventoryExistenceObserver::changed(U32 mask)
}
}
+void LLInventoryAddedObserver::changed(U32 mask)
+{
+ if(!(mask & LLInventoryObserver::ADD))
+ {
+ return;
+ }
+
+ // *HACK: If this was in response to a packet off
+ // the network, figure out which item was updated.
+ // Code from Gigs Taggert, sin allowed by JC.
+ LLMessageSystem* msg = gMessageSystem;
+ const char* msg_name = msg->getMessageName();
+ if (!msg_name) return;
+
+ if (!(!strcmp(msg_name, "UpdateCreateInventoryItem")
+ || !strcmp(msg_name, "FetchInventoryReply")))
+ {
+ return;
+ }
+
+ LLPointer<LLViewerInventoryItem> titem = new LLViewerInventoryItem;
+ S32 num_blocks = msg->getNumberOfBlocksFast(_PREHASH_InventoryData);
+ for(S32 i = 0; i < num_blocks; ++i)
+ {
+ titem->unpackMessage(msg, _PREHASH_InventoryData, i);
+ if (!(titem->getUUID().isNull()))
+ {
+ //we don't do anything with null keys
+ mAdded.push_back(titem->getUUID());
+ }
+ }
+ if (!mAdded.empty())
+ {
+ done();
+ }
+}
+
LLInventoryTransactionObserver::LLInventoryTransactionObserver(
const LLTransactionID& transaction_id) :
mTransactionID(transaction_id)
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index b8bd559704..514448d1b1 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -9,10 +9,8 @@
#ifndef LL_LLINVENTORYMODEL_H
#define LL_LLINVENTORYMODEL_H
-#include "llassetstorage.h"
+#include "llassettype.h"
#include "lldarray.h"
-//#include "llskiplist.h"
-//#include "llptrskipmap.h"
#include "lluuid.h"
#include "llpermissionsflags.h"
#include "llstring.h"
@@ -367,7 +365,7 @@ protected:
static void processMoveInventoryItem(LLMessageSystem* msg, void**);
static void processFetchInventoryReply(LLMessageSystem* msg, void**);
- bool messageUpdateCore(LLMessageSystem* msg, bool do_accounting, bool highlight_new);
+ bool messageUpdateCore(LLMessageSystem* msg, bool do_accounting);
protected:
// Varaibles used to track what has changed since the last notify.
@@ -731,6 +729,29 @@ protected:
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLInventoryAddedObserver
+//
+// This class is used as a base class for doing something when
+// a new item arrives in inventory.
+// It does not watch for a certain UUID, rather it acts when anything is added
+// Derive a class from this class and implement the done() method to do
+// something useful.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class LLInventoryAddedObserver : public LLInventoryObserver
+{
+public:
+ LLInventoryAddedObserver() : mAdded() {}
+ virtual void changed(U32 mask);
+
+protected:
+ virtual void done() = 0;
+
+ typedef std::vector<LLUUID> item_ref_t;
+ item_ref_t mAdded;
+};
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLInventoryTransactionObserver
//
// Class which can be used as a base class for doing something when an
diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp
index 383d2846c0..b2fc91f536 100644
--- a/indra/newview/llpanelavatar.cpp
+++ b/indra/newview/llpanelavatar.cpp
@@ -1502,40 +1502,43 @@ void LLPanelAvatar::resetGroupList()
{
return;
}
- LLScrollListCtrl* group_list = LLUICtrlFactory::getScrollListByName(mPanelSecondLife,"groups");
- if (mPanelSecondLife && group_list)
+ if (mPanelSecondLife)
{
- group_list->deleteAllItems();
-
- S32 count = gAgent.mGroups.count();
- LLUUID id;
-
- for(S32 i = 0; i < count; ++i)
+ LLScrollListCtrl* group_list = LLUICtrlFactory::getScrollListByName(mPanelSecondLife,"groups");
+ if (group_list)
{
- LLGroupData group_data = gAgent.mGroups.get(i);
- id = group_data.mID;
- std::string group_string;
- /* Show group title? DUMMY_POWER for Don Grep
- if(group_data.mOfficer)
- {
- group_string = "Officer of ";
- }
- else
+ group_list->deleteAllItems();
+
+ S32 count = gAgent.mGroups.count();
+ LLUUID id;
+
+ for(S32 i = 0; i < count; ++i)
{
- group_string = "Member of ";
- }
- */
+ LLGroupData group_data = gAgent.mGroups.get(i);
+ id = group_data.mID;
+ std::string group_string;
+ /* Show group title? DUMMY_POWER for Don Grep
+ if(group_data.mOfficer)
+ {
+ group_string = "Officer of ";
+ }
+ else
+ {
+ group_string = "Member of ";
+ }
+ */
+
+ group_string += group_data.mName;
- group_string += group_data.mName;
-
- LLSD row;
- row["columns"][0]["value"] = group_string;
- row["columns"][0]["font"] = "SANSSERIF_SMALL";
- row["columns"][0]["width"] = 0;
- group_list->addElement(row);
+ LLSD row;
+ row["columns"][0]["value"] = group_string;
+ row["columns"][0]["font"] = "SANSSERIF_SMALL";
+ row["columns"][0]["width"] = 0;
+ group_list->addElement(row);
+ }
+ group_list->sortByColumn(0, TRUE);
}
- group_list->sortByColumn(0, TRUE);
}
}
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index cdcaed43f9..158421f7a0 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -485,7 +485,16 @@ void LLPanelFace::getState()
{
F32 shinyf = 0.f;
identical = allFacesSameValue( &LLPanelFace::valueShiny, &shinyf );
- childGetSelectionInterface("combobox shininess")->selectNthItem((S32)shinyf);
+ LLCtrlSelectionInterface* combobox_shininess =
+ childGetSelectionInterface("combobox shininess");
+ if (combobox_shininess)
+ {
+ combobox_shininess->selectNthItem((S32)shinyf);
+ }
+ else
+ {
+ llwarns << "failed childGetSelectionInterface for 'combobox shininess'" << llendl;
+ }
childSetEnabled("combobox shininess",editable);
childSetTentative("combobox shininess",!identical);
childSetEnabled("label shininess",editable);
@@ -494,7 +503,16 @@ void LLPanelFace::getState()
{
F32 bumpf = 0.f;
identical = allFacesSameValue( &LLPanelFace::valueBump, &bumpf );
- childGetSelectionInterface("combobox bumpiness")->selectNthItem((S32)bumpf);
+ LLCtrlSelectionInterface* combobox_bumpiness =
+ childGetSelectionInterface("combobox bumpiness");
+ if (combobox_bumpiness)
+ {
+ combobox_bumpiness->selectNthItem((S32)bumpf);
+ }
+ else
+ {
+ llwarns << "failed childGetSelectionInterface for 'combobox bumpiness'" << llendl;
+ }
childSetEnabled("combobox bumpiness",editable);
childSetTentative("combobox bumpiness",!identical);
childSetEnabled("label bumpiness",editable);
@@ -503,8 +521,17 @@ void LLPanelFace::getState()
{
F32 genf = 0.f;
identical = allFacesSameValue( &LLPanelFace::valueTexGen, &genf);
- S32 selected_texgen = ((S32) genf) >> TEM_TEX_GEN_SHIFT;
- childGetSelectionInterface("combobox texgen")->selectNthItem(selected_texgen);
+ S32 selected_texgen = ((S32) genf) >> TEM_TEX_GEN_SHIFT;
+ LLCtrlSelectionInterface* combobox_texgen =
+ childGetSelectionInterface("combobox texgen");
+ if (combobox_texgen)
+ {
+ combobox_texgen->selectNthItem(selected_texgen);
+ }
+ else
+ {
+ llwarns << "failed childGetSelectionInterface for 'combobox texgen'" << llendl;
+ }
childSetEnabled("combobox texgen",editable);
childSetTentative("combobox texgen",!identical);
childSetEnabled("tex gen",editable);
diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp
index 121dc4c67e..4962329619 100644
--- a/indra/newview/llpanelgroup.cpp
+++ b/indra/newview/llpanelgroup.cpp
@@ -640,7 +640,7 @@ void LLPanelGroup::showNotice(const char* subject,
// We need to clean up that inventory offer.
if (inventory_offer)
{
- inventory_offer_callback( 1 , inventory_offer);
+ inventory_offer_callback( IOR_DECLINE , inventory_offer);
}
return;
}
diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp
index 610bfec8ae..161b46a17c 100644
--- a/indra/newview/llpanelgroupgeneral.cpp
+++ b/indra/newview/llpanelgroupgeneral.cpp
@@ -25,10 +25,10 @@
#include "llnamebox.h"
#include "llnamelistctrl.h"
#include "llspinctrl.h"
+#include "llstatusbar.h" // can_afford_transaction()
#include "lltextbox.h"
#include "lltexteditor.h"
#include "lltexturectrl.h"
-#include "llviewermessage.h"
#include "llviewerwindow.h"
// static
@@ -302,19 +302,27 @@ void LLPanelGroupGeneral::onClickJoin(void *userdata)
LLGroupMgrGroupData* gdatap = gGroupMgr->getGroupData(self->mGroupID);
- S32 cost = gdatap->mMembershipFee;
- LLString::format_map_t args;
- args["[COST]"] = llformat("%d", cost);
-
- if (can_afford_transaction(cost))
+ if (gdatap)
{
- gViewerWindow->alertXml("JoinGroupCanAfford", args,
- LLPanelGroupGeneral::joinDlgCB,
- self);
+ S32 cost = gdatap->mMembershipFee;
+ LLString::format_map_t args;
+ args["[COST]"] = llformat("%d", cost);
+
+ if (can_afford_transaction(cost))
+ {
+ gViewerWindow->alertXml("JoinGroupCanAfford", args,
+ LLPanelGroupGeneral::joinDlgCB,
+ self);
+ }
+ else
+ {
+ gViewerWindow->alertXml("JoinGroupCannotAfford", args);
+ }
}
else
{
- gViewerWindow->alertXml("JoinGroupCannotAfford", args);
+ llwarns << "gGroupMgr->getGroupData(" << self->mGroupID
+ << ") was NULL" << llendl;
}
}
diff --git a/indra/newview/llpanelgroupnotices.cpp b/indra/newview/llpanelgroupnotices.cpp
index b03747c68b..b0fc26f22a 100644
--- a/indra/newview/llpanelgroupnotices.cpp
+++ b/indra/newview/llpanelgroupnotices.cpp
@@ -184,7 +184,7 @@ LLPanelGroupNotices::~LLPanelGroupNotices()
if (mInventoryOffer)
{
// Cancel the inventory offer.
- inventory_offer_callback( 1 , mInventoryOffer);
+ inventory_offer_callback( IOR_DECLINE , mInventoryOffer);
mInventoryOffer = NULL;
}
}
@@ -339,7 +339,7 @@ void LLPanelGroupNotices::onClickOpenAttachment(void* data)
{
LLPanelGroupNotices* self = (LLPanelGroupNotices*)data;
- inventory_offer_callback( 0 , self->mInventoryOffer);
+ inventory_offer_callback( IOR_ACCEPT , self->mInventoryOffer);
self->mInventoryOffer = NULL;
self->mBtnOpenAttachment->setEnabled(FALSE);
}
@@ -378,7 +378,7 @@ void LLPanelGroupNotices::onClickNewMessage(void* data)
if (self->mInventoryOffer)
{
- inventory_offer_callback( 1 , self->mInventoryOffer);
+ inventory_offer_callback( IOR_DECLINE , self->mInventoryOffer);
self->mInventoryOffer = NULL;
}
@@ -528,7 +528,7 @@ void LLPanelGroupNotices::showNotice(const char* subject,
if (mInventoryOffer)
{
// Cancel the inventory offer for the previously viewed notice
- inventory_offer_callback( 1 , mInventoryOffer);
+ inventory_offer_callback( IOR_DECLINE , mInventoryOffer);
mInventoryOffer = NULL;
}
diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp
index bda962ca56..30a86a40b2 100644
--- a/indra/newview/llpanelgrouproles.cpp
+++ b/indra/newview/llpanelgrouproles.cpp
@@ -1303,13 +1303,17 @@ void LLPanelGroupMembersSubTab::onRoleCheck(LLUICtrl* ctrl, void* user_data)
LLCheckBoxCtrl* check_box = static_cast<LLCheckBoxCtrl*>(ctrl);
if (!check_box || !self) return;
-
- LLUUID role_id = self->mAssignedRolesList->getFirstSelected()->getUUID();
- LLRoleMemberChangeType change_type = (check_box->get() ?
- RMC_ADD :
- RMC_REMOVE);
-
- self->handleRoleCheck(role_id, change_type);
+ LLScrollListItem* first_selected =
+ self->mAssignedRolesList->getFirstSelected();
+ if (first_selected)
+ {
+ LLUUID role_id = first_selected->getUUID();
+ LLRoleMemberChangeType change_type = (check_box->get() ?
+ RMC_ADD :
+ RMC_REMOVE);
+
+ self->handleRoleCheck(role_id, change_type);
+ }
}
void LLPanelGroupMembersSubTab::handleMemberDoubleClick()
@@ -2036,8 +2040,9 @@ void LLPanelGroupRolesSubTab::update(LLGroupChange gc)
}
if ((GC_ROLE_MEMBER_DATA == gc || GC_MEMBER_DATA == gc)
- && gdatap->isMemberDataComplete()
- && gdatap->isRoleMemberDataComplete())
+ && gdatap
+ && gdatap->isMemberDataComplete()
+ && gdatap->isRoleMemberDataComplete())
{
buildMembersList();
}
diff --git a/indra/newview/llpanelpermissions.cpp b/indra/newview/llpanelpermissions.cpp
index 9526965334..da7fc16cef 100644
--- a/indra/newview/llpanelpermissions.cpp
+++ b/indra/newview/llpanelpermissions.cpp
@@ -706,14 +706,17 @@ void LLPanelPermissions::refresh()
LLSaleInfo::EForSale sale_type = sale_info.getSaleType();
LLRadioGroup* RadioSaleType = gUICtrlFactory->getRadioGroupByName(this,"sale type");
- if(RadioSaleType && valid_sale_info)
+ if(RadioSaleType)
{
- RadioSaleType->setSelectedIndex((S32)sale_type - 1);
- }
- else
- {
- // default option is sell copy, determined to be safest
- RadioSaleType->setSelectedIndex((S32)LLSaleInfo::FS_COPY - 1);
+ if (valid_sale_info)
+ {
+ RadioSaleType->setSelectedIndex((S32)sale_type - 1);
+ }
+ else
+ {
+ // default option is sell copy, determined to be safest
+ RadioSaleType->setSelectedIndex((S32)LLSaleInfo::FS_COPY - 1);
+ }
}
if (is_for_sale)
diff --git a/indra/newview/llpatchvertexarray.cpp b/indra/newview/llpatchvertexarray.cpp
index 62f8ac87bb..0278ba32f8 100644
--- a/indra/newview/llpatchvertexarray.cpp
+++ b/indra/newview/llpatchvertexarray.cpp
@@ -106,8 +106,16 @@ void LLPatchVertexArray::create(U32 surface_width, U32 patch_width, F32 meters_p
mRenderStridep = new U32 [mPatchOrder + 1];
}
+ if (NULL == mRenderLevelp || NULL == mRenderStridep)
+ {
+ // init() and some other things all want to deref these
+ // pointers, so this is serious.
+ llerrs << "mRenderLevelp or mRenderStridep was NULL; we'd crash soon." << llendl;
+ return;
+ }
- // Now that we've allocated memory, we can initialize the arrays...
+ // Now that we've allocated memory, we can initialize
+ // the arrays...
init();
}
diff --git a/indra/newview/llpolymesh.cpp b/indra/newview/llpolymesh.cpp
index c49fee6d4a..125e1d211f 100644
--- a/indra/newview/llpolymesh.cpp
+++ b/indra/newview/llpolymesh.cpp
@@ -281,6 +281,7 @@ BOOL LLPolyMeshSharedData::loadMesh( const char *fileName )
if (numRead != 1)
{
llerrs << "can't read HasWeights flag from " << fileName << llendl;
+ return FALSE;
}
if (!isLOD())
{
@@ -295,6 +296,7 @@ BOOL LLPolyMeshSharedData::loadMesh( const char *fileName )
if (numRead != 1)
{
llerrs << "can't read HasDetailTexCoords flag from " << fileName << llendl;
+ return FALSE;
}
//----------------------------------------------------------------
@@ -306,6 +308,7 @@ BOOL LLPolyMeshSharedData::loadMesh( const char *fileName )
if (numRead != 3)
{
llerrs << "can't read Position from " << fileName << llendl;
+ return FALSE;
}
setPosition( position );
@@ -318,6 +321,7 @@ BOOL LLPolyMeshSharedData::loadMesh( const char *fileName )
if (numRead != 3)
{
llerrs << "can't read RotationAngles from " << fileName << llendl;
+ return FALSE;
}
U8 rotationOrder;
@@ -326,6 +330,7 @@ BOOL LLPolyMeshSharedData::loadMesh( const char *fileName )
if (numRead != 1)
{
llerrs << "can't read RotationOrder from " << fileName << llendl;
+ return FALSE;
}
rotationOrder = 0;
@@ -344,6 +349,7 @@ BOOL LLPolyMeshSharedData::loadMesh( const char *fileName )
if (numRead != 3)
{
llerrs << "can't read Scale from " << fileName << llendl;
+ return FALSE;
}
setScale( scale );
@@ -364,6 +370,7 @@ BOOL LLPolyMeshSharedData::loadMesh( const char *fileName )
if (numRead != 1)
{
llerrs << "can't read NumVertices from " << fileName << llendl;
+ return FALSE;
}
allocateVertexData( numVertices );
@@ -376,6 +383,7 @@ BOOL LLPolyMeshSharedData::loadMesh( const char *fileName )
if (numRead != numVertices)
{
llerrs << "can't read Coordinates from " << fileName << llendl;
+ return FALSE;
}
//----------------------------------------------------------------
@@ -386,6 +394,7 @@ BOOL LLPolyMeshSharedData::loadMesh( const char *fileName )
if (numRead != numVertices)
{
llerrs << " can't read Normals from " << fileName << llendl;
+ return FALSE;
}
//----------------------------------------------------------------
@@ -396,6 +405,7 @@ BOOL LLPolyMeshSharedData::loadMesh( const char *fileName )
if (numRead != numVertices)
{
llerrs << " can't read Binormals from " << fileName << llendl;
+ return FALSE;
}
@@ -407,6 +417,7 @@ BOOL LLPolyMeshSharedData::loadMesh( const char *fileName )
if (numRead != numVertices)
{
llerrs << "can't read TexCoords from " << fileName << llendl;
+ return FALSE;
}
//----------------------------------------------------------------
@@ -419,6 +430,7 @@ BOOL LLPolyMeshSharedData::loadMesh( const char *fileName )
if (numRead != numVertices)
{
llerrs << "can't read DetailTexCoords from " << fileName << llendl;
+ return FALSE;
}
}
@@ -432,6 +444,7 @@ BOOL LLPolyMeshSharedData::loadMesh( const char *fileName )
if (numRead != numVertices)
{
llerrs << "can't read Weights from " << fileName << llendl;
+ return FALSE;
}
}
}
@@ -445,6 +458,7 @@ BOOL LLPolyMeshSharedData::loadMesh( const char *fileName )
if (numRead != 1)
{
llerrs << "can't read NumFaces from " << fileName << llendl;
+ return FALSE;
}
allocateFaceData( numFaces );
@@ -462,6 +476,7 @@ BOOL LLPolyMeshSharedData::loadMesh( const char *fileName )
if (numRead != 3)
{
llerrs << "can't read Face[" << i << "] from " << fileName << llendl;
+ return FALSE;
}
if (mReferenceData)
{
@@ -518,6 +533,7 @@ BOOL LLPolyMeshSharedData::loadMesh( const char *fileName )
if (numRead != 1)
{
llerrs << "can't read NumSkinJoints from " << fileName << llendl;
+ return FALSE;
}
allocateJointNames( numSkinJoints );
}
@@ -527,11 +543,13 @@ BOOL LLPolyMeshSharedData::loadMesh( const char *fileName )
//----------------------------------------------------------------
for (i=0; i < numSkinJoints; i++)
{
- char jointName[64]; /*Flawfinder: ignore*/
- numRead = fread(jointName, sizeof(jointName), 1, fp);
+ char jointName[64+1];
+ numRead = fread(jointName, sizeof(jointName)-1, 1, fp);
+ jointName[sizeof(jointName)-1] = '\0'; // ensure nul-termination
if (numRead != 1)
{
llerrs << "can't read Skin[" << i << "].Name from " << fileName << llendl;
+ return FALSE;
}
std::string *jn = &mJointNames[i];
@@ -541,7 +559,8 @@ BOOL LLPolyMeshSharedData::loadMesh( const char *fileName )
//-------------------------------------------------------------------------
// look for morph section
//-------------------------------------------------------------------------
- char morphName[64]; /*Flawfinder: ignore*/
+ char morphName[64+1];
+ morphName[sizeof(morphName)-1] = '\0'; // ensure nul-termination
while(fread(&morphName, sizeof(char), 64, fp) == 64)
{
if (!strcmp(morphName, "End Morphs"))
@@ -971,6 +990,13 @@ BOOL LLPolySkeletalDistortionInfo::parseXml(LLXmlTreeNode* node)
LLXmlTreeNode* skeletalParam = node->getChildByName("param_skeleton");
+ if (NULL == skeletalParam)
+ {
+ llwarns << "Failed to getChildByName(\"param_skeleton\")"
+ << llendl;
+ return FALSE;
+ }
+
for( LLXmlTreeNode* bone = skeletalParam->getFirstChild(); bone; bone = skeletalParam->getNextChild() )
{
if (bone->hasName("bone"))
diff --git a/indra/newview/llpolymorph.cpp b/indra/newview/llpolymorph.cpp
index 9cbe6522cb..f531624830 100644
--- a/indra/newview/llpolymorph.cpp
+++ b/indra/newview/llpolymorph.cpp
@@ -194,6 +194,13 @@ BOOL LLPolyMorphTargetInfo::parseXml(LLXmlTreeNode* node)
LLXmlTreeNode *paramNode = node->getChildByName("param_morph");
+ if (NULL == paramNode)
+ {
+ llwarns << "Failed to getChildByName(\"param_morph\")"
+ << llendl;
+ return FALSE;
+ }
+
for (LLXmlTreeNode* child_node = paramNode->getFirstChild();
child_node;
child_node = paramNode->getNextChild())
@@ -236,7 +243,10 @@ LLPolyMorphTarget::LLPolyMorphTarget(LLPolyMesh *poly_mesh)
//-----------------------------------------------------------------------------
LLPolyMorphTarget::~LLPolyMorphTarget()
{
- delete mVertMask;
+ if (mVertMask)
+ {
+ delete mVertMask;
+ }
}
//-----------------------------------------------------------------------------
diff --git a/indra/newview/llpreview.cpp b/indra/newview/llpreview.cpp
index 52ce263e59..39cc290b0f 100644
--- a/indra/newview/llpreview.cpp
+++ b/indra/newview/llpreview.cpp
@@ -40,6 +40,7 @@ LLPreview::LLPreview(const std::string& name) :
LLFloater(name),
mCopyToInvBtn(NULL),
mForceClose(FALSE),
+ mUserResized(FALSE),
mCloseAfterSave(FALSE),
mAssetStatus(PREVIEW_ASSET_UNLOADED)
{
@@ -56,6 +57,7 @@ LLPreview::LLPreview(const std::string& name, const LLRect& rect, const std::str
mObjectUUID(object_uuid),
mCopyToInvBtn( NULL ),
mForceClose( FALSE ),
+ mUserResized(FALSE),
mCloseAfterSave(FALSE),
mAssetStatus(PREVIEW_ASSET_UNLOADED)
{
@@ -169,8 +171,6 @@ void LLPreview::onCommit()
}
LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
- BOOL has_sale_info = FALSE;
- LLSaleInfo sale_info;
new_item->setDescription(childGetText("desc"));
if(mObjectUUID.notNull())
{
@@ -202,11 +202,6 @@ void LLPreview::onCommit()
gSelectMgr->deselectAll();
gSelectMgr->addAsIndividual( obj, SELECT_ALL_TES, FALSE );
gSelectMgr->selectionSetObjectDescription( childGetText("desc") );
-
- if( has_sale_info )
- {
- gSelectMgr->selectionSetObjectSaleInfo( sale_info );
- }
gSelectMgr->deselectAll();
}
@@ -467,6 +462,12 @@ LLPreview* LLPreview::getFirstPreviewForSource(const LLUUID& source_id)
return NULL;
}
+void LLPreview::userSetShape(const LLRect& new_rect)
+{
+ userResized();
+ LLView::userSetShape(new_rect);
+}
+
//
// LLMultiPreview
//
@@ -486,6 +487,15 @@ void LLMultiPreview::open() /*Flawfinder: ignore*/
}
}
+
+void LLMultiPreview::userSetShape(const LLRect& new_rect)
+{
+ LLPreview* frontmost_preview = (LLPreview*)mTabContainer->getCurrentPanel();
+ if (frontmost_preview) frontmost_preview->userResized();
+ LLView::userSetShape(new_rect);
+}
+
+
void LLMultiPreview::tabOpen(LLFloater* opened_floater, bool from_click)
{
LLPreview* opened_preview = (LLPreview*)opened_floater;
diff --git a/indra/newview/llpreview.h b/indra/newview/llpreview.h
index ac3f4da996..5c7d6f30d0 100644
--- a/indra/newview/llpreview.h
+++ b/indra/newview/llpreview.h
@@ -28,6 +28,7 @@ public:
/*virtual*/void open(); /*Flawfinder: ignore*/
/*virtual*/void tabOpen(LLFloater* opened_floater, bool from_click);
+ /*virtual*/ void userSetShape(const LLRect& new_rect);
static LLMultiPreview* getAutoOpenInstance(const LLUUID& id);
static void setAutoOpenInstance(LLMultiPreview* previewp, const LLUUID& id);
@@ -81,6 +82,9 @@ public:
void addKeepDiscardButtons();
static void onKeepBtn(void* data);
static void onDiscardBtn(void* data);
+ /*virtual*/ void userSetShape(const LLRect& new_rect);
+
+ void userResized() { mUserResized = TRUE; };
virtual void loadAsset() { mAssetStatus = PREVIEW_ASSET_LOADED; }
virtual EAssetStatus getAssetStatus() { return mAssetStatus;}
@@ -115,6 +119,8 @@ protected:
// Close without saving changes
BOOL mForceClose;
+ BOOL mUserResized;
+
// When closing springs a "Want to save?" dialog, we want
// to keep the preview open until the save completes.
BOOL mCloseAfterSave;
diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp
index 39e32c31f5..9710fc8bf2 100644
--- a/indra/newview/llpreviewgesture.cpp
+++ b/indra/newview/llpreviewgesture.cpp
@@ -1570,6 +1570,11 @@ LLScrollListItem* LLPreviewGesture::addStep(const std::string& library_text)
{
step = new LLGestureStepWait();
}
+ else
+ {
+ llerrs << "Unknown step type: " << library_text << llendl;;
+ return NULL;
+ }
// Create an enabled item with this step
LLSD row;
@@ -1625,7 +1630,7 @@ void LLPreviewGesture::onClickDelete(void* data)
LLScrollListItem* item = self->mStepList->getFirstSelected();
S32 selected_index = self->mStepList->getFirstSelectedIndex();
- if (selected_index >= 0)
+ if (item && selected_index >= 0)
{
LLGestureStep* step = (LLGestureStep*)item->getUserdata();
delete step;
diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp
index a44a89dc19..1cba69b566 100644
--- a/indra/newview/llpreviewnotecard.cpp
+++ b/indra/newview/llpreviewnotecard.cpp
@@ -276,11 +276,12 @@ void LLPreviewNotecard::loadAsset()
{
// The object that we're trying to look at disappeared, bail.
llwarns << "Can't find object " << mObjectUUID << " associated with notecard." << llendl;
- mAssetID.setNull();
- editor->setText("Unable to find object containing this note.");
- editor->makePristine();
- editor->setEnabled(FALSE);
- mAssetStatus = PREVIEW_ASSET_LOADED;
+ mAssetID.setNull();
+ editor->setText("Unable to find object containing this note.");
+ editor->makePristine();
+ editor->setEnabled(FALSE);
+ mAssetStatus = PREVIEW_ASSET_LOADED;
+ delete new_uuid;
return;
}
}
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index 6a9965dbfb..4cf103508d 100644
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -450,12 +450,14 @@ void LLScriptEdCore::updateDynamicHelp(BOOL immediate)
LLFloater* help_floater = LLFloater::getFloaterByHandle(mLiveHelpHandle);
if (!help_floater) return;
+#if LL_LIBXUL_ENABLED
// update back and forward buttons
LLButton* fwd_button = LLUICtrlFactory::getButtonByName(help_floater, "fwd_btn");
LLButton* back_button = LLUICtrlFactory::getButtonByName(help_floater, "back_btn");
LLWebBrowserCtrl* browser = LLUICtrlFactory::getWebBrowserCtrlByName(help_floater, "lsl_guide_html");
back_button->setEnabled(browser->canNavigateBack());
fwd_button->setEnabled(browser->canNavigateForward());
+#endif // LL_LIBXUL_ENABLED
if (!immediate && !gSavedSettings.getBOOL("ScriptHelpFollowsCursor"))
{
@@ -523,7 +525,9 @@ void LLScriptEdCore::setHelpPage(const LLString& help_string)
url_string.setArg("[LSL_STRING]", help_string);
addHelpItemToHistory(help_string);
+#if LL_LIBXUL_ENABLED
web_browser->navigateTo(url_string);
+#endif // LL_LIBXUL_ENABLED
}
void LLScriptEdCore::addHelpItemToHistory(const LLString& help_string)
@@ -655,8 +659,10 @@ void LLScriptEdCore::onBtnDynamicHelp(void* userdata)
live_help_floater->childSetAction("back_btn", onClickBack, userdata);
live_help_floater->childSetAction("fwd_btn", onClickForward, userdata);
+#if LL_LIBXUL_ENABLED
LLWebBrowserCtrl* browser = LLUICtrlFactory::getWebBrowserCtrlByName(live_help_floater, "lsl_guide_html");
browser->setAlwaysRefresh(TRUE);
+#endif // LL_LIBXUL_ENABLED
LLComboBox* help_combo = LLUICtrlFactory::getComboBoxByName(live_help_floater, "history_combo");
LLKeywordToken *token;
@@ -680,6 +686,7 @@ void LLScriptEdCore::onBtnDynamicHelp(void* userdata)
//static
void LLScriptEdCore::onClickBack(void* userdata)
{
+#if LL_LIBXUL_ENABLED
LLScriptEdCore* corep = (LLScriptEdCore*)userdata;
LLFloater* live_help_floater = LLFloater::getFloaterByHandle(corep->mLiveHelpHandle);
if (live_help_floater)
@@ -690,11 +697,13 @@ void LLScriptEdCore::onClickBack(void* userdata)
browserp->navigateBack();
}
}
+#endif // LL_LIBXUL_ENABLED
}
//static
void LLScriptEdCore::onClickForward(void* userdata)
{
+#if LL_LIBXUL_ENABLED
LLScriptEdCore* corep = (LLScriptEdCore*)userdata;
LLFloater* live_help_floater = LLFloater::getFloaterByHandle(corep->mLiveHelpHandle);
if (live_help_floater)
@@ -705,6 +714,7 @@ void LLScriptEdCore::onClickForward(void* userdata)
browserp->navigateForward();
}
}
+#endif // LL_LIBXUL_ENABLED
}
// static
@@ -737,16 +747,17 @@ void LLScriptEdCore::onHelpComboCommit(LLUICtrl* ctrl, void* userdata)
LLFloater* live_help_floater = LLFloater::getFloaterByHandle(corep->mLiveHelpHandle);
if (live_help_floater)
{
- LLWebBrowserCtrl* web_browser = gUICtrlFactory->getWebBrowserCtrlByName(live_help_floater, "lsl_guide_html");
-
LLString help_string = ctrl->getValue().asString();
corep->addHelpItemToHistory(help_string);
+#if LL_LIBXUL_ENABLED
+ LLWebBrowserCtrl* web_browser = gUICtrlFactory->getWebBrowserCtrlByName(live_help_floater, "lsl_guide_html");
LLUIString url_string = gSavedSettings.getString("LSLHelpURL");
url_string.setArg("[APP_DIRECTORY]", gDirUtilp->getWorkingDir());
url_string.setArg("[LSL_STRING]", help_string);
web_browser->navigateTo(url_string);
+#endif // LL_LIBXUL_ENABLED
}
}
@@ -1316,10 +1327,6 @@ void LLPreviewLSL::uploadAssetLegacy(const std::string& filename,
{
break;
}
- else if(!buffer)
- {
- continue;
- }
else
{
line.assign(buffer);
@@ -1689,7 +1696,7 @@ void LLLiveLSLEditor::loadAsset(BOOL is_new)
mScriptEd->mEditor->setEnabled(FALSE);
mAssetStatus = PREVIEW_ASSET_LOADED;
}
- else if(mItem.notNull())
+ else if(item && mItem.notNull())
{
// request the text from the object
LLUUID* user_data = new LLUUID(mItemID ^ mObjectID);
@@ -1815,6 +1822,7 @@ void LLLiveLSLEditor::loadScriptText(const char* filename)
if(!filename)
{
llerrs << "Filename is Empty!" << llendl;
+ return;
}
FILE* file = LLFile::fopen(filename, "rb"); /*Flawfinder: ignore*/
if(file)
@@ -2095,10 +2103,6 @@ void LLLiveLSLEditor::uploadAssetLegacy(const std::string& filename,
{
break;
}
- else if(!buffer)
- {
- continue;
- }
else
{
line.assign(buffer);
diff --git a/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp
index b8f1e51e9e..214b3e38f8 100644
--- a/indra/newview/llpreviewtexture.cpp
+++ b/indra/newview/llpreviewtexture.cpp
@@ -368,29 +368,23 @@ void LLPreviewTexture::updateAspectRatio()
// If that fails, cut width by half.
S32 client_width = image_width;
S32 horiz_pad = 2 * (LLPANEL_BORDER_WIDTH + PREVIEW_PAD) + PREVIEW_RESIZE_HANDLE_SIZE;
+ S32 vert_pad = PREVIEW_HEADER_SIZE + 2 * CLIENT_RECT_VPAD + LLPANEL_BORDER_WIDTH;
S32 screen_width = gViewerWindow->getWindowWidth();
S32 max_client_width = screen_width - horiz_pad;
+ S32 max_client_height = gViewerWindow->getWindowHeight() - vert_pad;
+ F32 inv_aspect_ratio = (F32) image_height / (F32) image_width;
- while (client_width > max_client_width)
+ while ((client_width > max_client_width) || ( llround(client_width * inv_aspect_ratio) > max_client_height ) )
{
client_width /= 2;
}
- // Demand width at least 128
- if (client_width < 128)
- {
- client_width = 128;
- }
-
S32 view_width = client_width + horiz_pad;
// Adjust the height based on the width computed above.
- F32 inv_aspect_ratio = (F32) image_height / (F32) image_width;
S32 client_height = llround(client_width * inv_aspect_ratio);
- S32 view_height =
- PREVIEW_HEADER_SIZE + // header (includes top border)
- client_height + 2 * CLIENT_RECT_VPAD + // texture plus uniform spacing (which leaves room for resize handle)
- LLPANEL_BORDER_WIDTH; // bottom border
+ S32 view_height = client_height + vert_pad;
+
// set text on dimensions display (should be moved out of here and into a callback of some sort)
childSetTextArg("dimensions", "[WIDTH]", llformat("%d", mImage->mFullWidth));
@@ -433,28 +427,43 @@ void LLPreviewTexture::updateAspectRatio()
}
}
- // clamp texture size to fit within actual size of floater after attempting resize
- client_width = llmin(client_width, mRect.getWidth() - horiz_pad);
- client_height = llmin(client_height, mRect.getHeight() - PREVIEW_HEADER_SIZE - (2 * CLIENT_RECT_VPAD) - LLPANEL_BORDER_WIDTH - info_height);
-
- LLRect window_rect(0, mRect.getHeight(), mRect.getWidth(), 0);
- window_rect.mTop -= (PREVIEW_HEADER_SIZE + CLIENT_RECT_VPAD);
- window_rect.mBottom += PREVIEW_BORDER + button_height + CLIENT_RECT_VPAD + info_height + CLIENT_RECT_VPAD;
-
- if (getHost())
+
+ if (!mUserResized)
{
- // try to keep aspect ratio when hosted, as hosting view can resize without user input
- mClientRect.setLeftTopAndSize(window_rect.getCenterX() - (client_width / 2), window_rect.mTop, client_width, client_height);
+ // clamp texture size to fit within actual size of floater after attempting resize
+ client_width = llmin(client_width, mRect.getWidth() - horiz_pad);
+ client_height = llmin(client_height, mRect.getHeight() - PREVIEW_HEADER_SIZE
+ - (2 * CLIENT_RECT_VPAD) - LLPANEL_BORDER_WIDTH - info_height);
+
+
}
else
{
- mClientRect.setLeftTopAndSize(LLPANEL_BORDER_WIDTH + PREVIEW_PAD + 6,
- mRect.getHeight() - (PREVIEW_HEADER_SIZE + CLIENT_RECT_VPAD),
- mRect.getWidth() - horiz_pad,
- client_height);
+ client_width = mRect.getWidth() - horiz_pad;
+ client_height = llround(client_width * inv_aspect_ratio);
+ }
+
+
+ S32 max_height = mRect.getHeight() - PREVIEW_BORDER - button_height
+ - CLIENT_RECT_VPAD - info_height - CLIENT_RECT_VPAD - PREVIEW_HEADER_SIZE;
+ max_height = llmax(max_height, 1);
+
+ if (client_height > max_height)
+ {
+ F32 aspect_ratio = (F32) image_width / (F32) image_height;
+ client_height = max_height;
+ client_width = llround(client_height * aspect_ratio);
}
+
+ LLRect window_rect(0, mRect.getHeight(), mRect.getWidth(), 0);
+ window_rect.mTop -= (PREVIEW_HEADER_SIZE + CLIENT_RECT_VPAD);
+ window_rect.mBottom += PREVIEW_BORDER + button_height + CLIENT_RECT_VPAD + info_height + CLIENT_RECT_VPAD;
+
+ // try to keep aspect ratio when hosted, as hosting view can resize without user input
+ mClientRect.setLeftTopAndSize(window_rect.getCenterX() - (client_width / 2), window_rect.mTop, client_width, client_height);
}
+
void LLPreviewTexture::loadAsset()
{
mImage = gImageList.getImage(mImageID, MIPMAP_TRUE, FALSE);
diff --git a/indra/newview/llresourcedata.h b/indra/newview/llresourcedata.h
new file mode 100644
index 0000000000..20a8df4c22
--- /dev/null
+++ b/indra/newview/llresourcedata.h
@@ -0,0 +1,24 @@
+/**
+ * @file llresourcedata.h
+ * @brief Tracking object for uploads.
+ *
+ * Copyright (c) 2006-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+#ifndef LLRESOURCEDATA_H
+#define LLRESOURCEDATA_H
+
+#include "llassetstorage.h"
+#include "llinventorytype.h"
+
+struct LLResourceData
+{
+ LLAssetInfo mAssetInfo;
+ LLAssetType::EType mPreferredLocation;
+ LLInventoryType::EType mInventoryType;
+ U32 mNextOwnerPerm;
+ void *mUserData;
+};
+
+#endif
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index a02dd912e3..98f842902d 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -71,7 +71,6 @@ const S32 MAX_ACTION_QUEUE_SIZE = 20;
const S32 MAX_SILS_PER_FRAME = 50;
const S32 MAX_OBJECTS_PER_PACKET = 254;
-extern LLGlobalEconomy *gGlobalEconomy;
extern LLUUID gLastHitObjectID;
extern LLVector3d gLastHitObjectOffset;
@@ -188,6 +187,20 @@ LLSelectMgr::~LLSelectMgr()
void LLSelectMgr::updateEffects()
{
+
+ //keep reference grid objects active
+ for (LLSelectNode* grid_nodep = mGridObjects.getFirstNode();
+ grid_nodep;
+ grid_nodep = mGridObjects.getNextNode())
+ {
+ LLViewerObject* grid_object = grid_nodep->getObject();
+ LLDrawable* drawable = grid_object->mDrawable;
+ if (drawable)
+ {
+ gPipeline.markMoved(drawable);
+ }
+ }
+
if (mEffectsTimer.getElapsedTimeF32() > 1.f)
{
mSelectedObjects->updateEffects();
@@ -973,7 +986,7 @@ void LLSelectMgr::getGrid(LLVector3& origin, LLQuaternion &rotation, LLVector3 &
LLVector3 first_grid_obj_pos = grid_object->getRenderPosition();
LLVector3 min_extents(F32_MAX, F32_MAX, F32_MAX);
- LLVector3 max_extents(F32_MIN, F32_MIN, F32_MIN);
+ LLVector3 max_extents(-min_extents);
BOOL grid_changed = FALSE;
LLSelectNode* grid_nodep;
for (grid_nodep = mGridObjects.getFirstNode();
@@ -981,34 +994,23 @@ void LLSelectMgr::getGrid(LLVector3& origin, LLQuaternion &rotation, LLVector3 &
grid_nodep = mGridObjects.getNextNode())
{
grid_object = grid_nodep->getObject();
-
- LLVector3 local_min_extents(F32_MAX, F32_MAX, F32_MAX);
- LLVector3 local_max_extents(F32_MIN, F32_MIN, F32_MIN);
-
- // *FIX: silhouette flag is insufficient as it gets
- // cleared by view update.
- if (!mGridValid ||
- grid_object->isChanged(LLXform::SILHOUETTE)
- || (grid_object->getParent() && grid_object->getParent()->isChanged(LLXform::SILHOUETTE)))
+ LLDrawable* drawable = grid_object->mDrawable;
+ if (drawable)
{
- getSilhouetteExtents(grid_nodep, mGridRotation, local_min_extents, local_max_extents);
+ const LLVector3* ext = drawable->getSpatialExtents();
+ update_min_max(min_extents, max_extents, ext[0]);
+ update_min_max(min_extents, max_extents, ext[1]);
grid_changed = TRUE;
- LLVector3 object_offset = (grid_object->getRenderPosition() - first_grid_obj_pos) * ~mGridRotation;
- local_min_extents += object_offset;
- local_max_extents += object_offset;
}
- min_extents.mV[VX] = llmin(min_extents.mV[VX], local_min_extents.mV[VX]);
- min_extents.mV[VY] = llmin(min_extents.mV[VY], local_min_extents.mV[VY]);
- min_extents.mV[VZ] = llmin(min_extents.mV[VZ], local_min_extents.mV[VZ]);
- max_extents.mV[VX] = llmax(max_extents.mV[VX], local_max_extents.mV[VX]);
- max_extents.mV[VY] = llmax(max_extents.mV[VY], local_max_extents.mV[VY]);
- max_extents.mV[VZ] = llmax(max_extents.mV[VZ], local_max_extents.mV[VZ]);
}
if (grid_changed)
{
mGridOrigin = lerp(min_extents, max_extents, 0.5f);
- mGridOrigin = mGridOrigin * ~mGridRotation;
- mGridOrigin += first_grid_obj_pos;
+ LLDrawable* drawable = grid_object->mDrawable;
+ if (drawable && drawable->isActive())
+ {
+ mGridOrigin = mGridOrigin * grid_object->getRenderMatrix();
+ }
mGridScale = (max_extents - min_extents) * 0.5f;
}
}
@@ -4919,66 +4921,6 @@ void LLSelectMgr::generateSilhouette(LLSelectNode* nodep, const LLVector3& view_
}
}
-void LLSelectMgr::getSilhouetteExtents(LLSelectNode* nodep, const LLQuaternion& orientation, LLVector3& min_extents, LLVector3& max_extents)
-{
- LLViewerObject* objectp = nodep->getObject();
-
- if (objectp->mDrawable.isNull())
- {
- return;
- }
-
- LLQuaternion test_rot = orientation * ~objectp->getRenderRotation();
- LLVector3 x_axis_rot = LLVector3::x_axis * test_rot;
- LLVector3 y_axis_rot = LLVector3::y_axis * test_rot;
- LLVector3 z_axis_rot = LLVector3::z_axis * test_rot;
-
- x_axis_rot.scaleVec(objectp->mDrawable->getScale());
- y_axis_rot.scaleVec(objectp->mDrawable->getScale());
- z_axis_rot.scaleVec(objectp->mDrawable->getScale());
-
- generateSilhouette(nodep, objectp->mDrawable->getPositionAgent() + x_axis_rot * 100.f);
-
- S32 num_vertices = nodep->mSilhouetteVertices.size();
- if (num_vertices)
- {
- min_extents.mV[VY] = llmin(min_extents.mV[VY], nodep->mSilhouetteVertices[0] * y_axis_rot);
- max_extents.mV[VY] = llmax(max_extents.mV[VY], nodep->mSilhouetteVertices[0] * y_axis_rot);
-
- min_extents.mV[VZ] = llmin(min_extents.mV[VZ], nodep->mSilhouetteVertices[0] * z_axis_rot);
- max_extents.mV[VZ] = llmax(min_extents.mV[VZ], nodep->mSilhouetteVertices[0] * z_axis_rot);
-
- for (S32 vert = 1; vert < num_vertices; vert++)
- {
- F32 y_pos = nodep->mSilhouetteVertices[vert] * y_axis_rot;
- F32 z_pos = nodep->mSilhouetteVertices[vert] * z_axis_rot;
- min_extents.mV[VY] = llmin(y_pos, min_extents.mV[VY]);
- max_extents.mV[VY] = llmax(y_pos, max_extents.mV[VY]);
- min_extents.mV[VZ] = llmin(z_pos, min_extents.mV[VZ]);
- max_extents.mV[VZ] = llmax(z_pos, max_extents.mV[VZ]);
- }
- }
-
- generateSilhouette(nodep, objectp->mDrawable->getPositionAgent() + y_axis_rot * 100.f);
-
- num_vertices = nodep->mSilhouetteVertices.size();
- if (num_vertices)
- {
- min_extents.mV[VX] = llmin(min_extents.mV[VX], nodep->mSilhouetteVertices[0] * x_axis_rot);
- max_extents.mV[VX] = llmax(max_extents.mV[VX], nodep->mSilhouetteVertices[0] * x_axis_rot);
-
- for (S32 vert = 1; vert < num_vertices; vert++)
- {
- F32 x_pos = nodep->mSilhouetteVertices[vert] * x_axis_rot;
- min_extents.mV[VX] = llmin(x_pos, min_extents.mV[VX]);
- max_extents.mV[VX] = llmax(x_pos, max_extents.mV[VX]);
- }
- }
-
- generateSilhouette(nodep, gCamera->getOrigin());
-}
-
-
//
// Utility classes
//
@@ -6459,6 +6401,8 @@ LLViewerObject* LLObjectSelection::getFirstDeleteableObject(BOOL get_root)
}
else
{
+ // We've avoided this path for a while. It may not work.
+ llwarns << "!get_root code path may have bitrotted." << llendl;
for(LLViewerObject* current = getFirstObject();
current != NULL;
current = getNextObject())
diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h
index 04d55dcf7d..0b4392f318 100644
--- a/indra/newview/llselectmgr.h
+++ b/indra/newview/llselectmgr.h
@@ -472,7 +472,6 @@ private:
ESelectType getSelectTypeForObject(LLViewerObject* object);
void addAsFamily(LLDynamicArray<LLViewerObject*>& objects, BOOL add_to_end = FALSE);
void generateSilhouette(LLSelectNode *nodep, const LLVector3& view_point);
- void getSilhouetteExtents(LLSelectNode* nodep, const LLQuaternion& orientation, LLVector3& min_extents, LLVector3& max_extents);
// Send one message to each region containing an object on selection list.
void sendListToRegions( const LLString& message_name,
void (*pack_header)(void *user_data),
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index 333ed91e4a..315a8e2828 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -1160,6 +1160,13 @@ void LLSpatialPartition::move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL
{
LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
LLFastTimer t(LLFastTimer::FTM_UPDATE_MOVE);
+
+ // sanity check submitted by open source user bushing Spatula
+ // who was seeing crashing here. (See VWR-424 reported by Bunny Mayne)
+ if (!drawablep) {
+ OCT_ERRS << "LLSpatialPartition::move was passed a bad drawable." << llendl;
+ return;
+ }
BOOL was_visible = curp ? curp->isVisible() : FALSE;
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 4bbdca521c..44b4d77c1e 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -183,6 +183,7 @@ LLPointer<LLImageGL> gStartImageGL;
static LLHost gAgentSimHost;
static BOOL gSkipOptionalUpdate = FALSE;
+bool gUseQuickTime = true;
bool gQuickTimeInitialized = false;
static bool gGotUseCircuitCodeAck = false;
LLString gInitialOutfit;
@@ -1847,7 +1848,8 @@ BOOL idle_startup()
}
#if LL_QUICKTIME_ENABLED // windows only right now but will be ported to mac
- if (!gQuickTimeInitialized)
+ if (gUseQuickTime
+ && !gQuickTimeInitialized)
{
// initialize quicktime libraries (fails gracefully if quicktime not installed ($QUICKTIME)
llinfos << "Initializing QuickTime...." << llendl;
diff --git a/indra/newview/llstartup.h b/indra/newview/llstartup.h
index 7d64640fb0..75a525f241 100644
--- a/indra/newview/llstartup.h
+++ b/indra/newview/llstartup.h
@@ -62,6 +62,7 @@ enum EStartupState{
// exorted symbol
extern S32 gStartupState;
extern BOOL gAgentMovementCompleted;
+extern bool gUseQuickTime;
extern bool gQuickTimeInitialized;
extern LLPointer<LLImageGL> gStartImageGL;
diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp
index 59fd8e0a3a..6990102d24 100644
--- a/indra/newview/llstatusbar.cpp
+++ b/indra/newview/llstatusbar.cpp
@@ -686,3 +686,8 @@ void LLStatusBar::onClickBuyLand(void*)
gParcelMgr->selectParcelAt(gAgent.getPositionGlobal());
gParcelMgr->startBuyLand();
}
+
+BOOL can_afford_transaction(S32 cost)
+{
+ return((cost <= 0)||((gStatusBar) && (gStatusBar->getBalance() >=cost)));
+}
diff --git a/indra/newview/llstatusbar.h b/indra/newview/llstatusbar.h
index 7e9f05cf1e..f33a5d93e1 100644
--- a/indra/newview/llstatusbar.h
+++ b/indra/newview/llstatusbar.h
@@ -123,6 +123,9 @@ protected:
LLFrameTimer* mHealthTimer;
};
+// *HACK: Status bar owns your cached money balance. JC
+BOOL can_afford_transaction(S32 cost);
+
extern LLStatusBar *gStatusBar;
#endif
diff --git a/indra/newview/lltexlayer.cpp b/indra/newview/lltexlayer.cpp
index fcabdc8450..178c83f61e 100644
--- a/indra/newview/lltexlayer.cpp
+++ b/indra/newview/lltexlayer.cpp
@@ -257,7 +257,7 @@ BOOL LLTexLayerSetBuffer::render()
{
if (!success)
{
- delete baked_bump_data;
+ delete [] baked_bump_data;
llinfos << "Failed attempt to bake " << mTexLayerSet->getBodyRegion() << llendl;
mUploadPending = FALSE;
}
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index bc5efa20aa..958635c796 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -390,32 +390,35 @@ BOOL LLFloaterTexturePicker::handleKeyHere(KEY key, MASK mask, BOOL called_from_
{
LLFolderView* root_folder = mInventoryPanel->getRootFolder();
- if (!called_from_parent && root_folder &&
- mSearchEdit && mSearchEdit->hasFocus() &&
- (key == KEY_RETURN || key == KEY_DOWN) && mask == MASK_NONE)
+ if (root_folder && mSearchEdit)
{
- if (!root_folder->getCurSelectedItem())
+ if (!called_from_parent && mSearchEdit->hasFocus() &&
+ (key == KEY_RETURN || key == KEY_DOWN) &&
+ mask == MASK_NONE)
{
- LLFolderViewItem* itemp = root_folder->getItemByID(gAgent.getInventoryRootID());
- if (itemp)
+ if (!root_folder->getCurSelectedItem())
{
- root_folder->setSelection(itemp, FALSE, FALSE);
+ LLFolderViewItem* itemp = root_folder->getItemByID(gAgent.getInventoryRootID());
+ if (itemp)
+ {
+ root_folder->setSelection(itemp, FALSE, FALSE);
+ }
}
+ root_folder->scrollToShowSelection();
+
+ // move focus to inventory proper
+ root_folder->setFocus(TRUE);
+
+ // treat this as a user selection of the first filtered result
+ commitIfImmediateSet();
+
+ return TRUE;
}
- root_folder->scrollToShowSelection();
-
- // move focus to inventory proper
- root_folder->setFocus(TRUE);
- // treat this as a user selection of the first filtered result
- commitIfImmediateSet();
-
- return TRUE;
- }
-
- if (root_folder->hasFocus() && key == KEY_UP)
- {
- mSearchEdit->focusFirstItem(TRUE);
+ if (root_folder->hasFocus() && key == KEY_UP)
+ {
+ mSearchEdit->focusFirstItem(TRUE);
+ }
}
return LLFloater::handleKeyHere(key, mask, called_from_parent);
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index 64ec8f0b2f..930d6fa5f2 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -2555,7 +2555,13 @@ EAcceptance LLToolDragAndDrop::dad3dUpdateInventoryCategory(
LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
{
lldebugs << "LLToolDragAndDrop::dad3dUpdateInventoryCategory()" << llendl;
- if(mSource != SOURCE_AGENT && mSource != SOURCE_LIBRARY)
+ if (NULL==obj)
+ {
+ llwarns << "obj is NULL; aborting func with ACCEPT_NO" << llendl;
+ return ACCEPT_NO;
+ }
+
+ if (mSource != SOURCE_AGENT && mSource != SOURCE_LIBRARY)
{
return ACCEPT_NO;
}
@@ -2571,17 +2577,17 @@ EAcceptance LLToolDragAndDrop::dad3dUpdateInventoryCategory(
LLInventoryModel::cat_array_t cats;
LLInventoryModel::item_array_t items;
gInventory.collectDescendentsIf(cat->getUUID(),
- cats,
- items,
- LLInventoryModel::EXCLUDE_TRASH,
- droppable);
+ cats,
+ items,
+ LLInventoryModel::EXCLUDE_TRASH,
+ droppable);
cats.put(cat);
if(droppable.countNoCopy() > 0)
{
llwarns << "*** Need to confirm this step" << llendl;
}
LLViewerObject* root_object = obj;
- if (obj && obj->getParent())
+ if (obj->getParent())
{
LLViewerObject* parent_obj = (LLViewerObject*)obj->getParent();
if (!parent_obj->isAvatar())
diff --git a/indra/newview/lltoolgrab.cpp b/indra/newview/lltoolgrab.cpp
index 549719250c..3250e42232 100644
--- a/indra/newview/lltoolgrab.cpp
+++ b/indra/newview/lltoolgrab.cpp
@@ -160,6 +160,12 @@ BOOL LLToolGrab::handleObjectHit(LLViewerObject *objectp, S32 x, S32 y, MASK mas
llinfos << "LLToolGrab handleObjectHit " << mMouseDownX << "," << mMouseDownY << llendl;
}
+ if (NULL == objectp) // unexpected
+ {
+ llwarns << "objectp was NULL; returning FALSE" << llendl;
+ return FALSE;
+ }
+
if (objectp->isAvatar())
{
if (gGrabTransientTool)
@@ -178,7 +184,7 @@ BOOL LLToolGrab::handleObjectHit(LLViewerObject *objectp, S32 x, S32 y, MASK mas
// objectp = (LLViewerObject *)objectp->getRoot();
LLViewerObject* parent = objectp->getRootEdit();
- BOOL script_touch = (objectp && objectp->flagHandleTouch()) || (parent && parent->flagHandleTouch());
+ BOOL script_touch = (objectp->flagHandleTouch()) || (parent && parent->flagHandleTouch());
// Clicks on scripted or physical objects are temporary grabs, so
// not "Build mode"
diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index f9511f72a5..68eec329aa 100644
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -370,11 +370,11 @@ U8 final_click_action(LLViewerObject* obj)
if (obj->isAttachment()) return CLICK_ACTION_NONE;
U8 click_action = CLICK_ACTION_TOUCH;
- LLViewerObject* parent = (obj ? obj->getRootEdit() : NULL);
- if ((obj && obj->getClickAction())
- || (parent && parent->getClickAction()))
+ LLViewerObject* parent = obj->getRootEdit();
+ if (obj->getClickAction()
+ || (parent && parent->getClickAction()))
{
- if (obj && obj->getClickAction())
+ if (obj->getClickAction())
{
click_action = obj->getClickAction();
}
diff --git a/indra/newview/llviewerassetstorage.cpp b/indra/newview/llviewerassetstorage.cpp
index 88ffd016cf..e0a6786cb8 100644
--- a/indra/newview/llviewerassetstorage.cpp
+++ b/indra/newview/llviewerassetstorage.cpp
@@ -146,21 +146,22 @@ void LLViewerAssetStorage::storeAssetData(
if(!filename)
{
llerrs << "No filename specified" << llendl;
+ return;
}
LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
llinfos << "LLViewerAssetStorage::storeAssetData (legacy)" << asset_id << ":" << LLAssetType::lookup(asset_type) << llendl;
- LLLegacyAssetRequest *legacy = new LLLegacyAssetRequest;
-
llinfos << "ASSET_ID: " << asset_id << llendl;
- legacy->mUpCallback = callback;
- legacy->mUserData = user_data;
-
- FILE* fp = LLFile::fopen(filename, "rb"); /* Flawfinder: ignore */
+ FILE* fp = LLFile::fopen(filename, "rb");
if (fp)
{
+ LLLegacyAssetRequest *legacy = new LLLegacyAssetRequest;
+
+ legacy->mUpCallback = callback;
+ legacy->mUserData = user_data;
+
LLVFile file(mVFS, asset_id, asset_type, LLVFile::WRITE);
fseek(fp, 0, SEEK_END);
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index 225d599838..3dedaa3182 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -220,6 +220,14 @@ void LLFloaterSettingsDebug::updateControl(LLControlBase* controlp)
LLSpinCtrl* spinner3 = LLUICtrlFactory::getSpinnerByName(this, "val_spinner_3");
LLSpinCtrl* spinner4 = LLUICtrlFactory::getSpinnerByName(this, "val_spinner_4");
LLColorSwatchCtrl* color_swatch = LLUICtrlFactory::getColorSwatchByName(this, "color_swatch");
+
+ if (!spinner1 || !spinner2 || !spinner3 || !spinner4 || !color_swatch)
+ {
+ llwarns << "Could not find all desired controls by name"
+ << llendl;
+ return;
+ }
+
spinner1->setVisible(FALSE);
spinner2->setVisible(FALSE);
spinner3->setVisible(FALSE);
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index cbb37e5fe4..fa2a12b34a 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -544,6 +544,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield)
glPushMatrix();
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
+
if (LLPipeline::sShowHUDAttachments && !gDisconnected && setup_hud_matrices(FALSE))
{
LLCamera hud_cam = *gCamera;
@@ -578,7 +579,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield)
LLFastTimer ftm(LLFastTimer::FTM_REBUILD);
gPipeline.stateSort(hud_cam);
}
-
+
gPipeline.renderGeom(hud_cam);
//restore type mask
@@ -637,6 +638,7 @@ BOOL setup_hud_matrices(BOOL for_select)
}
LLBBox hud_bbox = my_avatarp->getHUDBBox();
+
// set up transform to encompass bounding box of HUD
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
@@ -665,7 +667,7 @@ BOOL setup_hud_matrices(BOOL for_select)
glLoadMatrixf(OGL_TO_CFR_ROTATION); // Load Cory's favorite reference frame
glTranslatef(-hud_bbox.getCenterLocal().mV[VX] + (hud_depth * 0.5f), 0.f, 0.f);
glScalef(zoom_level, zoom_level, zoom_level);
-
+
return TRUE;
}
else
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index 240100be61..d1a0b3724d 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -442,10 +442,6 @@ bool LLViewerInventoryCategory::importFileLocal(FILE* fp)
fgets(buffer, MAX_STRING, fp);
sscanf( /* Flawfinder: ignore */
buffer, " %254s %254s", keyword, valuestr);
- if(!keyword)
- {
- continue;
- }
if(0 == strcmp("{",keyword))
{
continue;
diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp
index 9bb4aa4cf9..150943465d 100644
--- a/indra/newview/llviewerjointmesh.cpp
+++ b/indra/newview/llviewerjointmesh.cpp
@@ -196,11 +196,11 @@ S32 LLViewerJointMesh::getBoundJointsByIndex(S32 index, S32 &joint_a, S32& joint
if (render_datap->mSkinJoint)
{
joint_b = render_datap->mSkinJoint->mJoint->mJointNum;
- }
- if (joint_a == -1)
- {
- joint_a = render_datap->mSkinJoint->mJoint->getParent()->mJointNum;
+ if (joint_a == -1)
+ {
+ joint_a = render_datap->mSkinJoint->mJoint->getParent()->mJointNum;
+ }
}
num_joints++;
}
diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp
index d970d1d086..17c9a1fc10 100644
--- a/indra/newview/llviewerkeyboard.cpp
+++ b/indra/newview/llviewerkeyboard.cpp
@@ -697,15 +697,16 @@ S32 LLViewerKeyboard::loadBindings(const char *filename)
S32 binding_count = 0;
S32 line_count = 0;
- fp = LLFile::fopen(filename, "r"); /* Flawfinder: ignore */
+ if(!filename)
+ {
+ llerrs << " No filename specified" << llendl;
+ return 0;
+ }
+
+ fp = LLFile::fopen(filename, "r");
if (!fp)
{
- if(!filename)
- {
- llerrs << " No filename specified" << llendl;
- return 0;
- }
return 0;
}
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 2ac1c30ae5..5a6ff851c4 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -14,15 +14,12 @@
#include <iostream>
#include <fstream>
#include <sstream>
-#include <boost/tokenizer.hpp>
// linden library includes
#include "audioengine.h"
#include "indra_constants.h"
-#include "llassetuploadresponders.h"
#include "llassetstorage.h"
#include "llchat.h"
-#include "lleconomy.h"
#include "llfocusmgr.h"
#include "llfontgl.h"
#include "llinstantmessage.h"
@@ -37,7 +34,6 @@
#include "raytrace.h"
#include "llsdserialize.h"
#include "lltimer.h"
-#include "vorbisencode.h"
#include "llvfile.h"
#include "llvolumemgr.h"
#include "llwindow.h" // for shell_open()
@@ -63,7 +59,6 @@
#include "llfloater.h"
#include "llfloaterabout.h"
#include "llfloaterbuycurrency.h"
-#include "llfloateranimpreview.h"
#include "llfloateravatarinfo.h"
#include "llfloateravatartextures.h"
#include "llfloaterbuildoptions.h"
@@ -84,21 +79,17 @@
#include "llfloaterhtml.h"
#include "llfloaterhtmlhelp.h"
#include "llfloaterhtmlfind.h"
-#include "llfloaterimport.h"
#include "llfloaterinspect.h"
#include "llfloaterland.h"
#include "llfloaterlandholdings.h"
#include "llfloatermap.h"
-#include "llfloaterimagepreview.h"
#include "llfloatermute.h"
-#include "llfloaternamedesc.h"
#include "llfloateropenobject.h"
#include "llfloaterpermissionsmgr.h"
#include "llfloaterpreference.h"
#include "llfloaterregioninfo.h"
#include "llfloaterreporter.h"
#include "llfloaterscriptdebug.h"
-#include "llfloatersnapshot.h"
#include "llfloatertest.h"
#include "llfloatertools.h"
#include "llfloaterworldmap.h"
@@ -127,8 +118,6 @@
#include "llnotify.h"
#include "llpanelobject.h"
#include "llparcel.h"
-#include "llpreviewscript.h"
-#include "llpreviewtexture.h"
#include "llprimitive.h"
#include "llresmgr.h"
#include "llselectmgr.h"
@@ -156,8 +145,8 @@
#include "llviewercamera.h"
#include "llviewergenericmessage.h"
#include "llviewergesture.h"
-#include "llviewerimagelist.h"
#include "llviewerinventory.h"
+#include "llviewermenufile.h" // init_menu_file()
#include "llviewermessage.h"
#include "llviewernetwork.h"
#include "llviewerobjectlist.h"
@@ -382,7 +371,6 @@ void handle_god_request_avatar_geometry(void *); // Hack for easy testing of new
void reload_personal_settings_overrides(void *);
void force_breakpoint(void *);
void reload_vertex_shader(void *);
-void flush_animations(void *);
void slow_mo_animations(void *);
void handle_disconnect_viewer(void *);
@@ -447,6 +435,7 @@ void handle_dump_avatar_local_textures(void*);
void handle_debug_avatar_textures(void*);
void handle_grab_texture(void*);
BOOL enable_grab_texture(void*);
+void handle_dump_region_object_cache(void*);
BOOL menu_ui_enabled(void *user_data);
void check_toggle_control( LLUICtrl *, void* user_data );
@@ -517,7 +506,7 @@ void pre_init_menus()
LLMenuItemGL::setHighlightFGColor( color );
}
-void initialize_menu_actions();
+void initialize_menus();
//-----------------------------------------------------------------------------
// Initialize main menus
@@ -545,7 +534,7 @@ void init_menus()
LLMenuGL::sMenuContainer = gMenuHolder;
// Initialize actions
- initialize_menu_actions();
+ initialize_menus();
///
/// Popup menu
@@ -945,6 +934,8 @@ void init_debug_world_menu(LLMenuGL* menu)
NULL,
&menu_check_control,
(void*)"FixedWeather"));
+ menu->append(new LLMenuItemCallGL("Dump Region Object Cache",
+ &handle_dump_region_object_cache, NULL, NULL));
menu->createJumpKeys();
}
@@ -1273,7 +1264,6 @@ void init_debug_avatar_menu(LLMenuGL* menu)
menu->append(new LLMenuItemCallGL("Force Params to Default", &LLAgent::clearVisualParams, NULL));
menu->append(new LLMenuItemCallGL("Reload Vertex Shader", &reload_vertex_shader, NULL));
menu->append(new LLMenuItemToggleGL("Animation Info", &LLVOAvatar::sShowAnimationDebug));
- menu->append(new LLMenuItemCallGL("Flush Animations", &flush_animations, NULL));
menu->append(new LLMenuItemCallGL("Slow Motion Animations", &slow_mo_animations, NULL));
menu->append(new LLMenuItemToggleGL("Show Look At", &LLHUDEffectLookAt::sDebugLookAt));
menu->append(new LLMenuItemToggleGL("Show Point At", &LLHUDEffectPointAt::sDebugPointAt));
@@ -2021,13 +2011,13 @@ class LLAvatarDebug : public view_listener_t
if( avatar )
{
avatar->dumpLocalTextures();
+ llinfos << "Dumping temporary asset data to simulator logs for avatar " << avatar->getID() << llendl;
+ std::vector<std::string> strings;
+ strings.push_back(avatar->getID().asString());
+ LLUUID invoice;
+ send_generic_message("dumptempassetdata", strings, invoice);
+ LLFloaterAvatarTextures::show( avatar->getID() );
}
- llinfos << "Dumping temporary asset data to simulator logs for avatar " << avatar->getID() << llendl;
- std::vector<std::string> strings;
- strings.push_back(avatar->getID().asString());
- LLUUID invoice;
- send_generic_message("dumptempassetdata", strings, invoice);
- LLFloaterAvatarTextures::show( avatar->getID() );
return true;
}
};
@@ -2317,16 +2307,6 @@ void handle_buy_contents(LLSaleInfo sale_info)
LLFloaterBuyContents::show(sale_info);
}
-class LLFileEnableSaveAs : public view_listener_t
-{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
- {
- bool new_value = gFloaterView->getFrontmost() && gFloaterView->getFrontmost()->canSaveAs();
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
- return true;
- }
-};
-
void handle_region_dump_temp_asset_data(void*)
{
llinfos << "Dumping temporary asset data to simulator logs" << llendl;
@@ -2377,6 +2357,15 @@ void handle_dump_capabilities_info(void *)
}
}
+void handle_dump_region_object_cache(void*)
+{
+ LLViewerRegion* regionp = gAgent.getRegion();
+ if (regionp)
+ {
+ regionp->dumpCache();
+ }
+}
+
void handle_dump_focus(void *)
{
LLView *view = gFocusMgr.getKeyboardFocus();
@@ -4259,7 +4248,10 @@ void show_buy_currency(const char* extra)
mesg << "Go to " << BUY_CURRENCY_URL << "\nfor information on purchasing currency?";
LLString::format_map_t args;
- args["[EXTRA]"] = extra;
+ if (extra != NULL)
+ {
+ args["[EXTRA]"] = extra;
+ }
args["[URL]"] = BUY_CURRENCY_URL;
gViewerWindow->alertXml("PromptGoToCurrencyPage", args,
callback_show_buy_currency);
@@ -4856,906 +4848,6 @@ void toggle_map( void* user_data )
}
}
-/**
- char* upload_pick(void* data)
-
- If applicable, brings up a file chooser in which the user selects a file
- to upload for a particular task. If the file is valid for the given action,
- returns the string to the full path filename, else returns NULL.
- Data is the load filter for the type of file as defined in LLFilePicker.
-**/
-const char* upload_pick(void* data)
-{
- if( gAgent.cameraMouselook() )
- {
- gAgent.changeCameraToDefault();
- // This doesn't seem necessary. JC
- // display();
- }
-
- LLFilePicker::ELoadFilter type;
- if(data)
- {
- type = (LLFilePicker::ELoadFilter)((intptr_t)data);
- }
- else
- {
- type = LLFilePicker::FFLOAD_ALL;
- }
-
- LLFilePicker& picker = LLFilePicker::instance();
- if (!picker.getOpenFile(type))
- {
- llinfos << "Couldn't import objects from file" << llendl;
- return NULL;
- }
-
- const char* filename = picker.getFirstFile();
- const char* ext = strrchr(filename, '.');
-
- //strincmp doesn't like NULL pointers
- if (ext == NULL)
- {
- const char* short_name = strrchr(filename,
- *gDirUtilp->getDirDelimiter().c_str());
-
- // No extension
- LLStringBase<char>::format_map_t args;
- args["[FILE]"] = LLString(short_name + 1);
- gViewerWindow->alertXml("NoFileExtension", args);
- return NULL;
- }
- else
- {
- //so there is an extension
- //loop over the valid extensions and compare to see
- //if the extension is valid
-
- //now grab the set of valid file extensions
- const char* valids = build_extensions_string(type);
- std::string valid_extensions = std::string(valids);
-
- BOOL ext_valid = FALSE;
-
- typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
- boost::char_separator<char> sep(" ");
- tokenizer tokens(valid_extensions, sep);
- tokenizer::iterator token_iter;
-
- //now loop over all valid file extensions
- //and compare them to the extension of the file
- //to be uploaded
- for( token_iter = tokens.begin();
- token_iter != tokens.end() && ext_valid != TRUE;
- ++token_iter)
- {
- const char* cur_token = token_iter->c_str();
-
- if (0 == strnicmp(cur_token, ext, strlen(cur_token)) || /* Flawfinder: ignore */
- 0 == strnicmp(cur_token, "*.*", strlen(cur_token))) /* Flawfinder: ignore */
- {
- //valid extension
- //or the acceptable extension is any
- ext_valid = TRUE;
- }
- }//end for (loop over all tokens)
-
- if (ext_valid == FALSE)
- {
- //should only get here if the extension exists
- //but is invalid
- LLStringBase<char>::format_map_t args;
- args["[EXTENSION]"] = ext;
- args["[VALIDS]"] = valids;
- gViewerWindow->alertXml("InvalidFileExtension", args);
- return NULL;
- }
- }//end else (non-null extension)
-
- //valid file extension
-
- //now we check to see
- //if the file is actually a valid image/sound/etc.
- if (type == LLFilePicker::FFLOAD_WAV)
- {
- // pre-qualify wavs to make sure the format is acceptable
- char error_msg[MAX_STRING]; /* Flawfinder: ignore */
- if (check_for_invalid_wav_formats(filename,error_msg))
- {
- llinfos << error_msg << ": " << filename << llendl;
- LLStringBase<char>::format_map_t args;
- args["[FILE]"] = filename;
- gViewerWindow->alertXml( error_msg, args );
- return NULL;
- }
- }//end if a wave/sound file
-
-
- return filename;
-}
-
-void handle_upload_object(void* data)
-{
- const char* filename = upload_pick(data);
- if (filename)
- {
- // start the import
- LLFloaterImport* floaterp = new LLFloaterImport(filename);
- gUICtrlFactory->buildFloater(floaterp, "floater_import.xml");
- }
-}
-
-class LLFileUploadImage : public view_listener_t
-{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
- {
- const char* filename = upload_pick((void *)(S32)LLFilePicker::FFLOAD_IMAGE);
- if (filename)
- {
- LLFloaterImagePreview* floaterp = new LLFloaterImagePreview(filename);
- gUICtrlFactory->buildFloater(floaterp, "floater_image_preview.xml");
- }
- return TRUE;
- }
-};
-
-class LLFileUploadSound : public view_listener_t
-{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
- {
- const char* filename = upload_pick((void*)((S32)LLFilePicker::FFLOAD_WAV));
- if (filename)
- {
- LLFloaterNameDesc* floaterp = new LLFloaterNameDesc(filename);
- gUICtrlFactory->buildFloater(floaterp, "floater_sound_preview.xml");
- }
- return true;
- }
-};
-
-class LLFileUploadAnim : public view_listener_t
-{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
- {
- const char* filename = upload_pick((void*)((S32)LLFilePicker::FFLOAD_ANIM));
- if (filename)
- {
- LLFloaterAnimPreview* floaterp = new LLFloaterAnimPreview(filename);
- gUICtrlFactory->buildFloater(floaterp, "floater_animation_preview.xml");
- }
- return true;
- }
-};
-
-class LLFileUploadBulk : public view_listener_t
-{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
- {
- if( gAgent.cameraMouselook() )
- {
- gAgent.changeCameraToDefault();
- }
-
- // TODO:
- // Iterate over all files
- // Check extensions for uploadability, cost
- // Check user balance for entire cost
- // Charge user entire cost
- // Loop, uploading
- // If an upload fails, refund the user for that one
- //
- // Also fix single upload to charge first, then refund
-
- LLFilePicker& picker = LLFilePicker::instance();
- if (picker.getMultipleOpenFiles())
- {
- const char* filename = picker.getFirstFile();
- const char* name = picker.getDirname();
-
- LLString asset_name = name;
- LLString::replaceNonstandardASCII( asset_name, '?' );
- LLString::replaceChar(asset_name, '|', '?');
- LLString::stripNonprintable(asset_name);
- LLString::trim(asset_name);
-
- char* asset_name_str = (char*)asset_name.c_str();
- char* end_p = strrchr(asset_name_str, '.'); // strip extension if exists
- if( !end_p )
- {
- end_p = asset_name_str + strlen( asset_name_str ); /* Flawfinder: ignore */
- }
-
- S32 len = llmin( (S32) (DB_INV_ITEM_NAME_STR_LEN), (S32) (end_p - asset_name_str) );
-
- asset_name = asset_name.substr( 0, len );
-
- upload_new_resource(filename, asset_name, asset_name, 0, LLAssetType::AT_NONE, LLInventoryType::IT_NONE); // file
- }
- else
- {
- llinfos << "Couldn't import objects from file" << llendl;
- }
- return true;
- }
-};
-
-void upload_error(const char* error_message, const char* label, const std::string filename, const LLStringBase<char>::format_map_t args)
-{
- llwarns << error_message << llendl;
- gViewerWindow->alertXml(label, args);
- if(remove(filename.c_str()) == -1)
- {
- lldebugs << "unable to remove temp file" << llendl;
- }
- LLFilePicker::instance().reset();
-}
-
-class LLFileEnableCloseWindow : public view_listener_t
-{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
- {
- bool new_value = gFloaterView->getFocusedFloater() != NULL || gSnapshotFloaterView->getFocusedFloater() != NULL;
- // horrendously opaque, this code
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
- return true;
- }
-};
-
-class LLFileCloseWindow : public view_listener_t
-{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
- {
- LLFloater::closeFocusedFloater();
-
- return true;
- }
-};
-
-class LLFileSaveTexture : public view_listener_t
-{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
- {
- LLFloater* top = gFloaterView->getFrontmost();
- if (top)
- {
- top->saveAs();
- }
- return true;
- }
-};
-
-class LLFileTakeSnapshot : public view_listener_t
-{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
- {
- LLFloaterSnapshot::show(NULL);
- return true;
- }
-};
-
-class LLFileTakeSnapshotToDisk : public view_listener_t
-{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
- {
- LLPointer<LLImageRaw> raw = new LLImageRaw;
-
- S32 width = gViewerWindow->getWindowDisplayWidth();
- S32 height = gViewerWindow->getWindowDisplayHeight();
-
- if (gSavedSettings.getBOOL("HighResSnapshot"))
- {
- width *= 2;
- height *= 2;
- }
-
- if (gViewerWindow->rawSnapshot(raw,
- width,
- height,
- TRUE,
- gSavedSettings.getBOOL("RenderUIInSnapshot"),
- FALSE))
- {
- if (!gQuietSnapshot)
- {
- gViewerWindow->playSnapshotAnimAndSound();
- }
- LLImageBase::setSizeOverride(TRUE);
- gViewerWindow->saveImageNumbered(raw);
- LLImageBase::setSizeOverride(FALSE);
- }
- return true;
- }
-};
-
-class LLFileSaveMovie : public view_listener_t
-{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
- {
- LLViewerWindow::saveMovieNumbered(NULL);
- return true;
- }
-};
-
-class LLFileSetWindowSize : public view_listener_t
-{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
- {
- LLString size = userdata.asString();
- S32 width, height;
- sscanf(size.c_str(), "%d,%d", &width, &height);
- LLViewerWindow::movieSize(width, height);
- return true;
- }
-};
-
-class LLFileQuit : public view_listener_t
-{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
- {
- app_request_quit();
- return true;
- }
-};
-
-void handle_upload(void* data)
-{
- const char* filename = upload_pick(data);
- if (filename)
- {
- LLFloaterNameDesc* floaterp = new LLFloaterNameDesc(filename);
- gUICtrlFactory->buildFloater(floaterp, "floater_name_description.xml");
- }
-}
-
-void handle_compress_image(void*)
-{
- LLFilePicker& picker = LLFilePicker::instance();
- if (picker.getOpenFile(LLFilePicker::FFLOAD_IMAGE))
- {
- std::string infile(picker.getFirstFile());
- std::string outfile = infile + ".j2c";
-
- llinfos << "Input: " << infile << llendl;
- llinfos << "Output: " << outfile << llendl;
-
- BOOL success;
-
- success = LLViewerImageList::createUploadFile(infile, outfile, IMG_CODEC_TGA);
-
- if (success)
- {
- llinfos << "Compression complete" << llendl;
- }
- else
- {
- llinfos << "Compression failed: " << LLImageBase::getLastError() << llendl;
- }
- }
-}
-
-void upload_new_resource(const LLString& src_filename, std::string name,
- std::string desc, S32 compression_info,
- LLAssetType::EType destination_folder_type,
- LLInventoryType::EType inv_type,
- U32 next_owner_perm,
- const LLString& display_name,
- LLAssetStorage::LLStoreAssetCallback callback,
- void *userdata)
-{
- // Generate the temporary UUID.
- LLString filename = gDirUtilp->getTempFilename();
- LLTransactionID tid;
- LLAssetID uuid;
-
- LLStringBase<char>::format_map_t args;
-
- LLString ext = src_filename.substr(src_filename.find_last_of('.'));
- LLAssetType::EType asset_type = LLAssetType::AT_NONE;
- char error_message[MAX_STRING]; /* Flawfinder: ignore */
- error_message[0] = '\0';
- LLString temp_str;
-
- BOOL error = FALSE;
-
- if (ext.empty())
- {
- LLString::size_type offset = filename.find_last_of(gDirUtilp->getDirDelimiter());
- if (offset != LLString::npos)
- offset++;
- LLString short_name = filename.substr(offset);
-
- // No extension
- snprintf(error_message, /* Flawfinder: ignore */
- MAX_STRING,
- "No file extension for the file: '%s'\nPlease make sure the file has a correct file extension",
- short_name.c_str());
- args["[FILE]"] = short_name;
- upload_error(error_message, "NofileExtension", filename, args);
- return;
- }
- else if( LLString::compareInsensitive(ext.c_str(),".bmp") == 0 )
- {
- asset_type = LLAssetType::AT_TEXTURE;
- if (!LLViewerImageList::createUploadFile(src_filename,
- filename,
- IMG_CODEC_BMP ))
- {
- snprintf(error_message, MAX_STRING, "Problem with file %s:\n\n%s\n", /* Flawfinder: ignore */
- src_filename.c_str(), LLImageBase::getLastError().c_str());
- args["[FILE]"] = src_filename;
- args["[ERROR]"] = LLImageBase::getLastError();
- upload_error(error_message, "ProblemWithFile", filename, args);
- return;
- }
- }
- else if( LLString::compareInsensitive(ext.c_str(),".tga") == 0 )
- {
- asset_type = LLAssetType::AT_TEXTURE;
- if (!LLViewerImageList::createUploadFile(src_filename,
- filename,
- IMG_CODEC_TGA ))
- {
- snprintf(error_message, MAX_STRING, "Problem with file %s:\n\n%s\n", /* Flawfinder: ignore */
- src_filename.c_str(), LLImageBase::getLastError().c_str());
- args["[FILE]"] = src_filename;
- args["[ERROR]"] = LLImageBase::getLastError();
- upload_error(error_message, "ProblemWithFile", filename, args);
- return;
- }
- }
- else if( LLString::compareInsensitive(ext.c_str(),".jpg") == 0 || LLString::compareInsensitive(ext.c_str(),".jpeg") == 0)
- {
- asset_type = LLAssetType::AT_TEXTURE;
- if (!LLViewerImageList::createUploadFile(src_filename,
- filename,
- IMG_CODEC_JPEG ))
- {
- snprintf(error_message, MAX_STRING, "Problem with file %s:\n\n%s\n", /* Flawfinder: ignore */
- src_filename.c_str(), LLImageBase::getLastError().c_str());
- args["[FILE]"] = src_filename;
- args["[ERROR]"] = LLImageBase::getLastError();
- upload_error(error_message, "ProblemWithFile", filename, args);
- return;
- }
- }
- else if(LLString::compareInsensitive(ext.c_str(),".wav") == 0)
- {
- asset_type = LLAssetType::AT_SOUND; // tag it as audio
- S32 encode_result = 0;
-
- S32 bitrate = 128;
-
- if (compression_info)
- {
- bitrate = compression_info;
- }
- llinfos << "Attempting to encode wav as an ogg file at " << bitrate << "kbps" << llendl;
-
- encode_result = encode_vorbis_file_at(src_filename.c_str(), filename.c_str(), bitrate*1000);
-
- if (LLVORBISENC_NOERR != encode_result)
- {
- switch(encode_result)
- {
- case LLVORBISENC_DEST_OPEN_ERR:
- snprintf(error_message, MAX_STRING, "Couldn't open temporary compressed sound file for writing: %s\n", filename.c_str()); /* Flawfinder: ignore */
- args["[FILE]"] = filename;
- upload_error(error_message, "CannotOpenTemporarySoundFile", filename, args);
- break;
-
- default:
- snprintf(error_message, MAX_STRING, "Unknown vorbis encode failure on: %s\n", src_filename.c_str()); /* Flawfinder: ignore */
- args["[FILE]"] = src_filename;
- upload_error(error_message, "UnknownVorbisEncodeFailure", filename, args);
- break;
- }
- return;
- }
- }
- else if(LLString::compareInsensitive(ext.c_str(),".tmp") == 0)
- {
- // This is a generic .lin resource file
- asset_type = LLAssetType::AT_OBJECT;
- FILE* in = LLFile::fopen(src_filename.c_str(), "rb"); /* Flawfinder: ignore */
- if (in)
- {
- // read in the file header
- char buf[16384]; /* Flawfinder: ignore */
- S32 read; /* Flawfinder: ignore */
- S32 version;
- if (fscanf(in, "LindenResource\nversion %d\n", &version))
- {
- if (2 == version)
- {
- // *NOTE: This buffer size is hard coded into scanf() below.
- char label[MAX_STRING]; /* Flawfinder: ignore */
- char value[MAX_STRING]; /* Flawfinder: ignore */
- S32 tokens_read;
- while (fgets(buf, 1024, in))
- {
- label[0] = '\0';
- value[0] = '\0';
- tokens_read = sscanf( /* Flawfinder: ignore */
- buf,
- "%254s %254s\n",
- label, value);
-
- llinfos << "got: " << label << " = " << value
- << llendl;
-
- if (EOF == tokens_read)
- {
- fclose(in);
- snprintf(error_message, MAX_STRING, "corrupt resource file: %s", src_filename.c_str()); /* Flawfinder: ignore */
- args["[FILE]"] = src_filename;
- upload_error(error_message, "CorruptResourceFile", filename, args);
- return;
- }
-
- if (2 == tokens_read)
- {
- if (! strcmp("type", label))
- {
- asset_type = (LLAssetType::EType)(atoi(value));
- }
- }
- else
- {
- if (! strcmp("_DATA_", label))
- {
- // below is the data section
- break;
- }
- }
- // other values are currently discarded
- }
-
- }
- else
- {
- fclose(in);
- snprintf(error_message, MAX_STRING, "unknown linden resource file version in file: %s", src_filename.c_str()); /* Flawfinder: ignore */
- args["[FILE]"] = src_filename;
- upload_error(error_message, "UnknownResourceFileVersion", filename, args);
- return;
- }
- }
- else
- {
- // this is an original binary formatted .lin file
- // start over at the beginning of the file
- fseek(in, 0, SEEK_SET);
-
- const S32 MAX_ASSET_DESCRIPTION_LENGTH = 256;
- const S32 MAX_ASSET_NAME_LENGTH = 64;
- S32 header_size = 34 + MAX_ASSET_DESCRIPTION_LENGTH + MAX_ASSET_NAME_LENGTH;
- S16 type_num;
-
- // read in and throw out most of the header except for the type
- fread(buf, header_size, 1, in);
- memcpy(&type_num, buf + 16, sizeof(S16)); /* Flawfinder: ignore */
- asset_type = (LLAssetType::EType)type_num;
- }
-
- // copy the file's data segment into another file for uploading
- FILE* out = LLFile::fopen(filename.c_str(), "wb"); /* Flawfinder: ignore */
- if (out)
- {
- while((read = fread(buf, 1, 16384, in))) /* Flawfinder: ignore */
- {
- fwrite(buf, 1, read, out); /* Flawfinder: ignore */
- }
- fclose(out);
- }
- else
- {
- fclose(in);
- snprintf(error_message, MAX_STRING, "Unable to create output file: %s", filename.c_str()); /* Flawfinder: ignore */
- args["[FILE]"] = filename;
- upload_error(error_message, "UnableToCreateOutputFile", filename, args);
- return;
- }
-
- fclose(in);
- }
- else
- {
- llinfos << "Couldn't open .lin file " << src_filename << llendl;
- }
- }
- else if (LLString::compareInsensitive(ext.c_str(),".bvh") == 0)
- {
- snprintf(error_message, MAX_STRING, "We do not currently support bulk upload of animation files\n"); /* Flawfinder: ignore */
- upload_error(error_message, "DoNotSupportBulkAnimationUpload", filename, args);
- return;
- }
- else
- {
- // Unknown extension
- snprintf(error_message, MAX_STRING, "Unknown file extension %s\nExpected .wav, .tga, .bmp, .jpg, .jpeg, or .bvh", ext.c_str()); /* Flawfinder: ignore */
- error = TRUE;;
- }
-
- // gen a new transaction ID for this asset
- tid.generate();
-
- if (!error)
- {
- uuid = tid.makeAssetID(gAgent.getSecureSessionID());
- // copy this file into the vfs for upload
- S32 file_size;
- apr_file_t* fp = ll_apr_file_open(filename, LL_APR_RB, &file_size);
- if (fp)
- {
- LLVFile file(gVFS, uuid, asset_type, LLVFile::WRITE);
-
- file.setMaxSize(file_size);
-
- const S32 buf_size = 65536;
- U8 copy_buf[buf_size];
- while ((file_size = ll_apr_file_read(fp, copy_buf, buf_size)))
- {
- file.write(copy_buf, file_size);
- }
- apr_file_close(fp);
- }
- else
- {
- snprintf(error_message, MAX_STRING, "Unable to access output file: %s", filename.c_str()); /* Flawfinder: ignore */
- error = TRUE;
- }
- }
-
- if (!error)
- {
- LLString t_disp_name = display_name;
- if (t_disp_name.empty())
- {
- t_disp_name = src_filename;
- }
- upload_new_resource(tid, asset_type, name, desc, compression_info, // tid
- destination_folder_type, inv_type, next_owner_perm,
- display_name, callback, userdata);
- }
- else
- {
- llwarns << error_message << llendl;
- LLStringBase<char>::format_map_t args;
- args["[ERROR_MESSAGE]"] = error_message;
- gViewerWindow->alertXml("ErrorMessage", args);
- if(LLFile::remove(filename.c_str()) == -1)
- {
- lldebugs << "unable to remove temp file" << llendl;
- }
- LLFilePicker::instance().reset();
- }
-}
-
-void upload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_type,
- std::string name,
- std::string desc, S32 compression_info,
- LLAssetType::EType destination_folder_type,
- LLInventoryType::EType inv_type,
- U32 next_owner_perm,
- const LLString& display_name,
- LLAssetStorage::LLStoreAssetCallback callback,
- void *userdata)
-{
- LLAssetID uuid = tid.makeAssetID(gAgent.getSecureSessionID());
-
- if( LLAssetType::AT_SOUND == asset_type )
- {
- gViewerStats->incStat(LLViewerStats::ST_UPLOAD_SOUND_COUNT );
- }
- else
- if( LLAssetType::AT_TEXTURE == asset_type )
- {
- gViewerStats->incStat(LLViewerStats::ST_UPLOAD_TEXTURE_COUNT );
- }
- else
- if( LLAssetType::AT_ANIMATION == asset_type)
- {
- gViewerStats->incStat(LLViewerStats::ST_UPLOAD_ANIM_COUNT );
- }
-
- if(LLInventoryType::IT_NONE == inv_type)
- {
- inv_type = LLInventoryType::defaultForAssetType(asset_type);
- }
- LLString::stripNonprintable(name);
- LLString::stripNonprintable(desc);
- if(name.empty())
- {
- name = "(No Name)";
- }
- if(desc.empty())
- {
- desc = "(No Description)";
- }
-
- // At this point, we're ready for the upload.
- LLString upload_message = "Uploading...\n\n";
- upload_message.append(display_name);
- LLUploadDialog::modalUploadDialog(upload_message);
-
- llinfos << "*** Uploading: " << llendl;
- llinfos << "Type: " << LLAssetType::lookup(asset_type) << llendl;
- llinfos << "UUID: " << uuid << llendl;
- llinfos << "Name: " << name << llendl;
- llinfos << "Desc: " << desc << llendl;
- lldebugs << "Folder: " << gInventory.findCategoryUUIDForType(destination_folder_type) << llendl;
- lldebugs << "Asset Type: " << LLAssetType::lookup(asset_type) << llendl;
- std::string url = gAgent.getRegion()->getCapability("NewFileAgentInventory");
- if (!url.empty())
- {
- llinfos << "New Agent Inventory via capability" << llendl;
- LLSD body;
- body["folder_id"] = gInventory.findCategoryUUIDForType((destination_folder_type == LLAssetType::AT_NONE) ? asset_type : destination_folder_type);
- body["asset_type"] = LLAssetType::lookup(asset_type);
- body["inventory_type"] = LLInventoryType::lookup(inv_type);
- body["name"] = name;
- body["description"] = desc;
-
- std::ostringstream llsdxml;
- LLSDSerialize::toXML(body, llsdxml);
- lldebugs << "posting body to capability: " << llsdxml.str() << llendl;
- LLHTTPClient::post(url, body, new LLNewAgentInventoryResponder(body, uuid, asset_type));
- }
- else
- {
- llinfos << "NewAgentInventory capability not found, new agent inventory via asset system." << llendl;
- // check for adequate funds
- // TODO: do this check on the sim
- if (LLAssetType::AT_SOUND == asset_type ||
- LLAssetType::AT_TEXTURE == asset_type ||
- LLAssetType::AT_ANIMATION == asset_type)
- {
- S32 upload_cost = gGlobalEconomy->getPriceUpload();
- S32 balance = gStatusBar->getBalance();
- if (balance < upload_cost)
- {
- // insufficient funds, bail on this upload
- LLFloaterBuyCurrency::buyCurrency("Uploading costs", upload_cost);
- return;
- }
- }
-
- LLResourceData* data = new LLResourceData;
- data->mAssetInfo.mTransactionID = tid;
- data->mAssetInfo.mUuid = uuid;
- data->mAssetInfo.mType = asset_type;
- data->mAssetInfo.mCreatorID = gAgentID;
- data->mInventoryType = inv_type;
- data->mNextOwnerPerm = next_owner_perm;
- data->mUserData = userdata;
- data->mAssetInfo.setName(name);
- data->mAssetInfo.setDescription(desc);
- data->mPreferredLocation = destination_folder_type;
-
- LLAssetStorage::LLStoreAssetCallback asset_callback = &upload_done_callback;
- if (callback)
- {
- asset_callback = callback;
- }
- gAssetStorage->storeAssetData(data->mAssetInfo.mTransactionID, data->mAssetInfo.mType,
- asset_callback,
- (void*)data,
- FALSE);
- }
-}
-
-void upload_done_callback(const LLUUID& uuid, void* user_data, S32 result) // StoreAssetData callback (fixed)
-{
- LLResourceData* data = (LLResourceData*)user_data;
- //LLAssetType::EType pref_loc = data->mPreferredLocation;
- BOOL is_balance_sufficient = TRUE;
- if(result >= 0)
- {
- LLAssetType::EType dest_loc = (data->mPreferredLocation == LLAssetType::AT_NONE) ? data->mAssetInfo.mType : data->mPreferredLocation;
-
- if (LLAssetType::AT_SOUND == data->mAssetInfo.mType ||
- LLAssetType::AT_TEXTURE == data->mAssetInfo.mType ||
- LLAssetType::AT_ANIMATION == data->mAssetInfo.mType)
- {
- // Charge the user for the upload.
- LLViewerRegion* region = gAgent.getRegion();
- S32 upload_cost = gGlobalEconomy->getPriceUpload();
-
- if(!(can_afford_transaction(upload_cost)))
- {
- LLFloaterBuyCurrency::buyCurrency(
- llformat("Uploading %s costs",
- data->mAssetInfo.getName().c_str()),
- upload_cost);
- is_balance_sufficient = FALSE;
- }
- else if(region)
- {
- // Charge user for upload
- gStatusBar->debitBalance(upload_cost);
-
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessageFast(_PREHASH_MoneyTransferRequest);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->nextBlockFast(_PREHASH_MoneyData);
- msg->addUUIDFast(_PREHASH_SourceID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_DestID, LLUUID::null);
- msg->addU8("Flags", 0);
- msg->addS32Fast(_PREHASH_Amount, upload_cost);
- msg->addU8Fast(_PREHASH_AggregatePermNextOwner, (U8)LLAggregatePermissions::AP_EMPTY);
- msg->addU8Fast(_PREHASH_AggregatePermInventory, (U8)LLAggregatePermissions::AP_EMPTY);
- msg->addS32Fast(_PREHASH_TransactionType, TRANS_UPLOAD_CHARGE);
- msg->addStringFast(_PREHASH_Description, NULL);
- msg->sendReliable(region->getHost());
- }
- }
-
- if(is_balance_sufficient)
- {
- // Actually add the upload to inventory
- llinfos << "Adding " << uuid << " to inventory." << llendl;
- LLUUID folder_id(gInventory.findCategoryUUIDForType(dest_loc));
- if(folder_id.notNull())
- {
- U32 next_owner_perm = data->mNextOwnerPerm;
- if(PERM_NONE == next_owner_perm)
- {
- next_owner_perm = PERM_MOVE | PERM_TRANSFER;
- }
- create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
- folder_id, data->mAssetInfo.mTransactionID, data->mAssetInfo.getName(),
- data->mAssetInfo.getDescription(), data->mAssetInfo.mType,
- data->mInventoryType, NOT_WEARABLE, next_owner_perm,
- LLPointer<LLInventoryCallback>(NULL));
- }
- else
- {
- llwarns << "Can't find a folder to put it in" << llendl;
- }
- }
- }
- else // if(result >= 0)
- {
- LLStringBase<char>::format_map_t args;
- args["[FILE]"] = LLInventoryType::lookupHumanReadable(data->mInventoryType);
- args["[REASON]"] = LLString(LLAssetStorage::getErrorString(result));
- gViewerWindow->alertXml("CannotUploadReason", args);
- }
-
- LLUploadDialog::modalUploadFinished();
- delete data;
-
- // *NOTE: This is a pretty big hack. What this does is check the
- // file picker if there are any more pending uploads. If so,
- // upload that file.
- const char* next_file = LLFilePicker::instance().getNextFile();
- if(is_balance_sufficient && next_file)
- {
- const char* name = LLFilePicker::instance().getDirname();
-
- LLString asset_name = name;
- LLString::replaceNonstandardASCII( asset_name, '?' );
- LLString::replaceChar(asset_name, '|', '?');
- LLString::stripNonprintable(asset_name);
- LLString::trim(asset_name);
-
- char* asset_name_str = (char*)asset_name.c_str();
- char* end_p = strrchr(asset_name_str, '.'); // strip extension if exists
- if( !end_p )
- {
- end_p = asset_name_str + strlen( asset_name_str ); /* Flawfinder: ignore */
- }
-
- S32 len = llmin( (S32) (DB_INV_ITEM_NAME_STR_LEN), (S32) (end_p - asset_name_str) );
-
- asset_name = asset_name.substr( 0, len );
-
- upload_new_resource(next_file, asset_name, asset_name, // file
- 0, LLAssetType::AT_NONE, LLInventoryType::IT_NONE);
- }
-}
LLUUID gExporterRequestID;
LLString gExportDirectory;
@@ -7614,15 +6706,6 @@ BOOL enable_not_thirdperson(void*)
return !gAgent.cameraThirdPerson();
}
-class LLFileEnableUpload : public view_listener_t
-{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
- {
- bool new_value = gStatusBar && gGlobalEconomy && (gStatusBar->getBalance() >= gGlobalEconomy->getPriceUpload());
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
- return true;
- }
-};
BOOL enable_export_selected(void *)
{
@@ -7837,14 +6920,6 @@ void reload_vertex_shader(void *)
//THIS WOULD BE AN AWESOME PLACE TO RELOAD SHADERS... just a thought - DaveP
}
-void flush_animations(void *)
-{
- if (gAgent.getAvatarObject())
- {
- gAgent.getAvatarObject()->resetAnimations();
- }
-}
-
void slow_mo_animations(void*)
{
static BOOL slow_mo = FALSE;
@@ -8430,24 +7505,10 @@ class LLToolsSelectTool : public view_listener_t
}
};
-void initialize_menu_actions()
+void initialize_menus()
{
// File menu
- (new LLFileUploadImage())->registerListener(gMenuHolder, "File.UploadImage");
- (new LLFileUploadSound())->registerListener(gMenuHolder, "File.UploadSound");
- (new LLFileUploadAnim())->registerListener(gMenuHolder, "File.UploadAnim");
- (new LLFileUploadBulk())->registerListener(gMenuHolder, "File.UploadBulk");
- (new LLFileCloseWindow())->registerListener(gMenuHolder, "File.CloseWindow");
- (new LLFileEnableCloseWindow())->registerListener(gMenuHolder, "File.EnableCloseWindow");
- (new LLFileSaveTexture())->registerListener(gMenuHolder, "File.SaveTexture");
- (new LLFileTakeSnapshot())->registerListener(gMenuHolder, "File.TakeSnapshot");
- (new LLFileTakeSnapshotToDisk())->registerListener(gMenuHolder, "File.TakeSnapshotToDisk");
- (new LLFileSaveMovie())->registerListener(gMenuHolder, "File.SaveMovie");
- (new LLFileSetWindowSize())->registerListener(gMenuHolder, "File.SetWindowSize");
- (new LLFileQuit())->registerListener(gMenuHolder, "File.Quit");
-
- (new LLFileEnableUpload())->registerListener(gMenuHolder, "File.EnableUpload");
- (new LLFileEnableSaveAs())->registerListener(gMenuHolder, "File.EnableSaveAs");
+ init_menu_file();
// Edit menu
(new LLEditUndo())->registerListener(gMenuHolder, "Edit.Undo");
diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h
index 70d34c73c3..2c6cbe7734 100644
--- a/indra/newview/llviewermenu.h
+++ b/indra/newview/llviewermenu.h
@@ -9,8 +9,6 @@
#ifndef LL_LLVIEWERMENU_H
#define LL_LLVIEWERMENU_H
-#include "llassetstorage.h"
-#include "llinventory.h"
#include "llmenugl.h"
//newview includes
@@ -21,14 +19,6 @@ class LLView;
class LLParcelSelection;
class LLObjectSelection;
-struct LLResourceData
-{
- LLAssetInfo mAssetInfo;
- LLAssetType::EType mPreferredLocation;
- LLInventoryType::EType mInventoryType;
- U32 mNextOwnerPerm;
- void *mUserData;
-};
void pre_init_menus();
void init_menus();
@@ -94,25 +84,6 @@ bool handle_give_money_dialog();
bool handle_object_open();
bool handle_go_to();
-void upload_new_resource(const LLString& src_filename, std::string name,
- std::string desc, S32 compression_info,
- LLAssetType::EType destination_folder_type,
- LLInventoryType::EType inv_type,
- U32 next_owner_perm = PERM_NONE,
- const LLString& display_name = LLString::null,
- LLAssetStorage::LLStoreAssetCallback callback = NULL,
- void *userdata = NULL);
-
-void upload_new_resource(const LLTransactionID &tid, LLAssetType::EType type,
- std::string name,
- std::string desc, S32 compression_info,
- LLAssetType::EType destination_folder_type,
- LLInventoryType::EType inv_type,
- U32 next_owner_perm = PERM_NONE,
- const LLString& display_name = LLString::null,
- LLAssetStorage::LLStoreAssetCallback callback = NULL,
- void *userdata = NULL);
-
// Export to XML or Collada
void handle_export_selected( void * );
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
new file mode 100644
index 0000000000..eec6c8f481
--- /dev/null
+++ b/indra/newview/llviewermenufile.cpp
@@ -0,0 +1,1002 @@
+/**
+ * @file llviewermenufile.cpp
+ * @brief "File" menu in the main menu bar.
+ *
+ * Copyright (c) 2002-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llviewermenufile.h"
+
+// project includes
+#include "llagent.h"
+#include "llfilepicker.h"
+#include "llfloateranimpreview.h"
+#include "llfloaterbuycurrency.h"
+#include "llfloaterimagepreview.h"
+#include "llfloaterimport.h"
+#include "llfloaternamedesc.h"
+#include "llfloatersnapshot.h"
+#include "llinventorymodel.h" // gInventory
+#include "llresourcedata.h"
+#include "llstatusbar.h"
+#include "llviewercontrol.h" // gSavedSettings
+#include "llviewerimagelist.h"
+#include "llvieweruictrlfactory.h"
+#include "llviewermenu.h" // gMenuHolder
+#include "llviewerregion.h"
+#include "llviewerstats.h"
+#include "llviewerwindow.h"
+#include "viewer.h" // app_request_quit()
+
+// linden libraries
+#include "llassetuploadresponders.h"
+#include "lleconomy.h"
+#include "llhttpclient.h"
+#include "llmemberlistener.h"
+#include "llsdserialize.h"
+#include "llstring.h"
+#include "lltransactiontypes.h"
+#include "lluuid.h"
+#include "vorbisencode.h"
+
+// system libraries
+#include <boost/tokenizer.hpp>
+
+typedef LLMemberListener<LLView> view_listener_t;
+
+
+class LLFileEnableSaveAs : public view_listener_t
+{
+ bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ {
+ bool new_value = gFloaterView->getFrontmost() && gFloaterView->getFrontmost()->canSaveAs();
+ gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
+ return true;
+ }
+};
+
+class LLFileEnableUpload : public view_listener_t
+{
+ bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ {
+ bool new_value = gStatusBar && gGlobalEconomy && (gStatusBar->getBalance() >= gGlobalEconomy->getPriceUpload());
+ gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
+ return true;
+ }
+};
+
+/**
+ char* upload_pick(void* data)
+
+ If applicable, brings up a file chooser in which the user selects a file
+ to upload for a particular task. If the file is valid for the given action,
+ returns the string to the full path filename, else returns NULL.
+ Data is the load filter for the type of file as defined in LLFilePicker.
+**/
+const char* upload_pick(void* data)
+{
+ if( gAgent.cameraMouselook() )
+ {
+ gAgent.changeCameraToDefault();
+ // This doesn't seem necessary. JC
+ // display();
+ }
+
+ LLFilePicker::ELoadFilter type;
+ if(data)
+ {
+ type = (LLFilePicker::ELoadFilter)((intptr_t)data);
+ }
+ else
+ {
+ type = LLFilePicker::FFLOAD_ALL;
+ }
+
+ LLFilePicker& picker = LLFilePicker::instance();
+ if (!picker.getOpenFile(type))
+ {
+ llinfos << "Couldn't import objects from file" << llendl;
+ return NULL;
+ }
+
+ const char* filename = picker.getFirstFile();
+ const char* ext = strrchr(filename, '.');
+
+ //strincmp doesn't like NULL pointers
+ if (ext == NULL)
+ {
+ const char* short_name = strrchr(filename,
+ *gDirUtilp->getDirDelimiter().c_str());
+
+ // No extension
+ LLStringBase<char>::format_map_t args;
+ args["[FILE]"] = LLString(short_name + 1);
+ gViewerWindow->alertXml("NoFileExtension", args);
+ return NULL;
+ }
+ else
+ {
+ //so there is an extension
+ //loop over the valid extensions and compare to see
+ //if the extension is valid
+
+ //now grab the set of valid file extensions
+ const char* valids = build_extensions_string(type);
+ std::string valid_extensions = std::string(valids);
+
+ BOOL ext_valid = FALSE;
+
+ typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
+ boost::char_separator<char> sep(" ");
+ tokenizer tokens(valid_extensions, sep);
+ tokenizer::iterator token_iter;
+
+ //now loop over all valid file extensions
+ //and compare them to the extension of the file
+ //to be uploaded
+ for( token_iter = tokens.begin();
+ token_iter != tokens.end() && ext_valid != TRUE;
+ ++token_iter)
+ {
+ const char* cur_token = token_iter->c_str();
+
+ if (0 == strnicmp(cur_token, ext, strlen(cur_token)) || /* Flawfinder: ignore */
+ 0 == strnicmp(cur_token, "*.*", strlen(cur_token))) /* Flawfinder: ignore */
+ {
+ //valid extension
+ //or the acceptable extension is any
+ ext_valid = TRUE;
+ }
+ }//end for (loop over all tokens)
+
+ if (ext_valid == FALSE)
+ {
+ //should only get here if the extension exists
+ //but is invalid
+ LLStringBase<char>::format_map_t args;
+ args["[EXTENSION]"] = ext;
+ args["[VALIDS]"] = valids;
+ gViewerWindow->alertXml("InvalidFileExtension", args);
+ return NULL;
+ }
+ }//end else (non-null extension)
+
+ //valid file extension
+
+ //now we check to see
+ //if the file is actually a valid image/sound/etc.
+ if (type == LLFilePicker::FFLOAD_WAV)
+ {
+ // pre-qualify wavs to make sure the format is acceptable
+ char error_msg[MAX_STRING]; /* Flawfinder: ignore */
+ if (check_for_invalid_wav_formats(filename,error_msg))
+ {
+ llinfos << error_msg << ": " << filename << llendl;
+ LLStringBase<char>::format_map_t args;
+ args["[FILE]"] = filename;
+ gViewerWindow->alertXml( error_msg, args );
+ return NULL;
+ }
+ }//end if a wave/sound file
+
+
+ return filename;
+}
+
+void handle_upload_object(void* data)
+{
+ const char* filename = upload_pick(data);
+ if (filename)
+ {
+ // start the import
+ LLFloaterImport* floaterp = new LLFloaterImport(filename);
+ gUICtrlFactory->buildFloater(floaterp, "floater_import.xml");
+ }
+}
+
+class LLFileUploadImage : public view_listener_t
+{
+ bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ {
+ const char* filename = upload_pick((void *)(S32)LLFilePicker::FFLOAD_IMAGE);
+ if (filename)
+ {
+ LLFloaterImagePreview* floaterp = new LLFloaterImagePreview(filename);
+ gUICtrlFactory->buildFloater(floaterp, "floater_image_preview.xml");
+ }
+ return TRUE;
+ }
+};
+
+class LLFileUploadSound : public view_listener_t
+{
+ bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ {
+ const char* filename = upload_pick((void*)((S32)LLFilePicker::FFLOAD_WAV));
+ if (filename)
+ {
+ LLFloaterNameDesc* floaterp = new LLFloaterNameDesc(filename);
+ gUICtrlFactory->buildFloater(floaterp, "floater_sound_preview.xml");
+ }
+ return true;
+ }
+};
+
+class LLFileUploadAnim : public view_listener_t
+{
+ bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ {
+ const char* filename = upload_pick((void*)((S32)LLFilePicker::FFLOAD_ANIM));
+ if (filename)
+ {
+ LLFloaterAnimPreview* floaterp = new LLFloaterAnimPreview(filename);
+ gUICtrlFactory->buildFloater(floaterp, "floater_animation_preview.xml");
+ }
+ return true;
+ }
+};
+
+class LLFileUploadBulk : public view_listener_t
+{
+ bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ {
+ if( gAgent.cameraMouselook() )
+ {
+ gAgent.changeCameraToDefault();
+ }
+
+ // TODO:
+ // Iterate over all files
+ // Check extensions for uploadability, cost
+ // Check user balance for entire cost
+ // Charge user entire cost
+ // Loop, uploading
+ // If an upload fails, refund the user for that one
+ //
+ // Also fix single upload to charge first, then refund
+
+ LLFilePicker& picker = LLFilePicker::instance();
+ if (picker.getMultipleOpenFiles())
+ {
+ const char* filename = picker.getFirstFile();
+ const char* name = picker.getDirname();
+
+ LLString asset_name = name;
+ LLString::replaceNonstandardASCII( asset_name, '?' );
+ LLString::replaceChar(asset_name, '|', '?');
+ LLString::stripNonprintable(asset_name);
+ LLString::trim(asset_name);
+
+ char* asset_name_str = (char*)asset_name.c_str();
+ char* end_p = strrchr(asset_name_str, '.'); // strip extension if exists
+ if( !end_p )
+ {
+ end_p = asset_name_str + strlen( asset_name_str ); /* Flawfinder: ignore */
+ }
+
+ S32 len = llmin( (S32) (DB_INV_ITEM_NAME_STR_LEN), (S32) (end_p - asset_name_str) );
+
+ asset_name = asset_name.substr( 0, len );
+
+ upload_new_resource(filename, asset_name, asset_name, 0, LLAssetType::AT_NONE, LLInventoryType::IT_NONE); // file
+ }
+ else
+ {
+ llinfos << "Couldn't import objects from file" << llendl;
+ }
+ return true;
+ }
+};
+
+void upload_error(const char* error_message, const char* label, const std::string filename, const LLStringBase<char>::format_map_t args)
+{
+ llwarns << error_message << llendl;
+ gViewerWindow->alertXml(label, args);
+ if(remove(filename.c_str()) == -1)
+ {
+ lldebugs << "unable to remove temp file" << llendl;
+ }
+ LLFilePicker::instance().reset();
+}
+
+class LLFileEnableCloseWindow : public view_listener_t
+{
+ bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ {
+ bool new_value = gFloaterView->getFocusedFloater() != NULL || gSnapshotFloaterView->getFocusedFloater() != NULL;
+ // horrendously opaque, this code
+ gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
+ return true;
+ }
+};
+
+class LLFileCloseWindow : public view_listener_t
+{
+ bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ {
+ LLFloater::closeFocusedFloater();
+
+ return true;
+ }
+};
+
+class LLFileCloseAllWindows : public view_listener_t
+{
+ bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ {
+ bool app_quitting = false;
+ gFloaterView->closeAllChildren(app_quitting);
+
+ return true;
+ }
+};
+
+class LLFileSaveTexture : public view_listener_t
+{
+ bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ {
+ LLFloater* top = gFloaterView->getFrontmost();
+ if (top)
+ {
+ top->saveAs();
+ }
+ return true;
+ }
+};
+
+class LLFileTakeSnapshot : public view_listener_t
+{
+ bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ {
+ LLFloaterSnapshot::show(NULL);
+ return true;
+ }
+};
+
+class LLFileTakeSnapshotToDisk : public view_listener_t
+{
+ bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ {
+ LLPointer<LLImageRaw> raw = new LLImageRaw;
+
+ S32 width = gViewerWindow->getWindowDisplayWidth();
+ S32 height = gViewerWindow->getWindowDisplayHeight();
+
+ if (gSavedSettings.getBOOL("HighResSnapshot"))
+ {
+ width *= 2;
+ height *= 2;
+ }
+
+ if (gViewerWindow->rawSnapshot(raw,
+ width,
+ height,
+ TRUE,
+ gSavedSettings.getBOOL("RenderUIInSnapshot"),
+ FALSE))
+ {
+ if (!gQuietSnapshot)
+ {
+ gViewerWindow->playSnapshotAnimAndSound();
+ }
+ LLImageBase::setSizeOverride(TRUE);
+ gViewerWindow->saveImageNumbered(raw);
+ LLImageBase::setSizeOverride(FALSE);
+ }
+ return true;
+ }
+};
+
+class LLFileSaveMovie : public view_listener_t
+{
+ bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ {
+ LLViewerWindow::saveMovieNumbered(NULL);
+ return true;
+ }
+};
+
+class LLFileSetWindowSize : public view_listener_t
+{
+ bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ {
+ LLString size = userdata.asString();
+ S32 width, height;
+ sscanf(size.c_str(), "%d,%d", &width, &height);
+ LLViewerWindow::movieSize(width, height);
+ return true;
+ }
+};
+
+class LLFileQuit : public view_listener_t
+{
+ bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ {
+ app_request_quit();
+ return true;
+ }
+};
+
+void handle_upload(void* data)
+{
+ const char* filename = upload_pick(data);
+ if (filename)
+ {
+ LLFloaterNameDesc* floaterp = new LLFloaterNameDesc(filename);
+ gUICtrlFactory->buildFloater(floaterp, "floater_name_description.xml");
+ }
+}
+
+void handle_compress_image(void*)
+{
+ LLFilePicker& picker = LLFilePicker::instance();
+ if (picker.getOpenFile(LLFilePicker::FFLOAD_IMAGE))
+ {
+ std::string infile(picker.getFirstFile());
+ std::string outfile = infile + ".j2c";
+
+ llinfos << "Input: " << infile << llendl;
+ llinfos << "Output: " << outfile << llendl;
+
+ BOOL success;
+
+ success = LLViewerImageList::createUploadFile(infile, outfile, IMG_CODEC_TGA);
+
+ if (success)
+ {
+ llinfos << "Compression complete" << llendl;
+ }
+ else
+ {
+ llinfos << "Compression failed: " << LLImageBase::getLastError() << llendl;
+ }
+ }
+}
+
+void upload_new_resource(const LLString& src_filename, std::string name,
+ std::string desc, S32 compression_info,
+ LLAssetType::EType destination_folder_type,
+ LLInventoryType::EType inv_type,
+ U32 next_owner_perm,
+ const LLString& display_name,
+ LLAssetStorage::LLStoreAssetCallback callback,
+ void *userdata)
+{
+ // Generate the temporary UUID.
+ LLString filename = gDirUtilp->getTempFilename();
+ LLTransactionID tid;
+ LLAssetID uuid;
+
+ LLStringBase<char>::format_map_t args;
+
+ LLString ext = src_filename.substr(src_filename.find_last_of('.'));
+ LLAssetType::EType asset_type = LLAssetType::AT_NONE;
+ char error_message[MAX_STRING]; /* Flawfinder: ignore */
+ error_message[0] = '\0';
+ LLString temp_str;
+
+ BOOL error = FALSE;
+
+ if (ext.empty())
+ {
+ LLString::size_type offset = filename.find_last_of(gDirUtilp->getDirDelimiter());
+ if (offset != LLString::npos)
+ offset++;
+ LLString short_name = filename.substr(offset);
+
+ // No extension
+ snprintf(error_message, /* Flawfinder: ignore */
+ MAX_STRING,
+ "No file extension for the file: '%s'\nPlease make sure the file has a correct file extension",
+ short_name.c_str());
+ args["[FILE]"] = short_name;
+ upload_error(error_message, "NofileExtension", filename, args);
+ return;
+ }
+ else if( LLString::compareInsensitive(ext.c_str(),".bmp") == 0 )
+ {
+ asset_type = LLAssetType::AT_TEXTURE;
+ if (!LLViewerImageList::createUploadFile(src_filename,
+ filename,
+ IMG_CODEC_BMP ))
+ {
+ snprintf(error_message, MAX_STRING, "Problem with file %s:\n\n%s\n", /* Flawfinder: ignore */
+ src_filename.c_str(), LLImageBase::getLastError().c_str());
+ args["[FILE]"] = src_filename;
+ args["[ERROR]"] = LLImageBase::getLastError();
+ upload_error(error_message, "ProblemWithFile", filename, args);
+ return;
+ }
+ }
+ else if( LLString::compareInsensitive(ext.c_str(),".tga") == 0 )
+ {
+ asset_type = LLAssetType::AT_TEXTURE;
+ if (!LLViewerImageList::createUploadFile(src_filename,
+ filename,
+ IMG_CODEC_TGA ))
+ {
+ snprintf(error_message, MAX_STRING, "Problem with file %s:\n\n%s\n", /* Flawfinder: ignore */
+ src_filename.c_str(), LLImageBase::getLastError().c_str());
+ args["[FILE]"] = src_filename;
+ args["[ERROR]"] = LLImageBase::getLastError();
+ upload_error(error_message, "ProblemWithFile", filename, args);
+ return;
+ }
+ }
+ else if( LLString::compareInsensitive(ext.c_str(),".jpg") == 0 || LLString::compareInsensitive(ext.c_str(),".jpeg") == 0)
+ {
+ asset_type = LLAssetType::AT_TEXTURE;
+ if (!LLViewerImageList::createUploadFile(src_filename,
+ filename,
+ IMG_CODEC_JPEG ))
+ {
+ snprintf(error_message, MAX_STRING, "Problem with file %s:\n\n%s\n", /* Flawfinder: ignore */
+ src_filename.c_str(), LLImageBase::getLastError().c_str());
+ args["[FILE]"] = src_filename;
+ args["[ERROR]"] = LLImageBase::getLastError();
+ upload_error(error_message, "ProblemWithFile", filename, args);
+ return;
+ }
+ }
+ else if(LLString::compareInsensitive(ext.c_str(),".wav") == 0)
+ {
+ asset_type = LLAssetType::AT_SOUND; // tag it as audio
+ S32 encode_result = 0;
+
+ S32 bitrate = 128;
+
+ if (compression_info)
+ {
+ bitrate = compression_info;
+ }
+ llinfos << "Attempting to encode wav as an ogg file at " << bitrate << "kbps" << llendl;
+
+ encode_result = encode_vorbis_file_at(src_filename.c_str(), filename.c_str(), bitrate*1000);
+
+ if (LLVORBISENC_NOERR != encode_result)
+ {
+ switch(encode_result)
+ {
+ case LLVORBISENC_DEST_OPEN_ERR:
+ snprintf(error_message, MAX_STRING, "Couldn't open temporary compressed sound file for writing: %s\n", filename.c_str()); /* Flawfinder: ignore */
+ args["[FILE]"] = filename;
+ upload_error(error_message, "CannotOpenTemporarySoundFile", filename, args);
+ break;
+
+ default:
+ snprintf(error_message, MAX_STRING, "Unknown vorbis encode failure on: %s\n", src_filename.c_str()); /* Flawfinder: ignore */
+ args["[FILE]"] = src_filename;
+ upload_error(error_message, "UnknownVorbisEncodeFailure", filename, args);
+ break;
+ }
+ return;
+ }
+ }
+ else if(LLString::compareInsensitive(ext.c_str(),".tmp") == 0)
+ {
+ // This is a generic .lin resource file
+ asset_type = LLAssetType::AT_OBJECT;
+ FILE* in = LLFile::fopen(src_filename.c_str(), "rb"); /* Flawfinder: ignore */
+ if (in)
+ {
+ // read in the file header
+ char buf[16384]; /* Flawfinder: ignore */
+ S32 read; /* Flawfinder: ignore */
+ S32 version;
+ if (fscanf(in, "LindenResource\nversion %d\n", &version))
+ {
+ if (2 == version)
+ {
+ // *NOTE: This buffer size is hard coded into scanf() below.
+ char label[MAX_STRING]; /* Flawfinder: ignore */
+ char value[MAX_STRING]; /* Flawfinder: ignore */
+ S32 tokens_read;
+ while (fgets(buf, 1024, in))
+ {
+ label[0] = '\0';
+ value[0] = '\0';
+ tokens_read = sscanf( /* Flawfinder: ignore */
+ buf,
+ "%254s %254s\n",
+ label, value);
+
+ llinfos << "got: " << label << " = " << value
+ << llendl;
+
+ if (EOF == tokens_read)
+ {
+ fclose(in);
+ snprintf(error_message, MAX_STRING, "corrupt resource file: %s", src_filename.c_str()); /* Flawfinder: ignore */
+ args["[FILE]"] = src_filename;
+ upload_error(error_message, "CorruptResourceFile", filename, args);
+ return;
+ }
+
+ if (2 == tokens_read)
+ {
+ if (! strcmp("type", label))
+ {
+ asset_type = (LLAssetType::EType)(atoi(value));
+ }
+ }
+ else
+ {
+ if (! strcmp("_DATA_", label))
+ {
+ // below is the data section
+ break;
+ }
+ }
+ // other values are currently discarded
+ }
+
+ }
+ else
+ {
+ fclose(in);
+ snprintf(error_message, MAX_STRING, "unknown linden resource file version in file: %s", src_filename.c_str()); /* Flawfinder: ignore */
+ args["[FILE]"] = src_filename;
+ upload_error(error_message, "UnknownResourceFileVersion", filename, args);
+ return;
+ }
+ }
+ else
+ {
+ // this is an original binary formatted .lin file
+ // start over at the beginning of the file
+ fseek(in, 0, SEEK_SET);
+
+ const S32 MAX_ASSET_DESCRIPTION_LENGTH = 256;
+ const S32 MAX_ASSET_NAME_LENGTH = 64;
+ S32 header_size = 34 + MAX_ASSET_DESCRIPTION_LENGTH + MAX_ASSET_NAME_LENGTH;
+ S16 type_num;
+
+ // read in and throw out most of the header except for the type
+ fread(buf, header_size, 1, in);
+ memcpy(&type_num, buf + 16, sizeof(S16)); /* Flawfinder: ignore */
+ asset_type = (LLAssetType::EType)type_num;
+ }
+
+ // copy the file's data segment into another file for uploading
+ FILE* out = LLFile::fopen(filename.c_str(), "wb"); /* Flawfinder: ignore */
+ if (out)
+ {
+ while((read = fread(buf, 1, 16384, in))) /* Flawfinder: ignore */
+ {
+ fwrite(buf, 1, read, out); /* Flawfinder: ignore */
+ }
+ fclose(out);
+ }
+ else
+ {
+ fclose(in);
+ snprintf(error_message, MAX_STRING, "Unable to create output file: %s", filename.c_str()); /* Flawfinder: ignore */
+ args["[FILE]"] = filename;
+ upload_error(error_message, "UnableToCreateOutputFile", filename, args);
+ return;
+ }
+
+ fclose(in);
+ }
+ else
+ {
+ llinfos << "Couldn't open .lin file " << src_filename << llendl;
+ }
+ }
+ else if (LLString::compareInsensitive(ext.c_str(),".bvh") == 0)
+ {
+ snprintf(error_message, MAX_STRING, "We do not currently support bulk upload of animation files\n"); /* Flawfinder: ignore */
+ upload_error(error_message, "DoNotSupportBulkAnimationUpload", filename, args);
+ return;
+ }
+ else
+ {
+ // Unknown extension
+ snprintf(error_message, MAX_STRING, "Unknown file extension %s\nExpected .wav, .tga, .bmp, .jpg, .jpeg, or .bvh", ext.c_str()); /* Flawfinder: ignore */
+ error = TRUE;;
+ }
+
+ // gen a new transaction ID for this asset
+ tid.generate();
+
+ if (!error)
+ {
+ uuid = tid.makeAssetID(gAgent.getSecureSessionID());
+ // copy this file into the vfs for upload
+ S32 file_size;
+ apr_file_t* fp = ll_apr_file_open(filename, LL_APR_RB, &file_size);
+ if (fp)
+ {
+ LLVFile file(gVFS, uuid, asset_type, LLVFile::WRITE);
+
+ file.setMaxSize(file_size);
+
+ const S32 buf_size = 65536;
+ U8 copy_buf[buf_size];
+ while ((file_size = ll_apr_file_read(fp, copy_buf, buf_size)))
+ {
+ file.write(copy_buf, file_size);
+ }
+ apr_file_close(fp);
+ }
+ else
+ {
+ snprintf(error_message, MAX_STRING, "Unable to access output file: %s", filename.c_str()); /* Flawfinder: ignore */
+ error = TRUE;
+ }
+ }
+
+ if (!error)
+ {
+ LLString t_disp_name = display_name;
+ if (t_disp_name.empty())
+ {
+ t_disp_name = src_filename;
+ }
+ upload_new_resource(tid, asset_type, name, desc, compression_info, // tid
+ destination_folder_type, inv_type, next_owner_perm,
+ display_name, callback, userdata);
+ }
+ else
+ {
+ llwarns << error_message << llendl;
+ LLStringBase<char>::format_map_t args;
+ args["[ERROR_MESSAGE]"] = error_message;
+ gViewerWindow->alertXml("ErrorMessage", args);
+ if(LLFile::remove(filename.c_str()) == -1)
+ {
+ lldebugs << "unable to remove temp file" << llendl;
+ }
+ LLFilePicker::instance().reset();
+ }
+}
+
+void upload_done_callback(const LLUUID& uuid, void* user_data, S32 result) // StoreAssetData callback (fixed)
+{
+ LLResourceData* data = (LLResourceData*)user_data;
+ //LLAssetType::EType pref_loc = data->mPreferredLocation;
+ BOOL is_balance_sufficient = TRUE;
+ if(result >= 0)
+ {
+ LLAssetType::EType dest_loc = (data->mPreferredLocation == LLAssetType::AT_NONE) ? data->mAssetInfo.mType : data->mPreferredLocation;
+
+ if (LLAssetType::AT_SOUND == data->mAssetInfo.mType ||
+ LLAssetType::AT_TEXTURE == data->mAssetInfo.mType ||
+ LLAssetType::AT_ANIMATION == data->mAssetInfo.mType)
+ {
+ // Charge the user for the upload.
+ LLViewerRegion* region = gAgent.getRegion();
+ S32 upload_cost = gGlobalEconomy->getPriceUpload();
+
+ if(!(can_afford_transaction(upload_cost)))
+ {
+ LLFloaterBuyCurrency::buyCurrency(
+ llformat("Uploading %s costs",
+ data->mAssetInfo.getName().c_str()),
+ upload_cost);
+ is_balance_sufficient = FALSE;
+ }
+ else if(region)
+ {
+ // Charge user for upload
+ gStatusBar->debitBalance(upload_cost);
+
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_MoneyTransferRequest);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->nextBlockFast(_PREHASH_MoneyData);
+ msg->addUUIDFast(_PREHASH_SourceID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_DestID, LLUUID::null);
+ msg->addU8("Flags", 0);
+ msg->addS32Fast(_PREHASH_Amount, upload_cost);
+ msg->addU8Fast(_PREHASH_AggregatePermNextOwner, (U8)LLAggregatePermissions::AP_EMPTY);
+ msg->addU8Fast(_PREHASH_AggregatePermInventory, (U8)LLAggregatePermissions::AP_EMPTY);
+ msg->addS32Fast(_PREHASH_TransactionType, TRANS_UPLOAD_CHARGE);
+ msg->addStringFast(_PREHASH_Description, NULL);
+ msg->sendReliable(region->getHost());
+ }
+ }
+
+ if(is_balance_sufficient)
+ {
+ // Actually add the upload to inventory
+ llinfos << "Adding " << uuid << " to inventory." << llendl;
+ LLUUID folder_id(gInventory.findCategoryUUIDForType(dest_loc));
+ if(folder_id.notNull())
+ {
+ U32 next_owner_perm = data->mNextOwnerPerm;
+ if(PERM_NONE == next_owner_perm)
+ {
+ next_owner_perm = PERM_MOVE | PERM_TRANSFER;
+ }
+ create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
+ folder_id, data->mAssetInfo.mTransactionID, data->mAssetInfo.getName(),
+ data->mAssetInfo.getDescription(), data->mAssetInfo.mType,
+ data->mInventoryType, NOT_WEARABLE, next_owner_perm,
+ LLPointer<LLInventoryCallback>(NULL));
+ }
+ else
+ {
+ llwarns << "Can't find a folder to put it in" << llendl;
+ }
+ }
+ }
+ else // if(result >= 0)
+ {
+ LLStringBase<char>::format_map_t args;
+ args["[FILE]"] = LLInventoryType::lookupHumanReadable(data->mInventoryType);
+ args["[REASON]"] = LLString(LLAssetStorage::getErrorString(result));
+ gViewerWindow->alertXml("CannotUploadReason", args);
+ }
+
+ LLUploadDialog::modalUploadFinished();
+ delete data;
+
+ // *NOTE: This is a pretty big hack. What this does is check the
+ // file picker if there are any more pending uploads. If so,
+ // upload that file.
+ const char* next_file = LLFilePicker::instance().getNextFile();
+ if(is_balance_sufficient && next_file)
+ {
+ const char* name = LLFilePicker::instance().getDirname();
+
+ LLString asset_name = name;
+ LLString::replaceNonstandardASCII( asset_name, '?' );
+ LLString::replaceChar(asset_name, '|', '?');
+ LLString::stripNonprintable(asset_name);
+ LLString::trim(asset_name);
+
+ char* asset_name_str = (char*)asset_name.c_str();
+ char* end_p = strrchr(asset_name_str, '.'); // strip extension if exists
+ if( !end_p )
+ {
+ end_p = asset_name_str + strlen( asset_name_str ); /* Flawfinder: ignore */
+ }
+
+ S32 len = llmin( (S32) (DB_INV_ITEM_NAME_STR_LEN), (S32) (end_p - asset_name_str) );
+
+ asset_name = asset_name.substr( 0, len );
+
+ upload_new_resource(next_file, asset_name, asset_name, // file
+ 0, LLAssetType::AT_NONE, LLInventoryType::IT_NONE);
+ }
+}
+
+void upload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_type,
+ std::string name,
+ std::string desc, S32 compression_info,
+ LLAssetType::EType destination_folder_type,
+ LLInventoryType::EType inv_type,
+ U32 next_owner_perm,
+ const LLString& display_name,
+ LLAssetStorage::LLStoreAssetCallback callback,
+ void *userdata)
+{
+ LLAssetID uuid = tid.makeAssetID(gAgent.getSecureSessionID());
+
+ if( LLAssetType::AT_SOUND == asset_type )
+ {
+ gViewerStats->incStat(LLViewerStats::ST_UPLOAD_SOUND_COUNT );
+ }
+ else
+ if( LLAssetType::AT_TEXTURE == asset_type )
+ {
+ gViewerStats->incStat(LLViewerStats::ST_UPLOAD_TEXTURE_COUNT );
+ }
+ else
+ if( LLAssetType::AT_ANIMATION == asset_type)
+ {
+ gViewerStats->incStat(LLViewerStats::ST_UPLOAD_ANIM_COUNT );
+ }
+
+ if(LLInventoryType::IT_NONE == inv_type)
+ {
+ inv_type = LLInventoryType::defaultForAssetType(asset_type);
+ }
+ LLString::stripNonprintable(name);
+ LLString::stripNonprintable(desc);
+ if(name.empty())
+ {
+ name = "(No Name)";
+ }
+ if(desc.empty())
+ {
+ desc = "(No Description)";
+ }
+
+ // At this point, we're ready for the upload.
+ LLString upload_message = "Uploading...\n\n";
+ upload_message.append(display_name);
+ LLUploadDialog::modalUploadDialog(upload_message);
+
+ llinfos << "*** Uploading: " << llendl;
+ llinfos << "Type: " << LLAssetType::lookup(asset_type) << llendl;
+ llinfos << "UUID: " << uuid << llendl;
+ llinfos << "Name: " << name << llendl;
+ llinfos << "Desc: " << desc << llendl;
+ lldebugs << "Folder: " << gInventory.findCategoryUUIDForType((destination_folder_type == LLAssetType::AT_NONE) ? asset_type : destination_folder_type) << llendl;
+ lldebugs << "Asset Type: " << LLAssetType::lookup(asset_type) << llendl;
+ std::string url = gAgent.getRegion()->getCapability("NewFileAgentInventory");
+ if (!url.empty())
+ {
+ llinfos << "New Agent Inventory via capability" << llendl;
+ LLSD body;
+ body["folder_id"] = gInventory.findCategoryUUIDForType((destination_folder_type == LLAssetType::AT_NONE) ? asset_type : destination_folder_type);
+ body["asset_type"] = LLAssetType::lookup(asset_type);
+ body["inventory_type"] = LLInventoryType::lookup(inv_type);
+ body["name"] = name;
+ body["description"] = desc;
+
+ std::ostringstream llsdxml;
+ LLSDSerialize::toXML(body, llsdxml);
+ lldebugs << "posting body to capability: " << llsdxml.str() << llendl;
+ LLHTTPClient::post(url, body, new LLNewAgentInventoryResponder(body, uuid, asset_type));
+ }
+ else
+ {
+ llinfos << "NewAgentInventory capability not found, new agent inventory via asset system." << llendl;
+ // check for adequate funds
+ // TODO: do this check on the sim
+ if (LLAssetType::AT_SOUND == asset_type ||
+ LLAssetType::AT_TEXTURE == asset_type ||
+ LLAssetType::AT_ANIMATION == asset_type)
+ {
+ S32 upload_cost = gGlobalEconomy->getPriceUpload();
+ S32 balance = gStatusBar->getBalance();
+ if (balance < upload_cost)
+ {
+ // insufficient funds, bail on this upload
+ LLFloaterBuyCurrency::buyCurrency("Uploading costs", upload_cost);
+ return;
+ }
+ }
+
+ LLResourceData* data = new LLResourceData;
+ data->mAssetInfo.mTransactionID = tid;
+ data->mAssetInfo.mUuid = uuid;
+ data->mAssetInfo.mType = asset_type;
+ data->mAssetInfo.mCreatorID = gAgentID;
+ data->mInventoryType = inv_type;
+ data->mNextOwnerPerm = next_owner_perm;
+ data->mUserData = userdata;
+ data->mAssetInfo.setName(name);
+ data->mAssetInfo.setDescription(desc);
+ data->mPreferredLocation = destination_folder_type;
+
+ LLAssetStorage::LLStoreAssetCallback asset_callback = &upload_done_callback;
+ if (callback)
+ {
+ asset_callback = callback;
+ }
+ gAssetStorage->storeAssetData(data->mAssetInfo.mTransactionID, data->mAssetInfo.mType,
+ asset_callback,
+ (void*)data,
+ FALSE);
+ }
+}
+
+
+void init_menu_file()
+{
+ (new LLFileUploadImage())->registerListener(gMenuHolder, "File.UploadImage");
+ (new LLFileUploadSound())->registerListener(gMenuHolder, "File.UploadSound");
+ (new LLFileUploadAnim())->registerListener(gMenuHolder, "File.UploadAnim");
+ (new LLFileUploadBulk())->registerListener(gMenuHolder, "File.UploadBulk");
+ (new LLFileCloseWindow())->registerListener(gMenuHolder, "File.CloseWindow");
+ (new LLFileCloseAllWindows())->registerListener(gMenuHolder, "File.CloseAllWindows");
+ (new LLFileEnableCloseWindow())->registerListener(gMenuHolder, "File.EnableCloseWindow");
+ (new LLFileSaveTexture())->registerListener(gMenuHolder, "File.SaveTexture");
+ (new LLFileTakeSnapshot())->registerListener(gMenuHolder, "File.TakeSnapshot");
+ (new LLFileTakeSnapshotToDisk())->registerListener(gMenuHolder, "File.TakeSnapshotToDisk");
+ (new LLFileSaveMovie())->registerListener(gMenuHolder, "File.SaveMovie");
+ (new LLFileSetWindowSize())->registerListener(gMenuHolder, "File.SetWindowSize");
+ (new LLFileQuit())->registerListener(gMenuHolder, "File.Quit");
+
+ (new LLFileEnableUpload())->registerListener(gMenuHolder, "File.EnableUpload");
+ (new LLFileEnableSaveAs())->registerListener(gMenuHolder, "File.EnableSaveAs");
+}
diff --git a/indra/newview/llviewermenufile.h b/indra/newview/llviewermenufile.h
new file mode 100644
index 0000000000..77861f8c48
--- /dev/null
+++ b/indra/newview/llviewermenufile.h
@@ -0,0 +1,39 @@
+/**
+ * @file llviewermenufile.h
+ * @brief "File" menu in the main menu bar.
+ *
+ * Copyright (c) 2002-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+#ifndef LLVIEWERMENUFILE_H
+#define LLVIEWERMENUFILE_H
+
+#include "llassettype.h"
+#include "llinventorytype.h"
+
+class LLTransactionID;
+
+
+void init_menu_file();
+
+void upload_new_resource(const LLString& src_filename, std::string name,
+ std::string desc, S32 compression_info,
+ LLAssetType::EType destination_folder_type,
+ LLInventoryType::EType inv_type,
+ U32 next_owner_perm = 0x0, // PERM_NONE
+ const LLString& display_name = LLString::null,
+ LLAssetStorage::LLStoreAssetCallback callback = NULL,
+ void *userdata = NULL);
+
+void upload_new_resource(const LLTransactionID &tid, LLAssetType::EType type,
+ std::string name,
+ std::string desc, S32 compression_info,
+ LLAssetType::EType destination_folder_type,
+ LLInventoryType::EType inv_type,
+ U32 next_owner_perm = 0x0, // PERM_NONE
+ const LLString& display_name = LLString::null,
+ LLAssetStorage::LLStoreAssetCallback callback = NULL,
+ void *userdata = NULL);
+
+#endif
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 316de37ce1..cb4077b21b 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -125,8 +125,14 @@ extern BOOL gDebugClicks;
extern void bad_network_handler();
// function prototypes
-void open_offer(const std::vector<LLUUID>& items);
+void open_offer(const std::vector<LLUUID>& items, const std::string& from_name);
void friendship_offer_callback(S32 option, void* user_data);
+bool check_offer_throttle(const std::string& from_name, bool check_only);
+
+//inventory offer throttle globals
+LLFrameTimer gThrottleTimer;
+const U32 OFFER_THROTTLE_MAX_COUNT=5; //number of items per time period
+const F32 OFFER_THROTTLE_TIME=10.f; //time period in seconds
struct LLFriendshipOffer
{
@@ -175,11 +181,6 @@ void give_money(const LLUUID& uuid, LLViewerRegion* region, S32 amount, BOOL is_
}
}
-BOOL can_afford_transaction(S32 cost)
-{
- return((cost <= 0)||((gStatusBar) && (gStatusBar->getBalance() >=cost)));
-}
-
void send_complete_agent_movement(const LLHost& sim_host)
{
LLMessageSystem* msg = gMessageSystem;
@@ -255,11 +256,19 @@ void process_layer_data(LLMessageSystem *mesgsys, void **user_data)
mesgsys->getS8Fast(_PREHASH_LayerID, _PREHASH_Type, type);
size = mesgsys->getSizeFast(_PREHASH_LayerData, _PREHASH_Data);
- if(!size)
+ if (0 == size)
{
llwarns << "Layer data has zero size." << llendl;
return;
}
+ if (size < 0)
+ {
+ // getSizeFast() is probably trying to tell us about an error
+ llwarns << "getSizeFast() returned negative result: "
+ << size
+ << llendl;
+ return;
+ }
U8 *datap = new U8[size];
mesgsys->getBinaryDataFast(_PREHASH_LayerData, _PREHASH_Data, datap, size);
LLVLData *vl_datap = new LLVLData(regionp, type, datap, size);
@@ -306,25 +315,29 @@ void export_complete()
while ((pos = strstr(pos+1, "<sl:image ")) != 0)
{
char *pos_check = strstr(pos, "checksum=\"");
- char *pos_uuid = strstr(pos_check, "\">");
- if (pos_check && pos_uuid)
+ if (pos_check)
{
- char image_uuid_str[UUID_STR_SIZE]; /* Flawfinder: ignore */
- memcpy(image_uuid_str, pos_uuid+2, UUID_STR_SIZE-1); /* Flawfinder: ignore */
- image_uuid_str[UUID_STR_SIZE-1] = 0;
+ char *pos_uuid = strstr(pos_check, "\">");
- LLUUID image_uuid(image_uuid_str);
+ if (pos_uuid)
+ {
+ char image_uuid_str[UUID_STR_SIZE]; /* Flawfinder: ignore */
+ memcpy(image_uuid_str, pos_uuid+2, UUID_STR_SIZE-1); /* Flawfinder: ignore */
+ image_uuid_str[UUID_STR_SIZE-1] = 0;
+
+ LLUUID image_uuid(image_uuid_str);
- llinfos << "Found UUID: " << image_uuid << llendl;
+ llinfos << "Found UUID: " << image_uuid << llendl;
- std::map<LLUUID, LLString>::iterator itor = gImageChecksums.find(image_uuid);
- if (itor != gImageChecksums.end())
- {
- llinfos << "Replacing with checksum: " << itor->second << llendl;
- if (itor->second.c_str() != NULL)
+ std::map<LLUUID, LLString>::iterator itor = gImageChecksums.find(image_uuid);
+ if (itor != gImageChecksums.end())
{
- memcpy(&pos_check[10], itor->second.c_str(), 32); /* Flawfinder: ignore */
+ llinfos << "Replacing with checksum: " << itor->second << llendl;
+ if (itor->second.c_str() != NULL)
+ {
+ memcpy(&pos_check[10], itor->second.c_str(), 32); /* Flawfinder: ignore */
+ }
}
}
}
@@ -334,7 +347,7 @@ void export_complete()
fwrite(buffer, 1, length, fXMLOut);
fclose(fXMLOut);
- delete buffer;
+ delete [] buffer;
}
@@ -412,7 +425,7 @@ void exported_j2c_complete(const LLTSCode status, void *user_data)
char *end = strrchr(file_path, gDirUtilp->getDirDelimiter()[0]);
end[0] = 0;
LLString output_file = llformat("%s/image-%03d.tga", file_path, image_num);//filename;
- delete file_path;
+ delete [] file_path;
//S32 name_len = output_file.length();
//strcpy(&output_file[name_len-3], "tga");
FILE* fOut = LLFile::fopen(output_file.c_str(), "wb"); /* Flawfinder: ignore */
@@ -579,31 +592,44 @@ void join_group_callback(S32 option, void* user_data)
class LLOpenAgentOffer : public LLInventoryFetchObserver
{
public:
- LLOpenAgentOffer() {}
- virtual ~LLOpenAgentOffer() {}
-
- virtual void done()
+ LLOpenAgentOffer(const std::string& from_name) : mFromName(from_name) {}
+ /*virtual*/ void done()
{
- open_offer(mComplete);
+ open_offer(mComplete, mFromName);
gInventory.removeObserver(this);
delete this;
}
+private:
+ std::string mFromName;
};
-class LLOpenTaskOffer : public LLInventoryExistenceObserver
+//unlike the FetchObserver for AgentOffer, we only make one
+//instance of the AddedObserver for TaskOffers
+//and it never dies. We do this because we don't know the UUID of
+//task offers until they are accepted, so we don't wouldn't
+//know what to watch for, so instead we just watch for all additions. -Gigs
+class LLOpenTaskOffer : public LLInventoryAddedObserver
{
-public:
- LLOpenTaskOffer() {}
- virtual ~LLOpenTaskOffer() {}
-
protected:
- virtual void done()
+ /*virtual*/ void done()
{
- open_offer(mExist);
- gInventory.removeObserver(this);
- delete this;
+ open_offer(mAdded, "");
+ mAdded.clear();
}
-};
+ };
+
+//one global instance to bind them
+LLOpenTaskOffer* gNewInventoryObserver=NULL;
+
+void start_new_inventory_observer()
+{
+ if (!gNewInventoryObserver) //task offer observer
+ {
+ // Observer is deleted by gInventory
+ gNewInventoryObserver = new LLOpenTaskOffer;
+ gInventory.addObserver(gNewInventoryObserver);
+ }
+}
class LLDiscardAgentOffer : public LLInventoryFetchComboObserver
{
@@ -655,7 +681,71 @@ protected:
};
-void open_offer(const std::vector<LLUUID>& items)
+//Returns TRUE if we are OK, FALSE if we are throttled
+//Set check_only true if you want to know the throttle status
+//without registering a hit -Gigs
+bool check_offer_throttle(const std::string& from_name, bool check_only)
+{
+ static U32 throttle_count;
+ static bool throttle_logged;
+ LLChat chat;
+ LLString log_message;
+
+ if (!gSavedSettings.getBOOL("ShowNewInventory"))
+ return false;
+
+ if (check_only)
+ {
+ return gThrottleTimer.hasExpired();
+ }
+
+ if(gThrottleTimer.checkExpirationAndReset(OFFER_THROTTLE_TIME))
+ {
+ //llinfos << "Throttle Expired" << llendl;
+ throttle_count=1;
+ throttle_logged=false;
+ return true;
+ }
+ else //has not expired
+ {
+ //llinfos << "Throttle Not Expired, Count: " << throttle_count << llendl;
+ // When downloading the initial inventory we get a lot of new items
+ // coming in and can't tell that from spam. JC
+ if (gStartupState >= STATE_STARTED
+ && throttle_count >= OFFER_THROTTLE_MAX_COUNT)
+ {
+ if (!throttle_logged)
+ {
+ // Use the name of the last item giver, who is probably the person
+ // spamming you. JC
+ std::ostringstream message;
+ message << gSecondLife;
+ if (!from_name.empty())
+ {
+ message << ": Items coming in too fast from " << from_name;
+ }
+ else
+ {
+ message << ": Items coming in too fast";
+ }
+ message << ", automatic preview disabled for "
+ << OFFER_THROTTLE_TIME << " seconds.";
+ chat.mText = message.str();
+ //this is kinda important, so actually put it on screen
+ LLFloaterChat::addChat(chat, FALSE, FALSE);
+ throttle_logged=true;
+ }
+ return false;
+ }
+ else
+ {
+ throttle_count++;
+ return true;
+ }
+ }
+}
+
+void open_offer(const std::vector<LLUUID>& items, const std::string& from_name)
{
std::vector<LLUUID>::const_iterator it = items.begin();
std::vector<LLUUID>::const_iterator end = items.end();
@@ -673,33 +763,66 @@ void open_offer(const std::vector<LLUUID>& items)
{
continue;
}
- switch(item->getType())
- {
- case LLAssetType::AT_NOTECARD:
- open_notecard(*it, LLString("Note: ") + item->getName(), TRUE, LLUUID::null, FALSE);
- break;
- case LLAssetType::AT_LANDMARK:
- open_landmark(*it, LLString("Landmark: ") + item->getName(), TRUE, LLUUID::null, FALSE);
- break;
- case LLAssetType::AT_TEXTURE:
- open_texture(*it, LLString("Texture: ") + item->getName(), TRUE, LLUUID::null, FALSE);
- break;
- default:
+ //if we are throttled, don't display them - Gigs
+ if (check_offer_throttle(from_name, false))
{
- // Don't auto-open the inventory - just select it if we
- // already have an active inventory.
- LLInventoryView* view = LLInventoryView::getActiveInventory();
- if(view)
+ // I'm not sure this is a good idea. JC
+ // bool show_keep_discard = item->getPermissions().getCreator() != gAgent.getID();
+ bool show_keep_discard = true;
+ switch(item->getType())
{
- LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus();
- LLFocusMgr::FocusLostCallback callback;
- callback = gFocusMgr.getFocusCallback();
- view->getPanel()->setSelection(item->getUUID(), TAKE_FOCUS_NO);
- gFocusMgr.setKeyboardFocus(focus_ctrl, callback);
+ case LLAssetType::AT_NOTECARD:
+ open_notecard(*it, LLString("Note: ") + item->getName(), show_keep_discard, LLUUID::null, FALSE);
+ break;
+ case LLAssetType::AT_LANDMARK:
+ open_landmark(*it, 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);
+ break;
+ default:
break;
}
}
+ //highlight item, if it's not in the trash or lost+found
+
+ // Don't auto-open the inventory floater
+ LLInventoryView* view = LLInventoryView::getActiveInventory();
+ if(!view)
+ {
+ return;
+ }
+
+ //Trash Check
+ LLUUID trash_id;
+ trash_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_TRASH);
+ if(gInventory.isObjectDescendentOf(item->getUUID(), trash_id))
+ {
+ return;
}
+ LLUUID lost_and_found_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_LOST_AND_FOUND);
+ //BOOL inventory_has_focus = gFocusMgr.childHasKeyboardFocus(view);
+ BOOL user_is_away = gAwayTimer.getStarted();
+
+ // don't select lost and found items if the user is active
+ if (gInventory.isObjectDescendentOf(item->getUUID(), lost_and_found_id)
+ && !user_is_away)
+ {
+ return;
+ }
+
+ //Not sure about this check. Could make it easy to miss incoming items. -Gigs
+ //don't dick with highlight while the user is working
+ //if(inventory_has_focus && !user_is_away)
+ // break;
+ //llinfos << "Highlighting" << item->getUUID() << llendl;
+ //highlight item
+
+ LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus();
+ LLFocusMgr::FocusLostCallback callback;
+ callback = gFocusMgr.getFocusCallback();
+ view->getPanel()->setSelection(item->getUUID(), TAKE_FOCUS_NO);
+ gFocusMgr.setKeyboardFocus(focus_ctrl, callback);
}
}
@@ -787,11 +910,11 @@ void inventory_offer_callback(S32 option, void* user_data)
char group_name[MAX_STRING]; /* Flawfinder: ignore */
if (gCacheName->getGroupName(info->mFromID, group_name))
{
- from_string = LLString("An object named ") + info->mFromName + " owned by the group '" + group_name + "'";
+ from_string = LLString("An object named '") + info->mFromName + "' owned by the group '" + group_name + "'";
}
else
{
- from_string = LLString("An object named ") + info->mFromName + " owned by an unknown group";
+ from_string = LLString("An object named '") + info->mFromName + "' owned by an unknown group";
}
}
else
@@ -800,11 +923,11 @@ void inventory_offer_callback(S32 option, void* user_data)
char last_name[MAX_STRING]; /* Flawfinder: ignore */
if (gCacheName->getName(info->mFromID, first_name, last_name))
{
- from_string = LLString("An object named ") + info->mFromName + " owned by " + first_name + " " + last_name;
+ from_string = LLString("An object named '") + info->mFromName + "' owned by " + first_name + " " + last_name;
}
else
{
- from_string = LLString("An object named ") + info->mFromName + " owned by an unknown user";
+ from_string = LLString("An object named '") + info->mFromName + "' owned by an unknown user";
}
}
}
@@ -813,9 +936,11 @@ void inventory_offer_callback(S32 option, void* user_data)
from_string = info->mFromName;
}
+ bool busy=FALSE;
+
switch(option)
{
- case 0:
+ case IOR_ACCEPT:
// ACCEPT. The math for the dialog works, because the accept
// for inventory_offered, task_inventory_offer or
// group_notice_inventory is 1 greater than the offer integer value.
@@ -826,9 +951,15 @@ void inventory_offer_callback(S32 option, void* user_data)
sizeof(info->mFolderID.mData));
// send the message
msg->sendReliable(info->mHost);
- log_message = info->mFromName + " gave you " + info->mDesc + ".";
- chat.mText = log_message;
- LLFloaterChat::addChatHistory(chat);
+
+ //don't spam them if they are getting flooded
+ if (check_offer_throttle(info->mFromName, true))
+ {
+ log_message = info->mFromName + " gave you " + info->mDesc + ".";
+ chat.mText = log_message;
+ LLFloaterChat::addChatHistory(chat);
+ }
+
// we will want to open this item when it comes back.
lldebugs << "Initializing an opener for tid: " << info->mTransactionID
<< llendl;
@@ -841,7 +972,7 @@ void inventory_offer_callback(S32 option, void* user_data)
// so we can fetch it out of our inventory.
LLInventoryFetchObserver::item_ref_t items;
items.push_back(info->mObjectID);
- LLOpenAgentOffer* open_agent_offer = new LLOpenAgentOffer;
+ LLOpenAgentOffer* open_agent_offer = new LLOpenAgentOffer(from_string);
open_agent_offer->fetchItems(items);
if(catp || (itemp && itemp->isComplete()))
{
@@ -857,22 +988,10 @@ void inventory_offer_callback(S32 option, void* user_data)
case IM_GROUP_NOTICE:
case IM_GROUP_NOTICE_REQUESTED:
{
- // This is an offer from a task or group.
- // Because it would be easy
- // to write a task which would overload your inventory, we
- // force the offer to stay in an instant message until
- // accepted. Thus, we have to respond, and then wait for
- // the update to come back before we open the item.
- LLOpenTaskOffer* open_task_offer = new LLOpenTaskOffer;
- open_task_offer->watchItem(info->mObjectID);
- if(itemp && itemp->isComplete())
- {
- opener->changed(0x0);
- }
- else
- {
- opener = open_task_offer;
- }
+ // This is an offer from a task or group.
+ // We don't use a new instance of an opener
+ // We instead use the singular observer gOpenTaskOffer
+ // Since it already exists, we don't need to actually do anything
}
break;
default:
@@ -881,9 +1000,12 @@ void inventory_offer_callback(S32 option, void* user_data)
}
break;
- case 2:
+ case IOR_BUSY:
+ //Busy falls through to decline. Says to make busy message.
+ busy=TRUE;
+ case IOR_MUTE:
// MUTE falls through to decline
- case 1:
+ case IOR_DECLINE:
// DECLINE. The math for the dialog works, because the decline
// for inventory_offered, task_inventory_offer or
// group_notice_inventory is 2 greater than the offer integer value.
@@ -921,7 +1043,7 @@ void inventory_offer_callback(S32 option, void* user_data)
}
}
- if (!info->mFromGroup && !info->mFromObject)
+ if (busy || (!info->mFromGroup && !info->mFromObject))
{
busy_message(msg,info->mFromID);
}
@@ -944,88 +1066,81 @@ void inventory_offer_callback(S32 option, void* user_data)
void inventory_offer_handler(LLOfferInfo* info, BOOL from_task)
{
- switch(info->mType)
+
+ //Until throttling is implmented, busy mode should reject inventory instead of silently
+ //accepting it. SEE SL-39554
+ if (gAgent.getBusy())
+ {
+ inventory_offer_callback(IOR_BUSY, info);
+ return;
+ }
+
+ //If muted, don't even go through the messaging stuff. Just curtail the offer here.
+ if (gMuteListp->isMuted(info->mFromID, info->mFromName))
+ {
+ inventory_offer_callback(IOR_MUTE, info);
+ return;
+ }
+
+ if (gSavedSettings.getBOOL("ShowNewInventory")
+ && (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.
- case LLAssetType::AT_NOTECARD:
- case LLAssetType::AT_LANDMARK:
- case LLAssetType::AT_TEXTURE:
- {
- // 0 = accept button
- inventory_offer_callback(0, info);
- //LLInventoryView::sOpenNextNewItem = TRUE;
- }
- break;
-
- case LLAssetType::AT_SOUND:
- case LLAssetType::AT_CALLINGCARD:
- case LLAssetType::AT_SCRIPT:
- case LLAssetType::AT_CLOTHING:
- case LLAssetType::AT_OBJECT:
- case LLAssetType::AT_CATEGORY:
- case LLAssetType::AT_ROOT_CATEGORY:
- case LLAssetType::AT_LSL_TEXT:
- case LLAssetType::AT_LSL_BYTECODE:
- case LLAssetType::AT_TEXTURE_TGA:
- case LLAssetType::AT_BODYPART:
- case LLAssetType::AT_TRASH:
- case LLAssetType::AT_SNAPSHOT_CATEGORY:
- case LLAssetType::AT_LOST_AND_FOUND:
- case LLAssetType::AT_ANIMATION:
- case LLAssetType::AT_GESTURE:
- default:
- {
- LLString::format_map_t args;
- args["[OBJECTNAME]"] = info->mDesc;
- args["[OBJECTTYPE]"] = LLAssetType::lookupHumanReadable(info->mType);
-
- // Name cache callbacks don't store userdata, so can't save
- // off the LLOfferInfo. Argh. JC
- BOOL name_found = FALSE;
- char first_name[MAX_STRING]; /* Flawfinder: ignore */
- char last_name[MAX_STRING]; /* Flawfinder: ignore */
- if (info->mFromGroup)
- {
- if (gCacheName->getGroupName(info->mFromID, first_name))
- {
- args["[FIRST]"] = first_name;
- args["[LAST]"] = "";
- name_found = TRUE;
- }
- }
- else
- {
- if (gCacheName->getName(info->mFromID, first_name, last_name))
- {
- args["[FIRST]"] = first_name;
- args["[LAST]"] = last_name;
- name_found = TRUE;
- }
- }
- if (from_task)
- {
- args["[OBJECTFROMNAME]"] = info->mFromName;
- if (name_found)
- {
- LLNotifyBox::showXml("ObjectGiveItem", args,
- &inventory_offer_callback, (void*)info);
- }
- else
- {
- LLNotifyBox::showXml("ObjectGiveItemUnknownUser", args,
- &inventory_offer_callback, (void*)info);
- }
- }
- else
- {
- // XUI:translate -> [FIRST] [LAST]
- args["[NAME]"] = info->mFromName;
- LLNotifyBox::showXml("UserGiveItem", args,
- &inventory_offer_callback, (void*)info);
- }
- break;
- }
+ // 0 = accept button
+ inventory_offer_callback(IOR_ACCEPT, info);
+ return;
+ }
+
+ LLString::format_map_t args;
+ args["[OBJECTNAME]"] = info->mDesc;
+ args["[OBJECTTYPE]"] = LLAssetType::lookupHumanReadable(info->mType);
+
+ // Name cache callbacks don't store userdata, so can't save
+ // off the LLOfferInfo. Argh. JC
+ BOOL name_found = FALSE;
+ char first_name[MAX_STRING]; /* Flawfinder: ignore */
+ char last_name[MAX_STRING]; /* Flawfinder: ignore */
+ if (info->mFromGroup)
+ {
+ if (gCacheName->getGroupName(info->mFromID, first_name))
+ {
+ args["[FIRST]"] = first_name;
+ args["[LAST]"] = "";
+ name_found = TRUE;
+ }
+ }
+ else
+ {
+ if (gCacheName->getName(info->mFromID, first_name, last_name))
+ {
+ args["[FIRST]"] = first_name;
+ args["[LAST]"] = last_name;
+ name_found = TRUE;
+ }
+ }
+ if (from_task)
+ {
+ args["[OBJECTFROMNAME]"] = info->mFromName;
+ if (name_found)
+ {
+ LLNotifyBox::showXml("ObjectGiveItem", args,
+ &inventory_offer_callback, (void*)info);
+ }
+ else
+ {
+ LLNotifyBox::showXml("ObjectGiveItemUnknownUser", args,
+ &inventory_offer_callback, (void*)info);
+ }
+ }
+ else
+ {
+ // XUI:translate -> [FIRST] [LAST]
+ args["[NAME]"] = info->mFromName;
+ LLNotifyBox::showXml("UserGiveItem", args,
+ &inventory_offer_callback, (void*)info);
}
}
@@ -1740,6 +1855,14 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
case IM_GOTO_URL:
{
+ if (binary_bucket_size <= 0)
+ {
+ llwarns << "bad binary_bucket_size: "
+ << binary_bucket_size
+ << " - aborting function." << llendl;
+ return;
+ }
+
char* url = new char[binary_bucket_size];
if (url == NULL)
{
@@ -1965,16 +2088,22 @@ void process_offer_callingcard(LLMessageSystem* msg, void**)
{
// automatically decline offer
callingcard_offer_callback(1, (void*)offerdata);
- return;
+ offerdata = NULL; // pointer was freed by callback
+ }
+ else
+ {
+ LLNotifyBox::showXml("OfferCallingCard", args,
+ &callingcard_offer_callback, (void*)offerdata);
+ offerdata = NULL; // pointer ownership transferred
}
-
- LLNotifyBox::showXml("OfferCallingCard", args,
- &callingcard_offer_callback, (void*)offerdata);
}
else
{
llwarns << "Calling card offer from an unknown source." << llendl;
}
+
+ delete offerdata; // !=NULL if we didn't give ownership away
+ offerdata = NULL;
}
void process_accept_callingcard(LLMessageSystem* msg, void**)
@@ -3589,7 +3718,7 @@ void process_avatar_sit_response(LLMessageSystem *mesgsys, void **user_data)
if (object)
{
LLVector3 sit_spot = object->getPositionAgent() + (sitPosition * object->getRotation());
- if (!use_autopilot || (avatar->mIsSitting && avatar->getRoot() == object->getRoot()))
+ if (!use_autopilot || (avatar && avatar->mIsSitting && avatar->getRoot() == object->getRoot()))
{
//we're already sitting on this object, so don't autopilot
}
@@ -4982,9 +5111,10 @@ void onCovenantLoadComplete(LLVFS *vfs,
if( (file_length > 19) && !strncmp( buffer, "Linden text version", 19 ) )
{
- LLViewerTextEditor* editor = new LLViewerTextEditor("temp",
- LLRect(0,0,0,0),
- file_length+1);
+ LLViewerTextEditor* editor =
+ new LLViewerTextEditor("temp",
+ LLRect(0,0,0,0),
+ file_length+1);
if( !editor->importBuffer( buffer ) )
{
llwarns << "Problem importing estate covenant." << llendl;
@@ -5000,27 +5130,32 @@ void onCovenantLoadComplete(LLVFS *vfs,
}
else
{
- if( gViewerStats )
- {
- gViewerStats->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );
- }
-
- if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ||
- LL_ERR_FILE_EMPTY == status)
- {
- covenant_text = "Estate covenant notecard is missing from database.";
- }
- else if (LL_ERR_INSUFFICIENT_PERMISSIONS == status)
- {
- covenant_text = "Insufficient permissions to view estate covenant.";
- }
- else
- {
- covenant_text = "Unable to load estate covenant at this time.";
- }
-
- llwarns << "Problem loading notecard: " << status << llendl;
+ llwarns << "Problem importing estate covenant: Covenant file format error." << llendl;
+ covenant_text = "Problem importing estate covenant: Covenant file format error.";
+ }
+ }
+ else
+ {
+ if( gViewerStats )
+ {
+ gViewerStats->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );
}
+
+ if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ||
+ LL_ERR_FILE_EMPTY == status)
+ {
+ covenant_text = "Estate covenant notecard is missing from database.";
+ }
+ else if (LL_ERR_INSUFFICIENT_PERMISSIONS == status)
+ {
+ covenant_text = "Insufficient permissions to view estate covenant.";
+ }
+ else
+ {
+ covenant_text = "Unable to load estate covenant at this time.";
+ }
+
+ llwarns << "Problem loading notecard: " << status << llendl;
}
LLPanelEstateCovenant::updateCovenantText(covenant_text, asset_uuid);
LLPanelLandCovenant::updateCovenantText(covenant_text);
diff --git a/indra/newview/llviewermessage.h b/indra/newview/llviewermessage.h
index 04fb668aba..ccfd1f7277 100644
--- a/indra/newview/llviewermessage.h
+++ b/indra/newview/llviewermessage.h
@@ -28,6 +28,14 @@ class LLViewerRegion;
// Prototypes
//
+enum InventoryOfferResponse
+{
+ IOR_ACCEPT,
+ IOR_DECLINE,
+ IOR_MUTE,
+ IOR_BUSY
+};
+
BOOL can_afford_transaction(S32 cost);
void give_money(const LLUUID& uuid, LLViewerRegion* region, S32 amount, BOOL is_group = FALSE,
S32 trx_type = TRANS_GIFT, const LLString& desc = LLString::null);
@@ -170,6 +178,7 @@ void invalid_message_callback(LLMessageSystem*, void*, EMessageException);
void process_initiate_download(LLMessageSystem* msg, void**);
void inventory_offer_callback(S32 option, void* user_data);
+void start_new_inventory_observer();
struct LLOfferInfo
{
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 7ae166849b..bf4ad172e6 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -619,10 +619,10 @@ BOOL LLViewerObject::setDrawableParent(LLDrawable* parentp)
}
U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
- void **user_data,
- U32 block_num,
- const EObjectUpdateType update_type,
- LLDataPacker *dp)
+ void **user_data,
+ U32 block_num,
+ const EObjectUpdateType update_type,
+ LLDataPacker *dp)
{
LLMemType mt(LLMemType::MTYPE_OBJECT);
@@ -638,6 +638,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
from_region_handle(region_handle, &x, &y);
llerrs << "Object has invalid region " << x << ":" << y << "!" << llendl;
+ return retval;
}
U16 time_dilation16;
@@ -914,7 +915,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
// Check for appended generic data
S32 data_size = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_Data);
- if (data_size == 0)
+ if (data_size <= 0)
{
mData = NULL;
}
@@ -1737,9 +1738,16 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
if (gPingInterpolate)
{
LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(mesgsys->getSender());
- F32 ping_delay = 0.5f * mTimeDilation * ( ((F32)cdp->getPingDelay()) * 0.001f + gFrameDTClamped);
- LLVector3 diff = getVelocity() * (0.5f*mTimeDilation*(gFrameDTClamped + ((F32)ping_delay)*0.001f));
- new_pos_parent += diff;
+ if (cdp)
+ {
+ F32 ping_delay = 0.5f * mTimeDilation * ( ((F32)cdp->getPingDelay()) * 0.001f + gFrameDTClamped);
+ LLVector3 diff = getVelocity() * (0.5f*mTimeDilation*(gFrameDTClamped + ((F32)ping_delay)*0.001f));
+ new_pos_parent += diff;
+ }
+ else
+ {
+ llwarns << "findCircuit() returned NULL; skipping interpolation" << llendl;
+ }
}
//////////////////////////
@@ -4114,7 +4122,7 @@ void LLViewerObject::setAttachedSound(const LLUUID &audio_uuid, const LLUUID& ow
{
return;
}
-
+
if (audio_uuid.isNull())
{
if (mAudioSourcep && mAudioSourcep->isLoop() && !mAudioSourcep->hasPendingPreloads())
@@ -4149,7 +4157,8 @@ void LLViewerObject::setAttachedSound(const LLUUID &audio_uuid, const LLUUID& ow
}
}
- if ( mAudioSourcep )
+ // don't clean up before previous sound is done. Solves: SL-33486
+ if ( mAudioSourcep && mAudioSourcep->isDone() )
{
gAudiop->cleanupAudioSource(mAudioSourcep);
mAudioSourcep = NULL;
diff --git a/indra/newview/llviewerparceloverlay.cpp b/indra/newview/llviewerparceloverlay.cpp
index f5d7aa1094..58785805b2 100644
--- a/indra/newview/llviewerparceloverlay.cpp
+++ b/indra/newview/llviewerparceloverlay.cpp
@@ -465,20 +465,21 @@ void LLViewerParcelOverlay::updatePropertyLines()
// shuffling.
S32 new_vertex_count = new_vertex_array.count();
- // NOTE: If the new_vertex_count is 0 and wasn't 0 previously
- // the arrays are still allocated as the arrays aren't set to NULL, etc.
- // This won't cause any problems, but might waste a few cycles copying over
- // old data. - jwolk
- if ( !(mVertexArray && mColorArray && new_vertex_count == mVertexCount) && new_vertex_count > 0 )
+ if (!(mVertexArray && mColorArray && new_vertex_count == mVertexCount))
{
// ...need new arrays
delete[] mVertexArray;
+ mVertexArray = NULL;
delete[] mColorArray;
+ mColorArray = NULL;
mVertexCount = new_vertex_count;
- mVertexArray = new F32[3 * mVertexCount];
- mColorArray = new U8 [4 * mVertexCount];
+ if (new_vertex_count > 0)
+ {
+ mVertexArray = new F32[3 * mVertexCount];
+ mColorArray = new U8 [4 * mVertexCount];
+ }
}
// Copy the new data into the arrays
diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp
index de67506e3f..f2cf4b3dc6 100644
--- a/indra/newview/llvlcomposition.cpp
+++ b/indra/newview/llvlcomposition.cpp
@@ -106,6 +106,13 @@ BOOL LLVLComposition::generateHeights(const F32 x, const F32 y,
}
llassert(mSurfacep);
+
+ if (!mSurfacep || !mSurfacep->getRegion())
+ {
+ // We don't always have the region yet here....
+ return FALSE;
+ }
+
S32 x_begin, y_begin, x_end, y_end;
x_begin = llround( x * mScaleInv );
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 2b821bed9f..1f1145624b 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -1466,6 +1466,7 @@ void LLVOAvatar::initClass()
if (!root)
{
llerrs << "No root node found in avatar configuration file: " << xmlFile << llendl;
+ return;
}
//-------------------------------------------------------------------------
@@ -1873,6 +1874,7 @@ void LLVOAvatar::buildCharacter()
mEyeRightp))
{
llerrs << "Failed to create avatar." << llendl;
+ return;
}
//-------------------------------------------------------------------------
@@ -2441,7 +2443,7 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
if (LLVOAvatar::sJointDebug)
{
- llinfos << getNVPair("FirstName")->getString() << getNVPair("LastName")->getString() << ": joint touches: " << LLJoint::sNumTouches << " updates: " << LLJoint::sNumUpdates << llendl;
+ llinfos << getFullname() << ": joint touches: " << LLJoint::sNumTouches << " updates: " << LLJoint::sNumUpdates << llendl;
}
LLJoint::sNumUpdates = 0;
@@ -4789,7 +4791,7 @@ BOOL LLVOAvatar::allocateCollisionVolumes( U32 num )
LLJoint *LLVOAvatar::getCharacterJoint( U32 num )
{
if ((S32)num >= mNumJoints
- || num < 0)
+ || (S32)num < 0)
{
return NULL;
}
diff --git a/indra/newview/llvoclouds.cpp b/indra/newview/llvoclouds.cpp
index 1e5caa17d4..7fc96975c9 100644
--- a/indra/newview/llvoclouds.cpp
+++ b/indra/newview/llvoclouds.cpp
@@ -106,6 +106,12 @@ BOOL LLVOClouds::updateGeometry(LLDrawable *drawable)
for ( ; face_indx < num_faces; face_indx++)
{
facep = drawable->getFace(face_indx);
+ if (!facep)
+ {
+ llwarns << "No facep for index " << face_indx << llendl;
+ continue;
+ }
+
if (isParticle())
{
facep->setSize(1,1);
@@ -123,6 +129,12 @@ BOOL LLVOClouds::updateGeometry(LLDrawable *drawable)
for ( ; face_indx < drawable->getNumFaces(); face_indx++)
{
facep = drawable->getFace(face_indx);
+ if (!facep)
+ {
+ llwarns << "No facep for index " << face_indx << llendl;
+ continue;
+ }
+
facep->setTEOffset(face_indx);
facep->setSize(0,0);
}
diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp
index b641bf6f27..c0df55b670 100644
--- a/indra/newview/llvopartgroup.cpp
+++ b/indra/newview/llvopartgroup.cpp
@@ -131,7 +131,7 @@ BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable)
if (!num_parts)
{
- if (drawable->getNumFaces())
+ if (group && drawable->getNumFaces())
{
group->dirtyGeom();
}
@@ -186,6 +186,12 @@ BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable)
count++;
facep = drawable->getFace(i);
+ if (!facep)
+ {
+ llwarns << "No face found for index " << i << "!" << llendl;
+ continue;
+ }
+
facep->setTEOffset(i);
const F32 NEAR_PART_DIST_SQ = 5.f*5.f; // Only discard particles > 5 m from the camera
const F32 MIN_PART_AREA = .005f*.005f; // only less than 5 mm x 5 mm at 1 m from camera
@@ -239,6 +245,11 @@ BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable)
for (i = count; i < drawable->getNumFaces(); i++)
{
LLFace* facep = drawable->getFace(i);
+ if (!facep)
+ {
+ llwarns << "No face found for index " << i << "!" << llendl;
+ continue;
+ }
facep->setTEOffset(i);
facep->setSize(0,0);
}
diff --git a/indra/newview/llwindebug.cpp b/indra/newview/llwindebug.cpp
index 428df0b45a..b24e222570 100644
--- a/indra/newview/llwindebug.cpp
+++ b/indra/newview/llwindebug.cpp
@@ -111,6 +111,8 @@ BOOL LLWinDebug::setupExceptionHandler()
if (!f_mdwp)
{
write_debug("No MiniDumpWriteDump!\n");
+ FreeLibrary(hDll);
+ hDll = NULL;
ok = FALSE;
}
}
diff --git a/indra/newview/llworldmap.cpp b/indra/newview/llworldmap.cpp
index 59587ef13c..e61b5f1af5 100644
--- a/indra/newview/llworldmap.cpp
+++ b/indra/newview/llworldmap.cpp
@@ -471,7 +471,7 @@ void LLWorldMap::processMapBlockReply(LLMessageSystem* msg, void**)
U32 agent_flags;
msg->getU32Fast(_PREHASH_AgentData, _PREHASH_Flags, agent_flags);
- if (agent_flags < 0 || agent_flags >= MAP_SIM_IMAGE_TYPES)
+ if ((S32)agent_flags < 0 || agent_flags >= MAP_SIM_IMAGE_TYPES)
{
llwarns << "Invalid map image type returned! " << agent_flags << llendl;
return;
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 43c587ed92..bb0efb48e1 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -748,6 +748,7 @@ void LLPipeline::updateMoveDampedAsync(LLDrawable* drawablep)
if (!drawablep)
{
llerrs << "updateMove called with NULL drawablep" << llendl;
+ return;
}
if (drawablep->isState(LLDrawable::EARLY_MOVE))
{
@@ -1104,7 +1105,7 @@ void LLPipeline::updateGeom(F32 max_dtime)
last_bridge = bridge;
BOOL update_complete = TRUE;
- if (drawablep && !drawablep->isDead())
+ if (!drawablep->isDead())
{
update_complete = updateDrawableGeom(drawablep, FALSE);
count++;
@@ -1378,7 +1379,9 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera)
LLMemType mt(LLMemType::MTYPE_PIPELINE);
LLFastTimer ftm(LLFastTimer::FTM_STATESORT_DRAWABLE);
- if (drawablep->isDead() || !hasRenderType(drawablep->getRenderType()))
+ if (!drawablep
+ || drawablep->isDead()
+ || !hasRenderType(drawablep->getRenderType()))
{
return;
}
@@ -1392,7 +1395,7 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera)
}
}
- if (drawablep && (hasRenderType(drawablep->mRenderType)))
+ if (hasRenderType(drawablep->mRenderType))
{
if (!drawablep->isState(LLDrawable::INVISIBLE|LLDrawable::FORCE_INVISIBLE))
{
@@ -1815,6 +1818,7 @@ void LLPipeline::renderHighlights()
if (!facep || facep->getDrawable()->isDead())
{
llerrs << "Bad face on selection" << llendl;
+ return;
}
facep->renderSelected(mFaceSelectImagep, color);
@@ -4025,4 +4029,4 @@ void LLPipeline::renderBloom(GLuint source, GLuint dest, GLuint buffer, U32 res,
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
-} \ No newline at end of file
+}