diff --git a/indra/cmake/Boost.cmake b/indra/cmake/Boost.cmake index c6677e1ac..9942a08a5 100644 --- a/indra/cmake/Boost.cmake +++ b/indra/cmake/Boost.cmake @@ -7,9 +7,11 @@ set(Boost_FIND_REQUIRED ON) if (STANDALONE) include(FindBoost) + set(BOOST_FILESYSTEM_LIBRARY boost_filesystem-mt) set(BOOST_PROGRAM_OPTIONS_LIBRARY boost_program_options-mt) set(BOOST_REGEX_LIBRARY boost_regex-mt) set(BOOST_SIGNALS_LIBRARY boost_signals-mt) + set(BOOST_SYSTEM_LIBRARY boost_system-mt) else (STANDALONE) use_prebuilt_binary(boost) set(Boost_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include) @@ -42,12 +44,16 @@ else (STANDALONE) debug libboost_signals-vc${MSVC_SUFFIX}-${BOOST_DEBUG_SUFFIX}-${BOOST_VERSION}) elseif (DARWIN) + set(BOOST_FILESYSTEM_LIBRARY boost_filesystem-mt) set(BOOST_PROGRAM_OPTIONS_LIBRARY boost_program_options-mt) set(BOOST_REGEX_LIBRARY boost_regex-mt) set(BOOST_SIGNALS_LIBRARY boost_signals-mt) + set(BOOST_SYSTEM_LIBRARY boost_system-mt) elseif (LINUX) + set(BOOST_FILESYSTEM_LIBRARY boost_filesystem-mt) set(BOOST_PROGRAM_OPTIONS_LIBRARY boost_program_options-mt) set(BOOST_REGEX_LIBRARY boost_regex-mt) set(BOOST_SIGNALS_LIBRARY boost_signals-mt) + set(BOOST_SYSTEM_LIBRARY boost_system-mt) endif (WINDOWS) endif (STANDALONE) diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp index f62a3ea88..7210bd2b1 100644 --- a/indra/llcommon/llapr.cpp +++ b/indra/llcommon/llapr.cpp @@ -598,8 +598,11 @@ bool LLAPRFile::remove(const std::string& filename) if (s != APR_SUCCESS) { + if (s != APR_ENOENT) // Not an issue if the file did not exist in the first place... + { ll_apr_warn_status(s); LL_WARNS("APR") << " Attempting to remove filename: " << filename << LL_ENDL; + } return false; } return true; diff --git a/indra/llplugin/slplugin/CMakeLists.txt b/indra/llplugin/slplugin/CMakeLists.txt index d6735a76f..fd555d394 100755 --- a/indra/llplugin/slplugin/CMakeLists.txt +++ b/indra/llplugin/slplugin/CMakeLists.txt @@ -6,6 +6,7 @@ include(LLPlugin) include(Linking) include(PluginAPI) include(LLMessage) +include(GooglePerfTools) include_directories( ${LLPLUGIN_INCLUDE_DIRS} diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 44bfe9d7a..3dcf25c0d 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -64,6 +64,7 @@ include_directories( ) set(viewer_SOURCE_FILES + floaterlocalassetbrowse.cpp aoremotectrl.cpp floaterao.cpp floatervoicelicense.cpp @@ -533,6 +534,7 @@ set(viewer_HEADER_FILES CMakeLists.txt ViewerInstall.cmake + floaterlocalassetbrowse.h aoremotectrl.h floaterao.h floatervoicelicense.h @@ -1418,8 +1420,11 @@ target_link_libraries(${VIEWER_BINARY_NAME} ${LLCOMMON_LIBRARIES} ${NDOF_LIBRARY} ${viewer_LIBRARIES} + ${BOOST_FILESYSTEM_LIBRARY} ${BOOST_PROGRAM_OPTIONS_LIBRARY} ${BOOST_REGEX_LIBRARY} + ${BOOST_SIGNALS_LIBRARY} + ${BOOST_SYSTEM_LIBRARY} ${DBUSGLIB_LIBRARIES} ${OPENGL_LIBRARIES} ${FMODWRAPPER_LIBRARY} diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 1d5664fbc..12bd93686 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -9,6 +9,23 @@ settings_rlv.xml + FloaterLocalbitmapbrowserRect + + Comment + LOLRectangle + Persist + 1 + Type + Rect + Value + + 0 + 400 + 400 + 0 + + + ShowAOSitPopup @@ -222,7 +239,7 @@ Type Boolean Value - 1 + 0 ResetFocusOnSelfClick @@ -6170,7 +6187,7 @@ Type F32 Value - 12.0 + 11.5 FontSizeMedium @@ -6181,7 +6198,7 @@ Type F32 Value - 10.0 + 9.5 FontSizeMonospace @@ -6192,7 +6209,7 @@ Type F32 Value - 8.1 + 9.0 FontSizeSmall @@ -6203,7 +6220,7 @@ Type F32 Value - 9.0 + 8.5 ForceNotecardDragCargoPermissive diff --git a/indra/newview/floaterlocalassetbrowse.cpp b/indra/newview/floaterlocalassetbrowse.cpp new file mode 100644 index 000000000..7b707deff --- /dev/null +++ b/indra/newview/floaterlocalassetbrowse.cpp @@ -0,0 +1,1030 @@ +/** +* @file floaterlocalassetbrowse.cpp +* @brief Local texture support +* +* $LicenseInfo:firstyear=2009&license=viewergpl$ +* +* Copyright (c) 2010, author unknown +* +* Imprudence Viewer Source Code +* The source code in this file ("Source Code") is provided to you +* under the terms of the GNU General Public License, version 2.0 +* ("GPL"). Terms of the GPL can be found in doc/GPL-license.txt in +* this distribution, or online at +* http://secondlifegrid.net/programs/open_source/licensing/gplv2 +* +* There are special exceptions to the terms and conditions of the GPL as +* it is applied to this Source Code. View the full text of the exception +* in the file doc/FLOSS-exception.txt in this software distribution, or +* online at http://secondlifegrid.net/programs/open_source/licensing/flossexception +* +* By copying, modifying or distributing this software, you acknowledge +* that you have read and understood your obligations described above, +* and agree to abide by those obligations. +* +* ALL SOURCE CODE IS PROVIDED "AS IS." THE AUTHOR MAKES NO +* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +* COMPLETENESS OR PERFORMANCE. +* $/LicenseInfo$ +*/ + +/* + +tag: vaa emerald local_asset_browser + +this feature is still a work in progress. + +*/ + +/* basic headers */ +#include "llviewerprecompiledheaders.h" +#include "lluictrlfactory.h" + +/* own class header && upload floater header */ +#include "floaterlocalassetbrowse.h" +//#include "floaterlocaluploader.h" <- in development. + +/* image compression headers. */ +#include "llimagebmp.h" +#include "llimagetga.h" +#include "llimagejpeg.h" +#include "llimagepng.h" + +/* misc headers */ +#include +#include +#include "llviewerimagelist.h" +#include "llviewerobjectlist.h" +#include "llfilepicker.h" +#include "llviewermenufile.h" +#include "llfloaterimagepreview.h" +#include "llfile.h" + +/* repeated in header */ +#include "lltexturectrl.h" +#include "llscrolllistctrl.h" +#include "llviewercontrol.h" + +/* including to force rebakes when needed */ +#include "llagent.h" +#include "llvoavatar.h" + +/* sculpt refresh */ +#include "llvovolume.h" +#include "llface.h" + + +/*=======================================*/ +/* Instantiating manager class */ +/* and formally declaring it's list */ +/*=======================================*/ +LocalAssetBrowser* gLocalBrowser; +LocalAssetBrowserTimer* gLocalBrowserTimer; +std::vector LocalAssetBrowser::loaded_bitmaps; +bool LocalAssetBrowser::mLayerUpdated; +bool LocalAssetBrowser::mSculptUpdated; + +/*=======================================*/ +/* LocalBitmap: unit class */ +/*=======================================*/ +/* + The basic unit class responsible for + containing one loaded local texture. +*/ + +LocalBitmap::LocalBitmap(std::string fullpath) +{ + this->valid = false; + if ( gDirUtilp->fileExists(fullpath) ) + { + /* taking care of basic properties */ + this->id.generate(); + this->filename = fullpath; + this->linkstatus = LINK_OFF; + this->keep_updating = false; + this->shortname = gDirUtilp->getBaseFileName(this->filename, true); + this->bitmap_type = TYPE_TEXTURE; + this->sculpt_dirty = false; + this->volume_dirty = false; + this->valid = false; + + /* taking care of extension type now to avoid switch madness */ + std::string temp_exten = gDirUtilp->getExtension(this->filename); + + if (temp_exten == "bmp") { this->extension = IMG_EXTEN_BMP; } + else if (temp_exten == "tga") { this->extension = IMG_EXTEN_TGA; } + else if (temp_exten == "jpg" || temp_exten == "jpeg") { this->extension = IMG_EXTEN_JPG; } + else if (temp_exten == "png") { this->extension = IMG_EXTEN_PNG; } + else { return; } // no valid extension. + + /* getting file's last modified */ + + llstat temp_stat; + LLFile::stat(this->filename, &temp_stat); + std::time_t time = temp_stat.st_mtime; + + this->last_modified = asctime( localtime(&time) ); + + /* checking if the bitmap is valid && decoding if it is */ + LLImageRaw* raw_image = new LLImageRaw(); + if ( this->decodeSelf(raw_image) ) + { + /* creating a shell LLViewerImage and fusing raw image into it */ + LLViewerImage* viewer_image = new LLViewerImage( "file://"+this->filename, this->id, LOCAL_USE_MIPMAPS ); + viewer_image->createGLTexture( LOCAL_DISCARD_LEVEL, raw_image ); + viewer_image->mCachedRawImage = raw_image; + + /* making damn sure gImageList will not delete it prematurely */ + viewer_image->ref(); + + /* finalizing by adding LLViewerImage instance into gImageList */ + gImageList.addImage(viewer_image); + + /* filename is valid, bitmap is decoded and valid, i can haz liftoff! */ + this->valid = true; + } + } +} + +LocalBitmap::~LocalBitmap() +{ +} + +/* [maintenence functions] */ +void LocalBitmap::updateSelf() +{ + if ( this->linkstatus == LINK_ON || this->linkstatus == LINK_UPDATING ) + { + /* making sure file still exists */ + if ( !gDirUtilp->fileExists(this->filename) ) { this->linkstatus = LINK_BROKEN; return; } + + /* exists, let's check if it's lastmod has changed */ + llstat temp_stat; + LLFile::stat(this->filename, &temp_stat); + std::time_t temp_time = temp_stat.st_mtime; + + LLSD new_last_modified = asctime( localtime(&temp_time) ); + if ( this->last_modified.asString() == new_last_modified.asString() ) { return; } + + /* here we update the image */ + LLImageRaw* new_imgraw = new LLImageRaw(); + + if ( !decodeSelf(new_imgraw) ) { this->linkstatus = LINK_UPDATING; return; } + else { this->linkstatus = LINK_ON; } + + LLViewerImage* image = gImageList.hasImage(this->id); + + if (!image->mForSculpt) + { image->createGLTexture( LOCAL_DISCARD_LEVEL, new_imgraw ); } + else + { image->mCachedRawImage = new_imgraw; } + + /* finalizing by updating lastmod to current */ + this->last_modified = new_last_modified; + + /* setting unit property to reflect that it has been changed */ + switch (this->bitmap_type) + { + case TYPE_TEXTURE: + { break; } + + case TYPE_SCULPT: + { + /* sets a bool to run through all visible sculpts in one go, and update the ones necessary. */ + this->sculpt_dirty = true; + this->volume_dirty = true; + gLocalBrowser->setSculptUpdated( true ); + break; + } + + case TYPE_LAYER: + { + /* sets a bool to rebake layers after the iteration is done with */ + gLocalBrowser->setLayerUpdated( true ); + break; + } + + default: + { break; } + + } + } + +} + +bool LocalBitmap::decodeSelf(LLImageRaw* rawimg) +{ + switch (this->extension) + { + case IMG_EXTEN_BMP: + { + LLPointer bmp_image = new LLImageBMP; + if ( !bmp_image->load(filename) ) { break; } + if ( !bmp_image->decode(rawimg, 0.0f) ) { break; } + + rawimg->biasedScaleToPowerOfTwo( LLViewerImage::MAX_IMAGE_SIZE_DEFAULT ); + return true; + } + + case IMG_EXTEN_TGA: + { + LLPointer tga_image = new LLImageTGA; + if ( !tga_image->load(filename) ) { break; } + if ( !tga_image->decode(rawimg) ) { break; } + + if( ( tga_image->getComponents() != 3) && + ( tga_image->getComponents() != 4) ) { break; } + + rawimg->biasedScaleToPowerOfTwo( LLViewerImage::MAX_IMAGE_SIZE_DEFAULT ); + return true; + } + + case IMG_EXTEN_JPG: + { + LLPointer jpeg_image = new LLImageJPEG; + if ( !jpeg_image->load(filename) ) { break; } + if ( !jpeg_image->decode(rawimg, 0.0f) ) { break; } + + rawimg->biasedScaleToPowerOfTwo( LLViewerImage::MAX_IMAGE_SIZE_DEFAULT ); + return true; + } + + case IMG_EXTEN_PNG: + { + LLPointer png_image = new LLImagePNG; + if ( !png_image->load(filename) ) { break; } + if ( !png_image->decode(rawimg, 0.0f) ) { break; } + + rawimg->biasedScaleToPowerOfTwo( LLViewerImage::MAX_IMAGE_SIZE_DEFAULT ); + return true; + } + + default: + break; + } + return false; +} + +void LocalBitmap::setUpdateBool() +{ + if ( this->linkstatus != LINK_BROKEN ) + { + if ( !this->keep_updating ) + { + this->linkstatus = LINK_ON; + this->keep_updating = true; + } + else + { + this->linkstatus = LINK_OFF; + this->keep_updating = false; + } + } + else + { + this->keep_updating = false; + } +} + +void LocalBitmap::setType( S32 type ) +{ + this->bitmap_type = type; +} + +/* [information query functions] */ +std::string LocalBitmap::getShortName() +{ + return this->shortname; +} + +std::string LocalBitmap::getFileName() +{ + return this->filename; +} + +LLUUID LocalBitmap::getID() +{ + return this->id; +} + +LLSD LocalBitmap::getLastModified() +{ + return this->last_modified; +} + +std::string LocalBitmap::getLinkStatus() +{ + switch(this->linkstatus) + { + case LINK_ON: + return "On"; + + case LINK_OFF: + return "Off"; + + case LINK_BROKEN: + return "Broken"; + + case LINK_UPDATING: + return "Updating"; + + default: + return "Unknown"; + } +} + +bool LocalBitmap::getUpdateBool() +{ + return this->keep_updating; +} + +bool LocalBitmap::getIfValidBool() +{ + return this->valid; +} + +LocalBitmap* LocalBitmap::getThis() +{ + return this; +} + +S32 LocalBitmap::getType() +{ + return this->bitmap_type; +} + +std::vector LocalBitmap::getFaceUsesThis(LLDrawable* drawable) +{ + std::vector matching_faces; + + for ( S32 face_iter = 0; face_iter <= drawable->getNumFaces(); face_iter++ ) + { + LLFace* newface = drawable->getFace(face_iter); + + if ( this->id == newface->getTexture()->getID() ) + { matching_faces.push_back(newface); } + } + + return matching_faces; +} + +std::vector LocalBitmap::getUsingObjects(bool seek_by_type, bool seek_textures, bool seek_sculptmaps) +{ + std::vector affected_vector; + + for( LLDynamicArrayPtr< LLPointer, 256 >::iterator iter = gObjectList.mObjects.begin(); + iter != gObjectList.mObjects.end(); iter++ ) + { + LLViewerObject* obj = *iter; + affected_object shell; + shell.object = obj; + shell.local_sculptmap = false; + bool obj_relevant = false; + + if ( obj && obj->mDrawable ) + { + /* looking for textures */ + if ( seek_textures || ( seek_by_type && this->bitmap_type == TYPE_TEXTURE ) ) + { + std::vector affected_faces = this->getFaceUsesThis( obj->mDrawable ); + if ( !affected_faces.empty() ) + { + shell.face_list = affected_faces; + obj_relevant = true; + } + } + + /* looking for sculptmaps */ + if ( ( seek_sculptmaps || ( seek_by_type && this->bitmap_type == TYPE_SCULPT ) ) + && obj->isSculpted() && obj->getVolume() + && this->id == obj->getVolume()->getParams().getSculptID() + ) + { + shell.local_sculptmap = true; + obj_relevant = true; + } + } + + if (obj_relevant) + { affected_vector.push_back(shell); } + } + + + + return affected_vector; +} + +void LocalBitmap::getDebugInfo() +{ + /* debug function: dumps everything human readable into llinfos */ + llinfos << "===[local bitmap debug]===" << "\n" + << "path: " << this->filename << "\n" + << "name: " << this->shortname << "\n" + << "extension: " << this->extension << "\n" + << "uuid: " << this->id << "\n" + << "last modified: " << this->last_modified << "\n" + << "link status: " << this->getLinkStatus() << "\n" + << "keep updated: " << this->keep_updating << "\n" + << "type: " << this->bitmap_type << "\n" + << "is valid: " << this->valid << "\n" + << "==========================" << llendl; + +} + +/*=======================================*/ +/* LocalAssetBrowser: internal class */ +/*=======================================*/ +/* + Responsible for internal workings. + Instantiated at the top of the source file. + Sits in memory until the viewer is closed. +*/ + +LocalAssetBrowser::LocalAssetBrowser() +{ + this->mLayerUpdated = false; + this->mSculptUpdated = false; +} + +LocalAssetBrowser::~LocalAssetBrowser() +{ + +} + +void LocalAssetBrowser::AddBitmap() +{ + LLFilePicker& picker = LLFilePicker::instance(); + if ( !picker.getMultipleOpenFiles(LLFilePicker::FFLOAD_IMAGE) ) + { return; } + + bool change_happened = false; + std::string filename = picker.getFirstFile(); + while( !filename.empty() ) + { + LocalBitmap* unit = new LocalBitmap( filename ); + + if ( unit->getIfValidBool() ) + { + loaded_bitmaps.push_back( unit ); + change_happened = true; + } + + filename = picker.getNextFile(); + } + + if ( change_happened ) + { onChangeHappened(); } +} + +void LocalAssetBrowser::DelBitmap( std::vector delete_vector, S32 column ) +{ + bool change_happened = false; + for( std::vector::iterator list_iter = delete_vector.begin(); + list_iter != delete_vector.end(); list_iter++ ) + { + LLScrollListItem* list_item = *list_iter; + if ( list_item ) + { + LLUUID id = list_item->getColumn(column)->getValue().asUUID(); + for (local_list_iter iter = loaded_bitmaps.begin(); + iter != loaded_bitmaps.end();) + { + LocalBitmap* unit = (*iter)->getThis(); + + if ( unit->getID() == id ) + { + LLViewerImage* image = gImageList.hasImage(id); + gImageList.deleteImage( image ); + image->unref(); + + iter = loaded_bitmaps.erase(iter); + delete unit; + unit = NULL; + + change_happened = true; + } + else + { iter++; } + } + } + } + + if ( change_happened ) + { onChangeHappened(); } +} + +void LocalAssetBrowser::onUpdateBool(LLUUID id) +{ + LocalBitmap* unit = GetBitmapUnit( id ); + if ( unit ) + { + unit->setUpdateBool(); + PingTimer(); + } +} + +void LocalAssetBrowser::onSetType(LLUUID id, S32 type) +{ + LocalBitmap* unit = GetBitmapUnit( id ); + if ( unit ) + { unit->setType(type); } +} + +LocalBitmap* LocalAssetBrowser::GetBitmapUnit(LLUUID id) +{ + local_list_iter iter = loaded_bitmaps.begin(); + for (; iter != loaded_bitmaps.end(); iter++) + { + if ( (*iter)->getID() == id ) + { + return (*iter)->getThis(); + } + } + + return NULL; +} + +bool LocalAssetBrowser::IsDoingUpdates() +{ + local_list_iter iter = loaded_bitmaps.begin(); + for (; iter != loaded_bitmaps.end(); iter++) + { + if ( (*iter)->getUpdateBool() ) + { return true; } /* if at least one unit in the list needs updates - we need a timer. */ + } + + return false; +} + + +/* Reaction to a change in bitmaplist, this function finds a texture picker floater's appropriate scrolllist + and passes this scrolllist's pointer to UpdateTextureCtrlList for processing. + it also processes timer start/stops as needed */ +void LocalAssetBrowser::onChangeHappened() +{ + /* own floater update */ + FloaterLocalAssetBrowser::UpdateBitmapScrollList(); + + /* texturepicker related */ + const LLView::child_list_t* child_list = gFloaterView->getChildList(); + LLView::child_list_const_iter_t child_list_iter = child_list->begin(); + + for (; child_list_iter != child_list->end(); child_list_iter++) + { + LLView* view = *child_list_iter; + if ( view->getName() == LOCAL_TEXTURE_PICKER_NAME ) + { + LLScrollListCtrl* ctrl = view->getChild + ( LOCAL_TEXTURE_PICKER_LIST_NAME, + LOCAL_TEXTURE_PICKER_RECURSE, + LOCAL_TEXTURE_PICKER_CREATEIFMISSING ); + + if ( ctrl ) { UpdateTextureCtrlList(ctrl); } + } + } + + /* poking timer to see if it's still needed/still not needed */ + PingTimer(); + +} + +void LocalAssetBrowser::PingTimer() +{ + if ( !loaded_bitmaps.empty() && IsDoingUpdates() ) + { + if (!gLocalBrowserTimer) + { gLocalBrowserTimer = new LocalAssetBrowserTimer(); } + + if ( !gLocalBrowserTimer->isRunning() ) + { gLocalBrowserTimer->start(); } + } + + else + { + if (gLocalBrowserTimer) + { + if ( gLocalBrowserTimer->isRunning() ) + { gLocalBrowserTimer->stop(); } + } + } +} + +/* This function refills the texture picker floater's scrolllist with the updated contents of bitmaplist */ +void LocalAssetBrowser::UpdateTextureCtrlList(LLScrollListCtrl* ctrl) +{ + if ( ctrl ) // checking again in case called externally for some silly reason. + { + ctrl->clearRows(); + if ( !loaded_bitmaps.empty() ) + { + local_list_iter iter = loaded_bitmaps.begin(); + for ( ; iter != loaded_bitmaps.end(); iter++ ) + { + LLSD element; + element["columns"][0]["column"] = "unit_name"; + element["columns"][0]["type"] = "text"; + element["columns"][0]["value"] = (*iter)->shortname; + + element["columns"][1]["column"] = "unit_id_HIDDEN"; + element["columns"][1]["type"] = "text"; + element["columns"][1]["value"] = (*iter)->id; + + ctrl->addElement(element); + } + } + } +} + +void LocalAssetBrowser::PerformTimedActions(void) +{ + // perform checking if updates are needed && update if so. + local_list_iter iter; + for (iter = loaded_bitmaps.begin(); iter != loaded_bitmaps.end(); iter++) + { (*iter)->updateSelf(); } + + // one or more sculpts have been updated, refreshing them. + if ( mSculptUpdated ) + { + LocalAssetBrowser::local_list_iter iter; + for(iter = loaded_bitmaps.begin(); iter != loaded_bitmaps.end(); iter++) + { + if ( (*iter)->sculpt_dirty ) + { + PerformSculptUpdates( (*iter)->getThis() ); + (*iter)->sculpt_dirty = false; + } + } + mSculptUpdated = false; + } + + // one of the layer bitmaps has been updated, we need to rebake. + if ( mLayerUpdated ) + { + LLVOAvatar* avatar = gAgent.getAvatarObject(); + if (avatar) { avatar->forceBakeAllTextures(SLAM_FOR_DEBUG); } + + mLayerUpdated = false; + } +} + +void LocalAssetBrowser::PerformSculptUpdates(LocalBitmap* unit) +{ + + /* looking for sculptmap using objects only */ + std::vector object_list = unit->getUsingObjects(false, false, true); + if (object_list.empty()) { return; } + + for( std::vector::iterator iter = object_list.begin(); + iter != object_list.end(); iter++ ) + { + affected_object aobj = *iter; + if ( aobj.object ) + { + if ( !aobj.local_sculptmap ) { continue; } // should never get here. only in case of misuse. + + // update code [begin] + if ( unit->volume_dirty ) + { + LLImageRaw* rawimage = gImageList.hasImage( unit->getID() )->getCachedRawImage(); + + aobj.object->getVolume()->sculpt(rawimage->getWidth(), rawimage->getHeight(), + rawimage->getComponents(), rawimage->getData(), 0); + unit->volume_dirty = false; + } + + // tell affected drawable it's got updated + aobj.object->mDrawable->getVOVolume()->setSculptChanged( true ); + aobj.object->mDrawable->getVOVolume()->markForUpdate( true ); + // update code [end] + } + + } + +} + +/*==================================================*/ +/* FloaterLocalAssetBrowser : floater class */ +/*==================================================*/ +/* + Responsible for talking to the user. + Instantiated by user request. + Destroyed when the floater is closed. + +*/ + +// Floater Globals +FloaterLocalAssetBrowser* FloaterLocalAssetBrowser::sLFInstance = NULL; + +// widgets: + LLButton* mAddBtn; + LLButton* mDelBtn; + LLButton* mMoreBtn; + LLButton* mLessBtn; + LLButton* mUploadBtn; + + + LLScrollListCtrl* mBitmapList; + LLTextureCtrl* mTextureView; + LLCheckBoxCtrl* mUpdateChkBox; + + LLLineEditor* mPathTxt; + LLLineEditor* mUUIDTxt; + LLLineEditor* mNameTxt; + + LLTextBox* mLinkTxt; + LLTextBox* mTimeTxt; + LLComboBox* mTypeComboBox; + + LLTextBox* mCaptionPathTxt; + LLTextBox* mCaptionUUIDTxt; + LLTextBox* mCaptionLinkTxt; + LLTextBox* mCaptionNameTxt; + LLTextBox* mCaptionTimeTxt; + +FloaterLocalAssetBrowser::FloaterLocalAssetBrowser() +: LLFloater(std::string("local_bitmap_browser_floater")) +{ + // xui creation: + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_local_asset_browse.xml"); + + // setting element/xui children: + mAddBtn = getChild("add_btn"); + mDelBtn = getChild("del_btn"); + mMoreBtn = getChild("more_btn"); + mLessBtn = getChild("less_btn"); + mUploadBtn = getChild("upload_btn"); + + mBitmapList = getChild("bitmap_list"); + mTextureView = getChild("texture_view"); + mUpdateChkBox = getChild("keep_updating_checkbox"); + + mPathTxt = getChild("path_text"); + mUUIDTxt = getChild("uuid_text"); + mNameTxt = getChild("name_text"); + + mLinkTxt = getChild("link_text"); + mTimeTxt = getChild("time_text"); + mTypeComboBox = getChild("type_combobox"); + + mCaptionPathTxt = getChild("path_caption_text"); + mCaptionUUIDTxt = getChild("uuid_caption_text"); + mCaptionLinkTxt = getChild("link_caption_text"); + mCaptionNameTxt = getChild("name_caption_text"); + mCaptionTimeTxt = getChild("time_caption_text"); + + // pre-disabling line editors, they're for view only and buttons that shouldn't be on on-spawn. + mPathTxt->setEnabled( false ); + mUUIDTxt->setEnabled( false ); + mNameTxt->setEnabled( false ); + + mDelBtn->setEnabled( false ); + mUploadBtn->setEnabled( false ); + + // setting button callbacks: + mAddBtn->setClickedCallback( onClickAdd, this); + mDelBtn->setClickedCallback( onClickDel, this); + mMoreBtn->setClickedCallback( onClickMore, this); + mLessBtn->setClickedCallback( onClickLess, this); + mUploadBtn->setClickedCallback( onClickUpload, this); + + // combo callback + mTypeComboBox->setCommitCallback(onCommitTypeCombo); + + // scrolllist callbacks + mBitmapList->setCommitCallback(onChooseBitmapList); + + // checkbox callbacks + mUpdateChkBox->setCommitCallback(onClickUpdateChkbox); + +} + +void FloaterLocalAssetBrowser::show(void*) +{ + if (!sLFInstance) + sLFInstance = new FloaterLocalAssetBrowser(); + sLFInstance->open(); + sLFInstance->UpdateBitmapScrollList(); +} + +FloaterLocalAssetBrowser::~FloaterLocalAssetBrowser() +{ + sLFInstance=NULL; +} + +void FloaterLocalAssetBrowser::onClickAdd(void* userdata) +{ + gLocalBrowser->AddBitmap(); +} + +void FloaterLocalAssetBrowser::onClickDel(void* userdata) +{ + gLocalBrowser->DelBitmap( sLFInstance->mBitmapList->getAllSelected() ); +} + +/* what stopped me from using a single button and simply changing it's label + is the fact that i'd need to hardcode the button labels here, and that is griff. */ +void FloaterLocalAssetBrowser::onClickMore(void* userdata) +{ + FloaterResize(true); +} + +void FloaterLocalAssetBrowser::onClickLess(void* userdata) +{ + FloaterResize(false); +} + +void FloaterLocalAssetBrowser::onClickUpload(void* userdata) +{ + std::string filename = gLocalBrowser->GetBitmapUnit( + (LLUUID)sLFInstance->mBitmapList->getSelectedItemLabel(BITMAPLIST_COL_ID) )->getFileName(); + + if ( !filename.empty() ) + { + LLFloaterImagePreview* floaterp = new LLFloaterImagePreview(filename); + LLUICtrlFactory::getInstance()->buildFloater(floaterp, "floater_image_preview.xml"); + } +} + +void FloaterLocalAssetBrowser::onChooseBitmapList(LLUICtrl* ctrl, void *userdata) +{ + bool button_status = sLFInstance->mBitmapList->isEmpty(); + sLFInstance->mDelBtn->setEnabled(!button_status); + sLFInstance->mUploadBtn->setEnabled(!button_status); + + sLFInstance->UpdateRightSide(); +} + +void FloaterLocalAssetBrowser::onClickUpdateChkbox(LLUICtrl *ctrl, void *userdata) +{ + std::string temp_str = sLFInstance->mBitmapList->getSelectedItemLabel(BITMAPLIST_COL_ID); + if ( !temp_str.empty() ) + { + gLocalBrowser->onUpdateBool( (LLUUID)temp_str ); + sLFInstance->UpdateRightSide(); + } +} + +void FloaterLocalAssetBrowser::onCommitTypeCombo(LLUICtrl* ctrl, void *userdata) +{ + std::string temp_str = sLFInstance->mBitmapList->getSelectedItemLabel(BITMAPLIST_COL_ID); + + if ( !temp_str.empty() ) + { + S32 selection = sLFInstance->mTypeComboBox->getCurrentIndex(); + gLocalBrowser->onSetType( (LLUUID)temp_str, selection ); + + } +} + +void FloaterLocalAssetBrowser::FloaterResize(bool expand) +{ + sLFInstance->mMoreBtn->setVisible(!expand); + sLFInstance->mLessBtn->setVisible(expand); + sLFInstance->mTextureView->setVisible(expand); + sLFInstance->mUpdateChkBox->setVisible(expand); + sLFInstance->mCaptionPathTxt->setVisible(expand); + sLFInstance->mCaptionUUIDTxt->setVisible(expand); + sLFInstance->mCaptionLinkTxt->setVisible(expand); + sLFInstance->mCaptionNameTxt->setVisible(expand); + sLFInstance->mCaptionTimeTxt->setVisible(expand); + sLFInstance->mTypeComboBox->setVisible(expand); + + sLFInstance->mTimeTxt->setVisible(expand); + sLFInstance->mPathTxt->setVisible(expand); + sLFInstance->mUUIDTxt->setVisible(expand); + sLFInstance->mLinkTxt->setVisible(expand); + sLFInstance->mNameTxt->setVisible(expand); + + if(expand) + { + sLFInstance->reshape(LF_FLOATER_EXPAND_WIDTH, LF_FLOATER_HEIGHT); + sLFInstance->setResizeLimits(LF_FLOATER_EXPAND_WIDTH, LF_FLOATER_HEIGHT); + sLFInstance->UpdateRightSide(); + } + else + { + sLFInstance->reshape(LF_FLOATER_CONTRACT_WIDTH, LF_FLOATER_HEIGHT); + sLFInstance->setResizeLimits(LF_FLOATER_CONTRACT_WIDTH, LF_FLOATER_HEIGHT); + } + +} + +void FloaterLocalAssetBrowser::UpdateBitmapScrollList() +{ + if ( !sLFInstance ) { return; } + + sLFInstance->mBitmapList->clearRows(); + if (!gLocalBrowser->loaded_bitmaps.empty()) + { + + LocalAssetBrowser::local_list_iter iter; + for(iter = gLocalBrowser->loaded_bitmaps.begin(); iter != gLocalBrowser->loaded_bitmaps.end(); iter++) + { + LLSD element; + element["columns"][BITMAPLIST_COL_NAME]["column"] = "bitmap_name"; + element["columns"][BITMAPLIST_COL_NAME]["type"] = "text"; + element["columns"][BITMAPLIST_COL_NAME]["value"] = (*iter)->getShortName(); + + element["columns"][BITMAPLIST_COL_ID]["column"] = "bitmap_uuid"; + element["columns"][BITMAPLIST_COL_ID]["type"] = "text"; + element["columns"][BITMAPLIST_COL_ID]["value"] = (*iter)->getID(); + + sLFInstance->mBitmapList->addElement(element); + } + + } + sLFInstance->UpdateRightSide(); +} + +void FloaterLocalAssetBrowser::UpdateRightSide() +{ + /* + Since i'm not keeping a bool on if the floater is expanded or not, i'll + just check if one of the widgets that shows when the floater is expanded is visible. + + Also obviously before updating - checking if something IS actually selected :o + */ + + if ( !sLFInstance->mTextureView->getVisible() ) { return; } + + if ( !sLFInstance->mBitmapList->getAllSelected().empty() ) + { + LocalBitmap* unit = gLocalBrowser->GetBitmapUnit( LLUUID(sLFInstance->mBitmapList->getSelectedItemLabel(BITMAPLIST_COL_ID)) ); + + if ( unit ) + { + sLFInstance->mTextureView->setImageAssetID( unit->getID() ); + sLFInstance->mUpdateChkBox->set( unit->getUpdateBool() ); + sLFInstance->mPathTxt->setText( unit->getFileName() ); + sLFInstance->mUUIDTxt->setText( unit->getID().asString() ); + sLFInstance->mNameTxt->setText( unit->getShortName() ); + sLFInstance->mTimeTxt->setText( unit->getLastModified().asString() ); + sLFInstance->mLinkTxt->setText( unit->getLinkStatus() ); + sLFInstance->mTypeComboBox->selectNthItem( unit->getType() ); + + sLFInstance->mTextureView->setEnabled(true); + sLFInstance->mUpdateChkBox->setEnabled(true); + sLFInstance->mTypeComboBox->setEnabled(true); + } + } + else + { + sLFInstance->mTextureView->setImageAssetID( NO_IMAGE ); + sLFInstance->mTextureView->setEnabled( false ); + sLFInstance->mUpdateChkBox->set( false ); + sLFInstance->mUpdateChkBox->setEnabled( false ); + + sLFInstance->mTypeComboBox->selectFirstItem(); + sLFInstance->mTypeComboBox->setEnabled( false ); + + sLFInstance->mPathTxt->setText( LLStringExplicit("None") ); + sLFInstance->mUUIDTxt->setText( LLStringExplicit("None") ); + sLFInstance->mNameTxt->setText( LLStringExplicit("None") ); + sLFInstance->mLinkTxt->setText( LLStringExplicit("None") ); + sLFInstance->mTimeTxt->setText( LLStringExplicit("None") ); + } +} + + +/*==================================================*/ +/* LocalAssetBrowserTimer: timer class */ +/*==================================================*/ +/* + A small, simple timer class inheriting from + LLEventTimer, responsible for pinging the + LocalAssetBrowser class to perform it's + updates / checks / etc. + +*/ + +LocalAssetBrowserTimer::LocalAssetBrowserTimer() : LLEventTimer( (F32)TIMER_HEARTBEAT ) +{ + +} + +LocalAssetBrowserTimer::~LocalAssetBrowserTimer() +{ + +} + +BOOL LocalAssetBrowserTimer::tick() +{ + gLocalBrowser->PerformTimedActions(); + return FALSE; +} + +void LocalAssetBrowserTimer::start() +{ + mEventTimer.start(); +} + +void LocalAssetBrowserTimer::stop() +{ + mEventTimer.stop(); +} + +bool LocalAssetBrowserTimer::isRunning() +{ + return mEventTimer.getStarted(); +} + diff --git a/indra/newview/floaterlocalassetbrowse.h b/indra/newview/floaterlocalassetbrowse.h new file mode 100644 index 000000000..6ee1c75a3 --- /dev/null +++ b/indra/newview/floaterlocalassetbrowse.h @@ -0,0 +1,305 @@ +/** +* @file floaterlocalassetbrowse.h +* @brief Local texture support +* +* $LicenseInfo:firstyear=2009&license=viewergpl$ +* +* Copyright (c) 2010, author unknown +* +* Imprudence Viewer Source Code +* The source code in this file ("Source Code") is provided to you +* under the terms of the GNU General Public License, version 2.0 +* ("GPL"). Terms of the GPL can be found in doc/GPL-license.txt in +* this distribution, or online at +* http://secondlifegrid.net/programs/open_source/licensing/gplv2 +* +* There are special exceptions to the terms and conditions of the GPL as +* it is applied to this Source Code. View the full text of the exception +* in the file doc/FLOSS-exception.txt in this software distribution, or +* online at http://secondlifegrid.net/programs/open_source/licensing/flossexception +* +* By copying, modifying or distributing this software, you acknowledge +* that you have read and understood your obligations described above, +* and agree to abide by those obligations. +* +* ALL SOURCE CODE IS PROVIDED "AS IS." THE AUTHOR MAKES NO +* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +* COMPLETENESS OR PERFORMANCE. +* $/LicenseInfo$ +*/ + +/* Local Asset Browser: header + +tag: vaa emerald local_asset_browser + +*/ + + +#ifndef VAA_LOCALBROWSER +#define VAA_LOCALBROWSER + +#include "llfloater.h" +#include "llscrolllistctrl.h" +#include "lltexturectrl.h" +#include "lldrawable.h" + + +/*=======================================*/ +/* Global structs / enums / defines */ +/*=======================================*/ + +#define LF_FLOATER_EXPAND_WIDTH 735 +#define LF_FLOATER_CONTRACT_WIDTH 415 +#define LF_FLOATER_HEIGHT 260 + +#define LOCAL_USE_MIPMAPS true +#define LOCAL_DISCARD_LEVEL 0 +#define NO_IMAGE LLUUID::null + +#define TIMER_HEARTBEAT 3.0 + +#define SLAM_FOR_DEBUG true + +enum bitmaplist_cols +{ + BITMAPLIST_COL_NAME, + BITMAPLIST_COL_ID +}; + +/* upload & sculpt update related */ +struct affected_object +{ + LLViewerObject* object; + std::vector face_list; + bool local_sculptmap; + +}; + +/* texture picker defines */ + +#define LOCAL_TEXTURE_PICKER_NAME "texture picker" +#define LOCAL_TEXTURE_PICKER_LIST_NAME "local_name_list" +#define LOCAL_TEXTURE_PICKER_RECURSE true +#define LOCAL_TEXTURE_PICKER_CREATEIFMISSING true + + +/*=======================================*/ +/* LocalBitmap: unit class */ +/*=======================================*/ +/* + The basic unit class responsible for + containing one loaded local texture. +*/ + +class LocalBitmap +{ + public: + LocalBitmap(std::string filename); + virtual ~LocalBitmap(void); + friend class LocalAssetBrowser; + + public: /* [enums, typedefs, etc] */ + enum link_status + { + LINK_UNKNOWN, /* default fallback */ + LINK_ON, + LINK_OFF, + LINK_BROKEN, + LINK_UPDATING /* currently redundant, but left in case necessary later. */ + }; + + enum extension_type + { + IMG_EXTEN_BMP, + IMG_EXTEN_TGA, + IMG_EXTEN_JPG, + IMG_EXTEN_PNG + }; + + enum bitmap_type + { + TYPE_TEXTURE = 0, + TYPE_SCULPT = 1, + TYPE_LAYER = 2 + }; + + public: /* [information query functions] */ + std::string getShortName(void); + std::string getFileName(void); + LLUUID getID(void); + LLSD getLastModified(void); + std::string getLinkStatus(void); + bool getUpdateBool(void); + void setType( S32 ); + bool getIfValidBool(void); + S32 getType(void); + void getDebugInfo(void); + + private: /* [maintenence functions] */ + void updateSelf(void); + bool decodeSelf(LLImageRaw* rawimg); + void setUpdateBool(void); + + LocalBitmap* getThis(void); + std::vector getFaceUsesThis(LLDrawable*); + std::vector getUsingObjects(bool seek_by_type = true, + bool seek_textures = false, bool seek_sculptmaps = false); + + protected: /* [basic properties] */ + std::string shortname; + std::string filename; + extension_type extension; + LLUUID id; + LLSD last_modified; + link_status linkstatus; + bool keep_updating; + bool valid; + S32 bitmap_type; + bool sculpt_dirty; + bool volume_dirty; +}; + +/*=======================================*/ +/* LocalAssetBrowser: main class */ +/*=======================================*/ +/* + Responsible for internal workings. + Instantiated at the top of the source file. + Sits in memory until the viewer is closed. + +*/ + + +class LocalAssetBrowser +{ + public: + LocalAssetBrowser(); + virtual ~LocalAssetBrowser(); + friend class FloaterLocalAssetBrowser; + friend class LocalAssetBrowserTimer; + static void UpdateTextureCtrlList(LLScrollListCtrl*); + static void setLayerUpdated(bool toggle) { mLayerUpdated = toggle; } + static void setSculptUpdated(bool toggle) { mSculptUpdated = toggle; } + static void AddBitmap(void); + static void DelBitmap( std::vector, S32 column = BITMAPLIST_COL_ID ); + + /* UpdateTextureCtrlList was made public cause texturectrl requests it once on spawn + ( added: when it's own add/remove funcs are used. ) + i've made it update on spawn instead of on pressing 'local' because the former does it once, + the latter - each time the button's pressed. */ + + private: + static void onChangeHappened(void); + static void onUpdateBool(LLUUID); + static void onSetType(LLUUID, S32); + static LocalBitmap* GetBitmapUnit(LLUUID); + static bool IsDoingUpdates(void); + static void PingTimer(void); + static void PerformTimedActions(void); + static void PerformSculptUpdates(LocalBitmap*); + + protected: + static std::vector loaded_bitmaps; + typedef std::vector::iterator local_list_iter; + static bool mLayerUpdated; + static bool mSculptUpdated; +}; + +/*==================================================*/ +/* FloaterLocalAssetBrowser : interface class */ +/*==================================================*/ +/* + Responsible for talking to the user. + Instantiated by user request. + Destroyed when the floater is closed. + +*/ +class FloaterLocalAssetBrowser : public LLFloater +{ +public: + FloaterLocalAssetBrowser(); + virtual ~FloaterLocalAssetBrowser(); + static void show(void*); + + + +private: + /* Widget related callbacks */ + // Button callback declarations + static void onClickAdd(void* userdata); + static void onClickDel(void* userdata); + static void onClickMore(void* userdata); + static void onClickLess(void* userdata); + static void onClickUpload(void* userdata); + + // ScrollList callback declarations + static void onChooseBitmapList(LLUICtrl* ctrl, void* userdata); + + // Checkbox callback declarations + static void onClickUpdateChkbox(LLUICtrl* ctrl, void* userdata); + + // Combobox type select + static void onCommitTypeCombo(LLUICtrl* ctrl, void* userdata); + + // Widgets + LLButton* mAddBtn; + LLButton* mDelBtn; + LLButton* mMoreBtn; + LLButton* mLessBtn; + LLButton* mUploadBtn; + + LLScrollListCtrl* mBitmapList; + LLScrollListCtrl* mUsedList; + LLTextureCtrl* mTextureView; + LLCheckBoxCtrl* mUpdateChkBox; + + LLLineEditor* mPathTxt; + LLLineEditor* mUUIDTxt; + LLLineEditor* mNameTxt; + + LLTextBox* mLinkTxt; + LLTextBox* mTimeTxt; + LLComboBox* mTypeComboBox; + + LLTextBox* mCaptionPathTxt; + LLTextBox* mCaptionUUIDTxt; + LLTextBox* mCaptionLinkTxt; + LLTextBox* mCaptionNameTxt; + LLTextBox* mCaptionTimeTxt; + + /* static pointer to self, wai? oh well. */ + static FloaterLocalAssetBrowser* sLFInstance; + + // non-widget functions + static void FloaterResize(bool expand); + static void UpdateRightSide(void); + +public: + static void UpdateBitmapScrollList(void); + + +}; + +/*==================================================*/ +/* LocalAssetBrowserTimer : timer class */ +/*==================================================*/ +/* + A small, simple timer class inheriting from + LLEventTimer, responsible for pinging the + LocalAssetBrowser class to perform it's + updates / checks / etc. + +*/ +class LocalAssetBrowserTimer : public LLEventTimer +{ + public: + LocalAssetBrowserTimer(); + ~LocalAssetBrowserTimer(); + virtual BOOL tick(); + void start(); + void stop(); + bool isRunning(); +}; + +#endif + diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index a3742afe1..34fbbdbd0 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -3654,6 +3654,8 @@ void LLAppViewer::idleShutdown() // close IM interface if(gIMMgr) { + // Save group chat ignore list -- MC + gIMMgr->saveIgnoreGroup(); gIMMgr->disconnectAllSessions(); } diff --git a/indra/newview/llhoverview.cpp b/indra/newview/llhoverview.cpp index 84a66247c..1b3fe90e7 100644 --- a/indra/newview/llhoverview.cpp +++ b/indra/newview/llhoverview.cpp @@ -500,6 +500,27 @@ void LLHoverView::updateText() } mText.push_back(line); } + line.clear(); + S32 prim_count = LLSelectMgr::getInstance()->getHoverObjects()->getObjectCount(); + line.append(llformat("Prims: %d", prim_count)); + mText.push_back(line); + + line.clear(); + line.append("Position: "); + + LLViewerRegion *region = gAgent.getRegion(); + LLVector3 position = region->getPosRegionFromGlobal(hit_object->getPositionGlobal());//regionp->getOriginAgent(); + LLVector3 mypos = region->getPosRegionFromGlobal(gAgent.getPositionGlobal()); + + + LLVector3 delta = position - mypos; + F32 distance = (F32)delta.magVec(); + + line.append(llformat("<%.02f,%.02f,%.02f>",position.mV[0],position.mV[1],position.mV[2])); + mText.push_back(line); + line.clear(); + line.append(llformat("Distance: %.02fm",distance)); + mText.push_back(line); // If the hover tip shouldn't be shown, delete all the object text if (suppressObjectHoverDisplay) diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 1f7f1bb04..b1e7dd664 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -53,6 +53,7 @@ #include "llhttpnode.h" #include "llimpanel.h" #include "llresizebar.h" +#include "llsdserialize.h" #include "lltabcontainer.h" #include "llviewercontrol.h" #include "llfloater.h" @@ -605,6 +606,30 @@ void LLIMMgr::addMessage( // create IM window as necessary if(!floater) { + if (gIMMgr->getIgnoreGroupListCount() > 0 && gAgent.isInGroup(session_id)) + { + // Check to see if we're blocking this group's chat + LLGroupData* group_data = NULL; + + // Search for this group in the agent's groups list + LLDynamicArray::iterator i; + + for (i = gAgent.mGroups.begin(); i != gAgent.mGroups.end(); i++) + { + if (i->mID == session_id) + { + group_data = &*i; + break; + } + } + + // If the group is in our list then return + if (group_data && gIMMgr->getIgnoreGroup(group_data->mID)) + { + return; + } + } + std::string name = from; if(!session_name.empty() && session_name.size()>1) { @@ -1286,6 +1311,111 @@ void LLIMMgr::updateFloaterSessionID( } } +void LLIMMgr::loadIgnoreGroup() +{ + std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "ignore_groups.xml"); + + LLSD settings_llsd; + llifstream file; + file.open(filename); + if (file.is_open()) + { + // llinfos << "loading group chat ignore from " << filename << "..." << llendl; + LLSDSerialize::fromXML(settings_llsd, file); + + mIgnoreGroupList.clear(); + + for(LLSD::array_const_iterator iter = settings_llsd.beginArray(); + iter != settings_llsd.endArray(); ++iter) + { + // llinfos << "added " << iter->asUUID() + // << " to group chat ignore list" << llendl; + mIgnoreGroupList.push_back( iter->asUUID() ); + } + } + else + { + // llinfos << "can't load " << filename + // << " (probably it doesn't exist yet)" << llendl; + } +} + +void LLIMMgr::saveIgnoreGroup() +{ + // llinfos << "saving ignore_groups.xml" << llendl; + + std::string user_dir = gDirUtilp->getLindenUserDir(); + if (!user_dir.empty()) + { + std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "ignore_groups.xml"); + + LLSD settings_llsd = LLSD::emptyArray(); + + for(std::list::iterator iter = mIgnoreGroupList.begin(); + iter != mIgnoreGroupList.end(); ++iter) + { + settings_llsd.append(*iter); + } + + llofstream file; + file.open(filename); + LLSDSerialize::toPrettyXML(settings_llsd, file); + } +} + +void LLIMMgr::updateIgnoreGroup(const LLUUID& group_id, bool ignore) +{ + if (group_id.notNull()) + { + std::list::iterator found = + std::find( mIgnoreGroupList.begin(), mIgnoreGroupList.end(), + group_id); + + if (found != mIgnoreGroupList.end() && !ignore) + { + // change from ignored to not ignored + // llinfos << "unignoring group " << group_id << llendl; + mIgnoreGroupList.remove(group_id); + } + else if (found == mIgnoreGroupList.end() && ignore) + { + // change from not ignored to ignored + // llinfos << "ignoring group " << group_id << llendl; + mIgnoreGroupList.push_back(group_id); + } + else + { + // nothing to do + // llinfos << "no change to group " << group_id << ", it is already " + // << (ignore ? "" : "not ") << "ignored" << llendl; + } + } +} + +bool LLIMMgr::getIgnoreGroup(const LLUUID& group_id) +{ + if (group_id.notNull()) + { + std::list::iterator found = + std::find( mIgnoreGroupList.begin(), mIgnoreGroupList.end(), + group_id); + + if (found != mIgnoreGroupList.end()) + { + // llinfos << "group " << group_id << " is ignored." << llendl; + return true; + } + } + // llinfos << "group " << group_id << " is not ignored." << llendl; + return false; +} + + +////////////////////// +///// ChatterBox ///// +////////////////////// + + LLFloaterChatterBox* LLIMMgr::getFloater() { return LLFloaterChatterBox::getInstance(LLSD()); diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h index 115076bf3..e1052c273 100644 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -172,6 +172,12 @@ public: //HACK: need a better way of enumerating existing session, or listening to session create/destroy events const std::set >& getIMFloaterHandles() { return mFloaters; } + void loadIgnoreGroup(); + void saveIgnoreGroup(); + void updateIgnoreGroup(const LLUUID& group_id, bool ignore); + // Returns true if group chat is ignored for the UUID, false if not + bool getIgnoreGroup(const LLUUID& group_id); + private: // create a panel and update internal representation for // consistency. Returns the pointer, caller (the class instance @@ -211,6 +217,12 @@ private: LLSD mPendingInvitations; LLSD mPendingAgentListUpdates; + + std::list mIgnoreGroupList; + +public: + + S32 getIgnoreGroupListCount() { return mIgnoreGroupList.size(); } }; diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp index c19011014..f5dbfc6c7 100644 --- a/indra/newview/llpanelgroupgeneral.cpp +++ b/indra/newview/llpanelgroupgeneral.cpp @@ -45,6 +45,7 @@ #include "llcheckboxctrl.h" #include "llcombobox.h" #include "lldbstrings.h" +#include "llimview.h" #include "lllineeditor.h" #include "llnamebox.h" #include "llnamelistctrl.h" @@ -91,6 +92,7 @@ LLPanelGroupGeneral::LLPanelGroupGeneral(const std::string& name, mCtrlEnrollmentFee(NULL), mSpinEnrollmentFee(NULL), mCtrlReceiveNotices(NULL), + mCtrlReceiveChat(NULL), mCtrlListGroup(NULL), mActiveTitleLabel(NULL), mComboActiveTitle(NULL) @@ -219,6 +221,15 @@ BOOL LLPanelGroupGeneral::postBuild() mCtrlReceiveNotices->set(accept_notices); mCtrlReceiveNotices->setEnabled(data.mID.notNull()); } + + mCtrlReceiveChat = getChild("receive_chat", recurse); + if (mCtrlReceiveChat) + { + mCtrlReceiveChat->setCommitCallback(onCommitUserOnly); + mCtrlReceiveChat->setCallbackUserData(this); + mCtrlReceiveChat->set(!gIMMgr->getIgnoreGroup(mGroupID)); + mCtrlReceiveChat->setEnabled(mGroupID.notNull()); + } mCtrlListGroup = getChild("list_groups_in_profile", recurse); if (mCtrlListGroup) @@ -544,6 +555,14 @@ bool LLPanelGroupGeneral::apply(std::string& mesg) gAgent.setUserGroupFlags(mGroupID, receive_notices, list_in_profile); + if (mCtrlReceiveChat) + { + bool receive_chat = mCtrlReceiveChat->get(); + gIMMgr->updateIgnoreGroup(mGroupID, !receive_chat); + // Save here too in case we crash somewhere down the road -- MC + gIMMgr->saveIgnoreGroup(); + } + mChanged = FALSE; return true; @@ -760,6 +779,13 @@ void LLPanelGroupGeneral::update(LLGroupChange gc) mCtrlReceiveNotices->resetDirty(); } + if (mCtrlReceiveChat) + { + mCtrlReceiveChat->setVisible(is_member); + mCtrlReceiveChat->setEnabled(TRUE); + mCtrlReceiveChat->resetDirty(); + } + if (mInsignia) mInsignia->setEnabled(mAllowEdit && can_change_ident); if (mEditCharter) mEditCharter->setEnabled(mAllowEdit && can_change_ident); @@ -914,6 +940,7 @@ void LLPanelGroupGeneral::updateChanged() mCtrlEnrollmentFee, mSpinEnrollmentFee, mCtrlReceiveNotices, + mCtrlReceiveChat, mCtrlListGroup, mActiveTitleLabel, mComboActiveTitle diff --git a/indra/newview/llpanelgroupgeneral.h b/indra/newview/llpanelgroupgeneral.h index 71356677f..c4572e2d4 100644 --- a/indra/newview/llpanelgroupgeneral.h +++ b/indra/newview/llpanelgroupgeneral.h @@ -107,6 +107,7 @@ private: LLCheckBoxCtrl *mCtrlEnrollmentFee; LLSpinCtrl *mSpinEnrollmentFee; LLCheckBoxCtrl *mCtrlReceiveNotices; + LLCheckBoxCtrl *mCtrlReceiveChat; LLCheckBoxCtrl *mCtrlListGroup; LLTextBox *mActiveTitleLabel; LLComboBox *mComboActiveTitle; diff --git a/indra/newview/llpanelnetwork.cpp b/indra/newview/llpanelnetwork.cpp index 4e00e9f0c..6e66628eb 100644 --- a/indra/newview/llpanelnetwork.cpp +++ b/indra/newview/llpanelnetwork.cpp @@ -103,7 +103,12 @@ LLPanelNetwork::~LLPanelNetwork() void LLPanelNetwork::apply() { - gSavedSettings.setU32("CacheSize", childGetValue("cache_size").asInteger()); + U32 cache_size = (U32)childGetValue("cache_size").asInteger(); + if (gSavedSettings.getU32("CacheSize") != cache_size) + { + onClickClearCache(this); + gSavedSettings.setU32("CacheSize", cache_size); + } gSavedSettings.setF32("ThrottleBandwidthKBPS", childGetValue("max_bandwidth").asReal()); gSavedSettings.setBOOL("ConnectionPortEnabled", childGetValue("connection_port_enabled")); gSavedSettings.setU32("ConnectionPort", childGetValue("connection_port").asInteger()); diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index b67178de1..9224cb5b0 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -119,6 +119,7 @@ #include "llhudmanager.h" #include "llhttpclient.h" #include "llimagebmp.h" +#include "llimview.h" // for gIMMgr #include "llinventorymodel.h" #include "llinventoryview.h" #include "llkeyboard.h" @@ -1833,6 +1834,8 @@ bool idle_startup() // OGPX : successful login path common to OGP and XML-RPC if (successful_login) { + gIMMgr->loadIgnoreGroup(); + // JC: gesture loading done below, when we have an asset system // in place. Don't delete/clear user_credentials until then. diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index 567c02500..8ccd47066 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -53,7 +53,7 @@ //note: there is no good to define 1024 for TEXTURE_CACHE_ENTRY_SIZE while FIRST_PACKET_SIZE is 600 on sim side. const S32 TEXTURE_CACHE_ENTRY_SIZE = FIRST_PACKET_SIZE;//1024; -const F32 TEXTURE_CACHE_PURGE_AMOUNT = .20f; // % amount to reduce the cache by when it exceeds its limit +const S64 TEXTURE_PURGED_CACHE_SIZE = 80; // % amount of cache left after a purge. const F32 TEXTURE_CACHE_LRU_SIZE = .10f; // % amount for LRU list (low overhead to regenerate) class LLTextureCacheWorker : public LLWorkerClass @@ -751,7 +751,7 @@ LLTextureCache::LLTextureCache(bool threaded) mTexturesSizeTotal(0), mDoPurge(FALSE) { - purgeTextures(false, true); + purgeTextureFilesTimeSliced(true); clearDeleteList(); writeUpdatedEntries(); } @@ -836,17 +836,15 @@ std::string LLTextureCache::getTextureFileName(const LLUUID& id) BOOL LLTextureCache::isInCache(const LLUUID& id) { LLMutexLock lock(&mHeaderMutex); - id_map_t::const_iterator iter = mHeaderIDMap.find(id); - - return (iter != mHeaderIDMap.end()); + return (mHeaderIDMap.find(id) != mHeaderIDMap.end()); } - + //debug BOOL LLTextureCache::isInLocal(const LLUUID& id) { S32 local_size = 0; std::string local_filename; - + std::string filename = getLocalFileName(id); // Is it a JPEG2000 file? { @@ -917,19 +915,13 @@ void LLTextureCache::purgeCache(ELLPath location) if(LLFile::isdir(mTexturesDirName)) { std::string file_name = gDirUtilp->getExpandedFilename(location, entries_filename); - if (LLAPRFile::isExist(file_name)) - { - LLAPRFile::remove(file_name); - } + LLAPRFile::remove(file_name); file_name = gDirUtilp->getExpandedFilename(location, cache_filename); - if (LLAPRFile::isExist(file_name)) - { - LLAPRFile::remove(file_name); - } + LLAPRFile::remove(file_name); purgeAllTextures(true); - } + } mTexturesDirName = texture_dir; } @@ -1323,7 +1315,7 @@ void LLTextureCache::writeEntriesAndClose(const std::vector& entries) { clearCorruptedCache(); //clear the cache. return; - } + } } closeHeaderEntriesFile(); } @@ -1555,22 +1547,16 @@ void LLTextureCache::purgeAllTextures(bool purge_directories) llinfos << "The entire texture cache is cleared." << llendl; } -void LLTextureCache::purgeTextures(bool validate, bool force) +void LLTextureCache::purgeTextures(bool validate) { - static LLTimer timeout; - const S32 min_purge_count = 20; - const F32 delay_between_passes = 15.0f; - const F32 max_time_per_pass = 0.5f; - static F32 time_per_pass = 0.05f; + mDoPurge = FALSE; - if (!force && timeout.getElapsedTimeF32() <= delay_between_passes) + if (mReadOnly) { return; } - mDoPurge = FALSE; - timeout.reset(); - if (mReadOnly) + if (!validate && mTexturesSizeTotal < sCacheMaxTexturesSize) { return; } @@ -1583,8 +1569,6 @@ void LLTextureCache::purgeTextures(bool validate, bool force) LLMutexLock lock(&mHeaderMutex); - llinfos << "TEXTURE CACHE: Purging." << llendl; - // Read the entries list std::vector entries; U32 num_entries = openAndReadEntries(entries); @@ -1594,9 +1578,11 @@ void LLTextureCache::purgeTextures(bool validate, bool force) return; // nothing to purge } + LL_INFOS("TextureCache") << "TEXTURE CACHE: Purging." << LL_ENDL; + // Use mTexturesSizeMap to collect UUIDs of textures with bodies typedef std::set > time_idx_set_t; - std::set > time_idx_set; + time_idx_set_t time_idx_set; for (size_map_t::iterator iter1 = mTexturesSizeMap.begin(); iter1 != mTexturesSizeMap.end(); ++iter1) { @@ -1629,26 +1615,12 @@ void LLTextureCache::purgeTextures(bool validate, bool force) LL_DEBUGS("TextureCache") << "TEXTURE CACHE: Validating: " << validate_idx << LL_ENDL; } - F32 overhead = timeout.getElapsedTimeF32(); - if (2.0f * overhead > time_per_pass) - { - time_per_pass = llmin(overhead, max_time_per_pass); - } - timeout.reset(); - S64 cache_size = mTexturesSizeTotal; - S64 purged_cache_size = (sCacheMaxTexturesSize * (S64)((1.f - TEXTURE_CACHE_PURGE_AMOUNT) * 100.f)) / 100; + S64 purged_cache_size = (TEXTURE_PURGED_CACHE_SIZE * sCacheMaxTexturesSize) / (S64)100; S32 purge_count = 0; for (time_idx_set_t::iterator iter = time_idx_set.begin(); iter != time_idx_set.end(); ++iter) { - if (!force && !validate && purge_count >= min_purge_count && timeout.getElapsedTimeF32() > time_per_pass) - { - LL_INFOS("TextureCache") << "Texture cache purge splitted to avoid long hiccup." << LL_ENDL; - mDoPurge = TRUE; - break; - } - S32 idx = iter->second; bool purge_entry = false; std::string filename = getTextureFileName(entries[idx].mID); @@ -1680,76 +1652,101 @@ void LLTextureCache::purgeTextures(bool validate, bool force) if (purge_entry) { purge_count++; - removeEntry(idx, entries[idx], filename); + mFilesToDelete.insert(std::make_pair(entries[idx].mID, filename)); cache_size -= entries[idx].mBodySize; + removeEntry(idx, entries[idx], filename, false); // remove the entry but not the file } } - mTimeLastFileDelete.reset(); - LL_DEBUGS("TextureCache") << "TEXTURE CACHE: Writing Entries: " << num_entries << LL_ENDL; - F32 purge_time = timeout.getElapsedTimeF32(); - timeout.reset(); writeEntriesAndClose(entries); - overhead += timeout.getElapsedTimeF32(); - time_per_pass = llmin(overhead, max_time_per_pass); + if (purge_count > 0) + { + writeEntriesAndClose(entries); + + LL_INFOS("TextureCache") << "TEXTURE CACHE:" + << " Purged: " << purge_count + << " - Entries: " << num_entries + << " - Cache size: " << mTexturesSizeTotal / (1024 * 1024) << " MB" + << " - Files scheduled for deletion: " << mFilesToDelete.size() + << LL_ENDL; + } + else + { + LL_INFOS("TextureCache") << "TEXTURE CACHE: nothing to purge." << LL_ENDL; + } // *FIX:Mani - watchdog back on. LLAppViewer::instance()->resumeMainloopTimeout(); - LL_INFOS("TextureCache") << "TEXTURE CACHE:" - << " Purged: " << purge_count - << " - Entries: " << num_entries - << " - Cache size: " << mTexturesSizeTotal / (1024 * 1024) << " MB" - << " - Time used for this purge: " << purge_time + overhead << "s (including " << overhead << "s of overhead)." - << LL_ENDL; - - timeout.reset(); + mSlicedPurgeTimer.reset(); } -void LLTextureCache::purgeTextureFilesTimeSliced(BOOL force_all) +void LLTextureCache::purgeTextureFilesTimeSliced(bool force) { - LLMutexLock lock(&mHeaderMutex); + const F32 delay_between_passes = 2.0f; // seconds + const F32 max_time_per_pass = 0.1f; // seconds - F32 delay_between_passes = 1.0f; // seconds - F32 max_time_per_pass = 0.1f; // seconds - - if (!force_all && mTimeLastFileDelete.getElapsedTimeF32() <= delay_between_passes) + if (!force && mSlicedPurgeTimer.getElapsedTimeF32() <= delay_between_passes) { return; } - LLTimer timer; - S32 howmany = 0; - if (!mFilesToDelete.empty()) { - LL_INFOS("TEXTURE CACHE") << "purging time sliced with " << mFilesToDelete.size() << " files scheduled for deletion" << llendl; + LL_INFOS("TextureCache") << "time sliced purging with " << mFilesToDelete.size() + << " files scheduled for deletion" << LL_ENDL; - for (LLTextureCache::filename_list_t::iterator iter = mFilesToDelete.begin(); iter!=mFilesToDelete.end(); ) + LLMutexLock lock(&mHeaderMutex); + mSlicedPurgeTimer.reset(); + U32 purged = 0; + std::string filename; + + for (LLTextureCache::purge_map_t::iterator iter = mFilesToDelete.begin(); iter != mFilesToDelete.end(); ) + { + LLTextureCache::purge_map_t::iterator curiter = iter++; + // Only remove files for textures that have not been cached again + // since we selected them for removal ! + if (mHeaderIDMap.find(curiter->first) == mHeaderIDMap.end()) + { + filename = curiter->second; + LLAPRFile::remove(filename); + } + else { - LLTextureCache::filename_list_t::iterator iter2 = iter++; - LLAPRFile::remove(*iter2); - mFilesToDelete.erase(iter2); - howmany++; + LL_DEBUGS("TextureCache") << curiter->second + << " selected for removal, but texture cached again since !" + << LL_ENDL; + } + mFilesToDelete.erase(curiter); + purged++; - if (!force_all && timer.getElapsedTimeF32() > max_time_per_pass) + if (!force && mSlicedPurgeTimer.getElapsedTimeF32() > max_time_per_pass) { break; } } - } - if (!mFilesToDelete.empty()) + if (mFilesToDelete.empty()) + { + LL_INFOS("TextureCache") << "time sliced purge finished with " << purged + << " files deleted in " + << mSlicedPurgeTimer.getElapsedTimeF32() + << "s" << LL_ENDL; + } + else { - LL_INFOS("TEXTURE CACHE") << "purging time sliced with " << howmany << " files deleted (" - << mFilesToDelete.size() << " files left for next pass)" - << llendl; + LL_INFOS("TextureCache") << "time sliced purge: " << purged + << " files deleted in " + << mSlicedPurgeTimer.getElapsedTimeF32() + << "s (" << mFilesToDelete.size() + << " files left for next pass)" << LL_ENDL; } - mTimeLastFileDelete.reset(); + mSlicedPurgeTimer.reset(); + } } ////////////////////////////////////////////////////////////////////////////// @@ -1943,23 +1940,20 @@ void LLTextureCache::addCompleted(Responder* responder, bool success) //called after mHeaderMutex is locked. void LLTextureCache::removeCachedTexture(const LLUUID& id) { - if(mTexturesSizeMap.find(id) != mTexturesSizeMap.end()) + if (mTexturesSizeMap.find(id) != mTexturesSizeMap.end()) { mTexturesSizeTotal -= mTexturesSizeMap[id]; mTexturesSizeMap.erase(id); } mHeaderIDMap.erase(id); std::string filename = getTextureFileName(id); - if (LLAPRFile::isExist(filename)) - { - LLAPRFile::remove(filename); - } + LLAPRFile::remove(filename); } //called after mHeaderMutex is locked. -void LLTextureCache::removeEntry(S32 idx, Entry& entry, std::string& filename) +void LLTextureCache::removeEntry(S32 idx, Entry& entry, std::string& filename, bool remove_file) { - if(idx >= 0) //valid entry + if (idx >= 0) //valid entry { entry.mImageSize = -1; entry.mBodySize = 0; @@ -1970,7 +1964,7 @@ void LLTextureCache::removeEntry(S32 idx, Entry& entry, std::string& filename) mFreeList.insert(idx); } - if (LLAPRFile::isExist(filename)) + if (remove_file) { LLAPRFile::remove(filename); } diff --git a/indra/newview/lltexturecache.h b/indra/newview/lltexturecache.h index ac9285008..45ec5e211 100644 --- a/indra/newview/lltexturecache.h +++ b/indra/newview/lltexturecache.h @@ -151,8 +151,8 @@ private: void readHeaderCache(); void clearCorruptedCache(); void purgeAllTextures(bool purge_directories); - void purgeTextures(bool validate, bool force = false); - void purgeTextureFilesTimeSliced(BOOL force_all = FALSE); // VWR-3878 - NB + void purgeTextures(bool validate); + void purgeTextureFilesTimeSliced(bool force = false); LLAPRFile* openHeaderEntriesFile(bool readonly, S32 offset); void closeHeaderEntriesFile(); void readEntriesHeader(); @@ -164,7 +164,7 @@ private: void writeEntriesAndClose(const std::vector& entries); void readEntryFromHeaderImmediately(S32& idx, Entry& entry) ; void writeEntryToHeaderImmediately(S32& idx, Entry& entry, bool write_header = false) ; - void removeEntry(S32 idx, Entry& entry, std::string& filename); + void removeEntry(S32 idx, Entry& entry, std::string& filename, bool remove_file = true); void removeCachedTexture(const LLUUID& id) ; S32 getHeaderCacheEntry(const LLUUID& id, Entry& entry); S32 setHeaderCacheEntry(const LLUUID& id, Entry& entry, S32 imagesize, S32 datasize); @@ -190,9 +190,10 @@ private: typedef std::vector, bool> > responder_list_t; responder_list_t mCompletedList; - typedef std::list filename_list_t; - filename_list_t mFilesToDelete; - LLTimer mTimeLastFileDelete; + typedef std::map purge_map_t; + purge_map_t mFilesToDelete; + LLTimer mSlicedPurgeTimer; + BOOL mReadOnly; // HEADERS (Include first mip) diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index ffca05686..4df2f6dd0 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -72,6 +72,12 @@ #include "lllocalinventory.h" // +// tag: vaa emerald local_asset_browser [begin] +#include "floaterlocalassetbrowse.h" +#include "llscrolllistctrl.h" +#include "llfilepicker.h" +#define LOCALLIST_COL_ID 1 +// tag: vaa emerald local_asset_browser [end] static const S32 CLOSE_BTN_WIDTH = 100; const S32 PIPETTE_BTN_WIDTH = 32; @@ -168,6 +174,18 @@ public: static void onSearchEdit(const std::string& search_string, void* user_data ); static void onTextureSelect( const LLTextureEntry& te, void *data ); + // tag: vaa emerald local_asset_browser [begin] +// static void onBtnLocal( void* userdata ); +// static void onBtnServer( void* userdata ); +// static void switchModes( bool localmode, void* userdata ); + + static void onBtnAdd( void* userdata ); + static void onBtnRemove( void* userdata ); + static void onBtnBrowser( void* userdata ); + + static void onLocalScrollCommit ( LLUICtrl* ctrl, void *userdata ); + // tag: vaa emerald local_asset_browser [end] + protected: LLPointer mTexturep; LLTextureCtrl* mOwner; @@ -198,6 +216,7 @@ protected: BOOL mNoCopyTextureSelected; F32 mContextConeOpacity; LLSaveFolderState mSavedFolderState; + LLScrollListCtrl* mLocalScrollCtrl; // tag: vaa emerald local_asset_browser }; LLFloaterTexturePicker::LLFloaterTexturePicker( @@ -243,6 +262,18 @@ LLFloaterTexturePicker::LLFloaterTexturePicker( childSetAction("Blank", LLFloaterTexturePicker::onBtnWhite,this); childSetAction("Invisible", LLFloaterTexturePicker::onBtnInvisible,this); + // tag: vaa emerald local_asset_browser [begin] +// childSetAction("Local", LLFloaterTexturePicker::onBtnLocal, this); +// childSetAction("Server", LLFloaterTexturePicker::onBtnServer, this); + childSetAction("Add", LLFloaterTexturePicker::onBtnAdd, this); + childSetAction("Remove", LLFloaterTexturePicker::onBtnRemove, this); + childSetAction("Browser", LLFloaterTexturePicker::onBtnBrowser, this); + + mLocalScrollCtrl = getChild("local_name_list"); + mLocalScrollCtrl->setCallbackUserData(this); + mLocalScrollCtrl->setCommitCallback(onLocalScrollCommit); + LocalAssetBrowser::UpdateTextureCtrlList( mLocalScrollCtrl ); + // tag: vaa emerald local_asset_browser [end] childSetCommitCallback("show_folders_check", onShowFolders, this); childSetVisible("show_folders_check", FALSE); @@ -779,6 +810,70 @@ void LLFloaterTexturePicker::onBtnSelect(void* userdata) self->close(); } +// tag: vaa emerald local_asset_browser [begin] + +// static, switches between showing inventory instance for global bitmaps +// to showing the scroll list for local ones and back. +/* +void LLFloaterTexturePicker::onBtnLocal(void *userdata) +{ + switchModes( true, userdata ); +} + +void LLFloaterTexturePicker::onBtnServer(void *userdata) +{ + switchModes( false, userdata ); +} + +void LLFloaterTexturePicker::switchModes(bool localmode, void *userdata) +{ + LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; + + // servermode widgets + self->childSetVisible("Local", !localmode); + self->childSetVisible("Default", !localmode); + self->childSetVisible("None", !localmode); + self->childSetVisible("Blank", !localmode); + self->mSearchEdit->setVisible(!localmode); + self->mInventoryPanel->setVisible(!localmode); + + // localmode widgets + self->childSetVisible("Server", localmode); + self->childSetVisible("Add", localmode); + self->childSetVisible("Remove", localmode); + self->childSetVisible("Browser", localmode); + self->mLocalScrollCtrl->setVisible(localmode); +} +*/ +void LLFloaterTexturePicker::onBtnAdd(void *userdata) +{ + LocalAssetBrowser::AddBitmap(); +} + +void LLFloaterTexturePicker::onBtnRemove(void *userdata) +{ + LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; + LocalAssetBrowser::DelBitmap( self->mLocalScrollCtrl->getAllSelected(), LOCALLIST_COL_ID ); +} + +void LLFloaterTexturePicker::onBtnBrowser(void *userdata) +{ + FloaterLocalAssetBrowser::show(NULL); +} + +// static, reacts to user clicking a valid field in the local scroll list. +void LLFloaterTexturePicker::onLocalScrollCommit(LLUICtrl *ctrl, void *userdata) +{ + LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; + LLUUID id = (LLUUID)self->mLocalScrollCtrl->getSelectedItemLabel( LOCALLIST_COL_ID ); + + self->mOwner->setImageAssetID( id ); + if ( self->childGetValue("apply_immediate_check").asBoolean() ) + { self->mOwner->onFloaterCommit(LLTextureCtrl::TEXTURE_CHANGE, id); } // calls an overridden function. +} + +// tag: vaa emerald local_asset_browser [end] + // static void LLFloaterTexturePicker::onBtnPipette( void* userdata ) { @@ -1322,6 +1417,40 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op) } } +// tag: vaa emerald local_asset_browser [begin] + +/* + overriding onFloaterCommit to forcefeed it a uuid. + also, i still don't get the difference beween mImageItemID and mImageAssetID, + they seem to affect the same thing? using mImageAssetID. +*/ +void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLUUID id) +{ + LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get(); + + if( floaterp && getEnabled()) + { + mImageItemID = id; + mImageAssetID = id; //floaterp->getAssetID(); // using same as on above func. + // seems to work anyway. + + if (op == TEXTURE_SELECT && mOnSelectCallback) + { + mOnSelectCallback(this, mCallbackUserData); + } + else if (op == TEXTURE_CANCEL && mOnCancelCallback) + { + mOnCancelCallback(this, mCallbackUserData); + } + else + { + onCommit(); + } + } +} + +// tag: vaa emerald local_asset_browser [end] + void LLTextureCtrl::setImageAssetID( const LLUUID& asset_id ) { if( mImageAssetID != asset_id ) diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h index a39a18988..79c0f29ef 100644 --- a/indra/newview/lltexturectrl.h +++ b/indra/newview/lltexturectrl.h @@ -141,6 +141,7 @@ public: void onFloaterClose(); void onFloaterCommit(ETexturePickOp op); + void onFloaterCommit(ETexturePickOp op, LLUUID id); // tag: vaa emerald local_asset_browser // This call is returned when a drag is detected. Your callback // should return TRUE if the drag is acceptable. diff --git a/indra/newview/llviewerimage.h b/indra/newview/llviewerimage.h index 58e596c85..abff3ed64 100644 --- a/indra/newview/llviewerimage.h +++ b/indra/newview/llviewerimage.h @@ -335,6 +335,8 @@ public: void setCanUseHTTP(bool can_use_http) {mCanUseHTTP = can_use_http;}; + friend class LocalBitmap; // tag: vaa emerald local_asset_browser + private: /*virtual*/ void cleanup(); // Cleanup the LLViewerImage (so we can reinitialize it) diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h index 61292b343..66a386a9e 100644 --- a/indra/newview/llviewerobjectlist.h +++ b/indra/newview/llviewerobjectlist.h @@ -65,6 +65,8 @@ public: ~LLViewerObjectList(); void destroy(); + + friend class LocalBitmap; // tag: vaa emerald local_asset_browser // For internal use only. Does NOT take a local id, takes an index into // an internal dynamic array. diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 882616cd0..5935316e4 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -215,6 +215,9 @@ public: BOOL isVolumeGlobal() const; BOOL canBeFlexible() const; BOOL setIsFlexible(BOOL is_flexible); + + // tag: vaa emerald local_asset_browser + void setSculptChanged(BOOL has_changed) { mSculptChanged = has_changed; } protected: S32 computeLODDetail(F32 distance, F32 radius); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 90540d1ea..ad6a702dd 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -330,7 +330,7 @@ void LLPipeline::init() sDynamicLOD = gSavedSettings.getBOOL("RenderDynamicLOD"); sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("ShyotlRenderUseStreamVBO"); - LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("SianaRenderOmitBlankVBO"); + LLVertexBuffer::sOmitBlank = gSavedSettings.getBOOL("SianaRenderOmitBlankVBO"); sRenderAttachedLights = gSavedSettings.getBOOL("RenderAttachedLights"); sRenderAttachedParticles = gSavedSettings.getBOOL("RenderAttachedParticles"); @@ -4931,7 +4931,7 @@ void LLPipeline::resetVertexBuffers() { sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("ShyotlRenderUseStreamVBO"); - LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("SianaRenderOmitBlankVBO"); + LLVertexBuffer::sOmitBlank = gSavedSettings.getBOOL("SianaRenderOmitBlankVBO"); for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { diff --git a/indra/newview/skins/default/xui/en-us/floater_about.xml b/indra/newview/skins/default/xui/en-us/floater_about.xml index 3aa908d14..f41797f6a 100644 --- a/indra/newview/skins/default/xui/en-us/floater_about.xml +++ b/indra/newview/skins/default/xui/en-us/floater_about.xml @@ -58,7 +58,7 @@ bottom="0" width="446" word_wrap="true"> -Singularity Viewer is developed and maintained by Siana Gearz with contributions by Shyotl Kuhr and Narv Czervik. Singularity is based upon Ascent source code. Credits for Ascent include Hg Beeks, Charley Levenque, Hazim Gazov, Zwagoth Klaar, Qarl Fizz, and others. Ascent is based upon the Inertia source code. +Singularity Viewer is developed and maintained by Siana Gearz, Shyotl Kuhr and Narv Czervik, with contributions by Henri Beauchamp, Kitty Barnett, Thickbrick Sleaford, Wolfspirit Magic and others. Singularity is based upon Ascent source code. Credits for Ascent include Hg Beeks, Charley Levenque, Hazim Gazov, Zwagoth Klaar, Qarl Fizz, and others. Ascent is based upon the Inertia source code. Singularity Viewer includes source code contributions of the following residents: Able Whitman, Adam Marker, Agathos Frascati, Aimee Trescothick, Alejandro Rosenthal, Aleric Inglewood, Alissa Sabre, Angus Boyd, Ann Congrejo, Argent Stonecutter, Asuka Neely, Balp Allen, Benja Kepler, Biancaluce Robbiani, Blakar Ogre, blino Nakamura, Boroondas Gupte, Bulli Schumann, bushing Spatula, Carjay McGinnis, Catherine Pfeffer, Celierra Darling, Cron Stardust, Dale Glass, Drewan Keats, Dylan Haskell, Dzonatas Sol, Eddy Stryker, EponymousDylan Ra, Eva Nowicka, Farallon Greyskin, Feep Larsson, Flemming Congrejo, Fluf Fredriksson, Fremont Cunningham, Geneko Nemeth, Gigs Taggart, Ginko Bayliss, Grazer Kline, Gudmund Shepherd, Hamncheese Omlet, HappySmurf Papp, Henri Beauchamp, Hikkoshi Sakai, Hiro Sommambulist, Hoze Menges, Ian Kas, Irene Muni, Iskar Ariantho, Jacek Antonelli, JB Kraft, Joghert LeSabre, Kage Pixel, Ken March, Kerutsen Sellery, Khyota Wulluf, Kunnis Basiat, Lisa Lowe, Lockhart Cordoso, maciek marksman, Magnus Balczo, Malwina Dollinger, march Korda, Matthew Dowd, McCabe Maxsted, Michelle2 Zenovka, Mm Alder, Mr Greggan, Nicholaz Beresford, Nounouch Hapmouche, Patric Mills, Paul Churchill, Paula Innis, Peekay Semyorka, Peter Lameth, Pf Shan, princess niven, Renault Clio, Ringo Tuxing, Robin Cornelius, Ryozu Kojima, Salahzar Stenvaag, Sammy Frederix, Scrippy Scofield, Seg Baphomet, Sergen Davies, SignpostMarv Martin, Simon Nolan, SpacedOut Frye, Sporked Friis, Stevex Janus, Still Defiant, Strife Onizuka, Tayra Dagostino, TBBle Kurosawa, Teardrops Fall, tenebrous pau, Tharax Ferraris, Thickbrick Sleaford, Thraxis Epsilon, tiamat bingyi, TraductoresAnonimos Alter, Tue Torok, Vadim Bigbear, Vixen Heron, Whoops Babii, Wilton Lundquist, Zarkonnen Decosta, Zi Ree, Zipherius Turas diff --git a/indra/newview/skins/default/xui/en-us/floater_local_asset_browse.xml b/indra/newview/skins/default/xui/en-us/floater_local_asset_browse.xml new file mode 100644 index 000000000..3ea7ce4af --- /dev/null +++ b/indra/newview/skins/default/xui/en-us/floater_local_asset_browse.xml @@ -0,0 +1,261 @@ + + + + + + + + +