Skip to content
Snippets Groups Projects
llfloaterpreference.cpp 117 KiB
Newer Older
    icon_cell_params.font_halign = LLFontGL::LEFT;
    icon_cell_params.type = "icontext";

    LLScrollListCell::Params cell_params;
    // init basic cell params
    cell_params.font = LLFontGL::getFontSansSerif();
    cell_params.font_halign = LLFontGL::LEFT;

    std::string control_name = LLKeyConflictHandler::getControlName((LLKeyConflictHandler::EControlTypes)index);
    std::string label;
    if (hasString(control_name))
    {
        label = getString(control_name);
    }
    else
    {
        label = control_name;
    }
    icon_cell_params.column = "lst_action";
    icon_cell_params.text = label;
    icon_cell_params.value = icon;
    item_params.columns.add(icon_cell_params);
    //dummy cells
    cell_params.column = "lst_ctrl1";
    cell_params.value = "";
    item_params.columns.add(cell_params);
    cell_params.column = "lst_ctrl2";
    cell_params.value = "";
    item_params.columns.add(cell_params);
    cell_params.column = "lst_ctrl3";
    cell_params.value = "";
    item_params.columns.add(cell_params);
    pControlsTable->addRow(item_params, EAddPosition::ADD_BOTTOM);
}

void LLPanelPreferenceControls::regenerateControls()
{
    mEditingMode = pKeyModeBox->getValue().asInteger();
    mConflictHandler[mEditingMode].loadFromSettings((LLKeyConflictHandler::ESourceMode)mEditingMode);
    populateControlTable();
}

andreykproductengine's avatar
andreykproductengine committed
void LLPanelPreferenceControls::populateControlTable()
{
    pControlsTable->clearRows();

    if (mHighlightedCell)
    {
        mHighlightedCell->setHighlighted(false);
        mHighlightedCell = NULL;
    }

andreykproductengine's avatar
andreykproductengine committed
    // todo: subsections need sorting?
    std::string label, control_name;
andreykproductengine's avatar
andreykproductengine committed
    LLScrollListCell::Params cell_params;
    // init basic cell params
    cell_params.font = LLFontGL::getFontSansSerif();
    cell_params.font_halign = LLFontGL::LEFT;
    cell_params.column = "";
    cell_params.value = label;

    S32 start = mEditingMode == LLKeyConflictHandler::MODE_GENERAL ? LLKeyConflictHandler::CONTROL_VIEW_ACTIONS : LLKeyConflictHandler::CONTROL_MOVEMENTS;
    S32 end = mEditingMode == LLKeyConflictHandler::MODE_GENERAL ? LLKeyConflictHandler::CONTROL_NUM_INDICES : LLKeyConflictHandler::CONTROL_RESERVED;
    for (S32 i = start; i < end; i++)
        LLKeyConflictHandler::EControlTypes type = (LLKeyConflictHandler::EControlTypes)i;
        switch (type)
        case LLKeyConflictHandler::CONTROL_VIEW_ACTIONS:
            addSeparator();
            addGroupRow("Search_Icon", i);
            break;
        case LLKeyConflictHandler::CONTROL_INTERACTIONS:
            addSeparator();
            addGroupRow("Command_Gestures_Icon", i);
            break;
        case LLKeyConflictHandler::CONTROL_MOVEMENTS:
            addSeparator();
            addGroupRow("Move_Walk_Off", i);
            break;
        case LLKeyConflictHandler::CONTROL_MEDIACONTENT:
            addSeparator();
            addGroupRow("Audio_Press", i);
            break;
        case LLKeyConflictHandler::CONTROL_CAMERA:
            addSeparator();
            addGroupRow("Cam_FreeCam_Off", i);
            break;
        case LLKeyConflictHandler::CONTROL_EDIT_TITLE:
            addSeparator();
            addGroupRow("Tool_Dozer", i);
            break;
        case LLKeyConflictHandler::CONTROL_RESERVED:
            addSeparator();
            addGroupRow("Info_Small", i);
            break;
        default:
andreykproductengine's avatar
andreykproductengine committed
            {
                //default insert
                LLScrollListItem::Params item_params;
                item_params.value = LLSD::Integer(i);

                cell_params.column = "lst_action";
                bool enabled = mConflictHandler[mEditingMode].canAssignControl(type);
                control_name = LLKeyConflictHandler::getControlName(type);
                if (hasString(control_name))
                {
                    label = getString(control_name);
                }
                else
                {
                    label = control_name;
                }
andreykproductengine's avatar
andreykproductengine committed
                cell_params.value = label;
                item_params.columns.add(cell_params);
                cell_params.column = "lst_ctrl1";
                cell_params.value = mConflictHandler[mEditingMode].getControlString(type, 0);
                cell_params.enabled = enabled;
andreykproductengine's avatar
andreykproductengine committed
                item_params.columns.add(cell_params);
                cell_params.column = "lst_ctrl2";
                cell_params.value = mConflictHandler[mEditingMode].getControlString(type, 1);
                cell_params.enabled = enabled;
                item_params.columns.add(cell_params);
                cell_params.column = "lst_ctrl3";
                cell_params.value = mConflictHandler[mEditingMode].getControlString(type, 2);
                cell_params.enabled = enabled;
andreykproductengine's avatar
andreykproductengine committed
                item_params.columns.add(cell_params);

                pControlsTable->addRow(item_params, EAddPosition::ADD_BOTTOM);
                break;
            }
        }
    }
}

// Just a workaround to not care about first separator before headers (we can start from random header)
void LLPanelPreferenceControls::addSeparator()
    if (pControlsTable->getItemCount() > 0)
    {
        pControlsTable->addSeparator(EAddPosition::ADD_BOTTOM);
    }
void LLPanelPreferenceControls::updateTable()
{
    std::vector<LLScrollListItem*> list = pControlsTable->getAllData();
    for (S32 i = 0; i < list.size(); ++i)
    {
        S32 value = list[i]->getValue().asInteger();
        if (value > 0)
        {
            LLKeyConflictHandler::EControlTypes control = (LLKeyConflictHandler::EControlTypes)value;
            LLScrollListCell* cell = list[i]->getColumn(1);
            cell->setValue(mConflictHandler[mEditingMode].getControlString(control, 0));
            cell = list[i]->getColumn(2);
            cell->setValue(mConflictHandler[mEditingMode].getControlString(control, 1));
            cell = list[i]->getColumn(3);
            cell->setValue(mConflictHandler[mEditingMode].getControlString(control, 2));
        }
    }

    if (mHighlightedCell)
    {
        mHighlightedCell->setHighlighted(false);
        mHighlightedCell = NULL;
    }
}

void LLPanelPreferenceControls::apply()
    for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i)
    {
        if (mConflictHandler[i].hasUnsavedChanges())
        {
            mConflictHandler[i].saveToSettings();
        }
    }
    if (mHighlightedCell)
    {
        mHighlightedCell->setHighlighted(false);
        mHighlightedCell = NULL;
    }
void LLPanelPreferenceControls::cancel()
    for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i)
    {
        if (mConflictHandler[i].hasUnsavedChanges())
        {
            mConflictHandler[i].clear();
        }
    }
    pControlsTable->clear();
    if (mHighlightedCell)
    {
        mHighlightedCell->setHighlighted(false);
        mHighlightedCell = NULL;
    }
void LLPanelPreferenceControls::saveSettings()
    for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i)
    {
        if (mConflictHandler[i].hasUnsavedChanges())
        {
            mConflictHandler[i].saveToSettings();
        }
    }

    S32 mode = pKeyModeBox->getValue().asInteger();
    if (mConflictHandler[mode].empty())
    {
        regenerateControls();
    }
    else if (mHighlightedCell)
    {
        mHighlightedCell->setHighlighted(false);
        mHighlightedCell = NULL;
    }
}

void LLPanelPreferenceControls::resetDirtyChilds()
{
    regenerateControls();
andreykproductengine's avatar
andreykproductengine committed
}

void LLPanelPreferenceControls::onListCommit()
{
    LLScrollListItem* item = pControlsTable->getFirstSelected();
    if (item == NULL)
    {
        return;
    }

    S32 control = item->getValue().asInteger();

    if (control <= 0)
    if (!mConflictHandler[mEditingMode].canAssignControl((LLKeyConflictHandler::EControlTypes)control))

    // List does not tell us what cell was clicked, so we have to figure it out manually, but
    // fresh mouse coordinates are not yet accessible during onCommit() and there are other issues,
    // so we cheat: remember item user clicked at, trigger 'key dialog' on hover that comes next,
    // use coordinates from hover to calculate cell
    mEditingIndex = control;
    mShowKeyDialog = true;

    if (mHighlightedCell)
    {
        mHighlightedCell->setHighlighted(false);
        mHighlightedCell = NULL;
    }
void LLPanelPreferenceControls::onModeCommit()
// todo: copy onSetKeyBind to interface and inherit from interface
void LLPanelPreferenceControls::onSetKeyBind(EMouseClickType click, KEY key, MASK mask, bool ignore_mask)
{
    LLKeyConflictHandler::EControlTypes control = (LLKeyConflictHandler::EControlTypes)mEditingIndex;

    if (!mConflictHandler[mEditingMode].canAssignControl(control))
    pControlsTable->deselectAllItems();
    pControlsTable->selectByValue(mEditingIndex);
    if ( mEditingColumn > 0)
        mConflictHandler[mEditingMode].registerControl(control, mEditingColumn - 1, click, key, mask, ignore_mask);
    updateTable();
void LLPanelPreferenceControls::onRestoreDefaults()
{
    for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i)
    {
        mConflictHandler[mEditingMode].resetToDefaults();
    }
void LLPanelPreferenceControls::onDefaultKeyBind()
    LLKeyConflictHandler::EControlTypes control = (LLKeyConflictHandler::EControlTypes)mEditingIndex;
    if (!mConflictHandler[mEditingMode].canAssignControl(control))
    pControlsTable->deselectAllItems();
    pControlsTable->selectByValue(mEditingIndex);

    if (mEditingColumn > 0)
        mConflictHandler[mEditingMode].resetToDefault(control, mEditingColumn - 1);
    }
    updateTable();
}
void LLPanelPreferenceControls::onCancelKeyBind()
{
    if (mHighlightedCell)
    {
        mHighlightedCell->setHighlighted(false);
        mHighlightedCell = NULL;
LLFloaterPreferenceGraphicsAdvanced::LLFloaterPreferenceGraphicsAdvanced(const LLSD& key)
	: LLFloater(key)
    mCommitCallbackRegistrar.add("Pref.RenderOptionUpdate",            boost::bind(&LLFloaterPreferenceGraphicsAdvanced::onRenderOptionEnable, this));
	mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxNonImpostors", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateMaxNonImpostors,this));
	mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxComplexity",   boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateMaxComplexity,this));
}

LLFloaterPreferenceGraphicsAdvanced::~LLFloaterPreferenceGraphicsAdvanced()
{
}

LLFloaterPreferenceProxy::LLFloaterPreferenceProxy(const LLSD& key)
	: LLFloater(key),
	  mSocksSettingsDirty(false)
	mCommitCallbackRegistrar.add("Proxy.OK",                boost::bind(&LLFloaterPreferenceProxy::onBtnOk, this));
	mCommitCallbackRegistrar.add("Proxy.Cancel",            boost::bind(&LLFloaterPreferenceProxy::onBtnCancel, this));
	mCommitCallbackRegistrar.add("Proxy.Change",            boost::bind(&LLFloaterPreferenceProxy::onChangeSocksSettings, this));
BOOL LLFloaterPreferenceGraphicsAdvanced::postBuild()
{
    // Don't do this on Mac as their braindead GL versioning
    // sets this when 8x and 16x are indeed available
    //
#if !LL_DARWIN
    if (gGLManager.mIsIntel || gGLManager.mGLVersion < 3.f)
    { //remove FSAA settings above "4x"
        LLComboBox* combo = getChild<LLComboBox>("fsaa");
        combo->remove("8x");
        combo->remove("16x");
    }
	
	LLCheckBoxCtrl *use_HiDPI = getChild<LLCheckBoxCtrl>("use HiDPI");
	use_HiDPI->setVisible(FALSE);
void LLFloaterPreferenceGraphicsAdvanced::onOpen(const LLSD& key)
{
    refresh();
}

void LLFloaterPreferenceGraphicsAdvanced::onClickCloseBtn(bool app_quitting)
{
	LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
	if (instance)
	{
		instance->cancel();
	}
LLFloaterPreferenceProxy::~LLFloaterPreferenceProxy()
{
}

BOOL LLFloaterPreferenceProxy::postBuild()
{
	LLRadioGroup* socksAuth = getChild<LLRadioGroup>("socks5_auth_type");
	if (!socksAuth)
	{
		return FALSE;
	}
	if (socksAuth->getSelectedValue().asString() == "None")
	{
		getChild<LLLineEditor>("socks5_username")->setEnabled(false);
		getChild<LLLineEditor>("socks5_password")->setEnabled(false);
	}
	else
	{
		// Populate the SOCKS 5 credential fields with protected values.
		LLPointer<LLCredential> socks_cred = gSecAPIHandler->loadCredential("SOCKS5");
		getChild<LLLineEditor>("socks5_username")->setValue(socks_cred->getIdentifier()["username"].asString());
		getChild<LLLineEditor>("socks5_password")->setValue(socks_cred->getAuthenticator()["creds"].asString());
	}

	return TRUE;
}

void LLFloaterPreferenceProxy::onOpen(const LLSD& key)
{
	saveSettings();
}

void LLFloaterPreferenceProxy::onClose(bool app_quitting)
{
	if(app_quitting)
	{
		cancel();
	}
	if (mSocksSettingsDirty)
	{
		// If the user plays with the Socks proxy settings after login, it's only fair we let them know
		// it will not be updated until next restart.
		if (LLStartUp::getStartupState()>STATE_LOGIN_WAIT)
		{
			LLNotifications::instance().add("ChangeProxySettings", LLSD(), LLSD());
			mSocksSettingsDirty = false; // we have notified the user now be quiet again
		}
	}
}

void LLFloaterPreferenceProxy::saveSettings()
{
	// Save the value of all controls in the hierarchy
	mSavedValues.clear();
	std::list<LLView*> view_stack;
	view_stack.push_back(this);
	while(!view_stack.empty())
	{
		// Process view on top of the stack
		LLView* curview = view_stack.front();
		view_stack.pop_front();

		LLUICtrl* ctrl = dynamic_cast<LLUICtrl*>(curview);
		if (ctrl)
		{
			LLControlVariable* control = ctrl->getControlVariable();
			if (control)
			{
				mSavedValues[control] = control->getValue();
			}
		}

		// Push children onto the end of the work stack
		for (child_list_t::const_iterator iter = curview->getChildList()->begin();
				iter != curview->getChildList()->end(); ++iter)
		{
			view_stack.push_back(*iter);
		}
	}
}

void LLFloaterPreferenceProxy::onBtnOk()
{
	// commit any outstanding text entry
	if (hasFocus())
	{
		LLUICtrl* cur_focus = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus());
		if (cur_focus && cur_focus->acceptsTextInput())
		{
			cur_focus->onCommit();
		}
	}

	// Save SOCKS proxy credentials securely if password auth is enabled
	LLRadioGroup* socksAuth = getChild<LLRadioGroup>("socks5_auth_type");
	if (socksAuth->getSelectedValue().asString() == "UserPass")
	{
		LLSD socks_id = LLSD::emptyMap();
		socks_id["type"] = "SOCKS5";
		socks_id["username"] = getChild<LLLineEditor>("socks5_username")->getValue().asString();

		LLSD socks_authenticator = LLSD::emptyMap();
		socks_authenticator["type"] = "SOCKS5";
		socks_authenticator["creds"] = getChild<LLLineEditor>("socks5_password")->getValue().asString();

		// Using "SOCKS5" as the "grid" argument since the same proxy
		// settings will be used for all grids and because there is no
		// way to specify the type of credential.
		LLPointer<LLCredential> socks_cred = gSecAPIHandler->createCredential("SOCKS5", socks_id, socks_authenticator);
		gSecAPIHandler->saveCredential(socks_cred, true);
	}
	else
	{
		// Clear SOCKS5 credentials since they are no longer needed.
		LLPointer<LLCredential> socks_cred = new LLCredential("SOCKS5");
		gSecAPIHandler->deleteCredential(socks_cred);
	}

	closeFloater(false);
}

void LLFloaterPreferenceProxy::onBtnCancel()
{
	if (hasFocus())
	{
		LLUICtrl* cur_focus = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus());
		if (cur_focus && cur_focus->acceptsTextInput())
		{
			cur_focus->onCommit();
		}
		refresh();
	}
	cancel();
void LLFloaterPreferenceProxy::onClickCloseBtn(bool app_quitting)
{
	cancel();
void LLFloaterPreferenceProxy::cancel()
{

	for (control_values_map_t::iterator iter =  mSavedValues.begin();
			iter !=  mSavedValues.end(); ++iter)
	{
		LLControlVariable* control = iter->first;
		LLSD ctrl_value = iter->second;
		control->set(ctrl_value);
	}
	mSocksSettingsDirty = false;
	closeFloater();
}

void LLFloaterPreferenceProxy::onChangeSocksSettings() 
{
	mSocksSettingsDirty = true;

	LLRadioGroup* socksAuth = getChild<LLRadioGroup>("socks5_auth_type");
	if (socksAuth->getSelectedValue().asString() == "None")
	{
		getChild<LLLineEditor>("socks5_username")->setEnabled(false);
		getChild<LLLineEditor>("socks5_password")->setEnabled(false);
	}
	else
	{
		getChild<LLLineEditor>("socks5_username")->setEnabled(true);
		getChild<LLLineEditor>("socks5_password")->setEnabled(true);
	}

	// Check for invalid states for the other HTTP proxy radio
	LLRadioGroup* otherHttpProxy = getChild<LLRadioGroup>("other_http_proxy_type");
	if ((otherHttpProxy->getSelectedValue().asString() == "Socks" &&
			getChild<LLCheckBoxCtrl>("socks_proxy_enabled")->get() == FALSE )||(
					otherHttpProxy->getSelectedValue().asString() == "Web" &&
					getChild<LLCheckBoxCtrl>("web_proxy_enabled")->get() == FALSE ) )
	{
		otherHttpProxy->selectFirstItem();
	}
void LLFloaterPreference::onUpdateFilterTerm(bool force)
{
	LLWString seachValue = utf8str_to_wstring( mFilterEdit->getValue() );
	LLWStringUtil::toLower( seachValue );

	if( !mSearchData || (mSearchData->mLastFilter == seachValue && !force))
		return;

	mSearchData->mLastFilter = seachValue;

	if( !mSearchData->mRootTab )
		return;

	mSearchData->mRootTab->hightlightAndHide( seachValue );
	LLTabContainer *pRoot = getChild< LLTabContainer >( "pref core" );
	if( pRoot )
		pRoot->selectFirstTab();
}

void collectChildren( LLView const *aView, ll::prefs::PanelDataPtr aParentPanel, ll::prefs::TabContainerDataPtr aParentTabContainer )
{
	if( !aView )
		return;

	llassert_always( aParentPanel || aParentTabContainer );

	LLView::child_list_const_iter_t itr = aView->beginChild();
	LLView::child_list_const_iter_t itrEnd = aView->endChild();

	while( itr != itrEnd )
	{
		LLView *pView = *itr;
		ll::prefs::PanelDataPtr pCurPanelData = aParentPanel;
		ll::prefs::TabContainerDataPtr pCurTabContainer = aParentTabContainer;
		if( !pView )
			continue;
		LLPanel const *pPanel = dynamic_cast< LLPanel const *>( pView );
		LLTabContainer const *pTabContainer = dynamic_cast< LLTabContainer const *>( pView );
		ll::ui::SearchableControl const *pSCtrl = dynamic_cast< ll::ui::SearchableControl const *>( pView );

		if( pTabContainer )
		{
			pCurPanelData.reset();

			pCurTabContainer = ll::prefs::TabContainerDataPtr( new ll::prefs::TabContainerData );
			pCurTabContainer->mTabContainer = const_cast< LLTabContainer *>( pTabContainer );
			pCurTabContainer->mLabel = pTabContainer->getLabel();
			pCurTabContainer->mPanel = 0;

			if( aParentPanel )
				aParentPanel->mChildPanel.push_back( pCurTabContainer );
			if( aParentTabContainer )
				aParentTabContainer->mChildPanel.push_back( pCurTabContainer );
		}
		else if( pPanel )
		{
			pCurTabContainer.reset();

			pCurPanelData = ll::prefs::PanelDataPtr( new ll::prefs::PanelData );
			pCurPanelData->mPanel = pPanel;
			pCurPanelData->mLabel = pPanel->getLabel();

			llassert_always( aParentPanel || aParentTabContainer );

			if( aParentTabContainer )
				aParentTabContainer->mChildPanel.push_back( pCurPanelData );
			else if( aParentPanel )
				aParentPanel->mChildPanel.push_back( pCurPanelData );
		}
		else if( pSCtrl && pSCtrl->getSearchText().size() )
		{
			ll::prefs::SearchableItemPtr item = ll::prefs::SearchableItemPtr( new ll::prefs::SearchableItem() );
			item->mView = pView;
			item->mCtrl = pSCtrl;

			item->mLabel = utf8str_to_wstring( pSCtrl->getSearchText() );
			LLWStringUtil::toLower( item->mLabel );

			llassert_always( aParentPanel || aParentTabContainer );

			if( aParentPanel )
				aParentPanel->mChildren.push_back( item );
			if( aParentTabContainer )
				aParentTabContainer->mChildren.push_back( item );
		}
		collectChildren( pView, pCurPanelData, pCurTabContainer );
		++itr;
	}
}

void LLFloaterPreference::collectSearchableItems()
{
	mSearchData.reset( nullptr );
	LLTabContainer *pRoot = getChild< LLTabContainer >( "pref core" );
	if( mFilterEdit && pRoot )
	{
		mSearchData.reset(new ll::prefs::SearchData() );

		ll::prefs::TabContainerDataPtr pRootTabcontainer = ll::prefs::TabContainerDataPtr( new ll::prefs::TabContainerData );
		pRootTabcontainer->mTabContainer = pRoot;
		pRootTabcontainer->mLabel = pRoot->getLabel();
		mSearchData->mRootTab = pRootTabcontainer;

		collectChildren( this, ll::prefs::PanelDataPtr(), pRootTabcontainer );
	}
}