seems that 'per app' and 'per window' modes are working ok
[jrugr.git] / src / jrugrconfui.cpp
blob1dda8d113452673cb43307f2c8a446d6c1ea3319
1 ////////////////////////////////////////
2 // Copyright : GPL //
3 ////////////////////////////////////////
4 #include "jrugrconfui.h"
7 JrugrConfigForm::JrugrConfigForm (QWidget *parent) : QDialog(parent) {
8 setAttribute(Qt::WA_DeleteOnClose);
9 //
10 cfgUI.setupUi(this);
11 // initialize the binding between list and stackedWidget
12 cfgUI.listWidget->setCurrentRow(0);
15 QSettings settings(QDir::homePath()+"/.config/jrugr.cfg", QSettings::IniFormat, this);
16 settings.beginGroup("Style");
17 mTheme = settings.value("path").toString();
18 mIcoPath = mTheme+"/language/";
19 settings.endGroup(); //Style
21 qDebug() << "Theme " << mTheme;
22 qDebug() << "Icons " << mIcoPath;
24 mJCfg = X11Tools::loadXKBconf();
26 switch (mJCfg->switching) {
27 case GLOBAL_LAYOUT: cfgUI.rbPolicyGlobal->setChecked(true); break;
28 case APP_LAYOUT: cfgUI.rbPolicyApp->setChecked(true); break;
29 case WIN_LAYOUT: cfgUI.rbPolicyWin->setChecked(true); break;
30 case DESK_LAYOUT: cfgUI.rbPolicyDesk->setChecked(true); break;
33 connect(cfgUI.buttonBox, SIGNAL(rejected()), this, SLOT(close()));
34 connect(cfgUI.buttonBox, SIGNAL(accepted()), SLOT(apply()));
35 connect(cfgUI.rbUseXkb, SIGNAL(clicked(bool)), SLOT(statSelect(bool)));
36 connect(cfgUI.rbIndicator, SIGNAL(clicked(bool)), SLOT(statSelect(bool)));
37 connect(cfgUI.rbNoXkb, SIGNAL(clicked(bool)), SLOT(statSelect(bool)));
39 connect(cfgUI.rbPolicyGlobal, SIGNAL(clicked(bool)), SLOT(statSwitching(bool)));
40 connect(cfgUI.rbPolicyApp, SIGNAL(clicked(bool)), SLOT(statSwitching(bool)));
41 connect(cfgUI.rbPolicyWin, SIGNAL(clicked(bool)), SLOT(statSwitching(bool)));
42 connect(cfgUI.rbPolicyDesk, SIGNAL(clicked(bool)), SLOT(statSwitching(bool)));
44 cfgUI.btnAdd->setEnabled(false);
45 cfgUI.btnAdd->setIcon(QIcon::fromTheme(QString("arrow-right"), QIcon(mTheme+"/add.png")));
47 cfgUI.btnRemove->setEnabled(false);
48 cfgUI.btnRemove->setIcon(QIcon::fromTheme(QString("arrow-left"), QIcon(mTheme+"/rem.png")));
50 cfgUI.btnUp->setEnabled(false);
51 cfgUI.btnUp->setIcon(QIcon::fromTheme(QString("arrow-up"), QIcon(mTheme+"/up.png")));
53 cfgUI.btnDown->setEnabled(false);
54 cfgUI.btnDown->setIcon(QIcon::fromTheme(QString("arrow-down"), QIcon(mTheme+"/down.png")));
56 if (!setStat()) return;
57 initXKBTab();
61 JrugrConfigForm::~JrugrConfigForm () {
62 delete mJCfg;
66 void JrugrConfigForm::apply () {
67 X11Tools::saveXKBconf(mJCfg);
69 if (cfgUI.stackedWidget->currentIndex() == 0 && mJCfg->status == USE_XKB) {
70 QStringList parm = cfgUI.editCmdLine->text().split(" ");
71 int qpres;
73 parm.removeAt(0);
74 qDebug() << "parm:" << parm;
75 qpres = QProcess::execute("setxkbmap", parm);
76 qDebug() << "Set XKB result" << qpres;
77 } else if (cfgUI.stackedWidget->currentIndex() == 2 && mJCfg->status == USE_XKB) {
78 QStringList parm = cfgUI.editCmdLineOpt->text().split(" ");
79 int qpres;
81 parm.removeAt(0);
82 qDebug() << "parm:" << parm;
83 qpres = QProcess::execute("setxkbmap", parm);
84 qDebug() << "Set XKB result" << qpres;
86 //qDebug()<<"Close";
87 //close();
88 emit saveConfig();
92 void JrugrConfigForm::statSelect (bool check) {
93 Q_UNUSED(check)
95 if (cfgUI.rbUseXkb->isChecked()) mJCfg->status = USE_XKB;
96 if (cfgUI.rbIndicator->isChecked()) mJCfg->status = ONLY_INDICATION;
97 if (cfgUI.rbNoXkb->isChecked()) mJCfg->status = DONT_USE_XKB;
98 if (!setStat()) return;
99 initXKBTab();
103 void JrugrConfigForm::initXKBTab () {
104 connect(cfgUI.btnAdd, SIGNAL(clicked()), SLOT(addLayout()));
105 connect(cfgUI.btnRemove, SIGNAL(clicked()), SLOT(delLayout()));
106 loadRules();
107 //set comboModel list
108 QHashIterator<QString, QString> i(mCurRule->models);
109 while (i.hasNext()) { i.next(); mModelList << i.value(); }
110 // set avaleble language
111 mSrcLayoutModel = new SrcLayoutModel(mCurRule, mIcoPath, this);
112 qDebug() << mIcoPath;
113 mDstLayoutModel = new DstLayoutModel(mCurRule, mJCfg, mIcoPath, this);
114 mXkbOptionsModel = new XkbOptionsModel(mCurRule, mJCfg, this);
115 cfgUI.comboModel->addItems(mModelList);
116 cfgUI.comboModel->setCurrentIndex(mModelList.indexOf(mCurRule->models.value(mJCfg->model)));
117 cfgUI.srcTableView->setModel(mSrcLayoutModel);
118 cfgUI.srcTableView->resizeColumnToContents(0);
119 cfgUI.dstTableView->setModel(mDstLayoutModel);
120 cfgUI.dstTableView->resizeColumnToContents(0);
121 cfgUI.xkbOptionsTreeView->setModel(mXkbOptionsModel);
122 cfgUI.xkbOptionsTreeView->header()->hide();
123 cfgUI.xkbOptionsTreeView->expandAll();
125 connect(cfgUI.srcTableView, SIGNAL(clicked(const QModelIndex &)), SLOT(srcClick(QModelIndex)));
126 connect(cfgUI.dstTableView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), SLOT(dstClick()));
127 connect(cfgUI.comboModel, SIGNAL(currentIndexChanged (int)) , SLOT(comboModelCh(int)));
128 connect(cfgUI.comboVariant, SIGNAL(currentIndexChanged (int)), SLOT(comboVariantCh(int)));
129 connect(cfgUI.btnUp, SIGNAL(clicked()), SLOT(layoutUp()));
130 connect(cfgUI.btnDown, SIGNAL(clicked()), SLOT(layoutDown()));
131 connect(mXkbOptionsModel, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), SLOT(xkbOptionsChanged(const QModelIndex &, const QModelIndex &)));
133 setCmdLine();
134 updateOptionsCommand();
138 bool JrugrConfigForm::setStat () {
139 if (mJCfg->status != DONT_USE_XKB) {
140 cfgUI.chkShowFlag->setChecked(mJCfg->showFlag);
141 cfgUI.chkShowSingle->setChecked(mJCfg->showSingle);
142 connect(cfgUI.chkShowFlag, SIGNAL(clicked()), SLOT(setFlagUse()));
143 connect(cfgUI.chkShowSingle, SIGNAL(clicked()), SLOT(setSinglShow()));
146 switch (mJCfg->status) {
147 case DONT_USE_XKB:
148 cfgUI.grpIndicatorOptions->setEnabled(false);
149 cfgUI.grpLayouts->setEnabled(false);
150 cfgUI.pgPolicy->setEnabled(false);
151 cfgUI.pgXkb->setEnabled(false);
152 cfgUI.rbUseXkb->setChecked(false);
153 cfgUI.rbIndicator->setChecked(false);
154 cfgUI.rbNoXkb->setChecked(true);
155 return false;
156 case ONLY_INDICATION:
157 cfgUI.grpIndicatorOptions->setEnabled(true);
158 cfgUI.grpLayouts->setEnabled(false);
159 cfgUI.pgPolicy->setEnabled(true);
160 cfgUI.pgXkb->setEnabled(false);
161 cfgUI.rbUseXkb->setChecked(false);
162 cfgUI.rbIndicator->setChecked(true);
163 cfgUI.rbNoXkb->setChecked(false);
164 return false;
165 case USE_XKB:
166 cfgUI.grpIndicatorOptions->setEnabled(true);
167 cfgUI.grpLayouts->setEnabled(true);
168 cfgUI.pgPolicy->setEnabled(true);
169 cfgUI.pgXkb->setEnabled(true);
170 cfgUI.rbUseXkb->setChecked(true);
171 cfgUI.rbIndicator->setChecked(false);
172 cfgUI.rbNoXkb->setChecked(false);
173 return true;
175 return false;
179 void JrugrConfigForm::setCmdLine () {
180 QString cmdLine = "setxkbmap -model "+mJCfg->model;
182 cmdLine += " -layout ";
183 for (int f = 0;f < mJCfg->layouts.size(); ++f) {
184 cmdLine += mJCfg->layouts[f].layout;
185 if (f < mJCfg->layouts.size()-1) cmdLine += ',';
188 cmdLine += " -variant ";
189 for (int f = 0; f < mJCfg->layouts.size(); ++f) {
190 cmdLine += mJCfg->layouts[f].variant;
191 if (f < mJCfg->layouts.size()-1) cmdLine += ',';
193 cfgUI.editCmdLine->setText(cmdLine);
197 void JrugrConfigForm::addLayout () {
198 LayoutUnit lu;
199 QItemSelectionModel *selectionModel = cfgUI.srcTableView->selectionModel();
201 if (selectionModel == NULL || !selectionModel->hasSelection() || mJCfg->layouts.size() >= 4) return;
202 QModelIndexList selected = selectionModel->selectedRows();
203 qDebug() << "selected : " << selected;
204 QString layout = mSrcLayoutModel->getLayoutAt(selected[0].row());
205 if (layout.isEmpty() || mJCfg->layouts.contains(layout)) return;
206 lu.layout = layout;
207 mJCfg->layouts.append(lu);
208 mDstLayoutModel->reset();
209 cfgUI.dstTableView->update();
210 setCmdLine();
214 void JrugrConfigForm::delLayout () {
215 QItemSelectionModel *selectionModel = cfgUI.dstTableView->selectionModel();
216 if (selectionModel == NULL || !selectionModel->hasSelection()|| mJCfg->layouts.size() == 0) return;
217 QModelIndexList selected = selectionModel->selectedRows();
218 mJCfg->layouts.removeAt(selected[0].row());
219 mDstLayoutModel->reset();
220 cfgUI.dstTableView->update();
221 setCmdLine();
225 void JrugrConfigForm::srcClick (QModelIndex index) {
226 Q_UNUSED(index)
227 cfgUI.btnAdd->setEnabled(true);
231 void JrugrConfigForm::dstClick () {
232 int row = getSelectedDstLayout();
233 cfgUI.btnRemove->setEnabled(row!=-1);
234 int el_count = cfgUI.comboVariant->count();
235 for (int f = el_count; f > 0; --f) cfgUI.comboVariant->removeItem(f);
236 //cfgUI.comboVariant->clear(); some sheet seg fail in use
237 cfgUI.comboVariant->setEnabled(row!=-1);
238 cfgUI.btnUp->setEnabled(row!=-1);
239 cfgUI.btnDown->setEnabled(row!=-1);
240 if (row == -1) return;
241 QString layout = mJCfg->layouts[row].layout;
242 qDebug() << layout;
243 mVariants = X11Tools::getVariants(layout, X11Tools::findX11Dir());
244 qDebug() << "JrugrConfigForm:addItem";
245 if (cfgUI.comboVariant->count() == 0) {
246 cfgUI.comboVariant->addItem(tr("Default"), "Default");
247 cfgUI.comboVariant->setItemData(0, tr("Default"), Qt::ToolTipRole);
248 cfgUI.comboVariant->setItemText(0, tr("Default"));
250 if (mVariants.count() > 0) {
251 for (int f = 0; f < mVariants.count(); ++f) {
252 cfgUI.comboVariant->addItem(mVariants[f].description, mVariants[f].name);
253 cfgUI.comboVariant->setItemData(cfgUI.comboVariant->count()-1, mVariants[f].description, Qt::ToolTipRole);
255 QString variant = mJCfg->layouts[row].variant;
256 if (variant != NULL && !variant.isEmpty()) {
257 int idx = cfgUI.comboVariant->findData(variant);
258 cfgUI.comboVariant->setCurrentIndex(idx);
259 } else {
260 cfgUI.comboVariant->setCurrentIndex(0);
266 bool JrugrConfigForm::loadRules () {
267 QString x11dir = X11Tools::findX11Dir();
268 if (x11dir.isNull() || x11dir.isEmpty()) return false;
269 QString rulesFile = X11Tools::findXkbRulesFile(x11dir, QX11Info::display());
270 if (rulesFile.isNull() || rulesFile.isEmpty()) return false;
271 mCurRule = X11Tools::loadRules(rulesFile, false);
272 if (mCurRule == NULL) return false;
273 return true;
277 void JrugrConfigForm::comboModelCh (int index) {
278 mJCfg->model= mCurRule->models.key(cfgUI.comboModel->itemText(index));
279 setCmdLine();
283 void JrugrConfigForm::comboVariantCh (int index) {
284 if (index == 0) mJCfg->layouts[getSelectedDstLayout()].variant = "";
285 else if (index < mVariants.count()) mJCfg->layouts[getSelectedDstLayout()].variant = mVariants.at(index-1).name; // it sometimes crashed here with "index out of bounds"
286 setCmdLine();
290 int JrugrConfigForm::getSelectedDstLayout () {
291 QItemSelectionModel *selectionModel = cfgUI.dstTableView->selectionModel();
292 if (selectionModel == NULL || !selectionModel->hasSelection()) return -1;
293 QModelIndexList selected = selectionModel->selectedRows();
294 int row = selected.count() > 0 ? selected[0].row() : -1;
295 return row;
299 void JrugrConfigForm::setFlagUse () {
300 mJCfg->showFlag = cfgUI.chkShowFlag->isChecked();
304 void JrugrConfigForm::setSinglShow () {
305 mJCfg->showSingle = cfgUI.chkShowSingle->isChecked();
309 void JrugrConfigForm::layoutUp () {
310 int row = getSelectedDstLayout();
311 if (row>0) {
312 LayoutUnit lu = mJCfg->layouts[row-1];
313 mJCfg->layouts[row-1] = mJCfg->layouts[row];
314 mJCfg->layouts[row] = lu;
315 mDstLayoutModel->reset();
316 cfgUI.dstTableView->update();
317 setCmdLine();
322 void JrugrConfigForm::layoutDown () {
323 int row = getSelectedDstLayout();
324 if (row < mJCfg->layouts.count()-1 && row > -1) {
325 LayoutUnit lu = mJCfg->layouts[row+1];
326 mJCfg->layouts[row+1] = mJCfg->layouts[row];
327 mJCfg->layouts[row] = lu;
328 mDstLayoutModel->reset();
329 setCmdLine();
334 void JrugrConfigForm::updateOptionsCommand () {
335 QString cmd = "setxkbmap";
336 if (cfgUI.chkResetOld->isChecked()) cmd += " -option";
337 if (!mJCfg->options.empty()) {
338 cmd += " -option ";
339 cmd += mJCfg->options.join(",");
341 cfgUI.editCmdLineOpt->setText(cmd);
345 void JrugrConfigForm::xkbOptionsChanged (const QModelIndex &topLeft, const QModelIndex &bottomRight) {
346 Q_UNUSED(topLeft)
347 Q_UNUSED(bottomRight)
348 updateOptionsCommand();
352 void JrugrConfigForm::closeEvent (QCloseEvent *event) {
354 hide();
355 event->ignore();
360 void JrugrConfigForm::statSwitching (bool checked) {
361 //Q_UNUSED(checked)
362 qDebug() << "statSwitching";
363 if (checked) {
364 QRadioButton *radio = qobject_cast<QRadioButton *>(QObject::sender());
365 if (radio == cfgUI.rbPolicyGlobal) mJCfg->switching = GLOBAL_LAYOUT;
366 if (radio == cfgUI.rbPolicyApp) mJCfg->switching = APP_LAYOUT;
367 if (radio == cfgUI.rbPolicyWin) mJCfg->switching = WIN_LAYOUT;
368 if (radio == cfgUI.rbPolicyDesk) mJCfg->switching = DESK_LAYOUT;
369 qDebug(" %d", mJCfg->switching);
372 if (cfgUI.rbPolicyGlobal->isChecked()) mJCfg->switching = GLOBAL_LAYOUT;
373 if (cfgUI.rbPolicyApp->isChecked()) mJCfg->switching = APP_LAYOUT;
374 if (cfgUI.rbPolicyWin->isChecked()) mJCfg->switching = WIN_LAYOUT;
375 if (cfgUI.rbPolicyDesk->isChecked()) mJCfg->switching = DESK_LAYOUT;
380 void JrugrConfigForm::getHotKeys (XEvent *event) {
381 XKeyEvent *keys = (XKeyEvent *)event;
383 switch (XKeycodeToKeysym(QX11Info::display(), keys->keycode, 0)) {
384 case XK_Shift_L:
385 case XK_Shift_R:
386 mMods = "Shift";
387 mKey.clear();
388 break;
389 case XK_Control_L:
390 case XK_Control_R:
391 mMods = "Ctrl";
392 mKey.clear();
393 break;
394 case XK_Alt_L:
395 case XK_Alt_R:
396 mMods = "Alt";
397 mKey.clear();
398 break;
399 default:
400 mKey = QString(XKeysymToString(XKeycodeToKeysym(QX11Info::display(), keys->keycode, 0)));
401 if (mKey.count() < 2) mKey = mKey.toUpper();
403 if (!mMods.isEmpty()) mHotKeys =mMods+"+"+mKey;
404 else if (mKey.count() > 1) mHotKeys = mKey;
408 void JrugrConfigForm::clearHotKeys () {
409 qDebug() << "JrugrConfigForm:: Current mMods " << mMods;
410 if (mMods.isEmpty()) return;
411 qDebug() << "JrugrConfigForm:: Current mKey " << mKey;
412 if (!mKey.isEmpty()) return;
413 mMods.clear();