diff options
Diffstat (limited to 'kxkb/kcmlayout.cpp')
-rw-r--r-- | kxkb/kcmlayout.cpp | 769 |
1 files changed, 573 insertions, 196 deletions
diff --git a/kxkb/kcmlayout.cpp b/kxkb/kcmlayout.cpp index a022b6389..d9efb9e57 100644 --- a/kxkb/kcmlayout.cpp +++ b/kxkb/kcmlayout.cpp @@ -13,6 +13,8 @@ #include <tqlistview.h> #include <tqbuttongroup.h> #include <tqspinbox.h> +#include <tqvbox.h> +#include <tqtimer.h> #include <tdefontrequester.h> #include <kcolorbutton.h> @@ -20,10 +22,12 @@ #include <tdeglobal.h> #include <tdeconfig.h> #include <tdelocale.h> -#include <kstandarddirs.h> +#include <tdestandarddirs.h> #include <kdebug.h> #include <tdeapplication.h> #include <kiconloader.h> +#include <tdemessagebox.h> +#include <tdeglobalaccel.h> #include <dcopref.h> #include <dcopclient.h> @@ -33,6 +37,7 @@ #include "pixmap.h" #include "kcmmisc.h" #include "kcmlayoutwidget.h" +#include "x11helper.h" #include "kcmlayout.h" #include "kcmlayout.moc" @@ -43,8 +48,7 @@ enum { LAYOUT_COLUMN_NAME = 1, LAYOUT_COLUMN_MAP = 2, LAYOUT_COLUMN_VARIANT = 3, - LAYOUT_COLUMN_INCLUDE = 4, - LAYOUT_COLUMN_DISPLAY_NAME = 5, + LAYOUT_COLUMN_DISPLAY_NAME = 4, SRC_LAYOUT_COLUMN_COUNT = 3, DST_LAYOUT_COLUMN_COUNT = 6 }; @@ -100,65 +104,76 @@ static TQListViewItem* copyLVI(const TQListViewItem* src, TQListView* parent) LayoutConfig::LayoutConfig(TQWidget *parent, const char *name) : TDECModule(parent, name), - m_rules(NULL) + m_rules(NULL), + m_forceGrpOverwrite(false) { + X11Helper::initializeTranslations(); + + m_icoMgr = new LayoutIconManager(&m_kxkbConfig); + TQVBoxLayout *main = new TQVBoxLayout(this, 0, KDialog::spacingHint()); widget = new LayoutConfigWidget(this, "widget"); - main->addWidget(TQT_TQWIDGET(widget)); - - connect( TQT_TQOBJECT(widget->chkEnable), TQT_SIGNAL( toggled( bool )), TQT_TQOBJECT(this), TQT_SLOT(changed())); - connect( TQT_TQOBJECT(widget->chkShowSingle), TQT_SIGNAL( toggled( bool )), TQT_TQOBJECT(this), TQT_SLOT(changed())); + main->addWidget(widget); - connect( TQT_TQOBJECT(widget->comboModel), TQT_SIGNAL(activated(int)), TQT_TQOBJECT(this), TQT_SLOT(changed())); + connect( widget->chkEnable, TQ_SIGNAL( toggled( bool )), this, TQ_SLOT(changed())); + connect( widget->chkShowSingle, TQ_SIGNAL( toggled( bool )), this, TQ_SLOT(changed())); - connect( TQT_TQOBJECT(widget->listLayoutsSrc), TQT_SIGNAL(doubleClicked(TQListViewItem*,const TQPoint&, int)), - TQT_TQOBJECT(this), TQT_SLOT(add())); - connect( TQT_TQOBJECT(widget->btnAdd), TQT_SIGNAL(clicked()), TQT_TQOBJECT(this), TQT_SLOT(add())); - connect( TQT_TQOBJECT(widget->btnRemove), TQT_SIGNAL(clicked()), TQT_TQOBJECT(this), TQT_SLOT(remove())); + connect( widget->comboHotkey, TQ_SIGNAL(activated(int)), this, TQ_SLOT(hotkeyComboChanged())); + connect( widget->comboHotkey, TQ_SIGNAL(activated(int)), this, TQ_SLOT(updateOptionsCommand())); + connect( widget->comboHotkey, TQ_SIGNAL(activated(int)), this, TQ_SLOT(changed())); + connect( widget->comboModel, TQ_SIGNAL(activated(int)), this, TQ_SLOT(changed())); - connect( TQT_TQOBJECT(widget->comboVariant), TQT_SIGNAL(activated(int)), TQT_TQOBJECT(this), TQT_SLOT(changed())); - connect( TQT_TQOBJECT(widget->comboVariant), TQT_SIGNAL(activated(int)), TQT_TQOBJECT(this), TQT_SLOT(variantChanged())); - connect( TQT_TQOBJECT(widget->listLayoutsDst), TQT_SIGNAL(selectionChanged(TQListViewItem *)), - TQT_TQOBJECT(this), TQT_SLOT(layoutSelChanged(TQListViewItem *))); + connect( widget->listLayoutsSrc, TQ_SIGNAL(doubleClicked(TQListViewItem*,const TQPoint&, int)), + this, TQ_SLOT(add())); + connect( widget->btnAdd, TQ_SIGNAL(clicked()), this, TQ_SLOT(add())); + connect( widget->btnRemove, TQ_SIGNAL(clicked()), this, TQ_SLOT(remove())); - connect( widget->editDisplayName, TQT_SIGNAL(textChanged(const TQString&)), TQT_TQOBJECT(this), TQT_SLOT(displayNameChanged(const TQString&))); + connect( widget->comboVariant, TQ_SIGNAL(activated(int)), this, TQ_SLOT(changed())); + connect( widget->comboVariant, TQ_SIGNAL(activated(int)), this, TQ_SLOT(variantChanged())); + connect( widget->listLayoutsDst, TQ_SIGNAL(selectionChanged(TQListViewItem *)), + this, TQ_SLOT(layoutSelChanged(TQListViewItem *))); - connect( widget->chkLatin, TQT_SIGNAL(clicked()), TQT_TQOBJECT(this), TQT_SLOT(changed())); - connect( widget->chkLatin, TQT_SIGNAL(clicked()), TQT_TQOBJECT(this), TQT_SLOT(latinChanged())); + connect( widget->editDisplayName, TQ_SIGNAL(textChanged(const TQString&)), this, TQ_SLOT(displayNameChanged(const TQString&))); widget->btnUp->setIconSet(SmallIconSet("1uparrow")); - connect( widget->btnUp, TQT_SIGNAL(clicked()), TQT_TQOBJECT(this), TQT_SLOT(changed())); - connect( widget->btnUp, TQT_SIGNAL(clicked()), TQT_TQOBJECT(this), TQT_SLOT(moveUp())); + connect( widget->btnUp, TQ_SIGNAL(clicked()), this, TQ_SLOT(changed())); + connect( widget->btnUp, TQ_SIGNAL(clicked()), this, TQ_SLOT(moveUp())); widget->btnDown->setIconSet(SmallIconSet("1downarrow")); - connect( widget->btnDown, TQT_SIGNAL(clicked()), TQT_TQOBJECT(this), TQT_SLOT(changed())); - connect( widget->btnDown, TQT_SIGNAL(clicked()), TQT_TQOBJECT(this), TQT_SLOT(moveDown())); + connect( widget->btnDown, TQ_SIGNAL(clicked()), this, TQ_SLOT(changed())); + connect( widget->btnDown, TQ_SIGNAL(clicked()), this, TQ_SLOT(moveDown())); + + connect( widget->grpStyle, TQ_SIGNAL( clicked( int ) ), TQ_SLOT(changed())); + connect( widget->grpSwitching, TQ_SIGNAL( clicked( int ) ), TQ_SLOT(changed())); + connect( widget->grpLabel, TQ_SIGNAL( clicked( int ) ), TQ_SLOT(changed())); + + connect( widget->chkFitToBox, TQ_SIGNAL(toggled(bool)), this, TQ_SLOT(changed())); + connect( widget->chkDimFlag, TQ_SIGNAL(toggled(bool)), this, TQ_SLOT(changed())); - connect( widget->grpStyle, TQT_SIGNAL( clicked( int ) ), TQT_SLOT(changed())); - connect( widget->grpSwitching, TQT_SIGNAL( clicked( int ) ), TQT_SLOT(changed())); - connect( widget->grpLabel, TQT_SIGNAL( clicked( int ) ), TQT_SLOT(changed())); + connect( widget->bgColor, TQ_SIGNAL( changed(const TQColor&) ), this, TQ_SLOT(changed())); + connect( widget->fgColor, TQ_SIGNAL( changed(const TQColor&) ), this, TQ_SLOT(changed())); + connect( widget->chkBgTransparent, TQ_SIGNAL( toggled(bool) ), this, TQ_SLOT(changed())); + connect( widget->labelFont, TQ_SIGNAL( fontSelected(const TQFont&) ), this, TQ_SLOT(changed())); + connect( widget->chkLabelShadow, TQ_SIGNAL( toggled( bool ) ), this, TQ_SLOT(changed())); + connect( widget->shColor, TQ_SIGNAL( changed(const TQColor&) ), this, TQ_SLOT(changed())); - connect( widget->bgColor, TQT_SIGNAL( changed(const TQColor&) ), TQT_TQOBJECT(this), TQT_SLOT(changed())); - connect( widget->fgColor, TQT_SIGNAL( changed(const TQColor&) ), TQT_TQOBJECT(this), TQT_SLOT(changed())); - connect( widget->labelFont, TQT_SIGNAL( fontSelected(const TQFont&) ), TQT_TQOBJECT(this), TQT_SLOT(changed())); - connect( widget->chkLabelShadow, TQT_SIGNAL( toggled( bool ) ), TQT_TQOBJECT(this), TQT_SLOT(changed())); - connect( widget->shColor, TQT_SIGNAL( changed(const TQColor&) ), TQT_TQOBJECT(this), TQT_SLOT(changed())); + connect( widget->chkBevel, TQ_SIGNAL(toggled(bool)), this, TQ_SLOT(changed())); - connect( widget->chkEnableSticky, TQT_SIGNAL(toggled(bool)), TQT_TQOBJECT(this), TQT_SLOT(changed())); - connect( widget->spinStickyDepth, TQT_SIGNAL(valueChanged(int)), TQT_TQOBJECT(this), TQT_SLOT(changed())); + connect( widget->chkEnableSticky, TQ_SIGNAL(toggled(bool)), this, TQ_SLOT(changed())); + connect( widget->spinStickyDepth, TQ_SIGNAL(valueChanged(int)), this, TQ_SLOT(changed())); + + connect(widget->chkEnableNotify, TQ_SIGNAL(toggled(bool)), TQ_SLOT(changed())); + connect(widget->chkNotifyUseKMilo, TQ_SIGNAL(toggled(bool)), TQ_SLOT(changed())); + connect(widget->chkEnableNotify, TQ_SIGNAL(toggled(bool)), widget->chkNotifyUseKMilo, TQ_SLOT(setEnabled(bool))); widget->listLayoutsSrc->setColumnText(LAYOUT_COLUMN_FLAG, ""); widget->listLayoutsDst->setColumnText(LAYOUT_COLUMN_FLAG, ""); - widget->listLayoutsDst->setColumnText(LAYOUT_COLUMN_INCLUDE, ""); // widget->listLayoutsDst->setColumnText(LAYOUT_COLUMN_DISPLAY_NAME, ""); widget->listLayoutsSrc->setColumnWidth(LAYOUT_COLUMN_FLAG, 28); widget->listLayoutsDst->setColumnWidth(LAYOUT_COLUMN_FLAG, 28); - widget->listLayoutsDst->header()->setResizeEnabled(FALSE, LAYOUT_COLUMN_INCLUDE); - widget->listLayoutsDst->header()->setResizeEnabled(FALSE, LAYOUT_COLUMN_DISPLAY_NAME); - widget->listLayoutsDst->setColumnWidthMode(LAYOUT_COLUMN_INCLUDE, TQListView::Manual); - widget->listLayoutsDst->setColumnWidth(LAYOUT_COLUMN_INCLUDE, 0); + widget->listLayoutsDst->header()->setResizeEnabled(false, LAYOUT_COLUMN_DISPLAY_NAME); // widget->listLayoutsDst->setColumnWidth(LAYOUT_COLUMN_DISPLAY_NAME, 0); widget->listLayoutsDst->setSorting(-1); @@ -171,26 +186,43 @@ LayoutConfig::LayoutConfig(TQWidget *parent, const char *name) //Read rules - we _must_ read _before_ creating xkb-options comboboxes loadRules(); - makeOptionsTab(); + // Load global shortcuts +#define NOSLOTS + keys = new TDEGlobalAccel(this); +#include "kxkbbindings.cpp" + keys->readSettings(); - load(); + makeOptionsTab(); + makeShortcutsTab(); + TQTimer::singleShot(0, this, TQ_SLOT(load())); } LayoutConfig::~LayoutConfig() { - delete m_rules; + delete m_rules; + delete m_icoMgr; } void LayoutConfig::load() { - m_kxkbConfig.load(KxkbConfig::LOAD_ALL); + bool modified = false; + m_kxkbConfig.load(KxkbConfig::LOAD_ALL_OPTIONS); - initUI(); + // Check if the active settings are different from the saved settings + if (m_kxkbConfig.m_useKxkb) + { + XkbOptions options = XKBExtension::the()->getServerOptions(); + modified = m_kxkbConfig.setFromXkbOptions(options); + } + + m_kxkbConfig.load(KxkbConfig::LOAD_ALL_OPTIONS); + keys->readSettings(); + initUI(modified); } -void LayoutConfig::initUI() { +void LayoutConfig::initUI(bool modified) { const char* modelName = m_rules->models()[m_kxkbConfig.m_model]; if( modelName == NULL ) modelName = DEFAULT_MODEL; @@ -207,12 +239,10 @@ void LayoutConfig::initUI() { for ( ; src_it.current(); ++src_it ) { TQListViewItem* srcItem = src_it.current(); - if ( layoutUnit.layout == src_it.current()->text(LAYOUT_COLUMN_MAP) ) { // check if current config knows about this layout TQListViewItem* newItem = copyLVI(srcItem, widget->listLayoutsDst); newItem->setText(LAYOUT_COLUMN_VARIANT, layoutUnit.variant); - newItem->setText(LAYOUT_COLUMN_INCLUDE, layoutUnit.includeGroup); newItem->setText(LAYOUT_COLUMN_DISPLAY_NAME, layoutUnit.displayName); widget->listLayoutsDst->insertItem(newItem); newItem->moveItem(widget->listLayoutsDst->lastItem()); @@ -222,6 +252,25 @@ void LayoutConfig::initUI() { } } + // initialize hotkey combo + TQDict<char> allOptions = m_rules->options(); + + TQStringList commonHotkeys; + commonHotkeys << "alt_shift_toggle" << "ctrl_shift_toggle" + << "win_space_toggle" << "alt_space_toggle" + << "caps_toggle" << "menu_toggle" + << "lwin_toggle" << "rwin_toggle"; + + for (TQStringList::ConstIterator hk = commonHotkeys.begin(); hk != commonHotkeys.end(); ++hk ) { + const char *hkOpt = tqstrdup(TQString("grp:" + (*hk)).ascii()); + const char *hkDesc = allOptions[hkOpt]; + if (hkDesc != 0) { // the option exists + widget->comboHotkey->insertItem(XkbRules::trOpt(hkDesc)); + } + } + widget->comboHotkey->insertItem(i18n("None")); + widget->comboHotkey->insertItem(i18n("Other...")); + // display KXKB switching options widget->chkShowSingle->setChecked(m_kxkbConfig.m_showSingle); @@ -230,9 +279,10 @@ void LayoutConfig::initUI() { widget->radFlagLabel->setChecked( showFlag && showLabel ); widget->radFlagOnly->setChecked( showFlag && !showLabel ); widget->radLabelOnly->setChecked( !showFlag && showLabel ); + widget->chkFitToBox->setChecked(m_kxkbConfig.m_fitToBox); + widget->chkDimFlag->setChecked(m_kxkbConfig.m_dimFlag); - widget->chkEnableOptions->setChecked( m_kxkbConfig.m_enableXkbOptions ); - widget->checkResetOld->setChecked(m_kxkbConfig.m_resetOldOptions); + widget->xkbOptsMode->setButton(m_kxkbConfig.m_resetOldOptions ? 0 : 1); widget->grpLabel->setButton( ( m_kxkbConfig.m_useThemeColors ? 0 : 1 ) ); widget->bgColor->setColor( m_kxkbConfig.m_colorBackground ); @@ -242,11 +292,15 @@ void LayoutConfig::initUI() { widget->chkLabelShadow->setChecked( m_kxkbConfig.m_labelShadow ); widget->shColor->setColor( m_kxkbConfig.m_colorShadow ); + widget->chkBevel->setChecked(m_kxkbConfig.m_bevel); + widget->grpLabel->setDisabled(showFlag && !showLabel); widget->grpLabelColors->setDisabled(m_kxkbConfig.m_useThemeColors); widget->labelBgColor->setDisabled(showFlag); widget->bgColor->setDisabled(showFlag); widget->chkBgTransparent->setDisabled(showFlag); + widget->grpFlag->setEnabled(showFlag); + widget->chkDimFlag->setEnabled(showFlag && showLabel); switch( m_kxkbConfig.m_switchingPolicy ) { default: @@ -265,20 +319,31 @@ void LayoutConfig::initUI() { widget->spinStickyDepth->setEnabled(m_kxkbConfig.m_stickySwitching); widget->spinStickyDepth->setValue( m_kxkbConfig.m_stickySwitchingDepth); + widget->chkEnableNotify->setChecked(m_kxkbConfig.m_enableNotify); + widget->chkNotifyUseKMilo->setChecked(m_kxkbConfig.m_notifyUseKMilo); + widget->chkNotifyUseKMilo->setEnabled(m_kxkbConfig.m_enableNotify); + updateStickyLimit(); widget->chkEnable->setChecked( m_kxkbConfig.m_useKxkb ); widget->grpLayouts->setEnabled( m_kxkbConfig.m_useKxkb ); - widget->optionsFrame->setEnabled( m_kxkbConfig.m_useKxkb ); + widget->swOptsFrame->setEnabled( m_kxkbConfig.m_useKxkb ); + widget->indOptsFrame->setEnabled( m_kxkbConfig.m_useKxkb ); // display xkb options - TQStringList options = TQStringList::split(',', m_kxkbConfig.m_options); - for (TQStringList::ConstIterator it = options.begin(); it != options.end(); ++it) + TQStringList activeOptions = TQStringList::split(',', m_kxkbConfig.m_options); + bool foundGrp = false; + for (TQStringList::ConstIterator it = activeOptions.begin(); it != activeOptions.end(); ++it) { TQString option = *it; TQString optionKey = option.mid(0, option.find(':')); TQString optionName = m_rules->options()[option]; - OptionListItem *item = m_optionGroups[i18n(optionKey.latin1())]; + + if (optionKey == "grp") { + foundGrp = true; + } + + OptionListItem *item = m_optionGroups[optionKey]; if (item != NULL) { OptionListItem *child = item->findChildItem( option ); @@ -293,8 +358,16 @@ void LayoutConfig::initUI() { } } + if (!foundGrp) { + OptionListItem *grpNone = itemForOption("grp:none"); + if (grpNone) { + grpNone->setOn(true); + } + } + updateOptionsCommand(); - emit TDECModule::changed( false ); + updateHotkeyCombo(true); + emit TDECModule::changed(modified); } @@ -303,10 +376,12 @@ void LayoutConfig::save() TQString model = lookupLocalized(m_rules->models(), widget->comboModel->currentText()); m_kxkbConfig.m_model = model; - m_kxkbConfig.m_enableXkbOptions = widget->chkEnableOptions->isChecked(); - m_kxkbConfig.m_resetOldOptions = widget->checkResetOld->isChecked(); + m_kxkbConfig.m_resetOldOptions = widget->radXkbOverwrite->isOn(); m_kxkbConfig.m_options = createOptionString(); + m_kxkbConfig.m_fitToBox = widget->chkFitToBox->isChecked(); + m_kxkbConfig.m_dimFlag = widget->chkDimFlag->isChecked(); + m_kxkbConfig.m_useThemeColors = widget->radLabelUseTheme->isChecked(); m_kxkbConfig.m_colorBackground = widget->bgColor->color(); m_kxkbConfig.m_colorLabel = widget->fgColor->color(); @@ -315,22 +390,21 @@ void LayoutConfig::save() m_kxkbConfig.m_labelShadow = widget->chkLabelShadow->isChecked(); m_kxkbConfig.m_colorShadow = widget->shColor->color(); + m_kxkbConfig.m_bevel = widget->chkBevel->isChecked(); + TQListViewItem *item = widget->listLayoutsDst->firstChild(); TQValueList<LayoutUnit> layouts; while (item) { TQString layout = item->text(LAYOUT_COLUMN_MAP); TQString variant = item->text(LAYOUT_COLUMN_VARIANT); - TQString includes = item->text(LAYOUT_COLUMN_INCLUDE); TQString displayName = item->text(LAYOUT_COLUMN_DISPLAY_NAME); LayoutUnit layoutUnit(layout, variant); - layoutUnit.includeGroup = includes; layoutUnit.displayName = displayName; layouts.append( layoutUnit ); item = item->nextSibling(); kdDebug() << "To save: layout " << layoutUnit.toPair() - << ", inc: " << layoutUnit.includeGroup << ", disp: " << layoutUnit.displayName << endl; } m_kxkbConfig.m_layouts = layouts; @@ -363,11 +437,48 @@ void LayoutConfig::save() m_kxkbConfig.m_stickySwitching = widget->chkEnableSticky->isChecked(); m_kxkbConfig.m_stickySwitchingDepth = widget->spinStickyDepth->value(); + m_kxkbConfig.m_enableNotify = widget->chkEnableNotify->isChecked(); + m_kxkbConfig.m_notifyUseKMilo = widget->chkNotifyUseKMilo->isChecked(); + m_kxkbConfig.save(); + // We might need to unset previous hotkey options + if (m_forceGrpOverwrite) + { + // First get all the server's options + XkbOptions _opt = XKBExtension::the()->getServerOptions(); + TQStringList srvOptions = TQStringList::split(",", _opt.options); + TQStringList newOptions; + + // Then remove all grp: options + for (TQStringList::Iterator it = srvOptions.begin(); it != srvOptions.end(); ++it) + { + TQString opt(*it); + if (!opt.startsWith("grp:")) + { + newOptions << opt; + } + } + + XkbOptions xkbOptions; + xkbOptions.options = newOptions.join(","); + xkbOptions.resetOld = true; + + if (!XKBExtension::the()->setXkbOptions(xkbOptions)) + { + kdWarning() << "[LayoutConfig::save] Could not overwrite previous grp: options!" << endl; + } + + m_forceGrpOverwrite = false; + } + + // Save and apply global shortcuts + m_keyChooser->commitChanges(); + keys->writeSettings(0, true); + // Get current layout from Kxkb - if (!kapp->dcopClient()->isAttached()) - kapp->dcopClient()->attach(); + if (!tdeApp->dcopClient()->isAttached()) + tdeApp->dcopClient()->attach(); DCOPRef kxkbref("kxkb", "kxkb"); DCOPReply reply = kxkbref.call( "getCurrentLayout" ); @@ -380,7 +491,7 @@ void LayoutConfig::save() } // Cause Kxkb to reread configuration - kapp->tdeinitExecWait("kxkb"); + tdeApp->tdeinitExecWait("kxkb"); // If previous call was valid, try to change layout if ( reply.isValid() ) { @@ -397,6 +508,8 @@ void LayoutConfig::save() } } + updateHotkeyCombo(); + emit TDECModule::changed( false ); } @@ -439,9 +552,6 @@ void LayoutConfig::add() // than one time, with different variants. TQListViewItem* toadd = copyLVI(sel, widget->listLayoutsDst); - // Turn on "Include Latin layout" for new language by default (bnc:204402) - toadd->setText(LAYOUT_COLUMN_INCLUDE, "us"); - widget->listLayoutsDst->insertItem(toadd); if( widget->listLayoutsDst->childCount() > 1 ) toadd->moveItem(widget->listLayoutsDst->lastItem()); @@ -513,6 +623,7 @@ void LayoutConfig::variantChanged() if( selectedVariant == DEFAULT_VARIANT_NAME ) selectedVariant = ""; selLayout->setText(LAYOUT_COLUMN_VARIANT, selectedVariant); + updateLayoutCommand(); } // helper @@ -551,33 +662,10 @@ void LayoutConfig::updateIndicator(TQListViewItem* selLayout) { } - -void LayoutConfig::latinChanged() -{ - TQListViewItem* selLayout = widget->listLayoutsDst->selectedItem(); - if ( !selLayout ) { - widget->chkLatin->setChecked( false ); - widget->chkLatin->setEnabled( false ); - return; - } - - TQString include; - if( widget->chkLatin->isChecked() ) - include = "us"; - else - include = ""; - selLayout->setText(LAYOUT_COLUMN_INCLUDE, include); - - LayoutUnit layoutUnitKey = getLayoutUnitKey(selLayout); - kdDebug() << "layout " << layoutUnitKey.toPair() << ", inc: " << include << endl; -} - void LayoutConfig::layoutSelChanged(TQListViewItem *sel) { widget->comboVariant->clear(); widget->comboVariant->setEnabled( sel != NULL ); - widget->chkLatin->setChecked( false ); - widget->chkLatin->setEnabled( sel != NULL ); if( sel == NULL ) { updateLayoutCommand(); @@ -588,21 +676,6 @@ void LayoutConfig::layoutSelChanged(TQListViewItem *sel) LayoutUnit layoutUnitKey = getLayoutUnitKey(sel); TQString kbdLayout = layoutUnitKey.layout; - // TODO: need better algorithm here for determining if needs us group - if ( ! m_rules->isSingleGroup(kbdLayout) - || kbdLayout.startsWith("us") || kbdLayout.startsWith("en") ) { - widget->chkLatin->setEnabled( false ); - } - else { - TQString inc = sel->text(LAYOUT_COLUMN_INCLUDE); - if ( inc.startsWith("us") || inc.startsWith("en") ) { - widget->chkLatin->setChecked(true); - } - else { - widget->chkLatin->setChecked(false); - } - } - TQStringList vars = m_rules->getAvailableVariants(kbdLayout); kdDebug() << "layout " << kbdLayout << " has " << vars.count() << " variants" << endl; @@ -630,13 +703,13 @@ TQWidget* LayoutConfig::makeOptionsTab() listView->setColumnText( 0, i18n( "Options" ) ); listView->clear(); - connect(listView, TQT_SIGNAL(clicked(TQListViewItem *)), TQT_SLOT(changed())); - connect(listView, TQT_SIGNAL(clicked(TQListViewItem *)), TQT_SLOT(updateOptionsCommand())); + connect(listView, TQ_SIGNAL(clicked(TQListViewItem *)), TQ_SLOT(changed())); + connect(listView, TQ_SIGNAL(clicked(TQListViewItem *)), TQ_SLOT(resolveConflicts(TQListViewItem *))); + connect(listView, TQ_SIGNAL(clicked(TQListViewItem *)), TQ_SLOT(updateHotkeyCombo())); - connect(widget->chkEnableOptions, TQT_SIGNAL(toggled(bool)), TQT_SLOT(changed())); - - connect(widget->checkResetOld, TQT_SIGNAL(toggled(bool)), TQT_SLOT(changed())); - connect(widget->checkResetOld, TQT_SIGNAL(toggled(bool)), TQT_SLOT(updateOptionsCommand())); + connect(widget->xkbOptsMode, TQ_SIGNAL(released(int)), TQ_SLOT(changed())); + connect(widget->xkbOptsMode, TQ_SIGNAL(released(int)), TQ_SLOT(updateOptionsCommand())); + connect(widget->xkbOptsMode, TQ_SIGNAL(released(int)), TQ_SLOT(updateHotkeyCombo())); //Create controllers for all options TQDictIterator<char> it(m_rules->options()); @@ -646,19 +719,26 @@ TQWidget* LayoutConfig::makeOptionsTab() if (!it.currentKey().contains(':')) { if( it.currentKey() == "ctrl" || it.currentKey() == "caps" - || it.currentKey() == "altwin" ) { - parent = new OptionListItem(listView, i18n( it.current() ), + || it.currentKey() == "altwin") { + parent = new OptionListItem(listView, XkbRules::trOpt( it.current() ), TQCheckListItem::RadioButtonController, it.currentKey()); OptionListItem *item = new OptionListItem(parent, i18n( "None" ), TQCheckListItem::RadioButton, "none"); item->setState(TQCheckListItem::On); } + else if (it.currentKey() == "grp") { + parent = new OptionListItem(listView, XkbRules::trOpt(it.current()), + TQCheckListItem::RadioButtonController, it.currentKey()); + parent->setSelectable(false); + OptionListItem *item = new OptionListItem(parent, i18n("None"), + TQCheckListItem::CheckBox, "grp:none"); + } else { - parent = new OptionListItem(listView, i18n( it.current() ), + parent = new OptionListItem(listView, XkbRules::trOpt( it.current() ), TQCheckListItem::CheckBoxController, it.currentKey()); } parent->setOpen(true); - m_optionGroups.insert(i18n(it.currentKey().local8Bit()), parent); + m_optionGroups.insert(it.currentKey(), parent); } } @@ -676,12 +756,13 @@ TQWidget* LayoutConfig::makeOptionsTab() // workaroung for mistake in rules file for xkb options in XFree 4.2.0 TQString text(it.current()); text = text.replace( "Cap$", "Caps." ); - if( parent->type() == TQCheckListItem::RadioButtonController ) - new OptionListItem(parent, i18n(text.utf8()), - TQCheckListItem::RadioButton, key); - else - new OptionListItem(parent, i18n(text.utf8()), + if ( parent->type() == TQCheckListItem::CheckBoxController + || key.startsWith("grp:")) + new OptionListItem(parent, XkbRules::trOpt(text), TQCheckListItem::CheckBox, key); + else + new OptionListItem(parent, XkbRules::trOpt(text), + TQCheckListItem::RadioButton, key); } } } @@ -691,68 +772,369 @@ TQWidget* LayoutConfig::makeOptionsTab() return listView; } +TQWidget* LayoutConfig::makeShortcutsTab() { + m_keyChooser = new KKeyChooser(keys, widget->tabShortcuts, false, false); + connect(m_keyChooser, TQ_SIGNAL(keyChange()), this, TQ_SLOT(changed())); + widget->tabShortcuts->layout()->add(m_keyChooser); + return m_keyChooser; +} + void LayoutConfig::updateOptionsCommand() { TQString setxkbmap; TQString options = createOptionString(); + bool overwrite = widget->radXkbOverwrite->isOn(); if( !options.isEmpty() ) { setxkbmap = "setxkbmap -option "; //-rules " + m_rule - if( widget->checkResetOld->isChecked() ) + if (overwrite) setxkbmap += "-option "; setxkbmap += options; } + else if (overwrite) { + setxkbmap = "setxkbmap -option"; + } widget->editCmdLineOpt->setText(setxkbmap); + widget->editCmdLineOpt->setDisabled(setxkbmap.isEmpty()); } void LayoutConfig::updateLayoutCommand() { - TQString setxkbmap; - TQString layoutDisplayName; - TQListViewItem* sel = widget->listLayoutsDst->selectedItem(); - - if( sel != NULL ) { - TQString kbdLayout = sel->text(LAYOUT_COLUMN_MAP); - TQString variant = widget->comboVariant->currentText(); - if( variant == DEFAULT_VARIANT_NAME ) - variant = ""; - - setxkbmap = "setxkbmap"; //-rules " + m_rule - setxkbmap += " -model " + lookupLocalized(m_rules->models(), widget->comboModel->currentText()) - + " -layout "; - setxkbmap += kbdLayout; - if( widget->chkLatin->isChecked() ) - setxkbmap += ",us"; - -/* LayoutUnit layoutUnitKey = getLayoutUnitKey(sel); - layoutDisplayName = m_kxkbConfig.getLayoutDisplayName( *m_kxkbConfig.m_layouts.find(layoutUnitKey) );*/ - layoutDisplayName = sel->text(LAYOUT_COLUMN_DISPLAY_NAME); - if( layoutDisplayName.isEmpty() ) { - int count = 0; - TQListViewItem *item = widget->listLayoutsDst->firstChild(); - while (item) { - TQString layout_ = item->text(LAYOUT_COLUMN_MAP); - if( layout_ == kbdLayout ) - ++count; - item = item->nextSibling(); - } - bool single = count < 2; - layoutDisplayName = m_kxkbConfig.getDefaultDisplayName(LayoutUnit(kbdLayout, variant), single); - } - kdDebug() << "disp: '" << layoutDisplayName << "'" << endl; - - if( !variant.isEmpty() ) { - setxkbmap += " -variant "; - if( widget->chkLatin->isChecked() ) - setxkbmap += ","; - setxkbmap += variant; + TQString setxkbmap = "setxkbmap"; + setxkbmap += " -model " + lookupLocalized(m_rules->models(), + widget->comboModel->currentText()); + TQStringList layoutCodes; + TQStringList layoutVariants; + TQListViewItem *item = widget->listLayoutsDst->firstChild(); + while (item) { + layoutCodes << item->text(LAYOUT_COLUMN_MAP); + + TQString layoutVariant = item->text(LAYOUT_COLUMN_VARIANT); + if (layoutVariant == DEFAULT_VARIANT_NAME) { + layoutVariant = ""; } + layoutVariants << layoutVariant; + + item = item->nextSibling(); + } + + setxkbmap += " -layout " + layoutCodes.join(","); + + if( !layoutVariants.isEmpty() ) { + setxkbmap += " -variant " + layoutVariants.join(","); } widget->editCmdLine->setText(setxkbmap); + /* update display name field */ + TQListViewItem *sel = widget->listLayoutsDst->selectedItem(); + if (!sel) { + return; + } + TQString selLayoutCode = sel->text(LAYOUT_COLUMN_MAP); + TQString selLayoutVariant = widget->comboVariant->currentText(); + TQString selDisplayName = sel->text(LAYOUT_COLUMN_DISPLAY_NAME); + if (selDisplayName.isEmpty()) { + int count = 0; + TQListViewItem *item = widget->listLayoutsDst->firstChild(); + while (item) { + TQString layoutCode_ = item->text(LAYOUT_COLUMN_MAP); + if (layoutCode_ == selLayoutCode) { + ++count; + } + item = item->nextSibling(); + } + bool single = count < 2; + selDisplayName = m_kxkbConfig.getDefaultDisplayName(LayoutUnit(selLayoutCode, selLayoutVariant), single); + } + widget->editDisplayName->setEnabled( sel != NULL ); - widget->editDisplayName->setText(layoutDisplayName); + widget->editDisplayName->setText(selDisplayName); +} + +void LayoutConfig::checkConflicts(OptionListItem *current, + TQStringList conflicting, + TQStringList &conflicts) +{ + if (!current || conflicting.count() < 2 || + !conflicting.contains(current->optionName())) + { + return; + } + TQStringList::Iterator it; + for (it = conflicting.begin(); it != conflicting.end(); ++it) { + TQString option(*it); + if (option == current->optionName()) { + continue; + } + + OptionListItem *item = itemForOption(option); + if (item && item->isOn()) { + conflicts << item->text(); + } + } +} + +void LayoutConfig::resolveConflicts(TQListViewItem *lvi) { + OptionListItem *current = (OptionListItem*)lvi; + + kdDebug() << "resolveConflicts : " << current->optionName() << endl; + + if (current->optionName().startsWith("grp:")) { + OptionListItem *grpItem = m_optionGroups["grp"]; + if (grpItem == NULL) { + kdWarning() << "LayoutConfig: cannot find grp item group" << endl; + return; + } + + OptionListItem *noneItem = grpItem->findChildItem("grp:none"); + if (!noneItem) { + kdDebug() << "LayoutConfig: unable to find None item for grp!" << endl; + } + else { + // Option "none" selected, uncheck all other options immediately + if (current->optionName() == "grp:none") { + if (current->isOn()) { + OptionListItem *child = (OptionListItem*)grpItem->firstChild(); + while (child) { + if (child != current) { + child->setOn(false); + } + child = (OptionListItem*)child->nextSibling(); + } + } + else { + current->setOn(true); + } + updateOptionsCommand(); + return; + } + + // If no options are selected then select "none" + bool notNone = false; + OptionListItem *child = (OptionListItem*)grpItem->firstChild(); + while (child) { + if (child->isOn() && child->optionName() != "none") { + notNone = true; + break; + } + child = (OptionListItem*)child->nextSibling(); + } + + noneItem->setOn(!notNone); + } + } + + TQStringList conflicts; + OptionListItem *conflict; + + TQStringList conflicting; + /* Might be incomplete */ + // Space + conflicting << "grp:win_space_toggle" + << "grp:alt_space_toggle" + << "grp:ctrl_space_toggle"; + checkConflicts(current, conflicting, conflicts); + + // Shift + conflicting.clear(); + conflicting << "grp:ctrl_shift_toggle" + << "grp:alt_shift_toggle"; + checkConflicts(current, conflicting, conflicts); + + // Control + conflicting.clear(); + conflicting << "grp:ctrl_select" + << "grp:ctrl_alt_toggle" + << "grp:ctrl_shift_toggle"; + checkConflicts(current, conflicting, conflicts); + + // Left Ctrl + conflicting.clear(); + conflicting << "grp:lctrl_toggle" + << "grp:lctrl_lshift_toggle"; + checkConflicts(current, conflicting, conflicts); + + // Right Ctrl + conflicting.clear(); + conflicting << "grp:rctrl_toggle" + << "grp:rctrl_rshift_toggle"; + checkConflicts(current, conflicting, conflicts); + + // Win + conflicting.clear(); + conflicting << "grp:win_space_toggle" + << "grp:win_switch" + << "win_menu_select"; + checkConflicts(current, conflicting, conflicts); + + // Left Alt + conflicting.clear(); + conflicting << "grp:lalt_toggle" + << "grp:lalt_lshift_toggle"; + checkConflicts(current, conflicting, conflicts); + + // Right Alt + conflicting.clear(); + conflicting << "grp:ralt_toggle" + << "grp:ralt_rshift_toggle"; + checkConflicts(current, conflicting, conflicts); + + // Caps Lock + conflicting.clear(); + conflicting << "grp:caps_toggle" + << "grp:caps_select" + << "grp:caps_switch" + << "grp:alt_caps_toggle"; + checkConflicts(current, conflicting, conflicts); + + if (conflicts.count()) { + TQString curText = current->text(); + int confirm = KMessageBox::warningYesNoList(this, + i18n("<qt>The option <b>%1</b> might conflict with " + "other options that you have already enabled.<br>" + "Are you sure that you really want to enable " + "<b>%2</b>?</qt>") + .arg(curText).arg(curText), + conflicts, + i18n("Conflicting options")); + if (confirm == KMessageBox::No) { + current->setOn(false); + } + } + updateOptionsCommand(); +} + +// Synchronizes Xkb grp options --> hotkeys combobox +void LayoutConfig::updateHotkeyCombo() { + updateHotkeyCombo(false); +} + +void LayoutConfig::updateHotkeyCombo(bool initial) { + OptionListItem *grpItem = m_optionGroups["grp"]; + if (grpItem == NULL) { + kdWarning() << "LayoutConfig: cannot find grp item group" << endl; + return; + } + + TQStringList hotkeys; + + // Get server options first + if (initial || widget->xkbOptsMode->selectedId() == 1) + { + XkbOptions _opt = XKBExtension::the()->getServerOptions(); + TQStringList opts = TQStringList::split(",", _opt.options); + for (TQStringList::Iterator it = opts.begin(); it != opts.end(); ++it) + { + TQString option(*it); + + if (!option.startsWith("grp:")) + { + continue; + } + + // Get description from existing item + // This spares us the trouble of querying Xkb rules second time + OptionListItem *item = itemForOption(option); + if (!item) + { + kdWarning() << "[updateHotkeyCombo] server has set unknown option: " + << option << endl; + continue; + } + + TQString optionName = item->text(); + if (!hotkeys.contains(optionName) && option != "grp:none") + { + hotkeys << optionName; + } + } + } + + OptionListItem *child = (OptionListItem*)grpItem->firstChild(); + while (child) { + TQString optionText = child->text(); + if (child->isOn() && !hotkeys.contains(optionText) && child->optionName() != "grp:none") { + hotkeys << optionText; + } + child = (OptionListItem*)child->nextSibling(); + } + + if (!hotkeys.count()) { + OptionListItem *noneItem = itemForOption("grp:none"); + if (noneItem) + { + hotkeys << noneItem->text(); + } + else + { + kdWarning() << "[updateHotkeyCombo] cannot find grp:none item!" << endl; + hotkeys << widget->comboHotkey->text(0); // fallback + } + } + + int other = widget->comboHotkey->count() - 1; + widget->comboHotkey->changeItem(i18n("Custom..."), other); + if (hotkeys.count() < 2) { + bool found = false; + for (int i = 0; i < widget->comboHotkey->count(); ++i) { + if (hotkeys[0] == widget->comboHotkey->text(i)) { + widget->comboHotkey->setCurrentItem(i); + found = true; + } + } + if (!found) { + widget->comboHotkey->changeItem(i18n("Other (%1)").arg(hotkeys[0]), + other); + widget->comboHotkey->setCurrentItem(other); + } + } + else { + widget->comboHotkey->changeItem(i18n("Multiple (%1)").arg(hotkeys.join("; ")), + other); + widget->comboHotkey->setCurrentItem(other); + } +} + +// Synchronizes hotkeys combobox --> Xkb grp options +void LayoutConfig::hotkeyComboChanged() { + TQStringList hotkeys; + int other = widget->comboHotkey->count() - 1; + + if (widget->comboHotkey->currentItem() != other) { + hotkeys << widget->comboHotkey->currentText(); + } + else { + TQString otherStr = widget->comboHotkey->text(other); + int i1 = otherStr.find("("); + if (i1 != -1) { // custom hotkey(s) set + ++i1; + int i2 = otherStr.findRev(")"); + if (i2 != -1) { + hotkeys = TQStringList::split("; ", otherStr.mid(i1, i2-i1)); + } + } + } + + OptionListItem *grpItem = m_optionGroups["grp"]; + if (grpItem == NULL) { + kdWarning() << "LayoutConfig: cannot find grp item group" << endl; + return; + } + + OptionListItem *child = (OptionListItem*)grpItem->firstChild(); + while (child) { + child->setOn(hotkeys.contains(child->text())); + child = (OptionListItem*)child->nextSibling(); + } + + if (widget->comboHotkey->currentItem() == other) { + widget->tabWidget->setCurrentPage(4); + widget->listOptions->ensureItemVisible(grpItem); + widget->listOptions->setFocus(); + } + + m_forceGrpOverwrite = true; } void LayoutConfig::changed() @@ -792,7 +1174,7 @@ void LayoutConfig::loadRules() TQString layoutName = it2.current(); TQListViewItem *item = new TQListViewItem(widget->listLayoutsSrc); - item->setPixmap(LAYOUT_COLUMN_FLAG, LayoutIcon::getInstance().findPixmap(layout, false)); + item->setPixmap(LAYOUT_COLUMN_FLAG, m_icoMgr->find(layout, PIXMAP_STYLE_CONTEXTMENU)); item->setText(LAYOUT_COLUMN_NAME, i18n(layoutName.latin1())); item->setText(LAYOUT_COLUMN_MAP, layout); ++it2; @@ -802,6 +1184,20 @@ void LayoutConfig::loadRules() //TODO: reset options and xkb options } +OptionListItem* LayoutConfig::itemForOption(TQString option) { + if (!option.contains(':')) { + return nullptr; + } + + TQString optionKey = option.mid(0, option.find(':')); + OptionListItem *item = m_optionGroups[optionKey]; + + if( !item ) { + kdDebug() << "WARNING: skipping empty group for " << option << endl; + return nullptr; + } + return (OptionListItem*)item->findChildItem(option); +} TQString LayoutConfig::createOptionString() { @@ -809,32 +1205,17 @@ TQString LayoutConfig::createOptionString() for (TQDictIterator<char> it(m_rules->options()); it.current(); ++it) { TQString option(it.currentKey()); - - if (option.contains(':')) { - - TQString optionKey = option.mid(0, option.find(':')); - OptionListItem *item = m_optionGroups[optionKey]; - - if( !item ) { - kdDebug() << "WARNING: skipping empty group for " << it.currentKey() - << endl; - continue; - } - - OptionListItem *child = item->findChildItem( option ); - - if ( child ) { - if ( child->state() == TQCheckListItem::On ) { - TQString selectedName = child->optionName(); - if ( !selectedName.isEmpty() && selectedName != "none" ) { - if (!options.isEmpty()) - options.append(','); - options.append(selectedName); - } - } + OptionListItem *child = itemForOption(option); + if (!child) { + continue; + } + if ( child->state() == TQCheckListItem::On ) { + TQString selectedName = child->optionName(); + if ( !selectedName.isEmpty() && selectedName != "none" ) { + if (!options.isEmpty()) + options.append(','); + options.append(selectedName); } - else - kdDebug() << "Empty option button for group " << it.currentKey() << endl; } } return options; @@ -881,17 +1262,17 @@ OptionListItem * OptionListItem::findChildItem( const TQString& optionName ) extern "C" { - KDE_EXPORT TDECModule *create_keyboard_layout(TQWidget *parent, const char *) + TDE_EXPORT TDECModule *create_keyboard_layout(TQWidget *parent, const char *) { return new LayoutConfig(parent, "kcmlayout"); } - KDE_EXPORT TDECModule *create_keyboard(TQWidget *parent, const char *) + TDE_EXPORT TDECModule *create_keyboard(TQWidget *parent, const char *) { return new KeyboardConfig(parent, "kcmlayout"); } - KDE_EXPORT void init_keyboard() + TDE_EXPORT void init_keyboard() { KeyboardConfig::init_keyboard(); @@ -899,15 +1280,11 @@ extern "C" m_kxkbConfig.load(KxkbConfig::LOAD_INIT_OPTIONS); if( m_kxkbConfig.m_useKxkb == true ) { - kapp->startServiceByDesktopName("kxkb"); + tdeApp->startServiceByDesktopName("kxkb"); } else { - // Even if the layouts have been disabled we still want to set Xkb options - // user can always switch them off now in the "Options" tab - if( m_kxkbConfig.m_enableXkbOptions ) { - if( !XKBExtension::setXkbOptions(m_kxkbConfig.m_options, m_kxkbConfig.m_resetOldOptions) ) { - kdDebug() << "Setting XKB options failed!" << endl; - } + if (!XKBExtension::the()->setXkbOptions(m_kxkbConfig.getKXkbOptions())) { + kdDebug() << "Setting XKB options failed!" << endl; } } } @@ -991,7 +1368,7 @@ extern "C" //these seem to be new in XFree86 4.4.0 I18N_NOOP("Shift with numpad keys works as in MS Windows."); - I18N_NOOP("Special keys (Ctrl+Alt+<key>) handled in a server."); + I18N_NOOP("Special keys (Ctrl+Alt+<key>) handled in a server."); I18N_NOOP("Miscellaneous compatibility options"); I18N_NOOP("Right Control key works as Right Alt"); |