summaryrefslogtreecommitdiffstats
path: root/kxkb/kcmlayout.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kxkb/kcmlayout.cpp')
-rw-r--r--kxkb/kcmlayout.cpp979
1 files changed, 979 insertions, 0 deletions
diff --git a/kxkb/kcmlayout.cpp b/kxkb/kcmlayout.cpp
new file mode 100644
index 000000000..2c601856f
--- /dev/null
+++ b/kxkb/kcmlayout.cpp
@@ -0,0 +1,979 @@
+#include <tqlayout.h>
+#include <tqlabel.h>
+#include <tqcombobox.h>
+#include <tqtabwidget.h>
+#include <tqvgroupbox.h>
+#include <tqpushbutton.h>
+#include <tqlistview.h>
+#include <tqheader.h>
+#include <tqwhatsthis.h>
+#include <tqcheckbox.h>
+#include <tqradiobutton.h>
+#include <tqlineedit.h>
+#include <tqlistview.h>
+#include <tqbuttongroup.h>
+#include <tqspinbox.h>
+
+#include <kkeydialog.h>
+#include <tdeglobal.h>
+#include <tdeconfig.h>
+#include <tdelocale.h>
+#include <kstandarddirs.h>
+#include <kdebug.h>
+#include <tdeapplication.h>
+#include <kiconloader.h>
+
+#include "extension.h"
+#include "kxkbconfig.h"
+#include "rules.h"
+#include "pixmap.h"
+#include "kcmmisc.h"
+#include "kcmlayoutwidget.h"
+
+#include "kcmlayout.h"
+#include "kcmlayout.moc"
+
+
+enum {
+ LAYOUT_COLUMN_FLAG = 0,
+ LAYOUT_COLUMN_NAME = 1,
+ LAYOUT_COLUMN_MAP = 2,
+ LAYOUT_COLUMN_VARIANT = 3,
+ LAYOUT_COLUMN_INCLUDE = 4,
+ LAYOUT_COLUMN_DISPLAY_NAME = 5,
+ SRC_LAYOUT_COLUMN_COUNT = 3,
+ DST_LAYOUT_COLUMN_COUNT = 6
+};
+
+static const TQString DEFAULT_VARIANT_NAME("<default>");
+
+
+class OptionListItem : public TQCheckListItem
+{
+ public:
+
+ OptionListItem( OptionListItem *parent, const TQString &text, Type tt,
+ const TQString &optionName );
+ OptionListItem( TQListView *parent, const TQString &text, Type tt,
+ const TQString &optionName );
+ ~OptionListItem() {}
+
+ TQString optionName() const { return m_OptionName; }
+
+ OptionListItem *findChildItem( const TQString& text );
+
+ protected:
+ TQString m_OptionName;
+};
+
+
+static TQString lookupLocalized(const TQDict<char> &dict, const TQString& text)
+{
+ TQDictIterator<char> it(dict);
+ while (it.current())
+ {
+ if ( i18n(it.current()) == text )
+ return it.currentKey();
+ ++it;
+ }
+
+ return TQString::null;
+}
+
+static TQListViewItem* copyLVI(const TQListViewItem* src, TQListView* parent)
+{
+ TQListViewItem* ret = new TQListViewItem(parent);
+ for(int i = 0; i < SRC_LAYOUT_COLUMN_COUNT; i++)
+ {
+ ret->setText(i, src->text(i));
+ if ( src->pixmap(i) )
+ ret->setPixmap(i, *src->pixmap(i));
+ }
+
+ return ret;
+}
+
+
+LayoutConfig::LayoutConfig(TQWidget *parent, const char *name)
+ : TDECModule(parent, name),
+ m_rules(NULL)
+{
+ 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()));
+ connect( TQT_TQOBJECT(widget->chkShowFlag), TQT_SIGNAL( toggled( bool )), TQT_TQOBJECT(this), TQT_SLOT(changed()));
+ connect( TQT_TQOBJECT(widget->comboModel), TQT_SIGNAL(activated(int)), TQT_TQOBJECT(this), TQT_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( 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->editDisplayName, TQT_SIGNAL(textChanged(const TQString&)), TQT_TQOBJECT(this), TQT_SLOT(displayNameChanged(const TQString&)));
+
+ connect( widget->chkLatin, TQT_SIGNAL(clicked()), TQT_TQOBJECT(this), TQT_SLOT(changed()));
+ connect( widget->chkLatin, TQT_SIGNAL(clicked()), TQT_TQOBJECT(this), TQT_SLOT(latinChanged()));
+
+ 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()));
+ 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->grpSwitching, TQT_SIGNAL( clicked( int ) ), TQT_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()));
+
+ 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->setColumnWidth(LAYOUT_COLUMN_DISPLAY_NAME, 0);
+
+ widget->listLayoutsDst->setSorting(-1);
+#if 0
+ widget->listLayoutsDst->setResizeMode(TQListView::LastColumn);
+ widget->listLayoutsSrc->setResizeMode(TQListView::LastColumn);
+#endif
+ widget->listLayoutsDst->setResizeMode(TQListView::LastColumn);
+
+ //Read rules - we _must_ read _before_ creating xkb-options comboboxes
+ loadRules();
+
+ makeOptionsTab();
+
+ load();
+}
+
+
+LayoutConfig::~LayoutConfig()
+{
+ delete m_rules;
+}
+
+
+void LayoutConfig::load()
+{
+ m_kxkbConfig.load(KxkbConfig::LOAD_ALL);
+
+ initUI();
+}
+
+void LayoutConfig::initUI() {
+ const char* modelName = m_rules->models()[m_kxkbConfig.m_model];
+ if( modelName == NULL )
+ modelName = DEFAULT_MODEL;
+
+ widget->comboModel->setCurrentText(i18n(modelName));
+
+ TQValueList<LayoutUnit> otherLayouts = m_kxkbConfig.m_layouts;
+ widget->listLayoutsDst->clear();
+// to optimize we should have gone from it.end to it.begin
+ TQValueList<LayoutUnit>::ConstIterator it;
+ for (it = otherLayouts.begin(); it != otherLayouts.end(); ++it ) {
+ TQListViewItemIterator src_it( widget->listLayoutsSrc );
+ LayoutUnit layoutUnit = *it;
+
+ 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());
+
+ break;
+ }
+ }
+ }
+
+ // display KXKB switching options
+ widget->chkShowSingle->setChecked(m_kxkbConfig.m_showSingle);
+ widget->chkShowFlag->setChecked(m_kxkbConfig.m_showFlag);
+
+ widget->chkEnableOptions->setChecked( m_kxkbConfig.m_enableXkbOptions );
+ widget->checkResetOld->setChecked(m_kxkbConfig.m_resetOldOptions);
+
+ switch( m_kxkbConfig.m_switchingPolicy ) {
+ default:
+ case SWITCH_POLICY_GLOBAL:
+ widget->grpSwitching->setButton(0);
+ break;
+ case SWITCH_POLICY_WIN_CLASS:
+ widget->grpSwitching->setButton(1);
+ break;
+ case SWITCH_POLICY_WINDOW:
+ widget->grpSwitching->setButton(2);
+ break;
+ }
+
+ widget->chkEnableSticky->setChecked(m_kxkbConfig.m_stickySwitching);
+ widget->spinStickyDepth->setEnabled(m_kxkbConfig.m_stickySwitching);
+ widget->spinStickyDepth->setValue( m_kxkbConfig.m_stickySwitchingDepth);
+
+ updateStickyLimit();
+
+ widget->chkEnable->setChecked( m_kxkbConfig.m_useKxkb );
+ widget->grpLayouts->setEnabled( m_kxkbConfig.m_useKxkb );
+ widget->optionsFrame->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)
+ {
+ TQString option = *it;
+ TQString optionKey = option.mid(0, option.find(':'));
+ TQString optionName = m_rules->options()[option];
+ OptionListItem *item = m_optionGroups[i18n(optionKey.latin1())];
+
+ if (item != NULL) {
+ OptionListItem *child = item->findChildItem( option );
+
+ if ( child )
+ child->setState( TQCheckListItem::On );
+ else
+ kdDebug() << "load: Unknown option: " << option << endl;
+ }
+ else {
+ kdDebug() << "load: Unknown option group: " << optionKey << " of " << option << endl;
+ }
+ }
+
+ updateOptionsCommand();
+ emit TDECModule::changed( false );
+}
+
+
+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_options = createOptionString();
+
+ 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;
+
+ if( m_kxkbConfig.m_layouts.count() == 0 ) {
+ m_kxkbConfig.m_layouts.append(LayoutUnit(DEFAULT_LAYOUT_UNIT));
+ widget->chkEnable->setChecked(false);
+ }
+
+ m_kxkbConfig.m_useKxkb = widget->chkEnable->isChecked();
+ m_kxkbConfig.m_showSingle = widget->chkShowSingle->isChecked();
+ m_kxkbConfig.m_showFlag = widget->chkShowFlag->isChecked();
+
+ int modeId = widget->grpSwitching->id(widget->grpSwitching->selected());
+ switch( modeId ) {
+ default:
+ case 0:
+ m_kxkbConfig.m_switchingPolicy = SWITCH_POLICY_GLOBAL;
+ break;
+ case 1:
+ m_kxkbConfig.m_switchingPolicy = SWITCH_POLICY_WIN_CLASS;
+ break;
+ case 2:
+ m_kxkbConfig.m_switchingPolicy = SWITCH_POLICY_WINDOW;
+ break;
+ }
+
+ m_kxkbConfig.m_stickySwitching = widget->chkEnableSticky->isChecked();
+ m_kxkbConfig.m_stickySwitchingDepth = widget->spinStickyDepth->value();
+
+ m_kxkbConfig.save();
+
+ kapp->tdeinitExec("kxkb");
+ emit TDECModule::changed( false );
+}
+
+
+void LayoutConfig::updateStickyLimit()
+{
+ int layoutsCnt = widget->listLayoutsDst->childCount();
+ int maxDepth = layoutsCnt - 1;
+
+ if( maxDepth < 2 ) {
+ maxDepth = 2;
+ }
+
+ widget->spinStickyDepth->setMaxValue(maxDepth);
+/* if( value > maxDepth )
+ setValue(maxDepth);*/
+}
+
+void LayoutConfig::add()
+{
+ TQListViewItem* sel = widget->listLayoutsSrc->selectedItem();
+ if( sel == 0 )
+ return;
+
+ // Create a copy of the sel widget, as one might add the same layout more
+ // 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());
+// disabling temporary: does not work reliable in Qt :(
+// widget->listLayoutsDst->setSelected(sel, true);
+// layoutSelChanged(sel);
+
+ updateStickyLimit();
+ changed();
+}
+
+void LayoutConfig::remove()
+{
+ TQListViewItem* sel = widget->listLayoutsDst->selectedItem();
+ TQListViewItem* newSel = 0;
+
+ if( sel == 0 )
+ return;
+
+ if( sel->itemBelow() )
+ newSel = sel->itemBelow();
+ else
+ if( sel->itemAbove() )
+ newSel = sel->itemAbove();
+
+ delete sel;
+ if( newSel )
+ widget->listLayoutsSrc->setSelected(newSel, true);
+ layoutSelChanged(newSel);
+
+ updateStickyLimit();
+ changed();
+}
+
+void LayoutConfig::moveUp()
+{
+ TQListViewItem* sel = widget->listLayoutsDst->selectedItem();
+ if( sel == 0 || sel->itemAbove() == 0 )
+ return;
+
+ if( sel->itemAbove()->itemAbove() == 0 ) {
+ widget->listLayoutsDst->takeItem(sel);
+ widget->listLayoutsDst->insertItem(sel);
+ widget->listLayoutsDst->setSelected(sel, true);
+ }
+ else
+ sel->moveItem(sel->itemAbove()->itemAbove());
+}
+
+void LayoutConfig::moveDown()
+{
+ TQListViewItem* sel = widget->listLayoutsDst->selectedItem();
+ if( sel == 0 || sel->itemBelow() == 0 )
+ return;
+
+ sel->moveItem(sel->itemBelow());
+}
+
+void LayoutConfig::variantChanged()
+{
+ TQListViewItem* selLayout = widget->listLayoutsDst->selectedItem();
+ if( selLayout == NULL ) {
+ widget->comboVariant->clear();
+ widget->comboVariant->setEnabled(false);
+ return;
+ }
+
+ TQString selectedVariant = widget->comboVariant->currentText();
+ if( selectedVariant == DEFAULT_VARIANT_NAME )
+ selectedVariant = "";
+ selLayout->setText(LAYOUT_COLUMN_VARIANT, selectedVariant);
+}
+
+// helper
+LayoutUnit LayoutConfig::getLayoutUnitKey(TQListViewItem *sel)
+{
+ TQString kbdLayout = sel->text(LAYOUT_COLUMN_MAP);
+ TQString kbdVariant = sel->text(LAYOUT_COLUMN_VARIANT);
+ return LayoutUnit(kbdLayout, kbdVariant);
+}
+
+void LayoutConfig::displayNameChanged(const TQString& newDisplayName)
+{
+ TQListViewItem* selLayout = widget->listLayoutsDst->selectedItem();
+ if( selLayout == NULL )
+ return;
+
+ const LayoutUnit layoutUnitKey = getLayoutUnitKey( selLayout );
+ LayoutUnit& layoutUnit = *m_kxkbConfig.m_layouts.find(layoutUnitKey);
+
+ TQString oldName = selLayout->text(LAYOUT_COLUMN_DISPLAY_NAME);
+
+ if( oldName.isEmpty() )
+ oldName = KxkbConfig::getDefaultDisplayName( layoutUnit );
+
+ if( oldName != newDisplayName ) {
+ kdDebug() << "setting label for " << layoutUnit.toPair() << " : " << newDisplayName << endl;
+ selLayout->setText(LAYOUT_COLUMN_DISPLAY_NAME, newDisplayName);
+ updateIndicator(selLayout);
+ emit changed();
+ }
+}
+
+/** will update flag with label if layout label has been edited
+*/
+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();
+ return;
+ }
+
+
+ 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;
+
+ if( vars.count() > 0 ) {
+ vars.prepend(DEFAULT_VARIANT_NAME);
+ widget->comboVariant->insertStringList(vars);
+
+ TQString variant = sel->text(LAYOUT_COLUMN_VARIANT);
+ if( variant != NULL && variant.isEmpty() == false ) {
+ widget->comboVariant->setCurrentText(variant);
+ }
+ else {
+ widget->comboVariant->setCurrentItem(0);
+ }
+ }
+ updateLayoutCommand();
+}
+
+TQWidget* LayoutConfig::makeOptionsTab()
+{
+ TQListView *listView = widget->listOptions;
+
+ listView->setMinimumHeight(150);
+ listView->setSortColumn( -1 );
+ 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(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()));
+
+ //Create controllers for all options
+ TQDictIterator<char> it(m_rules->options());
+ OptionListItem *parent;
+ for (; it.current(); ++it)
+ {
+ if (!it.currentKey().contains(':'))
+ {
+ if( it.currentKey() == "ctrl" || it.currentKey() == "caps"
+ || it.currentKey() == "altwin" ) {
+ parent = new OptionListItem(listView, i18n( it.current() ),
+ TQCheckListItem::RadioButtonController, it.currentKey());
+ OptionListItem *item = new OptionListItem(parent, i18n( "None" ),
+ TQCheckListItem::RadioButton, "none");
+ item->setState(TQCheckListItem::On);
+ }
+ else {
+ parent = new OptionListItem(listView, i18n( it.current() ),
+ TQCheckListItem::CheckBoxController, it.currentKey());
+ }
+ parent->setOpen(true);
+ m_optionGroups.insert(i18n(it.currentKey().local8Bit()), parent);
+ }
+ }
+
+ it.toFirst();
+ for( ; it.current(); ++it)
+ {
+ TQString key = it.currentKey();
+ int pos = key.find(':');
+ if (pos >= 0)
+ {
+ OptionListItem *parent = m_optionGroups[key.left(pos)];
+ if (parent == NULL )
+ parent = m_optionGroups["misc"];
+ if (parent != NULL) {
+ // 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()),
+ TQCheckListItem::CheckBox, key);
+ }
+ }
+ }
+
+ //scroll->setMinimumSize(450, 330);
+
+ return listView;
+}
+
+void LayoutConfig::updateOptionsCommand()
+{
+ TQString setxkbmap;
+ TQString options = createOptionString();
+
+ if( !options.isEmpty() ) {
+ setxkbmap = "setxkbmap -option "; //-rules " + m_rule
+ if( widget->checkResetOld->isChecked() )
+ setxkbmap += "-option ";
+ setxkbmap += options;
+ }
+ widget->editCmdLineOpt->setText(setxkbmap);
+}
+
+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;
+ }
+ }
+
+ widget->editCmdLine->setText(setxkbmap);
+
+ widget->editDisplayName->setEnabled( sel != NULL );
+ widget->editDisplayName->setText(layoutDisplayName);
+}
+
+void LayoutConfig::changed()
+{
+ updateLayoutCommand();
+ emit TDECModule::changed( true );
+}
+
+
+void LayoutConfig::loadRules()
+{
+ // do we need this ?
+ // this could obly be used if rules are changed and 'Defaults' is pressed
+ delete m_rules;
+ m_rules = new XkbRules();
+
+ TQStringList modelsList;
+ TQDictIterator<char> it(m_rules->models());
+ while (it.current()) {
+ modelsList.append(i18n(it.current()));
+ ++it;
+ }
+ modelsList.sort();
+
+ widget->comboModel->clear();
+ widget->comboModel->insertStringList(modelsList);
+ widget->comboModel->setCurrentItem(0);
+
+ // fill in the additional layouts
+ widget->listLayoutsSrc->clear();
+ widget->listLayoutsDst->clear();
+ TQDictIterator<char> it2(m_rules->layouts());
+
+ while (it2.current())
+ {
+ TQString layout = it2.currentKey();
+ TQString layoutName = it2.current();
+ TQListViewItem *item = new TQListViewItem(widget->listLayoutsSrc);
+
+ item->setPixmap(LAYOUT_COLUMN_FLAG, LayoutIcon::getInstance().findPixmap(layout, true));
+ item->setText(LAYOUT_COLUMN_NAME, i18n(layoutName.latin1()));
+ item->setText(LAYOUT_COLUMN_MAP, layout);
+ ++it2;
+ }
+ widget->listLayoutsSrc->setSorting(LAYOUT_COLUMN_NAME); // from Qt3 TQListView sorts by language
+
+ //TODO: reset options and xkb options
+}
+
+
+TQString LayoutConfig::createOptionString()
+{
+ TQString options;
+ 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);
+ }
+ }
+ }
+ else
+ kdDebug() << "Empty option button for group " << it.currentKey() << endl;
+ }
+ }
+ return options;
+}
+
+
+void LayoutConfig::defaults()
+{
+ loadRules();
+ m_kxkbConfig.setDefaults();
+
+ initUI();
+
+ emit TDECModule::changed( true );
+}
+
+
+OptionListItem::OptionListItem( OptionListItem *parent, const TQString &text,
+ Type tt, const TQString &optionName )
+ : TQCheckListItem( parent, text, tt ), m_OptionName( optionName )
+{
+}
+
+OptionListItem::OptionListItem( TQListView *parent, const TQString &text,
+ Type tt, const TQString &optionName )
+ : TQCheckListItem( parent, text, tt ), m_OptionName( optionName )
+{
+}
+
+OptionListItem * OptionListItem::findChildItem( const TQString& optionName )
+{
+ OptionListItem *child = static_cast<OptionListItem *>( firstChild() );
+
+ while ( child )
+ {
+ if ( child->optionName() == optionName )
+ break;
+ child = static_cast<OptionListItem *>( child->nextSibling() );
+ }
+
+ return child;
+}
+
+
+extern "C"
+{
+ KDE_EXPORT TDECModule *create_keyboard_layout(TQWidget *parent, const char *)
+ {
+ return new LayoutConfig(parent, "kcmlayout");
+ }
+
+ KDE_EXPORT TDECModule *create_keyboard(TQWidget *parent, const char *)
+ {
+ return new KeyboardConfig(parent, "kcmlayout");
+ }
+
+ KDE_EXPORT void init_keyboard()
+ {
+ KeyboardConfig::init_keyboard();
+
+ KxkbConfig m_kxkbConfig;
+ m_kxkbConfig.load(KxkbConfig::LOAD_INIT_OPTIONS);
+
+ if( m_kxkbConfig.m_useKxkb == true ) {
+ kapp->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 0// do not remove!
+// please don't change/fix messages below
+// they're taken from XFree86 as is and should stay the same
+ I18N_NOOP("Brazilian ABNT2");
+ I18N_NOOP("Dell 101-key PC");
+ I18N_NOOP("Everex STEPnote");
+ I18N_NOOP("Generic 101-key PC");
+ I18N_NOOP("Generic 102-key (Intl) PC");
+ I18N_NOOP("Generic 104-key PC");
+ I18N_NOOP("Generic 105-key (Intl) PC");
+ I18N_NOOP("Japanese 106-key");
+ I18N_NOOP("Microsoft Natural");
+ I18N_NOOP("Northgate OmniKey 101");
+ I18N_NOOP("Keytronic FlexPro");
+ I18N_NOOP("Winbook Model XP5");
+
+// These options are from XFree 4.1.0
+ I18N_NOOP("Group Shift/Lock behavior");
+ I18N_NOOP("R-Alt switches group while pressed");
+ I18N_NOOP("Right Alt key changes group");
+ I18N_NOOP("Caps Lock key changes group");
+ I18N_NOOP("Menu key changes group");
+ I18N_NOOP("Both Shift keys together change group");
+ I18N_NOOP("Control+Shift changes group");
+ I18N_NOOP("Alt+Control changes group");
+ I18N_NOOP("Alt+Shift changes group");
+ I18N_NOOP("Control Key Position");
+ I18N_NOOP("Make CapsLock an additional Control");
+ I18N_NOOP("Swap Control and Caps Lock");
+ I18N_NOOP("Control key at left of 'A'");
+ I18N_NOOP("Control key at bottom left");
+ I18N_NOOP("Use keyboard LED to show alternative group");
+ I18N_NOOP("Num_Lock LED shows alternative group");
+ I18N_NOOP("Caps_Lock LED shows alternative group");
+ I18N_NOOP("Scroll_Lock LED shows alternative group");
+
+//these seem to be new in XFree86 4.2.0
+ I18N_NOOP("Left Win-key switches group while pressed");
+ I18N_NOOP("Right Win-key switches group while pressed");
+ I18N_NOOP("Both Win-keys switch group while pressed");
+ I18N_NOOP("Left Win-key changes group");
+ I18N_NOOP("Right Win-key changes group");
+ I18N_NOOP("Third level choosers");
+ I18N_NOOP("Press Right Control to choose 3rd level");
+ I18N_NOOP("Press Menu key to choose 3rd level");
+ I18N_NOOP("Press any of Win-keys to choose 3rd level");
+ I18N_NOOP("Press Left Win-key to choose 3rd level");
+ I18N_NOOP("Press Right Win-key to choose 3rd level");
+ I18N_NOOP("CapsLock key behavior");
+ I18N_NOOP("uses internal capitalization. Shift cancels Caps.");
+ I18N_NOOP("uses internal capitalization. Shift doesn't cancel Caps.");
+ I18N_NOOP("acts as Shift with locking. Shift cancels Caps.");
+ I18N_NOOP("acts as Shift with locking. Shift doesn't cancel Caps.");
+ I18N_NOOP("Alt/Win key behavior");
+ I18N_NOOP("Add the standard behavior to Menu key.");
+ I18N_NOOP("Alt and Meta on the Alt keys (default).");
+ I18N_NOOP("Meta is mapped to the Win-keys.");
+ I18N_NOOP("Meta is mapped to the left Win-key.");
+ I18N_NOOP("Super is mapped to the Win-keys (default).");
+ I18N_NOOP("Hyper is mapped to the Win-keys.");
+ I18N_NOOP("Right Alt is Compose");
+ I18N_NOOP("Right Win-key is Compose");
+ I18N_NOOP("Menu is Compose");
+
+//these seem to be new in XFree86 4.3.0
+ I18N_NOOP( "Both Ctrl keys together change group" );
+ I18N_NOOP( "Both Alt keys together change group" );
+ I18N_NOOP( "Left Shift key changes group" );
+ I18N_NOOP( "Right Shift key changes group" );
+ I18N_NOOP( "Right Ctrl key changes group" );
+ I18N_NOOP( "Left Alt key changes group" );
+ I18N_NOOP( "Left Ctrl key changes group" );
+ I18N_NOOP( "Compose Key" );
+
+//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("Miscellaneous compatibility options");
+ I18N_NOOP("Right Control key works as Right Alt");
+
+//these seem to be in x.org and Debian XFree86 4.3
+ I18N_NOOP("Right Alt key switches group while pressed");
+ I18N_NOOP("Left Alt key switches group while pressed");
+ I18N_NOOP("Press Right Alt-key to choose 3rd level");
+
+//new in Xorg 6.9
+ I18N_NOOP("R-Alt switches group while pressed.");
+ I18N_NOOP("Left Alt key switches group while pressed.");
+ I18N_NOOP("Left Win-key switches group while pressed.");
+ I18N_NOOP("Right Win-key switches group while pressed.");
+ I18N_NOOP("Both Win-keys switch group while pressed.");
+ I18N_NOOP("Right Ctrl key switches group while pressed.");
+ I18N_NOOP("Right Alt key changes group.");
+ I18N_NOOP("Left Alt key changes group.");
+ I18N_NOOP("CapsLock key changes group.");
+ I18N_NOOP("Shift+CapsLock changes group.");
+ I18N_NOOP("Both Shift keys together change group.");
+ I18N_NOOP("Both Alt keys together change group.");
+ I18N_NOOP("Both Ctrl keys together change group.");
+ I18N_NOOP("Ctrl+Shift changes group.");
+ I18N_NOOP("Alt+Ctrl changes group.");
+ I18N_NOOP("Alt+Shift changes group.");
+ I18N_NOOP("Menu key changes group.");
+ I18N_NOOP("Left Win-key changes group.");
+ I18N_NOOP("Right Win-key changes group.");
+ I18N_NOOP("Left Shift key changes group.");
+ I18N_NOOP("Right Shift key changes group.");
+ I18N_NOOP("Left Ctrl key changes group.");
+ I18N_NOOP("Right Ctrl key changes group.");
+ I18N_NOOP("Press Right Ctrl to choose 3rd level.");
+ I18N_NOOP("Press Menu key to choose 3rd level.");
+ I18N_NOOP("Press any of Win-keys to choose 3rd level.");
+ I18N_NOOP("Press Left Win-key to choose 3rd level.");
+ I18N_NOOP("Press Right Win-key to choose 3rd level.");
+ I18N_NOOP("Press any of Alt keys to choose 3rd level.");
+ I18N_NOOP("Press Left Alt key to choose 3rd level.");
+ I18N_NOOP("Press Right Alt key to choose 3rd level.");
+ I18N_NOOP("Ctrl key position");
+ I18N_NOOP("Make CapsLock an additional Ctrl.");
+ I18N_NOOP("Swap Ctrl and CapsLock.");
+ I18N_NOOP("Ctrl key at left of 'A'");
+ I18N_NOOP("Ctrl key at bottom left");
+ I18N_NOOP("Right Ctrl key works as Right Alt.");
+ I18N_NOOP("Use keyboard LED to show alternative group.");
+ I18N_NOOP("NumLock LED shows alternative group.");
+ I18N_NOOP("CapsLock LED shows alternative group.");
+ I18N_NOOP("ScrollLock LED shows alternative group.");
+ I18N_NOOP("CapsLock uses internal capitalization. Shift cancels CapsLock.");
+ I18N_NOOP("CapsLock uses internal capitalization. Shift doesn't cancel CapsLock.");
+ I18N_NOOP("CapsLock acts as Shift with locking. Shift cancels CapsLock.");
+ I18N_NOOP("CapsLock acts as Shift with locking. Shift doesn't cancel CapsLock.");
+ I18N_NOOP("CapsLock just locks the Shift modifier.");
+ I18N_NOOP("CapsLock toggles normal capitalization of alphabetic characters.");
+ I18N_NOOP("CapsLock toggles Shift so all keys are affected.");
+ I18N_NOOP("Alt and Meta are on the Alt keys (default).");
+ I18N_NOOP("Alt is mapped to the right Win-key and Super to Menu.");
+ I18N_NOOP("Compose key position");
+ I18N_NOOP("Right Alt is Compose.");
+ I18N_NOOP("Right Win-key is Compose.");
+ I18N_NOOP("Menu is Compose.");
+ I18N_NOOP("Right Ctrl is Compose.");
+ I18N_NOOP("Caps Lock is Compose.");
+ I18N_NOOP("Special keys (Ctrl+Alt+&lt;key&gt;) handled in a server.");
+ I18N_NOOP("Adding the EuroSign to certain keys");
+ I18N_NOOP("Add the EuroSign to the E key.");
+ I18N_NOOP("Add the EuroSign to the 5 key.");
+ I18N_NOOP("Add the EuroSign to the 2 key.");
+#endif