Changeset View
Changeset View
Standalone View
Standalone View
kcms/keys/kglobalshortcutseditor.cpp
Show All 12 Lines | |||||
13 | * | 13 | * | ||
14 | * You should have received a copy of the GNU General Public License | 14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | 15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
17 | */ | 17 | */ | ||
18 | #include "kglobalshortcutseditor.h" | 18 | #include "kglobalshortcutseditor.h" | ||
19 | 19 | | |||
20 | #include "ui_kglobalshortcutseditor.h" | 20 | #include "ui_kglobalshortcutseditor.h" | ||
21 | #include "ui_select_application.h" | ||||
21 | #include "export_scheme_dialog.h" | 22 | #include "export_scheme_dialog.h" | ||
22 | #include "select_scheme_dialog.h" | 23 | #include "select_scheme_dialog.h" | ||
23 | #include "globalshortcuts.h" | 24 | #include "globalshortcuts.h" | ||
24 | #include "kglobalaccel_interface.h" | 25 | #include "kglobalaccel_interface.h" | ||
25 | #include "kglobalaccel_component_interface.h" | 26 | #include "kglobalaccel_component_interface.h" | ||
26 | 27 | | |||
27 | #include <KActionCollection> | 28 | #include <KActionCollection> | ||
28 | #include <KConfig> | 29 | #include <KConfig> | ||
29 | #include <QDebug> | 30 | #include <QDebug> | ||
30 | #include <KGlobalAccel> | 31 | #include <KGlobalAccel> | ||
31 | #include <KIconLoader> | 32 | #include <KIconLoader> | ||
32 | #include <KMessageBox> | 33 | #include <KMessageBox> | ||
33 | #include <KStringHandler> | 34 | #include <KStringHandler> | ||
34 | #include <KLocalizedString> | 35 | #include <KLocalizedString> | ||
36 | #include <KService> | ||||
37 | #include <KRecursiveFilterProxyModel> | ||||
38 | #include <KServiceGroup> | ||||
39 | #include <KDesktopFile> | ||||
40 | #include <KCategorizedSortFilterProxyModel> | ||||
41 | #include <KCategoryDrawer> | ||||
35 | 42 | | |||
36 | #include <QStackedWidget> | 43 | #include <QStackedWidget> | ||
37 | #include <QMenu> | 44 | #include <QMenu> | ||
38 | #include <QSortFilterProxyModel> | 45 | #include <QSortFilterProxyModel> | ||
39 | #include <QStandardItemModel> | 46 | #include <QStandardItemModel> | ||
40 | #include <QHash> | 47 | #include <QHash> | ||
41 | 48 | | |||
42 | #include <QDBusConnection> | 49 | #include <QDBusConnection> | ||
▲ Show 20 Lines • Show All 96 Lines • ▼ Show 20 Line(s) | 132 | public: | |||
139 | //! Return the componentPath for component | 146 | //! Return the componentPath for component | ||
140 | QDBusObjectPath componentPath(const QString &componentUnique); | 147 | QDBusObjectPath componentPath(const QString &componentUnique); | ||
141 | 148 | | |||
142 | //! Remove the component | 149 | //! Remove the component | ||
143 | void removeComponent(const QString &componentUnique); | 150 | void removeComponent(const QString &componentUnique); | ||
144 | 151 | | |||
145 | KGlobalShortcutsEditor *q; | 152 | KGlobalShortcutsEditor *q; | ||
146 | Ui::KGlobalShortcutsEditor ui; | 153 | Ui::KGlobalShortcutsEditor ui; | ||
154 | Ui::SelectApplicationDialog selectApplicationDialogUi; | ||||
155 | QDialog *selectApplicationDialog; | ||||
147 | QStackedWidget *stack; | 156 | QStackedWidget *stack; | ||
148 | KShortcutsEditor::ActionTypes actionTypes; | 157 | KShortcutsEditor::ActionTypes actionTypes; | ||
149 | QHash<QString, ComponentData*> components; | 158 | QHash<QString, ComponentData*> components; | ||
150 | QDBusConnection bus; | 159 | QDBusConnection bus; | ||
151 | QStandardItemModel *model; | 160 | QStandardItemModel *model; | ||
161 | KCategorizedSortFilterProxyModel *proxyModel; | ||||
152 | }; | 162 | }; | ||
153 | 163 | | |||
164 | void loadAppsCategory(KServiceGroup::Ptr group, QStandardItemModel *model, QStandardItem *item) | ||||
165 | { | ||||
166 | if (group && group->isValid()) { | ||||
167 | KServiceGroup::List list = group->entries(); | ||||
168 | | ||||
169 | for( KServiceGroup::List::ConstIterator it = list.constBegin(); | ||||
170 | it != list.constEnd(); ++it) { | ||||
171 | const KSycocaEntry::Ptr p = (*it); | ||||
172 | | ||||
173 | if (p->isType(KST_KService)) { | ||||
174 | const KService::Ptr service(static_cast<KService*>(p.data())); | ||||
175 | | ||||
176 | if (!service->noDisplay()) { | ||||
177 | QString genericName = service->genericName(); | ||||
178 | if (genericName.isNull()) { | ||||
179 | genericName = service->comment(); | ||||
180 | } | ||||
181 | QString description; | ||||
182 | if (!service->genericName().isEmpty() && service->genericName() != service->name()) { | ||||
183 | description = service->genericName(); | ||||
184 | } else if (!service->comment().isEmpty()) { | ||||
185 | description = service->comment(); | ||||
186 | } | ||||
187 | | ||||
188 | QStandardItem *subItem = new QStandardItem(QIcon::fromTheme(service->icon()), service->name()); | ||||
189 | subItem->setData(service->entryPath()); | ||||
190 | if (item) { | ||||
191 | item->appendRow(subItem); | ||||
192 | } else { | ||||
193 | model->appendRow(subItem); | ||||
194 | } | ||||
195 | } | ||||
196 | | ||||
197 | } else if (p->isType(KST_KServiceGroup)) { | ||||
198 | KServiceGroup::Ptr subGroup(static_cast<KServiceGroup*>(p.data())); | ||||
199 | | ||||
200 | if (!subGroup->noDisplay() && subGroup->childCount() > 0) { | ||||
201 | if (item) { | ||||
202 | loadAppsCategory(subGroup, model, item); | ||||
203 | } else { | ||||
204 | QStandardItem *subItem = new QStandardItem(QIcon::fromTheme(subGroup->icon()), subGroup->caption()); | ||||
205 | model->appendRow(subItem); | ||||
206 | loadAppsCategory(subGroup, model, subItem); | ||||
207 | } | ||||
208 | } | ||||
209 | } | ||||
210 | } | ||||
211 | } | ||||
212 | } | ||||
154 | 213 | | |||
155 | void KGlobalShortcutsEditor::KGlobalShortcutsEditorPrivate::initGUI() | 214 | void KGlobalShortcutsEditor::KGlobalShortcutsEditorPrivate::initGUI() | ||
156 | { | 215 | { | ||
157 | ui.setupUi(q); | 216 | ui.setupUi(q); | ||
217 | selectApplicationDialog = new QDialog(); | ||||
218 | selectApplicationDialogUi.setupUi(selectApplicationDialog); | ||||
158 | // Create a stacked widget. | 219 | // Create a stacked widget. | ||
159 | stack = new QStackedWidget(q); | 220 | stack = new QStackedWidget(q); | ||
160 | q->layout()->addWidget(stack); | 221 | ui.currentComponentLayout->addWidget(stack); | ||
222 | //HACK to make those two un-alignable components, aligned | ||||
223 | ui.componentLabel->setMinimumHeight(ui.lineEditSpacer->sizeHint().height()); | ||||
224 | ui.lineEditSpacer->setVisible(false); | ||||
225 | ui.addButton->setIcon(QIcon::fromTheme("list-add")); | ||||
226 | ui.removeButton->setIcon(QIcon::fromTheme("list-remove")); | ||||
227 | ui.components->setCategoryDrawer(new KCategoryDrawer(ui.components)); | ||||
228 | ui.components->setModelColumn(0); | ||||
161 | 229 | | |||
162 | // Connect our components | 230 | // Connect our components | ||
163 | connect(ui.components, SIGNAL(activated(QString)), | 231 | connect(ui.components, &QListView::activated, | ||
164 | q, SLOT(activateComponent(QString))); | 232 | q, [this](const QModelIndex &index) { | ||
233 | QString name = proxyModel->data(index).toString(); | ||||
234 | q->activateComponent(name); | ||||
235 | }); | ||||
165 | 236 | | |||
166 | // Build the menu | 237 | // Build the menu | ||
167 | QMenu *menu = new QMenu(q); | 238 | QMenu *menu = new QMenu(q); | ||
168 | menu->addAction( QIcon::fromTheme(QStringLiteral("document-import")), i18n("Import Scheme..."), q, SLOT(importScheme())); | 239 | menu->addAction( QIcon::fromTheme(QStringLiteral("document-import")), i18n("Import Scheme..."), q, SLOT(importScheme())); | ||
169 | menu->addAction( QIcon::fromTheme(QStringLiteral("document-export")), i18n("Export Scheme..."), q, SLOT(exportScheme())); | 240 | menu->addAction( QIcon::fromTheme(QStringLiteral("document-export")), i18n("Export Scheme..."), q, SLOT(exportScheme())); | ||
170 | menu->addAction( i18n("Set All Shortcuts to None"), q, SLOT(clearConfiguration())); | 241 | menu->addAction( i18n("Set All Shortcuts to None"), q, SLOT(clearConfiguration())); | ||
171 | QAction *action = menu->addAction( QIcon::fromTheme(QStringLiteral("edit-delete")), i18n("Remove Component")); | 242 | | ||
172 | connect(action, &QAction::triggered, [this]() { | 243 | connect(ui.addButton, &QToolButton::clicked, [this]() { | ||
173 | QString name = ui.components->currentText(); | 244 | if (!selectApplicationDialogUi.treeView->model()) { | ||
245 | KRecursiveFilterProxyModel *filterModel = new KRecursiveFilterProxyModel(selectApplicationDialogUi.treeView); | ||||
246 | QStandardItemModel *appModel = new QStandardItemModel(selectApplicationDialogUi.treeView); | ||||
247 | selectApplicationDialogUi.kfilterproxysearchline->setProxy(filterModel); | ||||
248 | filterModel->setSourceModel(appModel); | ||||
249 | appModel->setHorizontalHeaderLabels({i18n("Applications")}); | ||||
250 | | ||||
251 | loadAppsCategory(KServiceGroup::root(), appModel, nullptr); | ||||
252 | | ||||
253 | selectApplicationDialogUi.treeView->setModel(filterModel); | ||||
254 | } | ||||
255 | selectApplicationDialog->show(); | ||||
256 | }); | ||||
257 | | ||||
258 | connect(selectApplicationDialog, &QDialog::accepted, [this]() { | ||||
259 | if (selectApplicationDialogUi.treeView->selectionModel()->selectedIndexes().length() == 1) { | ||||
260 | const QString desktopPath = selectApplicationDialogUi.treeView->model()->data(selectApplicationDialogUi.treeView->selectionModel()->selectedIndexes().first(), Qt::UserRole+1).toString(); | ||||
261 | | ||||
262 | if (!desktopPath.isEmpty() &&QFile::exists(desktopPath) ) { | ||||
263 | const QString desktopFile = desktopPath.split(QChar('/')).last(); | ||||
264 | | ||||
265 | if (!desktopPath.isEmpty()) { | ||||
266 | KDesktopFile sourceDF(desktopPath); | ||||
267 | KDesktopFile *destinationDF = sourceDF.copyTo(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/kglobalaccel/") + desktopFile); | ||||
268 | qWarning()<<QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/kglobalaccel/") + desktopFile; | ||||
269 | destinationDF->sync(); | ||||
270 | //TODO: a DBUS call to tell the daemon to refresh desktop files | ||||
271 | | ||||
272 | | ||||
273 | // Create a action collection for our current component:context | ||||
274 | KActionCollection *col = new KActionCollection(q, desktopFile); | ||||
275 | | ||||
276 | foreach(const QString &actionId, sourceDF.readActions()) { | ||||
277 | | ||||
278 | const QString friendlyName = sourceDF.actionGroup(actionId).readEntry(QStringLiteral("Name")); | ||||
279 | QAction *action = col->addAction(actionId); | ||||
280 | action->setProperty("isConfigurationAction", QVariant(true)); // see KAction::~KAction | ||||
281 | action->setProperty("componentDisplayName", friendlyName); | ||||
282 | action->setText(friendlyName); | ||||
283 | | ||||
284 | KGlobalAccel::self()->setShortcut(action, QList<QKeySequence>()); | ||||
285 | | ||||
286 | QStringList sequencesStrings = sourceDF.actionGroup(actionId).readEntry(QStringLiteral("X-KDE-Shortcuts"), QString()).split(QChar(',')); | ||||
287 | QList<QKeySequence> sequences; | ||||
288 | if (sequencesStrings.length() > 0) { | ||||
289 | Q_FOREACH (const QString &seqString, sequencesStrings) { | ||||
290 | sequences.append(QKeySequence(seqString)); | ||||
291 | } | ||||
292 | } | ||||
293 | | ||||
294 | if (sequences.count() > 0) { | ||||
295 | KGlobalAccel::self()->setDefaultShortcut(action, sequences); | ||||
296 | } | ||||
297 | } | ||||
298 | //Global launch action | ||||
299 | { | ||||
300 | const QString friendlyName = i18n("Launch %1", sourceDF.readName()); | ||||
301 | QAction *action = col->addAction(QStringLiteral("_launch")); | ||||
302 | action->setProperty("isConfigurationAction", QVariant(true)); // see KAction::~KAction | ||||
303 | action->setProperty("componentDisplayName", friendlyName); | ||||
304 | action->setText(friendlyName); | ||||
305 | | ||||
306 | KGlobalAccel::self()->setShortcut(action, QList<QKeySequence>()); | ||||
307 | | ||||
308 | QStringList sequencesStrings = sourceDF.desktopGroup().readEntry(QStringLiteral("X-KDE-Shortcuts"), QString()).split(QChar(',')); | ||||
309 | QList<QKeySequence> sequences; | ||||
310 | if (sequencesStrings.length() > 0) { | ||||
311 | Q_FOREACH (const QString &seqString, sequencesStrings) { | ||||
312 | sequences.append(QKeySequence(seqString)); | ||||
313 | } | ||||
314 | } | ||||
315 | | ||||
316 | if (sequences.count() > 0) { | ||||
317 | KGlobalAccel::self()->setDefaultShortcut(action, sequences); | ||||
318 | } | ||||
319 | } | ||||
320 | qWarning()<<"WWWWW"<<desktopFile<<sourceDF.readName(); | ||||
321 | q->addCollection(col, QDBusObjectPath(), desktopFile, sourceDF.readName()); | ||||
322 | } | ||||
323 | } | ||||
324 | } | ||||
325 | }); | ||||
326 | | ||||
327 | connect(ui.removeButton, &QToolButton::clicked, [this]() { | ||||
328 | //TODO: different way to remove components that are desktop files | ||||
329 | //disabled desktop files need Hidden=true key | ||||
330 | QString name = proxyModel->data(ui.components->currentIndex()).toString(); | ||||
174 | QString componentUnique = components.value(name)->uniqueName(); | 331 | QString componentUnique = components.value(name)->uniqueName(); | ||
175 | 332 | | |||
176 | // The confirmation text is different when the component is active | 333 | // The confirmation text is different when the component is active | ||
177 | if (KGlobalAccel::isComponentActive(componentUnique)) { | 334 | if (KGlobalAccel::isComponentActive(componentUnique)) { | ||
178 | if (KMessageBox::questionYesNo( | 335 | if (KMessageBox::questionYesNo( | ||
179 | q, | 336 | q, | ||
180 | i18n("Component '%1' is currently active. Only global shortcuts currently not active will be removed from the list.\n" | 337 | i18n("Component '%1' is currently active. Only global shortcuts currently not active will be removed from the list.\n" | ||
181 | "All global shortcuts will reregister themselves with their defaults when they are next started.", componentUnique), | 338 | "All global shortcuts will reregister themselves with their defaults when they are next started.", componentUnique), | ||
Show All 26 Lines | 364 | if (loadComponent(oPath)) { | |||
208 | // Active it | 365 | // Active it | ||
209 | q->activateComponent(name); | 366 | q->activateComponent(name); | ||
210 | } | 367 | } | ||
211 | } | 368 | } | ||
212 | }); | 369 | }); | ||
213 | 370 | | |||
214 | ui.menu_button->setMenu(menu); | 371 | ui.menu_button->setMenu(menu); | ||
215 | 372 | | |||
216 | QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel(q); | 373 | proxyModel = new KCategorizedSortFilterProxyModel(q); | ||
374 | proxyModel->setCategorizedModel(true); | ||||
217 | model = new QStandardItemModel(0, 1, proxyModel); | 375 | model = new QStandardItemModel(0, 1, proxyModel); | ||
218 | proxyModel->setSourceModel(model); | 376 | proxyModel->setSourceModel(model); | ||
219 | proxyModel->setSortCaseSensitivity(Qt::CaseInsensitive); | 377 | proxyModel->setSortCaseSensitivity(Qt::CaseInsensitive); | ||
220 | ui.components->setModel(proxyModel); | 378 | ui.components->setModel(proxyModel); | ||
221 | } | 379 | } | ||
222 | 380 | | |||
223 | 381 | | |||
224 | KGlobalShortcutsEditor::KGlobalShortcutsEditor(QWidget *parent, KShortcutsEditor::ActionTypes actionTypes) | 382 | KGlobalShortcutsEditor::KGlobalShortcutsEditor(QWidget *parent, KShortcutsEditor::ActionTypes actionTypes) | ||
225 | : QWidget(parent), | 383 | : QWidget(parent), | ||
226 | d(new KGlobalShortcutsEditorPrivate(this)) | 384 | d(new KGlobalShortcutsEditorPrivate(this)) | ||
227 | { | 385 | { | ||
228 | d->actionTypes = actionTypes; | 386 | d->actionTypes = actionTypes; | ||
229 | // Setup the ui | 387 | // Setup the ui | ||
230 | d->initGUI(); | 388 | d->initGUI(); | ||
231 | } | 389 | } | ||
232 | 390 | | |||
233 | 391 | | |||
234 | KGlobalShortcutsEditor::~KGlobalShortcutsEditor() | 392 | KGlobalShortcutsEditor::~KGlobalShortcutsEditor() | ||
235 | { | 393 | { | ||
236 | // Before closing the door, undo all changes | 394 | // Before closing the door, undo all changes | ||
237 | undo(); | 395 | undo(); | ||
396 | delete d->selectApplicationDialog; | ||||
238 | qDeleteAll(d->components); | 397 | qDeleteAll(d->components); | ||
239 | delete d; | 398 | delete d; | ||
240 | } | 399 | } | ||
241 | 400 | | |||
242 | 401 | | |||
243 | void KGlobalShortcutsEditor::activateComponent(const QString &component) | 402 | void KGlobalShortcutsEditor::activateComponent(const QString &component) | ||
244 | { | 403 | { | ||
245 | QHash<QString, ComponentData*>::Iterator iter = d->components.find(component); | 404 | QHash<QString, ComponentData*>::Iterator iter = d->components.find(component); | ||
246 | if (iter == d->components.end()) { | 405 | if (iter == d->components.end()) { | ||
247 | Q_ASSERT(iter != d->components.end()); | 406 | Q_ASSERT(iter != d->components.end()); | ||
248 | return; | 407 | return; | ||
249 | } else { | 408 | } else { | ||
250 | int index = d->ui.components->findText(component); | 409 | QModelIndexList results = d->proxyModel->match(d->proxyModel->index(0, 0), Qt::DisplayRole, component); | ||
251 | Q_ASSERT(index != -1); | 410 | Q_ASSERT(results.isEmpty()); | ||
252 | if (index > -1) { | 411 | if (results.first().isValid()) { | ||
253 | // Known component. Get it. | 412 | // Known component. Get it. | ||
254 | d->ui.components->setCurrentIndex(index); | 413 | d->ui.components->setCurrentIndex(results.first()); | ||
255 | d->stack->setCurrentWidget((*iter)->editor()); | 414 | d->stack->setCurrentWidget((*iter)->editor()); | ||
256 | } | 415 | } | ||
257 | } | 416 | } | ||
258 | } | 417 | } | ||
259 | 418 | | |||
260 | 419 | | |||
261 | void KGlobalShortcutsEditor::addCollection( | 420 | void KGlobalShortcutsEditor::addCollection( | ||
262 | KActionCollection *collection, | 421 | KActionCollection *collection, | ||
263 | const QDBusObjectPath &objectPath, | 422 | const QDBusObjectPath &objectPath, | ||
264 | const QString &id, | 423 | const QString &id, | ||
265 | const QString &friendlyName) | 424 | const QString &friendlyName) | ||
266 | { | 425 | { | ||
267 | KShortcutsEditor *editor; | 426 | KShortcutsEditor *editor; | ||
268 | // Check if this component is known | 427 | // Check if this component is known | ||
269 | QHash<QString, ComponentData*>::Iterator iter = d->components.find(friendlyName); | 428 | QHash<QString, ComponentData*>::Iterator iter = d->components.find(friendlyName); | ||
270 | if (iter == d->components.end()) { | 429 | if (iter == d->components.end()) { | ||
271 | // Unknown component. Create an editor. | 430 | // Unknown component. Create an editor. | ||
272 | editor = new KShortcutsEditor(this, d->actionTypes); | 431 | editor = new KShortcutsEditor(this, d->actionTypes); | ||
273 | d->stack->addWidget(editor); | 432 | d->stack->addWidget(editor); | ||
274 | 433 | | |||
275 | // try to find one appropriate icon ( allowing NULL pixmap to be returned) | 434 | // try to find one appropriate icon ( allowing NULL pixmap to be returned) | ||
276 | QPixmap pixmap = KIconLoader::global()->loadIcon(id, KIconLoader::Small, 0, | 435 | QPixmap pixmap = KIconLoader::global()->loadIcon(id, KIconLoader::Small, 0, | ||
277 | KIconLoader::DefaultState, QStringList(), 0, true); | 436 | KIconLoader::DefaultState, QStringList(), 0, true); | ||
437 | if (pixmap.isNull()) { | ||||
438 | KService::Ptr service = KService::serviceByStorageId(id); | ||||
439 | if(service) { | ||||
440 | pixmap = KIconLoader::global()->loadIcon(service->icon(), KIconLoader::Small, 0, | ||||
441 | KIconLoader::DefaultState, QStringList(), 0, true); | ||||
442 | } | ||||
443 | } | ||||
278 | // if NULL pixmap is returned, use the F.D.O "system-run" icon | 444 | // if NULL pixmap is returned, use the F.D.O "system-run" icon | ||
279 | if (pixmap.isNull()) { | 445 | if (pixmap.isNull()) { | ||
280 | pixmap = KIconLoader::global()->loadIcon(QStringLiteral("system-run"), KIconLoader::Small); | 446 | pixmap = KIconLoader::global()->loadIcon(QStringLiteral("system-run"), KIconLoader::Small); | ||
281 | } | 447 | } | ||
282 | 448 | | |||
283 | // Add to the component combobox | 449 | // Add to the component list | ||
284 | //FIXME: QCombobox.addItem apparently breaks with sort() in Qt5 | 450 | QStandardItem *item = new QStandardItem(pixmap, friendlyName); | ||
285 | d->model->appendRow(new QStandardItem(pixmap, friendlyName)); | 451 | if (id.endsWith(QStringLiteral(".desktop"))) { | ||
286 | d->ui.components->model()->sort(0); | 452 | item->setData(i18n("Application Launchers"), KCategorizedSortFilterProxyModel::CategoryDisplayRole); | ||
453 | item->setData(0, KCategorizedSortFilterProxyModel::CategorySortRole); | ||||
454 | } else { | ||||
455 | item->setData(i18n("Other Shortcuts"), KCategorizedSortFilterProxyModel::CategoryDisplayRole); | ||||
456 | item->setData(1, KCategorizedSortFilterProxyModel::CategorySortRole); | ||||
457 | } | ||||
458 | d->model->appendRow(item); | ||||
459 | d->proxyModel->sort(0); | ||||
287 | 460 | | |||
288 | // Add to our component registry | 461 | // Add to our component registry | ||
289 | ComponentData *cd = new ComponentData(id, objectPath, editor); | 462 | ComponentData *cd = new ComponentData(id, objectPath, editor); | ||
290 | d->components.insert(friendlyName, cd); | 463 | d->components.insert(friendlyName, cd); | ||
291 | 464 | | |||
292 | connect(editor, &KShortcutsEditor::keyChange, this, &KGlobalShortcutsEditor::_k_key_changed); | 465 | connect(editor, &KShortcutsEditor::keyChange, this, &KGlobalShortcutsEditor::_k_key_changed); | ||
293 | } else { | 466 | } else { | ||
294 | // Known component. | 467 | // Known component. | ||
295 | editor = (*iter)->editor(); | 468 | editor = (*iter)->editor(); | ||
296 | } | 469 | } | ||
297 | 470 | | |||
298 | // Add the collection to the editor of the component | 471 | // Add the collection to the editor of the component | ||
299 | editor->addCollection(collection, friendlyName); | 472 | editor->addCollection(collection, friendlyName); | ||
300 | 473 | | |||
301 | if (d->ui.components->count() > -1) { | 474 | if (d->proxyModel->rowCount() > -1) { | ||
302 | d->ui.components->setCurrentIndex(0); | 475 | d->ui.components->setCurrentIndex(d->proxyModel->index(0, 0)); | ||
303 | activateComponent(d->ui.components->itemText(0)); | 476 | QString name = d->proxyModel->data(d->proxyModel->index(0, 0)).toString(); | ||
477 | activateComponent(name); | ||||
304 | } | 478 | } | ||
305 | } | 479 | } | ||
306 | 480 | | |||
307 | 481 | | |||
308 | void KGlobalShortcutsEditor::clearConfiguration() | 482 | void KGlobalShortcutsEditor::clearConfiguration() | ||
309 | { | 483 | { | ||
310 | QString name = d->ui.components->currentText(); | 484 | QString name = d->proxyModel->data(d->ui.components->currentIndex()).toString(); | ||
311 | d->components[name]->editor()->clearConfiguration(); | 485 | d->components[name]->editor()->clearConfiguration(); | ||
312 | } | 486 | } | ||
313 | 487 | | |||
314 | 488 | | |||
315 | void KGlobalShortcutsEditor::defaults(ComponentScope scope) | 489 | void KGlobalShortcutsEditor::defaults(ComponentScope scope) | ||
316 | { | 490 | { | ||
317 | switch (scope) | 491 | switch (scope) | ||
318 | { | 492 | { | ||
319 | case AllComponents: | 493 | case AllComponents: | ||
320 | Q_FOREACH (ComponentData *cd, d->components) { | 494 | Q_FOREACH (ComponentData *cd, d->components) { | ||
321 | // The editors are responsible for the reset | 495 | // The editors are responsible for the reset | ||
322 | cd->editor()->allDefault(); | 496 | cd->editor()->allDefault(); | ||
323 | } | 497 | } | ||
324 | break; | 498 | break; | ||
325 | 499 | | |||
326 | case CurrentComponent: { | 500 | case CurrentComponent: { | ||
327 | QString name = d->ui.components->currentText(); | 501 | QString name = d->proxyModel->data(d->ui.components->currentIndex()).toString(); | ||
328 | // The editors are responsible for the reset | 502 | // The editors are responsible for the reset | ||
329 | d->components[name]->editor()->allDefault(); | 503 | d->components[name]->editor()->allDefault(); | ||
330 | } | 504 | } | ||
331 | break; | 505 | break; | ||
332 | 506 | | |||
333 | default: | 507 | default: | ||
334 | Q_ASSERT(false); | 508 | Q_ASSERT(false); | ||
335 | }; | 509 | }; | ||
336 | } | 510 | } | ||
337 | 511 | | |||
338 | 512 | | |||
339 | void KGlobalShortcutsEditor::clear() | 513 | void KGlobalShortcutsEditor::clear() | ||
340 | { | 514 | { | ||
341 | // Remove all components and their associated editors | 515 | // Remove all components and their associated editors | ||
342 | qDeleteAll(d->components); | 516 | qDeleteAll(d->components); | ||
343 | d->components.clear(); | 517 | d->components.clear(); | ||
344 | d->ui.components->clear(); | 518 | d->model->clear(); | ||
345 | } | 519 | } | ||
346 | 520 | | |||
347 | 521 | | |||
348 | static bool compare(const QString &a, const QString &b) | 522 | static bool compare(const QString &a, const QString &b) | ||
349 | { | 523 | { | ||
350 | return a.toLower().localeAwareCompare(b.toLower()) < 0; | 524 | return a.toLower().localeAwareCompare(b.toLower()) < 0; | ||
351 | } | 525 | } | ||
352 | 526 | | |||
▲ Show 20 Lines • Show All 301 Lines • ▼ Show 20 Line(s) | 826 | void KGlobalShortcutsEditor::KGlobalShortcutsEditorPrivate::removeComponent( | |||
654 | { | 828 | { | ||
655 | // TODO: Remove contexts too. | 829 | // TODO: Remove contexts too. | ||
656 | 830 | | |||
657 | Q_FOREACH (const QString &text, components.keys()) | 831 | Q_FOREACH (const QString &text, components.keys()) | ||
658 | { | 832 | { | ||
659 | if (components.value(text)->uniqueName() == componentUnique) | 833 | if (components.value(text)->uniqueName() == componentUnique) | ||
660 | { | 834 | { | ||
661 | // Remove from QComboBox | 835 | // Remove from QComboBox | ||
662 | int index = ui.components->findText(text); | 836 | QModelIndexList results = proxyModel->match(proxyModel->index(0, 0), Qt::DisplayRole, text); | ||
663 | Q_ASSERT(index != -1); | 837 | Q_ASSERT(results.isEmpty()); | ||
664 | ui.components->removeItem(index); | 838 | model->removeRow(proxyModel->mapToSource(results.first()).row()); | ||
665 | 839 | | |||
666 | // Remove from QStackedWidget | 840 | // Remove from QStackedWidget | ||
667 | stack->removeWidget(components[text]->editor()); | 841 | stack->removeWidget(components[text]->editor()); | ||
668 | 842 | | |||
669 | // Remove the componentData | 843 | // Remove the componentData | ||
670 | delete components.take(text); | 844 | delete components.take(text); | ||
671 | } | 845 | } | ||
672 | } | 846 | } | ||
673 | } | 847 | } | ||
674 | 848 | | |||
675 | 849 | |