void LLFloaterMessageLog::refreshNetList()
{
	LLScrollListCtrl* scrollp = getChild<LLScrollListCtrl>("net_list");

	// Update names of net list items
	std::list<LLNetListItem*>::iterator items_end = sNetListItems.end();
	for(std::list<LLNetListItem*>::iterator iter = sNetListItems.begin(); iter != items_end; ++iter)
	{
		LLNetListItem* itemp = (*iter);
		if(itemp->mAutoName)
		{
			if(itemp->mCircuitData)
			{
				LLViewerRegion* regionp = LLWorld::getInstance()->getRegion(itemp->mCircuitData->getHost());
				if(regionp)
				{
					std::string name = regionp->getName();
					if(name == "") name = llformat("%s (awaiting region name)", itemp->mCircuitData->getHost().getString().c_str());
					itemp->mName = name;
					itemp->mPreviousRegionName = name;
					itemp->mHandle = regionp->getHandle();
				}
				else
				{
					itemp->mName = itemp->mCircuitData->getHost().getString();
					if(itemp->mPreviousRegionName != "")
						itemp->mName.append(llformat(" (was %s)", itemp->mPreviousRegionName.c_str()));
				}
			}
			else
			{
				// an item just for an event queue, not handled yet
				itemp->mName = "Something else";
			}
		}
	}
	// Rebuild scroll list from scratch
	LLUUID selected_id = scrollp->getFirstSelected() ? scrollp->getFirstSelected()->getUUID() : LLUUID::null;
	S32 scroll_pos = scrollp->getScrollPos();
	scrollp->clearRows();
	for(std::list<LLNetListItem*>::iterator iter = sNetListItems.begin(); iter != items_end; ++iter)
	{
		LLNetListItem* itemp = (*iter);
		LLSD element;
		element["id"] = itemp->mID;
		LLSD& text_column = element["columns"][0];
		text_column["column"] = "text";
		text_column["value"] = itemp->mName + (itemp->mCircuitData->getHost() == gAgent.getRegionHost() ? " (main)" : "");
		for(int i = 0; i < 2; i++)
		{
			LLSD& icon_column = element["columns"][i + 1];
			icon_column["column"] = llformat("icon%d", i);
			icon_column["type"] = "icon";
			icon_column["value"] = "";
		}
		LLScrollListItem* scroll_itemp = scrollp->addElement(element);
		BOOL has_live_circuit = itemp->mCircuitData && itemp->mCircuitData->isAlive();
		if(has_live_circuit)
		{
			LLScrollListIcon* icon = (LLScrollListIcon*)scroll_itemp->getColumn(1);
			icon->setValue("icon_net_close_circuit.tga");
			icon->setClickCallback(onClickCloseCircuit, itemp);
		}
		else
		{
			LLScrollListIcon* icon = (LLScrollListIcon*)scroll_itemp->getColumn(1);
			icon->setValue("icon_net_close_circuit_gray.tga");
			icon->setClickCallback(NULL, NULL);
		}
		// Event queue isn't even supported yet... FIXME
		LLScrollListIcon* icon = (LLScrollListIcon*)scroll_itemp->getColumn(2);
		icon->setValue("icon_net_close_eventpoll_gray.tga");
		icon->setClickCallback(NULL, NULL);
	}
	if(selected_id.notNull()) scrollp->selectByID(selected_id);
	if(scroll_pos < scrollp->getItemCount()) scrollp->setScrollPos(scroll_pos);
}
// static
BOOL LLFloaterExploreSounds::tick()
{
    //if(childGetValue("pause_chk").asBoolean()) return FALSE;

    bool show_collision_sounds = childGetValue("collision_chk").asBoolean();
    bool show_repeated_assets = childGetValue("repeated_asset_chk").asBoolean();
    bool show_avatars = childGetValue("avatars_chk").asBoolean();
    bool show_objects = childGetValue("objects_chk").asBoolean();

    std::list<LLSoundHistoryItem> history;
    if(childGetValue("pause_chk").asBoolean())
    {
        history = mLastHistory;
    }
    else
    {
        std::map<LLUUID, LLSoundHistoryItem>::iterator map_iter = gSoundHistory.begin();
        std::map<LLUUID, LLSoundHistoryItem>::iterator map_end = gSoundHistory.end();
        for( ; map_iter != map_end; ++map_iter)
        {
            history.push_back((*map_iter).second);
        }
        LLSoundHistoryItemCompare c;
        history.sort(c);
        mLastHistory = history;
    }

    LLScrollListCtrl* list = getChild<LLScrollListCtrl>("sound_list");

    // Save scroll pos and selection so they can be restored
    S32 scroll_pos = list->getScrollPos();
    uuid_vec_t selected_ids = list->getSelectedIDs();
    list->clearRows();

    std::list<LLUUID> unique_asset_list;

    std::list<LLSoundHistoryItem>::iterator iter = history.begin();
    std::list<LLSoundHistoryItem>::iterator end = history.end();
    for( ; iter != end; ++iter)
    {
        LLSoundHistoryItem item = (*iter);

        bool is_avatar = item.mOwnerID == item.mSourceID;
        if(is_avatar && !show_avatars) continue;

        bool is_object = !is_avatar;
        if(is_object && !show_objects) continue;

        bool is_repeated_asset = std::find(unique_asset_list.begin(), unique_asset_list.end(), item.mAssetID) != unique_asset_list.end();
        if(is_repeated_asset && !show_repeated_assets) continue;

        if(!item.mReviewed)
        {
            item.mReviewedCollision	= std::find(&collision_sounds[0], &collision_sounds[num_collision_sounds], item.mAssetID) != &collision_sounds[num_collision_sounds];
            item.mReviewed = true;
        }
        bool is_collision_sound = item.mReviewedCollision;
        if(is_collision_sound && !show_collision_sounds) continue;

        unique_asset_list.push_back(item.mAssetID);

        LLSD element;
        element["id"] = item.mID;

        LLSD& playing_column = element["columns"][0];
        playing_column["column"] = "playing";
        if(item.isPlaying())
        {
            playing_column["value"] = item.mIsLooped ? " Looping" : " Playing";
        }
        else
        {
            S32 time = (LLTimer::getElapsedSeconds() - item.mTimeStopped);
            S32 hours = time / 3600;
            S32 mins = time / 60;
            S32 secs = time % 60;
            playing_column["value"] = llformat("%d:%02d:%02d", hours,mins,secs);
        }

        LLSD& type_column = element["columns"][1];
        type_column["column"] = "type";
        type_column["type"] = "icon";
        if(item.mType == LLAudioEngine::AUDIO_TYPE_UI)
        {
            // this shouldn't happen for now, as UI is forbidden in the log
            type_column["value"] = "UI";
        }
        else
        {
            std::string type;
            std::string icon;
            if(is_avatar)
            {
                type = "Avatar";
                icon = "inv_item_gesture.tga";
            }
            else
            {
                if(item.mIsTrigger)
                {
                    type = "llTriggerSound";
                    icon = "inv_item_sound.tga";
                }
                else
                {
                    if(item.mIsLooped)
                        type = "llLoopSound";
                    else
                        type = "llPlaySound";
                    icon = "inv_item_object.tga";
                }
            }

            type_column["value"] = icon;
            type_column["tool_tip"] = type;
        }

        LLSD& owner_column = element["columns"][2];
        owner_column["column"] = "owner";
        std::string fullname;
        BOOL is_group;
        if(gCacheName->getIfThere(item.mOwnerID, fullname, is_group))
        {
            if(is_group) fullname += " (Group)";
            owner_column["value"] = fullname;
        }
        else
            owner_column["value"] = item.mOwnerID.asString();

        LLSD& sound_column = element["columns"][3];
        sound_column["column"] = "sound";

        std::string uuid = item.mAssetID.asString();
        sound_column["value"] = uuid.substr(0, uuid.find_first_of("-")) + "...";

        list->addElement(element, ADD_BOTTOM);
    }

    list->selectMultiple(selected_ids);
    list->setScrollPos(scroll_pos);

    return FALSE;
}
void LLFloaterMessageBuilder::refreshNetList()
{
	LLScrollListCtrl* scrollp = getChild<LLScrollListCtrl>("net_list");
	// Update circuit data of net list items
	std::vector<LLCircuitData*> circuits = gMessageSystem->getCircuit()->getCircuitDataList();
	std::vector<LLCircuitData*>::iterator circuits_end = circuits.end();
	for(std::vector<LLCircuitData*>::iterator iter = circuits.begin(); iter != circuits_end; ++iter)
	{
		LLNetListItem* itemp = findNetListItem((*iter)->getHost());
		if(!itemp)
		{
			LLUUID id; id.generate();
			itemp = new LLNetListItem(id);
			sNetListItems.push_back(itemp);
		}
		itemp->mCircuitData = (*iter);
	}
	// Clear circuit data of items whose circuits are gone
	std::list<LLNetListItem*>::iterator items_end = sNetListItems.end();
	for(std::list<LLNetListItem*>::iterator iter = sNetListItems.begin(); iter != items_end; ++iter)
	{
		if(std::find(circuits.begin(), circuits.end(), (*iter)->mCircuitData) == circuits.end())
			(*iter)->mCircuitData = NULL;
	}
	// Remove net list items that are totally useless now
	for(std::list<LLNetListItem*>::iterator iter = sNetListItems.begin(); iter != sNetListItems.end();)
	{
		if((*iter)->mCircuitData == NULL)
			iter = sNetListItems.erase(iter);
		else ++iter;
	}
	// Update names of net list items
	items_end = sNetListItems.end();
	for(std::list<LLNetListItem*>::iterator iter = sNetListItems.begin(); iter != items_end; ++iter)
	{
		LLNetListItem* itemp = (*iter);
		if(itemp->mAutoName)
		{
			if(itemp->mCircuitData)
			{
				LLViewerRegion* regionp = LLWorld::getInstance()->getRegion(itemp->mCircuitData->getHost());
				if(regionp)
				{
					std::string name = regionp->getName();
					if(name == "") name = llformat("%s (awaiting region name)", itemp->mCircuitData->getHost().getString().c_str());
					itemp->mName = name;
					itemp->mPreviousRegionName = name;
				}
				else
				{
					itemp->mName = itemp->mCircuitData->getHost().getString();
					if(itemp->mPreviousRegionName != "")
						itemp->mName.append(llformat(" (was %s)", itemp->mPreviousRegionName.c_str()));
				}
			}
			else
			{
				// an item just for an event queue, not handled yet
				itemp->mName = "Something else";
			}
		}
	}
	// Rebuild scroll list from scratch
	LLUUID selected_id = scrollp->getFirstSelected() ? scrollp->getFirstSelected()->getUUID() : LLUUID::null;
	S32 scroll_pos = scrollp->getScrollPos();
	scrollp->clearRows();
	for(std::list<LLNetListItem*>::iterator iter = sNetListItems.begin(); iter != items_end; ++iter)
	{
		LLNetListItem* itemp = (*iter);
		LLSD element;
		element["id"] = itemp->mID;
		LLSD& text_column = element["columns"][0];
		text_column["column"] = "text";
		text_column["value"] = itemp->mName + (itemp->mCircuitData->getHost() == gAgent.getRegionHost() ? " (main)" : "");

		LLSD& state_column = element["columns"][ 1];
		state_column["column"] = "state";
		state_column["value"] = "";

		LLScrollListItem* scroll_itemp = scrollp->addElement(element);
		BOOL has_live_circuit = itemp->mCircuitData && itemp->mCircuitData->isAlive();

		LLScrollListText* state = (LLScrollListText*)scroll_itemp->getColumn(1);

		if(has_live_circuit)
			state->setText(std::string("Alive"));
		else
			state->setText(std::string("Alive"));
	}
	if(selected_id.notNull()) scrollp->selectByID(selected_id);
	if(scroll_pos < scrollp->getItemCount()) scrollp->setScrollPos(scroll_pos);
}