fixed crash on layout adding when jrugr is running
[jrugr.git] / src / jrugrconfui.cpp
blobaa7c5ec7f3459865ae9d8f6e8c21b1532973cf41
1 ////////////////////////////////////////
2 // Copyright : GPL //
3 ////////////////////////////////////////
4 #include "jrugrconfui.h"
7 JrugrConfigForm::JrugrConfigForm (const QString &optFileName, QWidget *parent) : QDialog(parent) {
8 setAttribute(Qt::WA_DeleteOnClose);
9 //
10 mCfgFileName = optFileName;
11 cfgUI.setupUi(this);
12 // initialize the binding between list and stackedWidget
13 cfgUI.listWidget->setCurrentRow(0);
16 QSettings settings(mCfgFileName, QSettings::IniFormat, this);
17 settings.beginGroup("Style");
18 mTheme = settings.value("path").toString();
19 mIcoPath = mTheme+"/language/";
20 settings.endGroup(); //Style
22 qDebug() << "Theme " << mTheme;
23 qDebug() << "Icons " << mIcoPath;
25 mJCfg = JrugrCfg::load(mCfgFileName);
27 switch (mJCfg->switching) {
28 case GLOBAL_LAYOUT: cfgUI.rbPolicyGlobal->setChecked(true); break;
29 case APP_LAYOUT: cfgUI.rbPolicyApp->setChecked(true); break;
30 case WIN_LAYOUT: cfgUI.rbPolicyWin->setChecked(true); break;
31 case DESK_LAYOUT: cfgUI.rbPolicyDesk->setChecked(true); break;
34 connect(cfgUI.chkMPHack, SIGNAL(clicked()), SLOT(setMPHack()));
35 cfgUI.chkMPHack->setChecked(mJCfg->mplayerHack);
37 connect(cfgUI.buttonBox, SIGNAL(rejected()), this, SLOT(close()));
38 connect(cfgUI.buttonBox, SIGNAL(accepted()), SLOT(apply()));
39 connect(cfgUI.rbUseXkb, SIGNAL(clicked(bool)), SLOT(statSelect(bool)));
40 connect(cfgUI.rbIndicator, SIGNAL(clicked(bool)), SLOT(statSelect(bool)));
41 connect(cfgUI.rbNoXkb, SIGNAL(clicked(bool)), SLOT(statSelect(bool)));
43 connect(cfgUI.rbPolicyGlobal, SIGNAL(clicked(bool)), SLOT(statSwitching(bool)));
44 connect(cfgUI.rbPolicyApp, SIGNAL(clicked(bool)), SLOT(statSwitching(bool)));
45 connect(cfgUI.rbPolicyWin, SIGNAL(clicked(bool)), SLOT(statSwitching(bool)));
46 connect(cfgUI.rbPolicyDesk, SIGNAL(clicked(bool)), SLOT(statSwitching(bool)));
48 cfgUI.btnAdd->setEnabled(false);
49 cfgUI.btnAdd->setIcon(QIcon::fromTheme(QString("arrow-right"), QIcon(mTheme+"/add.png")));
51 cfgUI.btnRemove->setEnabled(false);
52 cfgUI.btnRemove->setIcon(QIcon::fromTheme(QString("arrow-left"), QIcon(mTheme+"/rem.png")));
54 cfgUI.btnUp->setEnabled(false);
55 cfgUI.btnUp->setIcon(QIcon::fromTheme(QString("arrow-up"), QIcon(mTheme+"/up.png")));
57 cfgUI.btnDown->setEnabled(false);
58 cfgUI.btnDown->setIcon(QIcon::fromTheme(QString("arrow-down"), QIcon(mTheme+"/down.png")));
60 if (!setStat()) return;
61 initXKBTab();
65 JrugrConfigForm::~JrugrConfigForm () {
66 delete mJCfg;
70 void JrugrConfigForm::apply () {
71 mJCfg->save(mCfgFileName);
73 if (cfgUI.stackedWidget->currentIndex() == 0 && mJCfg->workMode == USE_XKB) {
74 QStringList parm = cfgUI.editCmdLine->text().split(" ");
75 int qpres;
77 parm.removeAt(0);
78 qDebug() << "parm:" << parm;
79 qpres = QProcess::execute("setxkbmap", parm);
80 qDebug() << "Set XKB result" << qpres;
81 } else if (cfgUI.stackedWidget->currentIndex() == 2 && mJCfg->workMode == USE_XKB) {
82 QStringList parm = cfgUI.editCmdLineOpt->text().split(" ");
83 int qpres;
85 parm.removeAt(0);
86 qDebug() << "parm:" << parm;
87 qpres = QProcess::execute("setxkbmap", parm);
88 qDebug() << "Set XKB result" << qpres;
90 //qDebug()<<"Close";
91 //close();
92 emit saveConfig();
96 void JrugrConfigForm::statSelect (bool check) {
97 Q_UNUSED(check)
99 if (cfgUI.rbUseXkb->isChecked()) mJCfg->workMode = USE_XKB;
100 if (cfgUI.rbIndicator->isChecked()) mJCfg->workMode = ONLY_INDICATION;
101 if (!setStat()) return;
102 initXKBTab();
106 void JrugrConfigForm::initXKBTab () {
107 connect(cfgUI.btnAdd, SIGNAL(clicked()), SLOT(addLayout()));
108 connect(cfgUI.btnRemove, SIGNAL(clicked()), SLOT(delLayout()));
109 loadRules();
110 //set comboModel list
111 QHashIterator<QString, QString> i(mCurRule->models);
112 while (i.hasNext()) { i.next(); mModelList << i.value(); }
113 // set avaleble language
114 mSrcLayoutModel = new SrcLayoutModel(mCurRule, mIcoPath, this);
115 qDebug() << mIcoPath;
116 mDstLayoutModel = new DstLayoutModel(mCurRule, mJCfg, mIcoPath, this);
117 mXkbOptionsModel = new XkbOptionsModel(mCurRule, mJCfg, this);
118 cfgUI.comboModel->addItems(mModelList);
119 cfgUI.comboModel->setCurrentIndex(mModelList.indexOf(mCurRule->models.value(mJCfg->model)));
120 cfgUI.srcTableView->setModel(mSrcLayoutModel);
121 cfgUI.srcTableView->resizeColumnToContents(0);
122 cfgUI.dstTableView->setModel(mDstLayoutModel);
123 cfgUI.dstTableView->resizeColumnToContents(0);
124 cfgUI.xkbOptionsTreeView->setModel(mXkbOptionsModel);
125 cfgUI.xkbOptionsTreeView->header()->hide();
126 cfgUI.xkbOptionsTreeView->expandAll();
128 connect(cfgUI.srcTableView, SIGNAL(clicked(const QModelIndex &)), SLOT(srcClick(QModelIndex)));
129 connect(cfgUI.dstTableView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), SLOT(dstClick()));
130 connect(cfgUI.comboModel, SIGNAL(currentIndexChanged (int)) , SLOT(comboModelCh(int)));
131 connect(cfgUI.comboVariant, SIGNAL(currentIndexChanged (int)), SLOT(comboVariantCh(int)));
132 connect(cfgUI.btnUp, SIGNAL(clicked()), SLOT(layoutUp()));
133 connect(cfgUI.btnDown, SIGNAL(clicked()), SLOT(layoutDown()));
134 connect(mXkbOptionsModel, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), SLOT(xkbOptionsChanged(const QModelIndex &, const QModelIndex &)));
136 setCmdLine();
137 updateOptionsCommand();
141 bool JrugrConfigForm::setStat () {
142 connect(cfgUI.chkShowFlag, SIGNAL(clicked()), SLOT(setFlagUse()));
144 switch (mJCfg->workMode) {
145 case ONLY_INDICATION:
146 cfgUI.grpIndicatorOptions->setEnabled(true);
147 cfgUI.grpLayouts->setEnabled(false);
148 cfgUI.pgPolicy->setEnabled(true);
149 cfgUI.pgXkb->setEnabled(false);
150 cfgUI.rbUseXkb->setChecked(false);
151 cfgUI.rbIndicator->setChecked(true);
152 cfgUI.rbNoXkb->setChecked(false);
153 return false;
154 case USE_XKB:
155 cfgUI.grpIndicatorOptions->setEnabled(true);
156 cfgUI.grpLayouts->setEnabled(true);
157 cfgUI.pgPolicy->setEnabled(true);
158 cfgUI.pgXkb->setEnabled(true);
159 cfgUI.rbUseXkb->setChecked(true);
160 cfgUI.rbIndicator->setChecked(false);
161 cfgUI.rbNoXkb->setChecked(false);
162 return true;
164 return false;
168 void JrugrConfigForm::setCmdLine () {
169 QString cmdLine = "setxkbmap -model "+mJCfg->model;
171 cmdLine += " -layout ";
172 for (int f = 0;f < mJCfg->layouts.size(); ++f) {
173 cmdLine += mJCfg->layouts[f].layout;
174 if (f < mJCfg->layouts.size()-1) cmdLine += ',';
177 cmdLine += " -variant ";
178 for (int f = 0; f < mJCfg->layouts.size(); ++f) {
179 cmdLine += mJCfg->layouts[f].variant;
180 if (f < mJCfg->layouts.size()-1) cmdLine += ',';
182 cfgUI.editCmdLine->setText(cmdLine);
186 void JrugrConfigForm::addLayout () {
187 LayoutUnit lu;
188 QItemSelectionModel *selectionModel = cfgUI.srcTableView->selectionModel();
190 if (selectionModel == NULL || !selectionModel->hasSelection() || mJCfg->layouts.size() >= 4) return;
191 QModelIndexList selected = selectionModel->selectedRows();
192 qDebug() << "selected : " << selected;
193 QString layout = mSrcLayoutModel->getLayoutAt(selected[0].row());
194 if (layout.isEmpty() || mJCfg->layouts.contains(layout)) return;
195 lu.layout = layout;
196 mJCfg->layouts.append(lu);
197 mDstLayoutModel->reset();
198 cfgUI.dstTableView->update();
199 setCmdLine();
203 void JrugrConfigForm::delLayout () {
204 QItemSelectionModel *selectionModel = cfgUI.dstTableView->selectionModel();
205 if (selectionModel == NULL || !selectionModel->hasSelection()|| mJCfg->layouts.size() == 0) return;
206 QModelIndexList selected = selectionModel->selectedRows();
207 mJCfg->layouts.removeAt(selected[0].row());
208 mDstLayoutModel->reset();
209 cfgUI.dstTableView->update();
210 setCmdLine();
214 void JrugrConfigForm::srcClick (QModelIndex index) {
215 Q_UNUSED(index)
216 cfgUI.btnAdd->setEnabled(true);
220 void JrugrConfigForm::dstClick () {
221 int row = getSelectedDstLayout();
222 cfgUI.btnRemove->setEnabled(row!=-1);
223 int el_count = cfgUI.comboVariant->count();
224 for (int f = el_count; f > 0; --f) cfgUI.comboVariant->removeItem(f);
225 //cfgUI.comboVariant->clear(); some sheet seg fail in use
226 cfgUI.comboVariant->setEnabled(row!=-1);
227 cfgUI.btnUp->setEnabled(row!=-1);
228 cfgUI.btnDown->setEnabled(row!=-1);
229 if (row == -1) return;
230 QString layout = mJCfg->layouts[row].layout;
231 qDebug() << layout;
232 mVariants = X11Tools::getVariants(layout, X11Tools::findX11Dir());
233 qDebug() << "JrugrConfigForm:addItem";
234 if (cfgUI.comboVariant->count() == 0) {
235 cfgUI.comboVariant->addItem(tr("Default"), "Default");
236 cfgUI.comboVariant->setItemData(0, tr("Default"), Qt::ToolTipRole);
237 cfgUI.comboVariant->setItemText(0, tr("Default"));
239 if (mVariants.count() > 0) {
240 for (int f = 0; f < mVariants.count(); ++f) {
241 cfgUI.comboVariant->addItem(mVariants[f].description, mVariants[f].name);
242 cfgUI.comboVariant->setItemData(cfgUI.comboVariant->count()-1, mVariants[f].description, Qt::ToolTipRole);
244 QString variant = mJCfg->layouts[row].variant;
245 if (variant != NULL && !variant.isEmpty()) {
246 int idx = cfgUI.comboVariant->findData(variant);
247 cfgUI.comboVariant->setCurrentIndex(idx);
248 } else {
249 cfgUI.comboVariant->setCurrentIndex(0);
255 bool JrugrConfigForm::loadRules () {
256 QString x11dir = X11Tools::findX11Dir();
257 if (x11dir.isNull() || x11dir.isEmpty()) return false;
258 QString rulesFile = X11Tools::findXkbRulesFile(x11dir, QX11Info::display());
259 if (rulesFile.isNull() || rulesFile.isEmpty()) return false;
260 mCurRule = X11Tools::loadRules(rulesFile, false);
261 if (mCurRule == NULL) return false;
262 return true;
266 void JrugrConfigForm::comboModelCh (int index) {
267 mJCfg->model= mCurRule->models.key(cfgUI.comboModel->itemText(index));
268 setCmdLine();
272 void JrugrConfigForm::comboVariantCh (int index) {
273 if (index == 0) mJCfg->layouts[getSelectedDstLayout()].variant = "";
274 else if (index < mVariants.count()) mJCfg->layouts[getSelectedDstLayout()].variant = mVariants.at(index-1).name; // it sometimes crashed here with "index out of bounds"
275 setCmdLine();
279 int JrugrConfigForm::getSelectedDstLayout () {
280 QItemSelectionModel *selectionModel = cfgUI.dstTableView->selectionModel();
281 if (selectionModel == NULL || !selectionModel->hasSelection()) return -1;
282 QModelIndexList selected = selectionModel->selectedRows();
283 int row = selected.count() > 0 ? selected[0].row() : -1;
284 return row;
288 void JrugrConfigForm::setFlagUse () {
289 mJCfg->showFlag = cfgUI.chkShowFlag->isChecked();
293 void JrugrConfigForm::setMPHack () {
294 mJCfg->mplayerHack = cfgUI.chkMPHack->isChecked();
298 void JrugrConfigForm::layoutUp () {
299 int row = getSelectedDstLayout();
300 if (row>0) {
301 LayoutUnit lu = mJCfg->layouts[row-1];
302 mJCfg->layouts[row-1] = mJCfg->layouts[row];
303 mJCfg->layouts[row] = lu;
304 mDstLayoutModel->reset();
305 cfgUI.dstTableView->update();
306 setCmdLine();
311 void JrugrConfigForm::layoutDown () {
312 int row = getSelectedDstLayout();
313 if (row < mJCfg->layouts.count()-1 && row > -1) {
314 LayoutUnit lu = mJCfg->layouts[row+1];
315 mJCfg->layouts[row+1] = mJCfg->layouts[row];
316 mJCfg->layouts[row] = lu;
317 mDstLayoutModel->reset();
318 setCmdLine();
323 void JrugrConfigForm::updateOptionsCommand () {
324 QString cmd = "setxkbmap";
325 if (cfgUI.chkResetOld->isChecked()) cmd += " -option";
326 if (!mJCfg->options.empty()) {
327 cmd += " -option ";
328 cmd += mJCfg->options.join(",");
330 cfgUI.editCmdLineOpt->setText(cmd);
334 void JrugrConfigForm::xkbOptionsChanged (const QModelIndex &topLeft, const QModelIndex &bottomRight) {
335 Q_UNUSED(topLeft)
336 Q_UNUSED(bottomRight)
337 updateOptionsCommand();
341 void JrugrConfigForm::closeEvent (QCloseEvent * /*event*/) {
343 hide();
344 event->ignore();
349 void JrugrConfigForm::statSwitching (bool checked) {
350 //Q_UNUSED(checked)
351 qDebug() << "statSwitching";
352 if (checked) {
353 QRadioButton *radio = qobject_cast<QRadioButton *>(QObject::sender());
354 if (radio == cfgUI.rbPolicyGlobal) mJCfg->switching = GLOBAL_LAYOUT;
355 if (radio == cfgUI.rbPolicyApp) mJCfg->switching = APP_LAYOUT;
356 if (radio == cfgUI.rbPolicyWin) mJCfg->switching = WIN_LAYOUT;
357 if (radio == cfgUI.rbPolicyDesk) mJCfg->switching = DESK_LAYOUT;
358 qDebug(" %d", mJCfg->switching);
361 if (cfgUI.rbPolicyGlobal->isChecked()) mJCfg->switching = GLOBAL_LAYOUT;
362 if (cfgUI.rbPolicyApp->isChecked()) mJCfg->switching = APP_LAYOUT;
363 if (cfgUI.rbPolicyWin->isChecked()) mJCfg->switching = WIN_LAYOUT;
364 if (cfgUI.rbPolicyDesk->isChecked()) mJCfg->switching = DESK_LAYOUT;
369 void JrugrConfigForm::getHotKeys (XEvent *event) {
370 XKeyEvent *keys = (XKeyEvent *)event;
372 switch (XKeycodeToKeysym(QX11Info::display(), keys->keycode, 0)) {
373 case XK_Shift_L:
374 case XK_Shift_R:
375 mMods = "Shift";
376 mKey.clear();
377 break;
378 case XK_Control_L:
379 case XK_Control_R:
380 mMods = "Ctrl";
381 mKey.clear();
382 break;
383 case XK_Alt_L:
384 case XK_Alt_R:
385 mMods = "Alt";
386 mKey.clear();
387 break;
388 default:
389 mKey = QString(XKeysymToString(XKeycodeToKeysym(QX11Info::display(), keys->keycode, 0)));
390 if (mKey.count() < 2) mKey = mKey.toUpper();
392 if (!mMods.isEmpty()) mHotKeys =mMods+"+"+mKey;
393 else if (mKey.count() > 1) mHotKeys = mKey;
397 void JrugrConfigForm::clearHotKeys () {
398 qDebug() << "JrugrConfigForm:: Current mMods " << mMods;
399 if (mMods.isEmpty()) return;
400 qDebug() << "JrugrConfigForm:: Current mKey " << mKey;
401 if (!mKey.isEmpty()) return;
402 mMods.clear();