/** * @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" /* 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" /* llui headers */ #include "llcheckboxctrl.h" #include "llcombobox.h" #include "llscrolllistitem.h" #include "lluictrlfactory.h" /* misc headers */ #include #include #include "llviewertexturelist.h" #include "llviewerobjectlist.h" #include "statemachine/aifilepicker.h" #include "llviewermenufile.h" #include "llfloaterimagepreview.h" #include "llfile.h" /* including to force rebakes when needed */ #include "llvoavatarself.h" /* sculpt refresh */ #include "llvovolume.h" #include "llface.h" /* static pointer to self, wai? oh well. */ static FloaterLocalAssetBrowser* sLFInstance = NULL; /*=======================================*/ /* 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) { valid = false; if ( gDirUtilp->fileExists(fullpath) ) { /* taking care of basic properties */ id.generate(); filename = fullpath; keep_updating = gSavedSettings.getBOOL("LocalBitmapUpdate"); linkstatus = keep_updating ? LINK_ON : LINK_OFF; shortname = gDirUtilp->getBaseFileName(filename, true); bitmap_type = TYPE_TEXTURE; sculpt_dirty = false; volume_dirty = false; valid = false; /* taking care of extension type now to avoid switch madness */ std::string temp_exten = gDirUtilp->getExtension(filename); if (temp_exten == "bmp") extension = IMG_EXTEN_BMP; else if (temp_exten == "tga") extension = IMG_EXTEN_TGA; else if (temp_exten == "jpg" || temp_exten == "jpeg") extension = IMG_EXTEN_JPG; else if (temp_exten == "png") extension = IMG_EXTEN_PNG; else return; // no valid extension. /* getting file's last modified */ llstat temp_stat; LLFile::stat(filename, &temp_stat); std::time_t time = temp_stat.st_mtime; last_modified = asctime( localtime(&time) ); /* checking if the bitmap is valid && decoding if it is */ LLPointer raw_image = new LLImageRaw; if (decodeSelf(raw_image)) { /* creating a shell LLViewerTexture and fusing raw image into it */ LLViewerFetchedTexture* viewer_image = new LLViewerFetchedTexture( "file://"+filename, id, LOCAL_USE_MIPMAPS ); viewer_image->createGLTexture( LOCAL_DISCARD_LEVEL, raw_image ); viewer_image->setCachedRawImage(-1,raw_image); /* making damn sure gTextureList will not delete it prematurely */ viewer_image->ref(); /* finalizing by adding LLViewerTexture instance into gTextureList */ gTextureList.addImage(viewer_image); /* filename is valid, bitmap is decoded and valid, i can haz liftoff! */ valid = true; } } } LocalBitmap::~LocalBitmap() { } /* [maintenence functions] */ void LocalBitmap::updateSelf() { if (linkstatus == LINK_ON || linkstatus == LINK_UPDATING) { /* making sure file still exists */ if (!gDirUtilp->fileExists(filename)) { linkstatus = LINK_BROKEN; return; } /* exists, let's check if it's lastmod has changed */ llstat temp_stat; LLFile::stat(filename, &temp_stat); std::time_t temp_time = temp_stat.st_mtime; LLSD new_last_modified = asctime( localtime(&temp_time) ); if (last_modified.asString() == new_last_modified.asString()) return; /* here we update the image */ LLPointer new_imgraw = new LLImageRaw; if (!decodeSelf(new_imgraw)) { linkstatus = LINK_UPDATING; return; } else { linkstatus = LINK_ON; } LLViewerFetchedTexture* image = gTextureList.findImage(id); if (!image->forSculpt()) image->createGLTexture(LOCAL_DISCARD_LEVEL, new_imgraw); else image->setCachedRawImage(-1,new_imgraw); /* finalizing by updating lastmod to current */ last_modified = new_last_modified; /* setting unit property to reflect that it has been changed */ switch (bitmap_type) { case TYPE_SCULPT: { /* sets a bool to run through all visible sculpts in one go, and update the ones necessary. */ sculpt_dirty = true; 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; } case TYPE_TEXTURE: default: break; } } } bool LocalBitmap::decodeSelf(LLImageRaw* rawimg) { switch (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(LLViewerTexture::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(LLViewerTexture::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(LLViewerTexture::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(LLViewerTexture::MAX_IMAGE_SIZE_DEFAULT); return true; } default: break; } return false; } void LocalBitmap::setUpdateBool() { if (linkstatus != LINK_BROKEN) { if (!keep_updating) { linkstatus = LINK_ON; keep_updating = true; } else { linkstatus = LINK_OFF; keep_updating = false; } } else { keep_updating = false; } gSavedSettings.setBOOL("LocalBitmapUpdate", keep_updating); } void LocalBitmap::setType( S32 type ) { bitmap_type = type; } /* [information query functions] */ std::string LocalBitmap::getShortName() { return shortname; } std::string LocalBitmap::getFileName() { return filename; } LLUUID LocalBitmap::getID() { return id; } LLSD LocalBitmap::getLastModified() { return last_modified; } std::string LocalBitmap::getLinkStatus() { switch(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 keep_updating; } bool LocalBitmap::getIfValidBool() { return valid; } S32 LocalBitmap::getType() { return 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 (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; if (obj->isDead()) { continue; } 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 && bitmap_type == TYPE_TEXTURE)) { std::vector affected_faces = getFaceUsesThis(obj->mDrawable); if (!affected_faces.empty()) { shell.face_list = affected_faces; obj_relevant = true; } } /* looking for sculptmaps */ if ((seek_sculptmaps || (seek_by_type && bitmap_type == TYPE_SCULPT)) && obj->isSculpted() && obj->getVolume() && 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: " << filename << "\n" << "name: " << shortname << "\n" << "extension: " << extension << "\n" << "uuid: " << id << "\n" << "last modified: " << last_modified << "\n" << "link status: " << getLinkStatus() << "\n" << "keep updated: " << keep_updating << "\n" << "type: " << bitmap_type << "\n" << "is valid: " << 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() { mLayerUpdated = false; mSculptUpdated = false; } LocalAssetBrowser::~LocalAssetBrowser() { } void LocalAssetBrowser::AddBitmap() { AIFilePicker* filepicker = AIFilePicker::create(); filepicker->open(FFLOAD_IMAGE, "", "image", true); filepicker->run(boost::bind(&LocalAssetBrowser::AddBitmap_continued, filepicker)); } void LocalAssetBrowser::AddBitmap_continued(AIFilePicker* filepicker) { if (!filepicker->hasFilename()) return; bool change_happened = false; std::vector const& filenames(filepicker->getFilenames()); for(std::vector::const_iterator filename = filenames.begin(); filename != filenames.end(); ++filename) { LocalBitmap unit(*filename); if (unit.getIfValidBool()) { loaded_bitmaps.push_back(unit); change_happened = true; } } 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();) { if ((*iter).getID() == id) { LLViewerFetchedTexture* image = gTextureList.findImage(id); gTextureList.deleteImage( image ); image->unref(); iter = loaded_bitmaps.erase(iter); change_happened = true; } else ++iter; } } } if (change_happened) onChangeHappened(); } void LocalAssetBrowser::onUpdateBool(LLUUID id) { if (LocalBitmap* unit = GetBitmapUnit(id)) { unit->setUpdateBool(); PingTimer(); } } void LocalAssetBrowser::onSetType(LLUUID id, S32 type) { if (LocalBitmap* unit = GetBitmapUnit(id)) unit->setType(type); } LocalBitmap* LocalAssetBrowser::GetBitmapUnit(LLUUID id) { for (local_list_iter iter = loaded_bitmaps.begin(); iter != loaded_bitmaps.end(); ++iter) if ((*iter).getID() == id) return &(*iter); return NULL; } bool LocalAssetBrowser::IsDoingUpdates() { for (local_list_iter iter = loaded_bitmaps.begin(); 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 */ if (sLFInstance) sLFInstance->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 && 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() ) { for (local_list_iter iter = loaded_bitmaps.begin(); 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() { // perform checking if updates are needed && update if so. for (local_list_iter iter = loaded_bitmaps.begin(); iter != loaded_bitmaps.end(); ++iter) { (*iter).updateSelf(); // one or more sculpts have been updated, refreshing them. if (mSculptUpdated && (*iter).sculpt_dirty) { PerformSculptUpdates(*iter); (*iter).sculpt_dirty = false; } } mSculptUpdated = false; // one of the layer bitmaps has been updated, we need to rebake. if (mLayerUpdated) { if (isAgentAvatarValid()) gAgentAvatarp->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 = gTextureList.findImage(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. */ 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 ); // Initialize visibility FloaterResize(true); // setting button callbacks: mAddBtn->setClickedCallback(boost::bind(&FloaterLocalAssetBrowser::onClickAdd, this)); mDelBtn->setClickedCallback(boost::bind(&FloaterLocalAssetBrowser::onClickDel, this)); mMoreBtn->setClickedCallback(boost::bind(&FloaterLocalAssetBrowser::FloaterResize, this, true)); mLessBtn->setClickedCallback(boost::bind(&FloaterLocalAssetBrowser::FloaterResize, this, false)); mUploadBtn->setClickedCallback(boost::bind(&FloaterLocalAssetBrowser::onClickUpload, this)); // combo callback mTypeComboBox->setCommitCallback(boost::bind(&FloaterLocalAssetBrowser::onCommitTypeCombo,this)); // scrolllist callbacks mBitmapList->setCommitCallback(boost::bind(&FloaterLocalAssetBrowser::onChooseBitmapList,this)); // checkbox callbacks mUpdateChkBox->setCommitCallback(boost::bind(&FloaterLocalAssetBrowser::onClickUpdateChkbox,this)); } void FloaterLocalAssetBrowser::show(void*) { if (!sLFInstance) sLFInstance = new FloaterLocalAssetBrowser(); sLFInstance->open(); sLFInstance->UpdateBitmapScrollList(); } FloaterLocalAssetBrowser::~FloaterLocalAssetBrowser() { sLFInstance = NULL; } void FloaterLocalAssetBrowser::onClickAdd() { gLocalBrowser->AddBitmap(); } void FloaterLocalAssetBrowser::onClickDel() { gLocalBrowser->DelBitmap(mBitmapList->getAllSelected()); } void FloaterLocalAssetBrowser::onClickUpload() { std::string filename = gLocalBrowser->GetBitmapUnit( (LLUUID)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() { bool button_status = !mBitmapList->isEmpty() && mBitmapList->getFirstSelected(); mDelBtn->setEnabled(button_status); mUploadBtn->setEnabled(button_status); UpdateRightSide(); } void FloaterLocalAssetBrowser::onClickUpdateChkbox() { std::string temp_str = mBitmapList->getSelectedItemLabel(BITMAPLIST_COL_ID); if ( !temp_str.empty() ) { gLocalBrowser->onUpdateBool( (LLUUID)temp_str ); UpdateRightSide(); } } void FloaterLocalAssetBrowser::onCommitTypeCombo() { std::string temp_str = mBitmapList->getSelectedItemLabel(BITMAPLIST_COL_ID); if (!temp_str.empty()) { S32 selection = mTypeComboBox->getCurrentIndex(); gLocalBrowser->onSetType((LLUUID)temp_str, selection); } } void FloaterLocalAssetBrowser::FloaterResize(bool expand) { mMoreBtn->setVisible(!expand); mLessBtn->setVisible(expand); mTextureView->setVisible(expand); mUpdateChkBox->setVisible(expand); mCaptionPathTxt->setVisible(expand); mCaptionUUIDTxt->setVisible(expand); mCaptionLinkTxt->setVisible(expand); mCaptionNameTxt->setVisible(expand); mCaptionTimeTxt->setVisible(expand); mTypeComboBox->setVisible(expand); mTimeTxt->setVisible(expand); mPathTxt->setVisible(expand); mUUIDTxt->setVisible(expand); mLinkTxt->setVisible(expand); mNameTxt->setVisible(expand); reshape(expand ? LF_FLOATER_EXPAND_WIDTH : LF_FLOATER_CONTRACT_WIDTH, LF_FLOATER_HEIGHT); setResizeLimits(expand ? LF_FLOATER_EXPAND_WIDTH : LF_FLOATER_CONTRACT_WIDTH, LF_FLOATER_HEIGHT); if (expand) UpdateRightSide(); } void FloaterLocalAssetBrowser::UpdateBitmapScrollList() { 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(); mBitmapList->addElement(element); } } onChooseBitmapList(); } 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 (!mTextureView->getVisible()) return; if (!mBitmapList->getAllSelected().empty()) { LocalBitmap* unit = gLocalBrowser->GetBitmapUnit( LLUUID(mBitmapList->getSelectedItemLabel(BITMAPLIST_COL_ID)) ); if ( unit ) { mTextureView->setImageAssetID(unit->getID()); mUpdateChkBox->set(unit->getUpdateBool()); mPathTxt->setText(unit->getFileName()); mUUIDTxt->setText(unit->getID().asString()); mNameTxt->setText(unit->getShortName()); mTimeTxt->setText(unit->getLastModified().asString()); mLinkTxt->setText(unit->getLinkStatus()); mTypeComboBox->selectNthItem(unit->getType()); mTextureView->setEnabled(true); mUpdateChkBox->setEnabled(true); mTypeComboBox->setEnabled(true); } } else { mTextureView->setImageAssetID(NO_IMAGE); mTextureView->setEnabled(false); mUpdateChkBox->set(false); mUpdateChkBox->setEnabled(false); mTypeComboBox->selectFirstItem(); mTypeComboBox->setEnabled(false); mPathTxt->setText(LLStringExplicit("None")); mUUIDTxt->setText(LLStringExplicit("None")); mNameTxt->setText(LLStringExplicit("None")); mLinkTxt->setText(LLStringExplicit("None")); 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(); }