cosmetix
[jrugr.git] / src / xkbconf.cpp
blobe7347903d02d01f811bd53e8cede40e0d8f142b6
1 ////////////////////////////////////////
2 // File : xkbconf.cpp //
3 // Written by: disels@gmail.com //
4 // Copyright : GPL //
5 ////////////////////////////////////////
6 #include "xkbconf.h"
9 QXKBconf::QXKBconf (QWidget *parent) : QDialog(parent) {
10 xkb_conf.setupUi(this);
11 // initialize the binding between list and stackedWidget
12 xkb_conf.listWidget->setCurrentRow(0);
13 QSettings qxkb(QDir::homePath()+"/.config/qxkb.cfg", QSettings::IniFormat, this);
14 qxkb.beginGroup("Style");
15 theme=qxkb.value("path").toString();
16 ico_path = theme+"/language/";
17 qxkb.endGroup(); //Style
18 qDebug() << "Theme " << theme;
19 qDebug() << "Icons " << ico_path;
20 xkbConf = X11tools::loadXKBconf();
22 connect(xkb_conf.buttonBox, SIGNAL(rejected()), this, SLOT(close()));
23 connect(xkb_conf.buttonBox, SIGNAL(accepted()), SLOT(apply()));
24 connect(xkb_conf.radioButton, SIGNAL(clicked(bool)), SLOT(statSelect(bool)));
25 connect(xkb_conf.radioButton_2, SIGNAL(clicked(bool)), SLOT(statSelect(bool)));
26 connect(xkb_conf.radioButton_3, SIGNAL(clicked(bool)), SLOT(statSelect(bool)));
28 xkb_conf.btnAdd->setEnabled(false);
29 xkb_conf.btnAdd->setIcon(QIcon::fromTheme(QString("arrow-right"), QIcon(theme+"/add.png")));
31 xkb_conf.btnRemove->setEnabled(false);
32 xkb_conf.btnRemove->setIcon(QIcon::fromTheme(QString("arrow-left"), QIcon(theme+"/rem.png")));
34 xkb_conf.btnUp->setEnabled(false);
35 xkb_conf.btnUp->setIcon(QIcon::fromTheme(QString("arrow-up"), QIcon(theme+"/up.png")));
37 xkb_conf.btnDown->setEnabled(false);
38 xkb_conf.btnDown->setIcon(QIcon::fromTheme(QString("arrow-down"), QIcon(theme+"/down.png")));
40 if (!setStat()) return;
41 initXKBTab();
42 xkbConf->lockKeys = true;
46 QXKBconf::~QXKBconf () {
47 delete xkbConf;
51 void QXKBconf::apply () {
52 X11tools::saveXKBconf(xkbConf);
54 if (xkb_conf.stackedWidget->currentIndex() == 0) {
55 QStringList parm = xkb_conf.editCmdLine->text().split(" ");
56 int qpres;
58 parm.removeAt(0);
59 qDebug() << "parm:" << parm;
60 qpres = 0;//QProcess::execute("setxkbmap", parm);
61 qDebug() << "Set XKB result" << qpres;
62 } else if (xkb_conf.stackedWidget->currentIndex() == 2) {
63 QStringList parm = xkb_conf.editCmdLineOpt->text().split(" ");
64 int qpres;
66 parm.removeAt(0);
67 qDebug() << "parm:" << parm;
68 qpres = 0;//QProcess::execute("setxkbmap", parm);
69 qDebug() << "Set XKB result" << qpres;
71 //qDebug()<<"Close";
72 //close();
73 emit saveConfig();
77 void QXKBconf::statSelect (bool check) {
78 Q_UNUSED(check)
80 if (xkb_conf.radioButton->isChecked()) xkbConf->status = 2;
81 if (xkb_conf.radioButton_2->isChecked()) xkbConf->status = 1;
82 if (xkb_conf.radioButton_3->isChecked()) xkbConf->status = 0;
83 if (!setStat()) return;
84 initXKBTab();
88 void QXKBconf::initXKBTab () {
89 connect(xkb_conf.btnAdd, SIGNAL(clicked()), SLOT(addLayout()));
90 connect(xkb_conf.btnRemove, SIGNAL(clicked()), SLOT(delLayout()));
91 load_rules();
92 //set comboModel list
93 QHashIterator<QString, QString> i(curRule->models);
94 while (i.hasNext()) { i.next(); listModels << i.value(); }
95 // set avaleble language
96 srcLayoutModel = new SrcLayoutModel(curRule, ico_path, this);
97 qDebug() << ico_path;
98 dstLayoutModel = new DstLayoutModel(curRule, xkbConf, ico_path, this);
99 xkbOptionsModel = new XkbOptionsModel(curRule, xkbConf, this);
100 xkb_conf.comboModel->addItems(listModels);
101 xkb_conf.comboModel->setCurrentIndex(listModels.indexOf(curRule->models.value(xkbConf->model)));
102 xkb_conf.srcTableView->setModel(srcLayoutModel);
103 xkb_conf.srcTableView->resizeColumnToContents(0);
104 xkb_conf.dstTableView->setModel(dstLayoutModel);
105 xkb_conf.dstTableView->resizeColumnToContents(0);
106 xkb_conf.xkbOptionsTreeView->setModel(xkbOptionsModel);
107 xkb_conf.xkbOptionsTreeView->header()->hide();
108 xkb_conf.xkbOptionsTreeView->expandAll();
110 for (int f = 0; f < xkbConf->options.count(); ++f) {
111 if (xkbConf->options[f].contains("grp:")) xkb_conf.btnXkbShortcut->setText(tr("Defined"));
112 if (xkbConf->options[f].contains("lv3:")) xkb_conf.btnXkbShortcut3d->setText(tr("Defined"));
115 switch (xkbConf->switching) {
116 case GLOBAL_LAYOUT: xkb_conf.rdBtnSwitchGlobal->setChecked(true); break;
117 case APP_LAYOUT: xkb_conf.rdBtnSwitchPerApp->setChecked(true); break;
118 case WIN_LAYOUT: xkb_conf.rdBtnSwitchPerWin->setChecked(true); break;
121 connect(xkb_conf.srcTableView, SIGNAL(clicked (const QModelIndex &)), SLOT(srcClick(QModelIndex)));
122 connect(xkb_conf.dstTableView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), SLOT(dstClick()));
123 connect(xkb_conf.comboModel, SIGNAL(currentIndexChanged (int)) , SLOT(comboModelCh(int)));
124 connect(xkb_conf.comboVariant, SIGNAL(currentIndexChanged (int)), SLOT(comboVariantCh(int)));
125 connect(xkb_conf.btnUp, SIGNAL(clicked()), SLOT(layoutUp()));
126 connect(xkb_conf.btnDown, SIGNAL(clicked()), SLOT(layoutDown()));
127 connect(xkbOptionsModel, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), SLOT(xkbOptionsChanged(const QModelIndex &, const QModelIndex &)));
128 connect( xkb_conf.btnXkbShortcut, SIGNAL(clicked()), SLOT(xkbShortcutPressed()));
129 connect(xkb_conf.btnXkbShortcut3d, SIGNAL(clicked()), SLOT(xkbShortcut3dPressed()));
131 setCmdLine();
132 updateOptionsCommand();
136 bool QXKBconf::setStat () {
137 switch (xkbConf->status) {
138 case DONT_USE_XKB:
139 xkb_conf.grpIndicatorOptions->setEnabled(false);
140 xkb_conf.grpLayouts->setEnabled(false);
141 xkb_conf.page_2->setEnabled(false);
142 xkb_conf.page_3->setEnabled(false);
143 xkb_conf.radioButton->setChecked(false);
144 xkb_conf.radioButton_2->setChecked(false);
145 xkb_conf.radioButton_3->setChecked(true);
146 return false;
147 case ONLY_INDICATION:
148 xkb_conf.grpIndicatorOptions->setEnabled(true);
149 xkb_conf.grpLayouts->setEnabled(false);
150 xkb_conf.page_2->setEnabled(false);
151 xkb_conf.page_3->setEnabled(false);
152 xkb_conf.radioButton->setChecked(false);
153 xkb_conf.radioButton_2->setChecked(true);
154 xkb_conf.radioButton_3->setChecked(false);
155 xkb_conf.chkShowFlag->setChecked(xkbConf->showFlag);
156 xkb_conf.chkShowSingle->setChecked(xkbConf->showSingle);
157 connect(xkb_conf.chkShowFlag, SIGNAL(clicked()), SLOT(setFlagUse()));
158 connect(xkb_conf.chkShowSingle, SIGNAL(clicked()), SLOT(setSinglShow()));
159 return false;
160 case USE_XKB:
161 xkb_conf.grpIndicatorOptions->setEnabled(true);
162 xkb_conf.grpLayouts->setEnabled(true);
163 xkb_conf.page_2->setEnabled(true);//not work yet
164 xkb_conf.page_3->setEnabled(true);
165 xkb_conf.radioButton->setChecked(true);
166 xkb_conf.radioButton_2->setChecked(false);
167 xkb_conf.radioButton_3->setChecked(false);
168 xkb_conf.chkShowFlag->setChecked(xkbConf->showFlag);
169 xkb_conf.chkShowSingle->setChecked(xkbConf->showSingle);
170 connect(xkb_conf.chkShowFlag, SIGNAL(clicked()), SLOT(setFlagUse()));
171 connect(xkb_conf.chkShowSingle, SIGNAL(clicked()), SLOT(setSinglShow()));
172 return true;
174 return false;
178 void QXKBconf::setCmdLine () {
179 QString cmdLine = "setxkbmap -model "+xkbConf->model;
181 cmdLine += " -layout ";
182 for (int f = 0;f < xkbConf->layouts.size(); ++f) {
183 cmdLine += xkbConf->layouts[f].layout;
184 if (f < xkbConf->layouts.size()-1) cmdLine += ',';
187 cmdLine += " -variant ";
188 for (int f = 0; f < xkbConf->layouts.size(); ++f) {
189 cmdLine += xkbConf->layouts[f].variant;
190 if (f < xkbConf->layouts.size()-1) cmdLine += ',';
192 xkb_conf.editCmdLine->setText(cmdLine);
196 void QXKBconf::addLayout () {
197 LayoutUnit lu;
198 QItemSelectionModel *selectionModel = xkb_conf.srcTableView->selectionModel();
200 if (selectionModel == NULL || !selectionModel->hasSelection() || xkbConf->layouts.size() >= 4) return;
201 QModelIndexList selected = selectionModel->selectedRows();
202 qDebug() << "selected : " << selected;
203 QString layout = srcLayoutModel->getLayoutAt(selected[0].row());
204 if (layout.isEmpty() || xkbConf->layouts.contains(layout)) return;
205 lu.layout = layout;
206 xkbConf->layouts.append(lu);
207 dstLayoutModel->reset();
208 xkb_conf.dstTableView->update();
209 setCmdLine();
213 void QXKBconf::delLayout () {
214 QItemSelectionModel *selectionModel = xkb_conf.dstTableView->selectionModel();
215 if (selectionModel == NULL || !selectionModel->hasSelection()|| xkbConf->layouts.size() == 0) return;
216 QModelIndexList selected = selectionModel->selectedRows();
217 xkbConf->layouts.removeAt(selected[0].row());
218 dstLayoutModel->reset();
219 xkb_conf.dstTableView->update();
220 setCmdLine();
224 void QXKBconf::srcClick (QModelIndex index) {
225 Q_UNUSED(index)
226 xkb_conf.btnAdd->setEnabled(true);
230 void QXKBconf::dstClick () {
231 int row = getSelectedDstLayout();
232 xkb_conf.btnRemove->setEnabled(row!=-1);
233 int el_count = xkb_conf.comboVariant->count();
234 for (int f = el_count; f > 0; --f) xkb_conf.comboVariant->removeItem(f);
235 //xkb_conf.comboVariant->clear(); some sheet seg fail in use
236 xkb_conf.comboVariant->setEnabled(row!=-1);
237 xkb_conf.btnUp->setEnabled(row!=-1);
238 xkb_conf.btnDown->setEnabled(row!=-1);
239 if (row == -1) return;
240 QString layout = xkbConf->layouts[row].layout;
241 qDebug() << layout;
242 variants = X11tools::getVariants(layout, X11tools::findX11Dir());
243 qDebug() << "QXKBconf:addItem";
244 if (xkb_conf.comboVariant->count() == 0) {
245 xkb_conf.comboVariant->addItem(tr("Default"), "Default");
246 xkb_conf.comboVariant->setItemData(0, tr("Default"), Qt::ToolTipRole);
247 xkb_conf.comboVariant->setItemText(0, tr("Default"));
249 if (variants.count() > 0) {
250 for (int f = 0; f < variants.count(); ++f) {
251 xkb_conf.comboVariant->addItem(variants[f].description, variants[f].name);
252 xkb_conf.comboVariant->setItemData(xkb_conf.comboVariant->count()-1, variants[f].description, Qt::ToolTipRole);
254 QString variant = xkbConf->layouts[row].variant;
255 if (variant != NULL && !variant.isEmpty()) {
256 int idx = xkb_conf.comboVariant->findData(variant);
257 xkb_conf.comboVariant->setCurrentIndex(idx);
258 } else {
259 xkb_conf.comboVariant->setCurrentIndex(0);
265 bool QXKBconf::load_rules () {
266 QString x11dir = X11tools::findX11Dir();
267 if (x11dir.isNull() || x11dir.isEmpty()) return false;
268 QString rulesFile = X11tools::findXkbRulesFile(x11dir, QX11Info::display());
269 if (rulesFile.isNull() || rulesFile.isEmpty()) return false;
270 curRule = X11tools::loadRules(rulesFile, false);
271 if (curRule == NULL) return false;
272 return true;
276 void QXKBconf::comboModelCh (int index) {
277 xkbConf->model= curRule->models.key(xkb_conf.comboModel->itemText(index));
278 setCmdLine();
282 void QXKBconf::comboVariantCh (int index) {
283 if (index == 0) xkbConf->layouts[getSelectedDstLayout()].variant = "";
284 else if (index < variants.count()) xkbConf->layouts[getSelectedDstLayout()].variant = variants.at(index-1).name; // it sometimes crashed here with "index out of bounds"
285 setCmdLine();
289 int QXKBconf::getSelectedDstLayout () {
290 QItemSelectionModel *selectionModel = xkb_conf.dstTableView->selectionModel();
291 if (selectionModel == NULL || !selectionModel->hasSelection()) return -1;
292 QModelIndexList selected = selectionModel->selectedRows();
293 int row = selected.count() > 0 ? selected[0].row() : -1;
294 return row;
298 void QXKBconf::setFlagUse () {
299 xkbConf->showFlag = xkb_conf.chkShowFlag->isChecked();
303 void QXKBconf::setSinglShow () {
304 xkbConf->showSingle = xkb_conf.chkShowSingle->isChecked();
308 void QXKBconf::layoutUp () {
309 int row = getSelectedDstLayout();
310 if (row>0) {
311 LayoutUnit lu = xkbConf->layouts[row-1];
312 xkbConf->layouts[row-1] = xkbConf->layouts[row];
313 xkbConf->layouts[row] = lu;
314 dstLayoutModel->reset();
315 xkb_conf.dstTableView->update();
316 setCmdLine();
321 void QXKBconf::layoutDown () {
322 int row = getSelectedDstLayout();
323 if (row < xkbConf->layouts.count()-1 && row > -1) {
324 LayoutUnit lu = xkbConf->layouts[row+1];
325 xkbConf->layouts[row+1]=xkbConf->layouts[row];
326 xkbConf->layouts[row]=lu;
327 dstLayoutModel->reset();
328 setCmdLine();
333 void QXKBconf::updateOptionsCommand () {
334 QString cmd = "setxkbmap";
335 if (xkb_conf.checkResetOld->isChecked()) cmd += " -option";
336 if (!xkbConf->options.empty()) {
337 cmd += " -option ";
338 cmd += xkbConf->options.join(",");
340 xkb_conf.editCmdLineOpt->setText(cmd);
344 void QXKBconf::xkbOptionsChanged (const QModelIndex &topLeft, const QModelIndex &bottomRight) {
345 Q_UNUSED(topLeft)
346 Q_UNUSED(bottomRight)
347 updateOptionsCommand();
351 void QXKBconf::closeEvent (QCloseEvent *event) {
352 xkbConf->lockKeys = false;
353 hide();
354 event->ignore();
358 void QXKBconf::xkbShortcutPressed () {
359 xkb_conf.stackedWidget->setCurrentIndex(2);
360 xkbOptionsModel->gotoGroup("grp", xkb_conf.xkbOptionsTreeView);
364 void QXKBconf::xkbShortcut3dPressed () {
365 xkb_conf.stackedWidget->setCurrentIndex(2);
366 xkbOptionsModel->gotoGroup("lv3", xkb_conf.xkbOptionsTreeView);
370 void QXKBconf::statSwitching (bool check) {
371 Q_UNUSED(check)
372 if (xkb_conf.rdBtnSwitchGlobal->isChecked()) xkbConf->switching = 2;
373 if (xkb_conf.rdBtnSwitchPerApp->isChecked()) xkbConf->switching = 1;
374 if (xkb_conf.rdBtnSwitchPerWin->isChecked()) xkbConf->switching = 0;
378 void QXKBconf::getHotKeys (XEvent *event) {
379 XKeyEvent *keys = (XKeyEvent *)event;
381 switch (XKeycodeToKeysym(QX11Info::display(), keys->keycode, 0)) {
382 case XK_Shift_L:
383 case XK_Shift_R:
384 mods = "Shift";
385 key.clear();
386 break;
387 case XK_Control_L:
388 case XK_Control_R:
389 mods = "Ctrl";
390 key.clear();
391 break;
392 case XK_Alt_L:
393 case XK_Alt_R:
394 mods = "Alt";
395 key.clear();
396 break;
397 default:
398 key = QString(XKeysymToString(XKeycodeToKeysym(QX11Info::display(), keys->keycode, 0)));
399 if (key.count() < 2) key = key.toUpper();
401 if (!mods.isEmpty()) hot_keys =mods+"+"+key;
402 else if (key.count() > 1) hot_keys = key;
406 void QXKBconf::clearHotKeys () {
407 qDebug() << "QXKBconf:: Kurrent mods " << mods;
408 if (mods.isEmpty()) return;
409 qDebug() << "QXKBconf:: Kurrent key " << key;
410 if (!key.isEmpty()) return;
411 mods.clear();