29 #include "kshortcutsdialog_p.h"
31 #include <QHeaderView>
35 #include <QTextDocument>
37 #include <QTextCursor>
38 #include <QTextTableFormat>
40 #include <QPrintDialog>
59 , d(new KShortcutsEditorPrivate(this))
61 d->initGUI(actionType, allowLetterShortcuts);
68 , d(new KShortcutsEditorPrivate(this))
70 d->initGUI(actionType, allowLetterShortcuts);
83 QTreeWidgetItemIterator it(d->ui.list, QTreeWidgetItemIterator::NoChildren);
86 KShortcutsEditorItem* item =
dynamic_cast<KShortcutsEditorItem *
>(*it);
87 if (item && item->isModified()) {
96 d->delegate->contractAll();
98 d->actionCollections.clear();
112 setUpdatesEnabled(
false);
114 d->actionCollections.append(collection);
117 d->delegate->setCheckActionCollections(d->actionCollections);
120 if (displayTitle.isEmpty()) {
123 displayTitle = about->programName();
126 if (displayTitle.isEmpty()) {
127 displayTitle =
i18n(
"Unknown");
131 QTreeWidgetItem *hier[3];
132 hier[KShortcutsEditorPrivate::Root] = d->ui.list->invisibleRootItem();
133 hier[KShortcutsEditorPrivate::Program] = d->findOrMakeItem( hier[KShortcutsEditorPrivate::Root], displayTitle);
134 hier[KShortcutsEditorPrivate::Action] = NULL;
142 hier[KShortcutsEditorPrivate::Action] = d->findOrMakeItem(hier[KShortcutsEditorPrivate::Program], category->
text());
145 actionsSeen.insert(action);
146 d->addAction(action, hier, KShortcutsEditorPrivate::Action);
153 if (actionsSeen.contains(action)) {
157 d->addAction(action, hier, KShortcutsEditorPrivate::Program);
161 d->ui.list->sortItems(Name, Qt::AscendingOrder);
164 setUpdatesEnabled(
true);
172 d->clearConfiguration();
176 #ifndef KDE_NO_DEPRECATED
179 d->importConfiguration(config);
186 d->importConfiguration(config);
190 #ifndef KDE_NO_DEPRECATED
204 QString groupName =
"Global Shortcuts";
211 QString groupName =
"Shortcuts";
230 for (
int i = 0; i < d->ui.list->columnCount(); i++)
231 d->ui.list->resizeColumnToContents(i);
237 for (QTreeWidgetItemIterator it(d->ui.list); (*it); ++it) {
238 if (KShortcutsEditorItem* item = dynamic_cast<KShortcutsEditorItem*>(*it)) {
262 for (QTreeWidgetItemIterator it(d->ui.list); (*it); ++it) {
263 if (KShortcutsEditorItem* item = dynamic_cast<KShortcutsEditorItem*>(*it)) {
299 q->layout()->setMargin(0);
300 ui.searchFilter->searchLine()->setTreeWidget(ui.list);
301 ui.list->header()->setResizeMode(QHeaderView::ResizeToContents);
302 ui.list->header()->hideSection(GlobalAlternate);
303 ui.list->header()->hideSection(ShapeGesture);
304 ui.list->header()->hideSection(RockerGesture);
306 ui.list->header()->hideSection(GlobalPrimary);
307 }
else if (!(actionTypes & ~KShortcutsEditor::GlobalAction)) {
308 ui.list->header()->hideSection(LocalPrimary);
309 ui.list->header()->hideSection(LocalAlternate);
314 delegate =
new KShortcutsEditorDelegate(
318 ui.list->setItemDelegate(delegate);
319 ui.list->setSelectionBehavior(QAbstractItemView::SelectItems);
320 ui.list->setSelectionMode(QAbstractItemView::SingleSelection);
322 ui.list->setEditTriggers(QAbstractItemView::NoEditTriggers);
323 ui.list->setAlternatingRowColors(
true);
326 QObject::connect(delegate, SIGNAL(shortcutChanged(
QVariant,QModelIndex)),
327 q, SLOT(capturedShortcut(
QVariant,QModelIndex)));
329 QObject::connect(ui.searchFilter->searchLine(), SIGNAL(hiddenChanged(QTreeWidgetItem*,
bool)),
330 delegate, SLOT(hiddenBySearchLine(QTreeWidgetItem*,
bool)));
332 ui.searchFilter->setFocus();
336 bool KShortcutsEditorPrivate::addAction(
QAction *action, QTreeWidgetItem *hier[], hierarchyLevel level)
340 QString actionName = action->objectName();
341 if (actionName.isEmpty() || actionName.startsWith(QLatin1String(
"unnamed-"))) {
342 kError() <<
"Skipping action without name " << action->text() <<
"," << actionName <<
"!";
351 new KShortcutsEditorItem((hier[level]), kact);
358 void KShortcutsEditorPrivate::allDefault()
360 for (QTreeWidgetItemIterator it(ui.list); (*it); ++it) {
361 if (!(*it)->parent() || (*it)->type() != ActionItem)
364 KShortcutsEditorItem *item =
static_cast<KShortcutsEditorItem *
>(*it);
386 KShortcutsEditorItem *KShortcutsEditorPrivate::itemFromIndex(
QTreeWidget *
const w,
387 const QModelIndex &index)
389 QTreeWidgetItem *item =
static_cast<QTreeWidgetHack *
>(w)->itemFromIndex(index);
390 if (item && item->type() == ActionItem) {
391 return static_cast<KShortcutsEditorItem *
>(item);
397 QTreeWidgetItem *KShortcutsEditorPrivate::findOrMakeItem(QTreeWidgetItem *parent,
const QString &
name)
399 for (
int i = 0; i < parent->childCount(); i++) {
400 QTreeWidgetItem *child = parent->child(i);
401 if (child->text(0) ==
name)
404 QTreeWidgetItem *ret =
new QTreeWidgetItem(parent, NonActionItem);
405 ret->setText(0, name);
406 ui.list->expandItem(ret);
407 ret->setFlags(ret->flags() & ~Qt::ItemIsSelectable);
413 void KShortcutsEditorPrivate::capturedShortcut(
const QVariant &newShortcut,
const QModelIndex &index)
416 if (!index.isValid())
418 int column = index.column();
419 KShortcutsEditorItem *item = itemFromIndex(ui.list, index);
422 if (column >= LocalPrimary && column <= GlobalAlternate)
423 changeKeyShortcut(item, column, newShortcut.value<QKeySequence>());
424 else if (column == ShapeGesture)
425 changeShapeGesture(item, newShortcut.value<
KShapeGesture>());
426 else if (column == RockerGesture)
431 void KShortcutsEditorPrivate::changeKeyShortcut(KShortcutsEditorItem *item, uint column,
const QKeySequence &capture)
434 if (capture == item->keySequence(column)) {
438 item->setKeySequence(column, capture);
441 item->setText(column, capture.toString(QKeySequence::NativeText));
445 void KShortcutsEditorPrivate::changeShapeGesture(KShortcutsEditorItem *item,
const KShapeGesture &capture)
447 if (capture == item->m_action->shapeGesture())
451 bool conflict =
false;
452 KShortcutsEditorItem *otherItem;
455 for (QTreeWidgetItemIterator it(ui.list); (*it); ++it) {
456 if (!(*it)->parent() || (*it == item))
459 otherItem =
static_cast<KShortcutsEditorItem *
>(*it);
462 if (!otherItem->m_action->shapeGesture().isValid())
465 if (capture == otherItem->m_action->shapeGesture()) {
471 if (conflict && !stealShapeGesture(otherItem, capture))
475 item->setShapeGesture(capture);
479 void KShortcutsEditorPrivate::changeRockerGesture(KShortcutsEditorItem *item,
const KRockerGesture &capture)
481 if (capture == item->m_action->rockerGesture())
485 bool conflict =
false;
486 KShortcutsEditorItem *otherItem;
488 for (QTreeWidgetItemIterator it(ui.list); (*it); ++it) {
489 if (!(*it)->parent() || (*it == item))
492 otherItem =
static_cast<KShortcutsEditorItem *
>(*it);
494 if (capture == otherItem->m_action->rockerGesture()) {
500 if (conflict && !stealRockerGesture(otherItem, capture))
504 item->setRockerGesture(capture);
508 void KShortcutsEditorPrivate::clearConfiguration()
510 for (QTreeWidgetItemIterator it(ui.list); (*it); ++it) {
511 if (!(*it)->parent())
514 KShortcutsEditorItem *item =
static_cast<KShortcutsEditorItem *
>(*it);
516 changeKeyShortcut(item, LocalPrimary, QKeySequence());
517 changeKeyShortcut(item, LocalAlternate, QKeySequence());
519 changeKeyShortcut(item, GlobalPrimary, QKeySequence());
520 changeKeyShortcut(item, GlobalAlternate, QKeySequence());
528 void KShortcutsEditorPrivate::importConfiguration(
KConfigBase *config)
533 KConfigGroup globalShortcutsGroup(config, QLatin1String(
"Global Shortcuts"));
534 if ((actionTypes & KShortcutsEditor::GlobalAction) && globalShortcutsGroup.exists()) {
536 for (QTreeWidgetItemIterator it(ui.list); (*it); ++it) {
538 if (!(*it)->parent())
541 KShortcutsEditorItem *item =
static_cast<KShortcutsEditorItem *
>(*it);
543 QString actionName = item->data(Id).toString();
545 changeKeyShortcut(item, GlobalPrimary, sc.primary());
549 KConfigGroup localShortcutsGroup(config, QLatin1String(
"Shortcuts"));
550 if (actionTypes & ~KShortcutsEditor::GlobalAction) {
552 for (QTreeWidgetItemIterator it(ui.list); (*it); ++it) {
554 if (!(*it)->parent())
557 KShortcutsEditorItem *item =
static_cast<KShortcutsEditorItem *
>(*it);
559 QString actionName = item->data(Name).toString();
561 changeKeyShortcut(item, LocalPrimary, sc.primary());
562 changeKeyShortcut(item, LocalAlternate, sc.alternate());
568 bool KShortcutsEditorPrivate::stealShapeGesture(KShortcutsEditorItem *item,
const KShapeGesture &gst)
571 QString message =
i18n(
"The '%1' shape gesture has already been allocated to the \"%2\" action.\n"
572 "Do you want to reassign it from that action to the current one?",
573 gst.
shapeName(), item->m_action->text());
584 bool KShortcutsEditorPrivate::stealRockerGesture(KShortcutsEditorItem *item,
const KRockerGesture &gst)
587 QString message =
i18n(
"The '%1' rocker gesture has already been allocated to the \"%2\" action.\n"
588 "Do you want to reassign it from that action to the current one?",
618 void KShortcutsEditorPrivate::printShortcuts()
const
622 QTreeWidgetItem* root = ui.list->invisibleRootItem();
625 QTextCursor cursor(&doc);
626 cursor.beginEditBlock();
627 QTextCharFormat headerFormat;
628 headerFormat.setProperty(QTextFormat::FontSizeAdjustment, 3);
629 headerFormat.setFontWeight(QFont::Bold);
630 cursor.insertText(
i18nc(
"header for an applications shortcut list",
"Shortcuts for %1",
633 QTextCharFormat componentFormat;
634 componentFormat.setProperty(QTextFormat::FontSizeAdjustment, 2);
635 componentFormat.setFontWeight(QFont::Bold);
636 QTextBlockFormat componentBlockFormat = cursor.blockFormat();
637 componentBlockFormat.setTopMargin(16);
638 componentBlockFormat.setBottomMargin(16);
640 QTextTableFormat tableformat;
641 tableformat.setHeaderRowCount(1);
642 tableformat.setCellPadding(4.0);
643 tableformat.setCellSpacing(0);
644 tableformat.setBorderStyle(QTextFrameFormat::BorderStyle_Solid);
645 tableformat.setBorder(0.5);
648 shortcutTitleToColumn << qMakePair(
i18n(
"Main:"), LocalPrimary);
649 shortcutTitleToColumn << qMakePair(
i18n(
"Alternate:"), LocalAlternate);
650 shortcutTitleToColumn << qMakePair(
i18n(
"Global:"), GlobalPrimary);
652 for (
int i = 0; i < root->childCount(); i++) {
653 QTreeWidgetItem* item = root->child(i);
654 cursor.insertBlock(componentBlockFormat, componentFormat);
655 cursor.insertText(item->text(0));
657 QTextTable* table = cursor.insertTable(1,3);
658 table->setFormat(tableformat);
661 QTextTableCell cell = table->cellAt(currow,0);
662 QTextCharFormat format = cell.format();
663 format.setFontWeight(QFont::Bold);
664 cell.setFormat(format);
665 cell.firstCursorPosition().insertText(
i18n(
"Action Name"));
667 cell = table->cellAt(currow,1);
668 cell.setFormat(format);
669 cell.firstCursorPosition().insertText(
i18n(
"Shortcuts"));
671 cell = table->cellAt(currow,2);
672 cell.setFormat(format);
673 cell.firstCursorPosition().insertText(
i18n(
"Description"));
676 for (QTreeWidgetItemIterator it(item); *it; ++it) {
677 if ((*it)->type() != ActionItem)
680 KShortcutsEditorItem* editoritem =
static_cast<KShortcutsEditorItem*
>(*it);
681 table->insertRows(table->rows(),1);
682 QVariant data = editoritem->data(Name,Qt::DisplayRole);
683 table->cellAt(currow, 0).firstCursorPosition().insertText(data.toString());
685 QTextTable* shortcutTable = 0 ;
686 for(
int k = 0; k < shortcutTitleToColumn.count(); k++) {
687 data = editoritem->data(shortcutTitleToColumn.at(k).second,Qt::DisplayRole);
688 QString key = data.value<QKeySequence>().toString();
691 if( !shortcutTable ) {
692 shortcutTable = table->cellAt(currow, 1).firstCursorPosition().insertTable(1,2);
693 QTextTableFormat shortcutTableFormat = tableformat;
694 shortcutTableFormat.setCellSpacing(0.0);
695 shortcutTableFormat.setHeaderRowCount(0);
696 shortcutTableFormat.setBorder(0.0);
697 shortcutTable->setFormat(shortcutTableFormat);
699 shortcutTable->insertRows(shortcutTable->rows(),1);
701 shortcutTable->cellAt(shortcutTable->rows()-1,0).firstCursorPosition().insertText(shortcutTitleToColumn.at(k).first);
702 shortcutTable->cellAt(shortcutTable->rows()-1,1).firstCursorPosition().insertText(key);
706 KAction* action = editoritem->m_action;
707 cell = table->cellAt(currow, 2);
708 format = cell.format();
709 format.setProperty(QTextFormat::FontSizeAdjustment, -1);
710 cell.setFormat(format);
711 cell.firstCursorPosition().insertHtml(action->whatsThis());
717 cursor.endEditBlock();
721 if (dlg->exec() == QDialog::Accepted) {
728 #include "kshortcutseditor.moc"
void writeConfiguration(KConfigGroup *config=0) const
Write the current settings to the config object.
void message(KMessage::MessageType messageType, const QString &text, const QString &caption=QString())
void undoChanges()
Undo all change made since the last commit().
QString i18n(const char *text)
Categorize actions for KShortcutsEditor.
A container for a set of QAction objects.
bool isValid() const
Return true if this gesture is valid.
KComponentData componentData() const
The KComponentData with which this class is associated.
KShapeGesture shapeGesture(ShortcutTypes type=ActiveShortcut) const
void exportConfiguration(KConfig *config) const
Export the current setting to configuration config.
const char * name(StandardAction id)
This will return the internal name of a given standard action.
static QDebug kError(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
Defines platform-independent classes for keyboard shortcut handling.
void writeSettings(KConfigGroup *config=0, bool writeDefaults=false, QAction *oneAction=0) const
Write the current configurable key associations to config.
void commit()
Commit the changes without saving.
const KAboutData * aboutData() const
The shortcut is a default shortcut - it becomes active when somebody decides to reset shortcuts to de...
QPrintDialog * createPrintDialog(QPrinter *printer, PageSelectPolicy pageSelectPolicy, const QList< QWidget * > &customTabs, QWidget *parent=0)
QString i18nc(const char *ctxt, const char *text)
void printShortcuts() const
Opens a printing dialog to print all the shortcuts.
Represents a keyboard shortcut.
void clearCollections()
Removes all action collections from the editor.
An abstract class for GUI data such as ToolTip and Icon.
QList< QAction * > actions() const
Returns the list of KActions which belong to this action collection.
Actions which are triggered by any keypress in the windowing system.
void save()
Save the changes.
Widget for configuration of KAccel and KGlobalAccel.
bool isModified() const
Are the unsaved changes?
void importConfiguration(KConfig *config)
Import the settings from configuration config.
void resizeColumns()
Resize columns to width required.
QKeySequence alternate() const
Returns the alternate key sequence of this shortcut.
void allDefault()
Set all shortcuts to their default values (bindings).
Letter shortcuts are allowed.
void addCollection(KActionCollection *, const QString &title=QString())
Insert an action collection, i.e.
QString rockerName() const
Return a user-friendly name of the button combination.
KRockerGesture rockerGesture(ShortcutTypes type=ActiveShortcut) const
void exportGlobalShortcuts(KConfigGroup *config, bool writeDefaults=false) const
Export the current configurable global key associations to config.
static QFont generalFont()
Returns the default general font.
const QList< QAction * > actions() const
Returns the actions belonging to this category.
Class to encapsulate user-driven action or event.
bool isEmpty() const
Returns whether the action collection is empty or not.
const KComponentData & mainComponent()
bool isShortcutConfigurable() const
Returns true if this action's shortcut is configurable.
bool isValid() const
Return true if this gesture is valid.
QKeySequence primary() const
Returns the primary key sequence of this shortcut.
void clearConfiguration()
Removes all configured shortcuts.
static int warningContinueCancel(QWidget *parent, const QString &text, const QString &caption=QString(), const KGuiItem &buttonContinue=KStandardGuiItem::cont(), const KGuiItem &buttonCancel=KStandardGuiItem::cancel(), const QString &dontAskAgainName=QString(), Options options=Notify)
Display a "warning" dialog.
virtual ~KShortcutsEditor()
Destructor.
KShortcutsEditor(KActionCollection *collection, QWidget *parent, ActionTypes actionTypes=AllActions, LetterShortcuts allowLetterShortcuts=LetterShortcutsAllowed)
Constructor.
QString shapeName() const
Return the user-visible name for this gesture's shape, like "triangle" or "line". ...