diff --git a/indra/llui/lldelayeduidelete.cpp b/indra/llui/lldelayeduidelete.cpp
new file mode 100644
index 000000000..d632c80fa
--- /dev/null
+++ b/indra/llui/lldelayeduidelete.cpp
@@ -0,0 +1,64 @@
+//
+#include "linden_common.h"
+#include "lldelayeduidelete.h"
+#define DELETE_DELAY 0.1f
+#define DELETES_PER_DELAY 512
+std::list LLDeleteScheduler::sJobs;
+LLDeleteScheduler::LLDeleteScheduler() : LLEventTimer(DELETE_DELAY)
+{
+}
+void LLDeleteScheduler::addViewDeleteJob(std::list views)
+{
+ if(!views.empty())
+ {
+ LLViewDeleteJob* job = new LLViewDeleteJob(views);
+ sJobs.push_back(job);
+ }
+}
+BOOL LLDeleteScheduler::tick() // IMPORTANT: never return TRUE
+{
+ if(!sJobs.empty())
+ {
+ U32 completed = 0;
+ do
+ {
+ LLDeleteJob* job = sJobs.front();
+ if(job->work(completed))
+ {
+ delete job;
+ sJobs.pop_front();
+ }
+ } while((completed < DELETES_PER_DELAY) && !sJobs.empty());
+ }
+ return FALSE; // EVER
+}
+BOOL LLDeleteJob::work(U32& completed)
+{
+ llwarns << "THIS IS SPOSED TO BE OVERRIDDEN" << llendl;
+ return TRUE;
+}
+LLViewDeleteJob::LLViewDeleteJob(std::list views)
+: mList(views)
+{
+}
+LLViewDeleteJob::~LLViewDeleteJob()
+{
+}
+BOOL LLViewDeleteJob::work(U32& completed)
+{
+ do
+ {
+ if(!mList.empty())
+ {
+ LLView* view = mList.front();
+ delete view;
+ mList.pop_front();
+ }
+ else
+ {
+ return TRUE; // job done
+ }
+ } while(++completed < DELETES_PER_DELAY);
+ return FALSE;
+}
+//
diff --git a/indra/llui/lldelayeduidelete.h b/indra/llui/lldelayeduidelete.h
new file mode 100644
index 000000000..904a7b6a5
--- /dev/null
+++ b/indra/llui/lldelayeduidelete.h
@@ -0,0 +1,31 @@
+//
+#ifndef LL_LLDELAYEDUIDELETE_H
+#define LL_LLDELAYEDUIDELETE_H
+#include "lltimer.h"
+#include "llview.h"
+class LLDeleteJob
+{
+public:
+ virtual BOOL work(U32& completed);
+};
+class LLViewDeleteJob : public LLDeleteJob
+{
+public:
+ LLViewDeleteJob(std::list views);
+ virtual ~LLViewDeleteJob();
+ virtual BOOL work(U32& completed);
+private:
+ std::list mList;
+};
+class LLDeleteScheduler : public LLEventTimer
+{
+public:
+ LLDeleteScheduler();
+ void addViewDeleteJob(std::list views);
+ BOOL tick();
+private:
+ static std::list sJobs;
+};
+static LLDeleteScheduler* gDeleteScheduler;
+#endif
+//
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index b6e8ab5e1..de520b47c 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -242,6 +242,7 @@ set(viewer_SOURCE_FILES
llinventoryview.cpp
lljoystickbutton.cpp
lllandmarklist.cpp
+ lllocalinventory.cpp
lllogchat.cpp
llloginhandler.cpp
llsavedlogins.cpp
@@ -668,6 +669,7 @@ set(viewer_HEADER_FILES
lljoystickbutton.h
lllandmarklist.h
lllightconstants.h
+ lllocalinventory.h
lllogchat.h
llloginhandler.h
llsavedlogins.h
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 2a8a2f824..5b38fe0ac 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -95,6 +95,10 @@
#include "lltexturefetch.h"
#include "llimageworker.h"
+//
+#include "lldelayeduidelete.h"
+#include "llbuildnewviewsscheduler.h"
+//
// The files below handle dependencies from cleanup.
#include "llkeyframemotion.h"
#include "llworldmap.h"
@@ -241,6 +245,9 @@ F32 gLogoutMaxTime = LOGOUT_REQUEST_TIME;
LLUUID gInventoryLibraryOwner;
LLUUID gInventoryLibraryRoot;
+//
+LLUUID gLocalInventoryRoot;
+//
BOOL gDisconnected = FALSE;
@@ -284,6 +291,9 @@ const std::string ERROR_MARKER_FILE_NAME("SecondLife.error_marker");
const std::string LLERROR_MARKER_FILE_NAME("SecondLife.llerror_marker");
const std::string LOGOUT_MARKER_FILE_NAME("SecondLife.logout_marker");
static BOOL gDoDisconnect = FALSE;
+//
+//static BOOL gBusyDisconnect = FALSE;
+//
static std::string gLaunchFileOnQuit;
// Used on Win32 for other apps to identify our window (eg, win_setup)
@@ -565,6 +575,10 @@ bool LLAppViewer::init()
initLogging();
+ //
+ gDeleteScheduler = new LLDeleteScheduler();
+ gBuildNewViewsScheduler = new LLBuildNewViewsScheduler();
+ //
//
// OK to write stuff to logs now, we've now crash reported if necessary
//
@@ -580,12 +594,19 @@ bool LLAppViewer::init()
writeSystemInfo();
// Build a string representing the current version number.
+ // meh
+ /*
+ //
gCurrentVersion = llformat("%s %d.%d.%d.%d",
gSavedSettings.getString("VersionChannelName").c_str(),
LL_VERSION_MAJOR,
LL_VERSION_MINOR,
LL_VERSION_PATCH,
LL_VERSION_BUILD );
+ //
+ */
+ gCurrentVersion = gSavedSettings.getString("SpecifiedChannel");
+ //
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
@@ -919,6 +940,7 @@ bool LLAppViewer::mainLoop()
pauseMainloopTimeout(); // *TODO: Remove. Messages shouldn't be stalling for 20+ seconds!
LLFastTimer t3(LLFastTimer::FTM_IDLE);
+ // bad_alloc!!
idle();
if (gAres != NULL && gAres->isInitialized())
@@ -1201,8 +1223,11 @@ bool LLAppViewer::cleanup()
// such that we can suck rectangle information out of
// it.
cleanupSavedSettings();
- llinfos << "Settings patched up" << llendflush;
-
+ llinfos << "Settings patched up" << llendflush;
+
+ // moving this to below.
+ /*
+ //
// delete some of the files left around in the cache.
removeCacheFiles("*.wav");
removeCacheFiles("*.tmp");
@@ -1211,6 +1236,9 @@ bool LLAppViewer::cleanup()
removeCacheFiles("*.dsf");
removeCacheFiles("*.bodypart");
removeCacheFiles("*.clothing");
+ //
+ */
+ //
llinfos << "Cache files removed" << llendflush;
@@ -1339,6 +1367,18 @@ bool LLAppViewer::cleanup()
}
removeMarkerFile(); // Any crashes from here on we'll just have to ignore
+ // moved this stuff from above to make it conditional here...
+ if(!anotherInstanceRunning())
+ {
+ removeCacheFiles("*.wav");
+ removeCacheFiles("*.tmp");
+ removeCacheFiles("*.lso");
+ removeCacheFiles("*.out");
+ removeCacheFiles("*.dsf");
+ removeCacheFiles("*.bodypart");
+ removeCacheFiles("*.clothing");
+ }
+ //
writeDebugInfo();
@@ -2148,8 +2188,10 @@ bool LLAppViewer::initWindow()
// always start windowed
BOOL ignorePixelDepth = gSavedSettings.getBOOL("IgnorePixelDepth");
- gViewerWindow = new LLViewerWindow(gWindowTitle,
- VIEWER_WINDOW_CLASSNAME,
+ //
+ //gViewerWindow = new LLViewerWindow(gWindowTitle, "Second Life",
+ gViewerWindow = new LLViewerWindow("Inertia", "Second Life",
+ //
gSavedSettings.getS32("WindowX"), gSavedSettings.getS32("WindowY"),
gSavedSettings.getS32("WindowWidth"), gSavedSettings.getS32("WindowHeight"),
FALSE, ignorePixelDepth);
@@ -2278,7 +2320,10 @@ void LLAppViewer::writeSystemInfo()
{
gDebugInfo["SLLog"] = LLError::logFileName();
- gDebugInfo["ClientInfo"]["Name"] = gSavedSettings.getString("VersionChannelName");
+ //
+ //gDebugInfo["ClientInfo"]["Name"] = gSavedSettings.getString("VersionChannelName");
+ gDebugInfo["ClientInfo"]["Name"] = gSavedSettings.getString("SpecifiedChannel");
+ //
gDebugInfo["ClientInfo"]["MajorVersion"] = LL_VERSION_MAJOR;
gDebugInfo["ClientInfo"]["MinorVersion"] = LL_VERSION_MINOR;
gDebugInfo["ClientInfo"]["PatchVersion"] = LL_VERSION_PATCH;
@@ -2374,7 +2419,10 @@ void LLAppViewer::handleViewerCrash()
//We already do this in writeSystemInfo(), but we do it again here to make /sure/ we have a version
//to check against no matter what
- gDebugInfo["ClientInfo"]["Name"] = gSavedSettings.getString("VersionChannelName");
+ //
+ //gDebugInfo["ClientInfo"]["Name"] = gSavedSettings.getString("VersionChannelName");
+ gDebugInfo["ClientInfo"]["Name"] = gSavedSettings.getString("SpecifiedChannel");
+ //
gDebugInfo["ClientInfo"]["MajorVersion"] = LL_VERSION_MAJOR;
gDebugInfo["ClientInfo"]["MinorVersion"] = LL_VERSION_MINOR;
@@ -3075,6 +3123,9 @@ void LLAppViewer::badNetworkHandler()
// Flush all of our caches on exit in the case of disconnect due to
// invalid packets.
+ //
+ if(1) return;
+ //
mPurgeOnExit = TRUE;
@@ -3291,8 +3342,10 @@ void LLAppViewer::idle()
// *FIX: (???) SAMANTHA
if (viewer_stats_timer.getElapsedTimeF32() >= SEND_STATS_PERIOD && !gDisconnected)
{
- llinfos << "Transmitting sessions stats" << llendl;
- send_stats();
+ // we are not transmitting session stats
+ //llinfos << "Transmitting sessions stats" << llendl;
+ //send_stats();
+ //
viewer_stats_timer.reset();
}
@@ -4030,7 +4083,10 @@ void LLAppViewer::handleLoginComplete()
initMainloopTimeout("Mainloop Init");
// Store some data to DebugInfo in case of a freeze.
- gDebugInfo["ClientInfo"]["Name"] = gSavedSettings.getString("VersionChannelName");
+ //
+ //gDebugInfo["ClientInfo"]["Name"] = gSavedSettings.getString("VersionChannelName");
+ gDebugInfo["ClientInfo"]["Name"] = gSavedSettings.getString("SpecifiedChannel");
+ //
gDebugInfo["ClientInfo"]["MajorVersion"] = LL_VERSION_MAJOR;
gDebugInfo["ClientInfo"]["MinorVersion"] = LL_VERSION_MINOR;
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index 1cd847b6e..f072f354a 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -307,6 +307,9 @@ extern F32 gSimFrames;
extern LLUUID gInventoryLibraryOwner;
extern LLUUID gInventoryLibraryRoot;
+//
+extern LLUUID gLocalInventoryRoot;
+//
extern BOOL gDisconnected;
diff --git a/indra/newview/lllocalinventory.cpp b/indra/newview/lllocalinventory.cpp
new file mode 100644
index 000000000..4b434eed8
--- /dev/null
+++ b/indra/newview/lllocalinventory.cpp
@@ -0,0 +1,521 @@
+//
+#include "llviewerprecompiledheaders.h"
+
+#include "lllocalinventory.h"
+
+#include "llviewerinventory.h"
+#include "llviewercontrol.h"
+
+#include "llpreviewsound.h"
+#include "llpreviewanim.h"
+#include "llpreviewtexture.h"
+#include "llpreviewgesture.h"
+#include "llpreviewlandmark.h"
+#include "dofloaterhex.h"
+#include "hgfloatertexteditor.h"
+
+#include "llappviewer.h"
+
+#include "lluictrlfactory.h"
+#include "llcombobox.h"
+
+#include "llagent.h" // gAgent
+#include "llviewerwindow.h" // alertXml
+
+
+LLUUID LLLocalInventory::addItem(std::string name, int type, LLUUID asset_id, bool open_automatically)
+{
+ LLUUID item_id = addItem(name, type, asset_id);
+ if(open_automatically) open(item_id);
+ return item_id;
+}
+
+LLUUID LLLocalInventory::addItem(std::string name, int type, LLUUID asset_id)
+{
+ LLUUID item_id;
+ item_id.generate();
+ LLPermissions* perms = new LLPermissions();
+ perms->set(LLPermissions::DEFAULT);
+ perms->setOwnerAndGroup(LLUUID::null, LLUUID::null, LLUUID::null, false);
+ perms->setMaskBase(0);
+ perms->setMaskEveryone(0);
+ perms->setMaskGroup(0);
+ perms->setMaskNext(0);
+ perms->setMaskOwner(0);
+ LLViewerInventoryItem* item = new LLViewerInventoryItem(
+ item_id,
+ gLocalInventoryRoot,
+ *perms,
+ asset_id,
+ (LLAssetType::EType)type,
+ (LLInventoryType::EType)type,
+ name,
+ "",
+ LLSaleInfo::DEFAULT,
+ 0,
+ 0);
+ addItem(item);
+ return item_id;
+}
+
+void LLLocalInventory::addItem(LLViewerInventoryItem* item)
+{
+ //gInventory.addPretendItem(item);
+ LLInventoryModel::update_map_t update;
+ ++update[item->getParentUUID()];
+ gInventory.accountForUpdate(update);
+ gInventory.updateItem(item);
+ gInventory.notifyObservers();
+}
+
+void LLLocalInventory::open(LLUUID item_id)
+{
+ LLViewerInventoryItem* item = gInventory.getItem(item_id);
+ if(!item)
+ {
+ llwarns << "Trying to open non-existent item" << llendl;
+ return;
+ }
+
+ LLAssetType::EType type = item->getType();
+
+ if(type == LLAssetType::AT_SOUND)
+ {
+ S32 left, top;
+ gFloaterView->getNewFloaterPosition(&left, &top);
+ LLRect rect = gSavedSettings.getRect("PreviewSoundRect");
+ rect.translate(left - rect.mLeft, top - rect.mTop);
+ LLPreviewSound* floaterp;
+ floaterp = new LLPreviewSound("Preview sound",
+ rect,
+ "",
+ item_id);
+ floaterp->setFocus(TRUE);
+ gFloaterView->adjustToFitScreen(floaterp, FALSE);
+ }
+ else if(type == LLAssetType::AT_ANIMATION)
+ {
+ S32 left, top;
+ gFloaterView->getNewFloaterPosition(&left, &top);
+ LLRect rect = gSavedSettings.getRect("PreviewAnimRect");
+ rect.translate(left - rect.mLeft, top - rect.mTop);
+ LLPreviewAnim* floaterp;
+ floaterp = new LLPreviewAnim("Preview anim",
+ rect,
+ "",
+ item_id,
+ 0);
+ floaterp->setFocus(TRUE);
+ gFloaterView->adjustToFitScreen(floaterp, FALSE);
+ }
+ else if(type == LLAssetType::AT_TEXTURE)
+ {
+ S32 left, top;
+ gFloaterView->getNewFloaterPosition(&left, &top);
+ LLRect rect = gSavedSettings.getRect("PreviewTextureRect");
+ rect.translate( left - rect.mLeft, top - rect.mTop );
+
+ LLPreviewTexture* preview;
+ preview = new LLPreviewTexture("preview texture",
+ rect,
+ "Preview texture",
+ item_id,
+ LLUUID::null,
+ FALSE);
+ //preview->setSourceID(source_id);
+ preview->setFocus(TRUE);
+
+ gFloaterView->adjustToFitScreen(preview, FALSE);
+ }
+ else if(type == LLAssetType::AT_GESTURE)
+ {
+ // If only the others were like this
+ LLPreviewGesture::show("preview gesture", item_id, LLUUID::null, TRUE);
+ }
+ else if(type == LLAssetType::AT_LANDMARK)
+ {
+ S32 left, top;
+ gFloaterView->getNewFloaterPosition(&left, &top);
+ LLRect rect = gSavedSettings.getRect("PreviewLandmarkRect");
+ rect.translate( left - rect.mLeft, top - rect.mTop );
+
+ LLPreviewLandmark* preview;
+ preview = new LLPreviewLandmark("preview landmark",
+ rect,
+ "Preview landmark",
+ item_id);
+ preview->setFocus(TRUE);
+
+ gFloaterView->adjustToFitScreen(preview, FALSE);
+ }
+ else
+ {
+ llwarns << "Dunno how to open type " << type << ", falling back to hex editor" << llendl;
+ DOFloaterHex::show(item_id);
+ }
+}
+
+//static
+void LLLocalInventory::loadInvCache(std::string filename)
+{
+ std::string extension = gDirUtilp->getExtension(filename);
+ std::string inv_filename = filename;
+ if(extension == "gz")
+ {
+ LLUUID random;
+ random.generate();
+ inv_filename = filename.substr(0, filename.length() - 3) + "." + random.asString();
+
+ if(!gunzip_file(filename, inv_filename))
+ {
+ // failure... message?
+ return;
+ }
+ }
+
+ int conflicting_cat_count = 0;
+ int conflicting_item_count = 0;
+ int conflicting_parent_count = 0;
+
+ LLInventoryModel::cat_array_t cats;
+ LLInventoryModel::item_array_t items;
+ if(LLInventoryModel::loadFromFile(inv_filename, cats, items))
+ {
+ // create a container category for everything
+ LLViewerInventoryCategory* container = new LLViewerInventoryCategory(gAgent.getID());
+ container->rename(gDirUtilp->getBaseFileName(filename, false));
+ LLUUID container_id;
+ container_id.generate();
+ container->setUUID(container_id);
+ container->setParent(gLocalInventoryRoot);
+ container->setPreferredType(LLAssetType::AT_NONE);
+ LLInventoryModel::update_map_t container_update;
+ ++container_update[container->getParentUUID()];
+ gInventory.accountForUpdate(container_update);
+ gInventory.updateCategory(container);
+ gInventory.notifyObservers();
+
+ // Add all categories
+ LLInventoryModel::cat_array_t::iterator cat_iter = cats.begin();
+ LLInventoryModel::cat_array_t::iterator cat_end = cats.end();
+ for(; cat_iter != cat_end; ++cat_iter)
+ {
+ // Conditionally change its parent
+ // Note: Should I search for missing parent id's?
+ if((*cat_iter)->getParentUUID().isNull())
+ {
+ (*cat_iter)->setParent(container_id);
+ }
+
+ // Avoid conflicts with real inventory...
+ // If this category already exists, ignore it
+ if(gInventory.getCategory((*cat_iter)->getUUID()))
+ {
+ conflicting_cat_count++;
+ continue;
+ }
+ // If the parent exists and outside of pretend inventory, ignore it
+ if(gInventory.getCategory((*cat_iter)->getParentUUID()))
+ {
+ if(!gInventory.isObjectDescendentOf((*cat_iter)->getParentUUID(), gLocalInventoryRoot))
+ {
+ conflicting_parent_count++;
+ continue;
+ }
+ }
+
+ LLInventoryModel::update_map_t update;
+ ++update[(*cat_iter)->getParentUUID()];
+ gInventory.accountForUpdate(update);
+ gInventory.updateCategory(*cat_iter);
+ gInventory.notifyObservers();
+ }
+
+ // Add all items
+ LLInventoryModel::item_array_t::iterator item_iter = items.begin();
+ LLInventoryModel::item_array_t::iterator item_end = items.end();
+ for(; item_iter != item_end; ++item_iter)
+ {
+ // Conditionally change its parent
+ // Note: Should I search for missing parent id's?
+ if((*item_iter)->getParentUUID().isNull())
+ {
+ (*item_iter)->setParent(container_id);
+ }
+
+ // Avoid conflicts with real inventory...
+ // If this item id already exists, ignore it
+ if(gInventory.getItem((*item_iter)->getUUID()))
+ {
+ conflicting_item_count++;
+ continue;
+ }
+ // If the parent exists and outside of pretend inventory, ignore it
+ if(gInventory.getCategory((*item_iter)->getParentUUID()))
+ {
+ if(!gInventory.isObjectDescendentOf((*item_iter)->getParentUUID(), gLocalInventoryRoot))
+ {
+ conflicting_parent_count++;
+ continue;
+ }
+ }
+
+ LLInventoryModel::update_map_t update;
+ ++update[(*item_iter)->getParentUUID()];
+ gInventory.accountForUpdate(update);
+ gInventory.updateItem(*item_iter);
+ gInventory.notifyObservers();
+ }
+ }
+
+ // remove temporary unzipped file
+ if(extension == "gz")
+ {
+ LLFile::remove(inv_filename);
+ }
+
+ // Quality time
+ if(conflicting_cat_count || conflicting_item_count || conflicting_parent_count)
+ {
+ std::ostringstream message;
+ message << "Some items were ignored due to conflicts:\n\n";
+ if(conflicting_cat_count) message << conflicting_cat_count << " folders\n";
+ if(conflicting_item_count) message << conflicting_item_count << " items\n";
+ if(conflicting_parent_count) message << conflicting_parent_count << " parents\n";
+ LLSD args;
+ args["ERROR_MESSAGE"] = message.str();
+ LLNotifications::instance().add("ErrorMessage", args);
+ }
+}
+
+//static
+void LLLocalInventory::saveInvCache(std::string filename, LLFolderView* folder)
+{
+ LLInventoryModel* model = &gInventory;
+ std::set selected_items;
+ folder->getSelectionList(selected_items);
+ if(selected_items.size() < 1)
+ {
+ // No items selected? Wtfboom
+ return;
+ }
+ LLInventoryModel::cat_array_t cats;
+ LLInventoryModel::item_array_t items;
+ // Make complete lists of child categories and items
+ std::set::iterator sel_iter = selected_items.begin();
+ std::set::iterator sel_end = selected_items.end();
+ for( ; sel_iter != sel_end; ++sel_iter)
+ {
+ LLInventoryCategory* cat = model->getCategory(*sel_iter);
+ if(cat)
+ {
+ climb(cat, cats, items);
+ }
+ }
+ // And what about items inside a folder that wasn't selected?
+ // I guess I will just add selected items, so long as they aren't already added
+ for(sel_iter = selected_items.begin(); sel_iter != sel_end; ++sel_iter)
+ {
+ LLInventoryItem* item = model->getItem(*sel_iter);
+ if(item)
+ {
+ if(std::find(items.begin(), items.end(), item) == items.end())
+ {
+ items.push_back(LLPointer((LLViewerInventoryItem*)item));
+ LLInventoryCategory* parent = model->getCategory(item->getParentUUID());
+ if(std::find(cats.begin(), cats.end(), parent) == cats.end())
+ {
+ cats.push_back(LLPointer((LLViewerInventoryCategory*)parent));
+ }
+ }
+ }
+ }
+ LLInventoryModel::saveToFile(filename, cats, items);
+}
+
+// static
+void LLLocalInventory::climb(LLInventoryCategory* cat,
+ LLInventoryModel::cat_array_t& cats,
+ LLInventoryModel::item_array_t& items)
+{
+ LLInventoryModel* model = &gInventory;
+
+ // Add this category
+ cats.push_back(LLPointer((LLViewerInventoryCategory*)cat));
+
+ LLInventoryModel::cat_array_t *direct_cats;
+ LLInventoryModel::item_array_t *direct_items;
+ model->getDirectDescendentsOf(cat->getUUID(), direct_cats, direct_items);
+
+ // Add items
+ LLInventoryModel::item_array_t::iterator item_iter = direct_items->begin();
+ LLInventoryModel::item_array_t::iterator item_end = direct_items->end();
+ for( ; item_iter != item_end; ++item_iter)
+ {
+ items.push_back(*item_iter);
+ }
+
+ // Do subcategories
+ LLInventoryModel::cat_array_t::iterator cat_iter = direct_cats->begin();
+ LLInventoryModel::cat_array_t::iterator cat_end = direct_cats->end();
+ for( ; cat_iter != cat_end; ++cat_iter)
+ {
+ climb(*cat_iter, cats, items);
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+LLUUID LLFloaterNewLocalInventory::sLastCreatorId = LLUUID::null;
+
+LLFloaterNewLocalInventory::LLFloaterNewLocalInventory()
+: LLFloater()
+{
+ LLUICtrlFactory::getInstance()->buildFloater(this, "floater_new_local_inventory.xml");
+}
+
+LLFloaterNewLocalInventory::~LLFloaterNewLocalInventory()
+{
+}
+
+BOOL LLFloaterNewLocalInventory::postBuild(void)
+{
+ // Fill in default values
+
+ getChild("creator_id_line")->setText(std::string("00000000-0000-0000-0000-000000000000"));
+ getChild("owner_id_line")->setText(gAgent.getID().asString());
+ getChild("asset_id_line")->setText(std::string("00000000-0000-0000-0000-000000000000"));
+ getChild("name_line")->setText(std::string(""));
+ getChild("desc_line")->setText(std::string(""));
+
+ // Set up callbacks
+
+ childSetAction("ok_btn", onClickOK, this);
+
+ return TRUE;
+}
+
+// static
+void LLFloaterNewLocalInventory::onClickOK(void* user_data)
+{
+ LLFloaterNewLocalInventory* floater = (LLFloaterNewLocalInventory*)user_data;
+
+ LLUUID item_id;
+ item_id.generate();
+
+ std::string name = floater->getChild("name_line")->getText();
+ std::string desc = floater->getChild("desc_line")->getText();
+ LLUUID asset_id = LLUUID(floater->getChild("asset_id_line")->getText());
+ LLUUID creator_id = LLUUID(floater->getChild("creator_id_line")->getText());
+ LLUUID owner_id = LLUUID(floater->getChild("owner_id_line")->getText());
+
+ LLAssetType::EType type = LLAssetType::lookup(floater->getChild("type_combo")->getValue().asString());
+ LLInventoryType::EType inv_type = LLInventoryType::IT_CALLINGCARD;
+ switch(type)
+ {
+ case LLAssetType::AT_TEXTURE:
+ case LLAssetType::AT_TEXTURE_TGA:
+ case LLAssetType::AT_IMAGE_TGA:
+ case LLAssetType::AT_IMAGE_JPEG:
+ inv_type = LLInventoryType::IT_TEXTURE;
+ break;
+ case LLAssetType::AT_SOUND:
+ case LLAssetType::AT_SOUND_WAV:
+ inv_type = LLInventoryType::IT_SOUND;
+ break;
+ case LLAssetType::AT_CALLINGCARD:
+ inv_type = LLInventoryType::IT_CALLINGCARD;
+ break;
+ case LLAssetType::AT_LANDMARK:
+ inv_type = LLInventoryType::IT_LANDMARK;
+ break;
+ case LLAssetType::AT_SCRIPT:
+ inv_type = LLInventoryType::IT_LSL;
+ break;
+ case LLAssetType::AT_CLOTHING:
+ inv_type = LLInventoryType::IT_WEARABLE;
+ break;
+ case LLAssetType::AT_OBJECT:
+ inv_type = LLInventoryType::IT_OBJECT;
+ break;
+ case LLAssetType::AT_NOTECARD:
+ inv_type = LLInventoryType::IT_NOTECARD;
+ break;
+ case LLAssetType::AT_CATEGORY:
+ inv_type = LLInventoryType::IT_CATEGORY;
+ break;
+ case LLAssetType::AT_ROOT_CATEGORY:
+ case LLAssetType::AT_TRASH:
+ case LLAssetType::AT_SNAPSHOT_CATEGORY:
+ case LLAssetType::AT_LOST_AND_FOUND:
+ inv_type = LLInventoryType::IT_ROOT_CATEGORY;
+ break;
+ case LLAssetType::AT_LSL_TEXT:
+ case LLAssetType::AT_LSL_BYTECODE:
+ inv_type = LLInventoryType::IT_LSL;
+ break;
+ case LLAssetType::AT_BODYPART:
+ inv_type = LLInventoryType::IT_WEARABLE;
+ break;
+ case LLAssetType::AT_ANIMATION:
+ inv_type = LLInventoryType::IT_ANIMATION;
+ break;
+ case LLAssetType::AT_GESTURE:
+ inv_type = LLInventoryType::IT_GESTURE;
+ break;
+ case LLAssetType::AT_SIMSTATE:
+ default:
+ inv_type = LLInventoryType::IT_CALLINGCARD;
+ break;
+ }
+
+
+ LLPermissions* perms = new LLPermissions();
+ perms->init(creator_id, owner_id, LLUUID::null, LLUUID::null);
+
+ LLViewerInventoryItem* item = new LLViewerInventoryItem(
+ item_id,
+ gLocalInventoryRoot,
+ *perms,
+ asset_id,
+ type,
+ inv_type,
+ name,
+ desc,
+ LLSaleInfo::DEFAULT,
+ 0,
+ 0);
+
+ LLLocalInventory::addItem(item);
+ if(floater->childGetValue("chk_open"))
+ {
+ LLLocalInventory::open(item_id);
+ }
+
+ LLFloaterNewLocalInventory::sLastCreatorId = creator_id;
+ floater->close();
+}
+
+
+
+//
diff --git a/indra/newview/lllocalinventory.h b/indra/newview/lllocalinventory.h
new file mode 100644
index 000000000..630605a70
--- /dev/null
+++ b/indra/newview/lllocalinventory.h
@@ -0,0 +1,45 @@
+//
+#ifndef LL_LLLOCALINVENTORY_H
+#define LL_LLLOCALINVENTORY_H
+
+#include "llviewerinventory.h"
+
+#include "llfloater.h"
+
+#include "llfolderview.h"
+#include "llinventorymodel.h" // cat_array_t, item_array_t
+
+class LLLocalInventory
+{
+public:
+ static LLUUID addItem(std::string name, int type, LLUUID asset_id, bool open);
+ static LLUUID addItem(std::string name, int type, LLUUID asset_id);
+ static void addItem(LLViewerInventoryItem* item);
+ static void open(LLUUID item_id);
+ static void loadInvCache(std::string filename);
+ static void saveInvCache(std::string filename, LLFolderView* folder);
+ static void climb(LLInventoryCategory* cat,
+ LLInventoryModel::cat_array_t& cats,
+ LLInventoryModel::item_array_t& items);
+};
+
+
+
+
+class LLFloaterNewLocalInventory
+: public LLFloater
+{
+public:
+ LLFloaterNewLocalInventory();
+ BOOL postBuild(void);
+
+ static void onClickOK(void* user_data);
+ static LLUUID sLastCreatorId;
+
+private:
+ virtual ~LLFloaterNewLocalInventory();
+
+};
+
+#endif
+//
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 8ac1521df..7c6573c4f 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -254,6 +254,9 @@ LLViewerObject::~LLViewerObject()
{
if(iter->second != NULL)
{
+ //
+ // There was a crash here
+ //
delete iter->second->data;
delete iter->second;
}
@@ -1877,8 +1880,11 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
if ( gShowObjectUpdates )
{
- if (!((mPrimitiveCode == LL_PCODE_LEGACY_AVATAR) && (((LLVOAvatar *) this)->isSelf()))
- && mRegionp)
+ // We want to see updates from our own avatar
+ //if (!((mPrimitiveCode == LL_PCODE_LEGACY_AVATAR) && (((LLVOAvatar *) this)->mIsSelf))
+ // && mRegionp)
+ if(mRegionp)
+ //
{
LLViewerObject* object = gObjectList.createObjectViewer(LL_PCODE_LEGACY_TEXT_BUBBLE, mRegionp);
LLVOTextBubble* bubble = (LLVOTextBubble*) object;
@@ -1929,6 +1935,11 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
if (needs_refresh)
{
+ //
+ if(isChanged(MOVED)) // Update "center" if this or children are selected,
+ // and translate, scale, or rotate occurred on this.
+ // Leave dialog refresh to happen always, as before.
+ //
LLSelectMgr::getInstance()->updateSelectionCenter();
dialog_refresh_all();
}
@@ -4076,6 +4087,14 @@ void LLViewerObject::setDebugText(const std::string &utf8text)
mText->setDoFade(FALSE);
updateText();
}
+//
+std::string LLViewerObject::getDebugText()
+{
+ if(mText)
+ return mText->getStringUTF8();
+ return "";
+}
+//
void LLViewerObject::setIcon(LLViewerImage* icon_image)
{
@@ -5141,3 +5160,20 @@ void LLViewerObject::resetChildrenPosition(const LLVector3& offset, BOOL simplif
return ;
}
+
+//
+S32 LLViewerObject::getAttachmentPoint()
+{
+ return ((S32)((((U8)mState & AGENT_ATTACH_MASK) >> 4) | (((U8)mState & ~AGENT_ATTACH_MASK) << 4)));
+}
+
+std::string LLViewerObject::getAttachmentPointName()
+{
+ S32 point = getAttachmentPoint();
+ if((point > 0) && (point < 39))
+ {
+ return gAgent.getAvatarObject()->mAttachmentPoints[point]->getName();
+ }
+ return llformat("unsupported point %d", point);
+}
+//
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index 33e8da2c5..762576ed6 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -353,6 +353,9 @@ public:
void setCanSelect(BOOL canSelect);
void setDebugText(const std::string &utf8text);
+ //
+ std::string getDebugText();
+ //
void setIcon(LLViewerImage* icon_image);
void clearIcon();
@@ -659,6 +662,11 @@ protected:
private:
static S32 sNumObjects;
+//
+public:
+ S32 getAttachmentPoint();
+ std::string getAttachmentPointName();
+//
};
///////////////////