• Skip to content
  • Skip to link menu
KDE 4.1 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

KDEUI

kshortcutseditor.cpp

Go to the documentation of this file.
00001 /* This file is part of the KDE libraries Copyright (C) 1998 Mark Donohoe <donohoe@kde.org>
00002     Copyright (C) 1997 Nicolas Hadacek <hadacek@kde.org>
00003     Copyright (C) 1998 Matthias Ettrich <ettrich@kde.org>
00004     Copyright (C) 2001 Ellis Whitehead <ellis@kde.org>
00005     Copyright (C) 2006 Hamish Rodda <rodda@kde.org>
00006     Copyright (C) 2007 Roberto Raggi <roberto@kdevelop.org>
00007     Copyright (C) 2007 Andreas Hartmetz <ahartmetz@gmail.com>
00008     Copyright (C) 2008 Michael Jansen <kde@michael-jansen.biz>
00009 
00010     This library is free software; you can redistribute it and/or
00011     modify it under the terms of the GNU Library General Public
00012     License as published by the Free Software Foundation; either
00013     version 2 of the License, or (at your option) any later version.
00014 
00015     This library is distributed in the hope that it will be useful,
00016     but WITHOUT ANY WARRANTY; without even the implied warranty of
00017     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018     Library General Public License for more details.
00019 
00020     You should have received a copy of the GNU Library General Public License
00021     along with this library; see the file COPYING.LIB.  If not, write to
00022     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00023     Boston, MA 02110-1301, USA.
00024 */
00025 
00026 #include "kshortcutseditor.h"
00027 
00028 // The following is needed for KShortcutsEditorPrivate
00029 #include "kshortcutsdialog_p.h"
00030 
00031 #include <QHeaderView>
00032 #include <QTimer>
00033 #include <QTextDocument>
00034 #include <QTextTable>
00035 #include <QTextCursor>
00036 #include <QTextTableFormat>
00037 #include <QPrinter>
00038 #include <QPrintDialog>
00039 
00040 #include "kaction.h"
00041 #include "kactioncollection.h"
00042 #include "kdebug.h"
00043 #include "kglobalaccel.h"
00044 #include "kmessagebox.h"
00045 #include "kaboutdata.h"
00046 
00047 //---------------------------------------------------------------------
00048 // KShortcutsEditor
00049 //---------------------------------------------------------------------
00050 
00051 KShortcutsEditor::KShortcutsEditor(KActionCollection *collection, QWidget *parent, ActionTypes actionType,
00052                                    LetterShortcuts allowLetterShortcuts )
00053 : QWidget( parent )
00054 , d(new KShortcutsEditorPrivate(this))
00055 {
00056     d->initGUI(actionType, allowLetterShortcuts);
00057     addCollection(collection);
00058 }
00059 
00060 
00061 KShortcutsEditor::KShortcutsEditor(QWidget *parent, ActionTypes actionType, LetterShortcuts allowLetterShortcuts)
00062 : QWidget(parent)
00063 , d(new KShortcutsEditorPrivate(this))
00064 {
00065     d->initGUI(actionType, allowLetterShortcuts);
00066 }
00067 
00068 
00069 KShortcutsEditor::~KShortcutsEditor()
00070 {
00071     delete d;
00072 }
00073 
00074 
00075 bool KShortcutsEditor::isModified() const
00076 {
00077     for (QTreeWidgetItemIterator it(d->ui.list); (*it); ++it) {
00078         if ((*it)->childCount())
00079             continue;
00080 
00081         if (static_cast<KShortcutsEditorItem *>(*it)->isModified()) {
00082             return true;
00083         }
00084     }
00085     return false;
00086 }
00087 
00088 void KShortcutsEditor::clearCollections()
00089 {
00090     d->delegate->contractAll();
00091     d->ui.list->clear();
00092     d->actionCollections.clear();
00093     QTimer::singleShot(0, this, SLOT(resizeColumns()));
00094 }
00095 
00096 void KShortcutsEditor::addCollection(KActionCollection *collection, const QString &title)
00097 {
00098     d->actionCollections.append(collection);
00099     enum hierarchyLevel {Root = 0, Program, Group, Action/*unused*/};
00100     KAction *kact;
00101     QTreeWidgetItem *hier[3];
00102     uint l = Program;
00103     hier[Root] = d->ui.list->invisibleRootItem();
00104     hier[Program] = d->findOrMakeItem(hier[Root], title.isEmpty() ? i18n("Shortcuts") : title);
00105     hier[Group] = d->findOrMakeItem(hier[Program], "if you see this, something went wrong");
00106 
00107     foreach (QAction *action, collection->actions()) {
00108         QString name = action->text().remove('&');
00109 
00110         if (name.startsWith(QLatin1String("Program:")))
00111             l = Program;
00112         else if (name.startsWith(QLatin1String("Group:")))
00113             l = Group;
00114         else if (qobject_cast<QAction *>(action)) {
00115             // TODO  non-KAction QActions are not listed
00116             if ((kact = qobject_cast<KAction *>(action)) && kact->isShortcutConfigurable()) {
00117                 // If the shortcut is not configurable skip it
00118                 if (!kact->isShortcutConfigurable()) {
00119                     continue;
00120                 }
00121                 // Create the editor
00122                 new KShortcutsEditorItem((hier[l]), kact);
00123             }
00124             continue;
00125         }
00126         if (!hier[l]->childCount())
00127             delete hier[l];
00128 
00129         hier[l] = d->findOrMakeItem(hier[l - 1], name);
00130     }
00131 
00132     for (l = Group; l >= Program; l--) {
00133         if (!hier[l]->childCount())
00134             delete hier[l];
00135     }
00136 
00137     d->ui.list->sortItems(0, Qt::AscendingOrder);
00138     QTimer::singleShot(0, this, SLOT(resizeColumns()));
00139 }
00140 
00141 void KShortcutsEditor::importConfiguration( KConfig *config)
00142 {
00143     if (d->actionTypes & KShortcutsEditor::GlobalAction) {
00144         QString groupName = "Global Shortcuts";
00145         KConfigGroup group( config, groupName );
00146         foreach (KActionCollection* collection, d->actionCollections) {
00147             collection->importGlobalShortcuts( &group );
00148         }
00149     }
00150     if (d->actionTypes & ~KShortcutsEditor::GlobalAction) {
00151         QString groupName = "Shortcuts";
00152         KConfigGroup group( config, groupName );
00153         foreach (KActionCollection* collection, d->actionCollections) {
00154             collection->readSettings( &group );
00155         }
00156     }
00157 }
00158 
00159 void KShortcutsEditor::exportConfiguration( KConfig *config) const
00160 {
00161     if (d->actionTypes & KShortcutsEditor::GlobalAction) {
00162         QString groupName = "Global Shortcuts";
00163         KConfigGroup group( config, groupName );
00164         foreach (KActionCollection* collection, d->actionCollections) {
00165             collection->exportGlobalShortcuts( &group, true );
00166         }
00167     }
00168     if (d->actionTypes & ~KShortcutsEditor::GlobalAction) {
00169         QString groupName = "Shortcuts";
00170         KConfigGroup group( config, groupName );
00171         foreach (KActionCollection* collection, d->actionCollections) {
00172             collection->writeSettings( &group, true );
00173         }
00174     }
00175 }
00176 
00177 
00178 void KShortcutsEditor::writeConfiguration( KConfigGroup *config) const
00179 {
00180     foreach (KActionCollection* collection, d->actionCollections) {
00181         collection->writeSettings(config);
00182     }
00183 }
00184 
00185 
00186 //slot
00187 void KShortcutsEditor::resizeColumns()
00188 {
00189     for (int i = 0; i < d->ui.list->columnCount(); i++)
00190         d->ui.list->resizeColumnToContents(i);
00191 }
00192 
00193 
00194 void KShortcutsEditor::save()
00195 {
00196     // we have to call commit on all items. If we wouldn't do that they would undo their changes
00197     // upon deletion! That would lead to weird problems. Changes to Global Shortcuts would vanish
00198     // completely. Changes to local shortcuts would vanish for this session.
00199     for (QTreeWidgetItemIterator it(d->ui.list); (*it); ++it) {
00200         if ((*it)->childCount())
00201             continue;
00202 
00203         static_cast<KShortcutsEditorItem *>(*it)->commit();
00204     }
00205 
00206     writeConfiguration();
00207 }
00208 
00209 // KDE5 : rename to undo()
00210 void KShortcutsEditor::undoChanges()
00211 {
00212     //This function used to crash sometimes when invoked by clicking on "cancel"
00213     //with Qt 4.2.something. Apparently items were deleted too early by Qt.
00214     //It seems to work with 4.3-ish Qt versions. Keep an eye on this.
00215     for (QTreeWidgetItemIterator it(d->ui.list); (*it); ++it) {
00216         if ((*it)->childCount())
00217             continue;
00218 
00219         static_cast<KShortcutsEditorItem *>(*it)->undo();
00220     }
00221 }
00222 
00223 
00224 //We ask the user here if there are any conflicts, as opposed to undoChanges().
00225 //They don't do the same thing anyway, this just not to confuse any readers.
00226 //slot
00227 void KShortcutsEditor::allDefault()
00228 {
00229     d->allDefault();
00230 }
00231 
00232 
00233 void KShortcutsEditor::printShortcuts() const
00234 {
00235     d->printShortcuts();
00236 }
00237 
00238 
00239 //---------------------------------------------------------------------
00240 // KShortcutsEditorPrivate
00241 //---------------------------------------------------------------------
00242 
00243 KShortcutsEditorPrivate::KShortcutsEditorPrivate( KShortcutsEditor *q )
00244     :   q(q),
00245         delegate(0)
00246     {}
00247 
00248 void KShortcutsEditorPrivate::initGUI( KShortcutsEditor::ActionTypes types, KShortcutsEditor::LetterShortcuts allowLetterShortcuts )
00249 {
00250 
00251     actionTypes = types;
00252 
00253     ui.setupUi(q);
00254     ui.searchFilter->searchLine()->setTreeWidget(ui.list); // Plug into search line
00255     ui.list->header()->setResizeMode(QHeaderView::ResizeToContents);
00256     ui.list->header()->hideSection(GlobalAlternate);  //not expected to be very useful
00257     ui.list->header()->hideSection(ShapeGesture);  //mouse gestures didn't make it in time...
00258     ui.list->header()->hideSection(RockerGesture);
00259     if (!(actionTypes & KShortcutsEditor::GlobalAction)) {
00260         ui.list->header()->hideSection(GlobalPrimary);
00261     } else if (!(actionTypes & ~KShortcutsEditor::GlobalAction)) {
00262         ui.list->header()->hideSection(LocalPrimary);
00263         ui.list->header()->hideSection(LocalAlternate);
00264     }
00265 
00266     delegate = new KShortcutsEditorDelegate(ui.list,
00267                                            allowLetterShortcuts == KShortcutsEditor::LetterShortcutsAllowed);
00268     ui.list->setItemDelegate(delegate);
00269     ui.list->setSelectionBehavior(QAbstractItemView::SelectItems);
00270     ui.list->setSelectionMode(QAbstractItemView::SingleSelection);
00271     //we have our own editing mechanism
00272     ui.list->setEditTriggers(QAbstractItemView::NoEditTriggers);
00273     ui.list->setAlternatingRowColors(true);
00274 
00275     //TODO listen to changes to global shortcuts
00276     QObject::connect(delegate, SIGNAL(shortcutChanged(QVariant, const QModelIndex &)),
00277                      q, SLOT(capturedShortcut(QVariant, const QModelIndex &)));
00278     //hide the editor widget chen its item becomes hidden
00279     QObject::connect(ui.searchFilter->searchLine(), SIGNAL(hiddenChanged(QTreeWidgetItem *, bool)),
00280                      delegate, SLOT(hiddenBySearchLine(QTreeWidgetItem *, bool)));
00281     
00282     ui.searchFilter->setFocus();
00283 }
00284 
00285 
00286 //a gross hack to make a protected method public
00287 class QTreeWidgetHack : public QTreeWidget
00288 {
00289 public:
00290     QTreeWidgetItem *itemFromIndex(const QModelIndex &index) const
00291         { return QTreeWidget::itemFromIndex(index); }
00292 };
00293 
00294 
00295 void KShortcutsEditorPrivate::allDefault()
00296 {
00297     for (QTreeWidgetItemIterator it(ui.list); (*it); ++it) {
00298         if (!(*it)->parent())
00299             continue;
00300 
00301         KShortcutsEditorItem *item = static_cast<KShortcutsEditorItem *>(*it);
00302         KAction *act = item->m_action;
00303 
00304         if (act->shortcut() != act->shortcut(KAction::DefaultShortcut)) {
00305             changeKeyShortcut(item, LocalPrimary, act->shortcut(KAction::DefaultShortcut).primary());
00306             changeKeyShortcut(item, LocalAlternate, act->shortcut(KAction::DefaultShortcut).alternate());
00307         }
00308 
00309         if (act->globalShortcut() != act->globalShortcut(KAction::DefaultShortcut)) {
00310             changeKeyShortcut(item, GlobalPrimary, act->globalShortcut(KAction::DefaultShortcut).primary());
00311             changeKeyShortcut(item, GlobalAlternate, act->globalShortcut(KAction::DefaultShortcut).alternate());
00312         }
00313 
00314         if (act->shapeGesture() != act->shapeGesture(KAction::DefaultShortcut))
00315             changeShapeGesture(item, act->shapeGesture(KAction::DefaultShortcut));
00316 
00317         if (act->rockerGesture() != act->rockerGesture(KAction::DefaultShortcut))
00318             changeRockerGesture(item, act->rockerGesture(KAction::DefaultShortcut));
00319     }
00320 }
00321 
00322 //static
00323 KShortcutsEditorItem *KShortcutsEditorPrivate::itemFromIndex(QTreeWidget *const w,
00324                                                              const QModelIndex &index)
00325 {
00326     QTreeWidgetItem *item = static_cast<QTreeWidgetHack *>(w)->itemFromIndex(index);
00327     if (item && item->type() == ActionItem) {
00328         return static_cast<KShortcutsEditorItem *>(item);
00329     }
00330     return 0;
00331 }
00332 
00333 
00334 QTreeWidgetItem *KShortcutsEditorPrivate::findOrMakeItem(QTreeWidgetItem *parent, const QString &name)
00335 {
00336     for (int i = 0; i < parent->childCount(); i++) {
00337         QTreeWidgetItem *child = parent->child(i);
00338         if (child->text(0) == name)
00339             return child;
00340     }
00341     QTreeWidgetItem *ret = new QTreeWidgetItem(parent, NonActionItem);
00342     ret->setText(0, name);
00343     ui.list->expandItem(ret);
00344     ret->setFlags(ret->flags() & ~Qt::ItemIsSelectable);
00345     return ret;
00346 }
00347 
00348 
00349 //private slot
00350 void KShortcutsEditorPrivate::capturedShortcut(const QVariant &newShortcut, const QModelIndex &index)
00351 {
00352     //dispatch to the right handler
00353     if (!index.isValid())
00354         return;
00355     int column = index.column();
00356     KShortcutsEditorItem *item = itemFromIndex(ui.list, index);
00357     Q_ASSERT(item);
00358 
00359     if (column >= LocalPrimary && column <= GlobalAlternate)
00360         changeKeyShortcut(item, column, newShortcut.value<QKeySequence>());
00361     else if (column == ShapeGesture)
00362         changeShapeGesture(item, newShortcut.value<KShapeGesture>());
00363     else if (column == RockerGesture)
00364         changeRockerGesture(item, newShortcut.value<KRockerGesture>());
00365 }
00366 
00367 
00368 void KShortcutsEditorPrivate::changeKeyShortcut(KShortcutsEditorItem *item, uint column, const QKeySequence &capture)
00369 {
00370     if (capture == item->keySequence(column))
00371         return;
00372 
00373     if (!capture.isEmpty()) {
00374         unsigned int i = 0;
00375 
00376         //refuse to assign a global shortcut occupied by a standard shortcut
00377         if (column == GlobalPrimary || column == GlobalAlternate) {
00378             KStandardShortcut::StandardShortcut ssc = KStandardShortcut::find(capture);
00379             if (ssc != KStandardShortcut::AccelNone && !stealStandardShortcut(ssc, capture)) {
00380                 return;
00381             }
00382         }
00383 
00384         //find conflicting shortcuts in this application
00385         bool conflict = false;
00386         KShortcutsEditorItem *otherItem = 0;
00387         for (QTreeWidgetItemIterator it(ui.list); (*it) && !conflict; ++it) {
00388             //when moving around a shortcut in the same action item the intent is clear
00389             //and we don't need to ask about conflicts
00390             if ((*it)->childCount() || (*it == item))
00391                 continue;
00392 
00393             otherItem = static_cast<KShortcutsEditorItem *>(*it);
00394 
00395             // We only check for conflicts with local shortcuts. If the app
00396             // has global shortcuts we will check against them below with the
00397             // global shortcuts of other applications
00398             for (i = LocalPrimary; i <= LocalAlternate; i++) {
00399                 if (capture == otherItem->keySequence(i)) {
00400                     conflict = true;
00401                     break;
00402                 }
00403             }
00404         }
00405 
00406         if (conflict && !stealShortcut(otherItem, i, capture))
00407             return;
00408 
00409         //check for conflicts with other applications' global shortcuts
00410         QStringList conflicting = KGlobalAccel::findActionNameSystemwide(capture);
00411         if (!conflicting.isEmpty()) {
00412             if (KGlobalAccel::promptStealShortcutSystemwide(0/*TODO:right?*/, conflicting, capture)) {
00413                 KGlobalAccel::stealShortcutSystemwide(capture);
00414             } else {
00415                 return;
00416             }
00417         }
00418     }
00419 
00420     item->setKeySequence(column, capture);
00421     q->keyChange();
00422     //force view update
00423     item->setText(column, capture.toString(QKeySequence::NativeText));
00424 }
00425 
00426 
00427 void KShortcutsEditorPrivate::changeShapeGesture(KShortcutsEditorItem *item, const KShapeGesture &capture)
00428 {
00429     if (capture == item->m_action->shapeGesture())
00430         return;
00431 
00432     if (capture.isValid()) {
00433         bool conflict = false;
00434         KShortcutsEditorItem *otherItem;
00435 
00436         //search for conflicts
00437         for (QTreeWidgetItemIterator it(ui.list); (*it); ++it) {
00438             if (!(*it)->parent() || (*it == item))
00439                 continue;
00440 
00441             otherItem = static_cast<KShortcutsEditorItem *>(*it);
00442 
00443             //comparisons are possibly expensive
00444             if (!otherItem->m_action->shapeGesture().isValid())
00445                 continue;
00446 
00447             if (capture == otherItem->m_action->shapeGesture()) {
00448                 conflict = true;
00449                 break;
00450             }
00451         }
00452 
00453         if (conflict && !stealShapeGesture(otherItem, capture))
00454             return;
00455     }
00456 
00457     item->setShapeGesture(capture);
00458 }
00459 
00460 
00461 void KShortcutsEditorPrivate::changeRockerGesture(KShortcutsEditorItem *item, const KRockerGesture &capture)
00462 {
00463     if (capture == item->m_action->rockerGesture())
00464         return;
00465 
00466     if (capture.isValid()) {
00467         bool conflict = false;
00468         KShortcutsEditorItem *otherItem;
00469 
00470         for (QTreeWidgetItemIterator it(ui.list); (*it); ++it) {
00471             if (!(*it)->parent() || (*it == item))
00472                 continue;
00473 
00474             otherItem = static_cast<KShortcutsEditorItem *>(*it);
00475 
00476             if (capture == otherItem->m_action->rockerGesture()) {
00477                 conflict = true;
00478                 break;
00479             }
00480         }
00481 
00482         if (conflict && !stealRockerGesture(otherItem, capture))
00483             return;
00484     }
00485 
00486     item->setRockerGesture(capture);
00487 }
00488 
00489 
00490 bool KShortcutsEditorPrivate::stealShortcut(KShortcutsEditorItem *item, unsigned int column, const QKeySequence &seq)
00491 {
00492     QString title = i18n("Key Conflict");
00493     QString message = i18n("The '%1' key combination has already been allocated to the \"%2\" action.\n"
00494                            "Do you want to reassign it from that action to the current one?",
00495                            seq.toString(QKeySequence::NativeText), item->m_action->text().remove('&'));
00496 
00497     if (KMessageBox::warningContinueCancel(q, message, title, KGuiItem(i18n("Reassign")))
00498         != KMessageBox::Continue)
00499         return false;
00500 
00501     item->setKeySequence(column - LocalPrimary, QKeySequence());
00502     q->keyChange();
00503     return true;
00504 }
00505 
00506 
00507 bool KShortcutsEditorPrivate::stealStandardShortcut(KStandardShortcut::StandardShortcut std, const QKeySequence &seq)
00508 {
00509     QString title = i18n("Conflict with Standard Application Shortcut");
00510     QString message = i18n("The '%1' key combination is also used for the standard action "
00511                            "\"%2\" that some applications use.\n"
00512                            "Do you really want to use it as a global shortcut as well?",
00513                            seq.toString(QKeySequence::NativeText), KStandardShortcut::name(std));
00514 
00515     if (KMessageBox::warningContinueCancel(q, message, title, KGuiItem(i18n("Reassign"))) != KMessageBox::Continue) {
00516         return false;
00517     }
00518     return true;
00519 }
00520 
00521 
00522 bool KShortcutsEditorPrivate::stealShapeGesture(KShortcutsEditorItem *item, const KShapeGesture &gst)
00523 {
00524     QString title = i18n("Key Conflict");
00525     QString message = i18n("The '%1' shape gesture has already been allocated to the \"%2\" action.\n"
00526                            "Do you want to reassign it from that action to the current one?",
00527                            gst.shapeName(), item->m_action->text());
00528 
00529     if (KMessageBox::warningContinueCancel(q, message, title, KGuiItem(i18n("Reassign")))
00530         != KMessageBox::Continue)
00531         return false;
00532 
00533     item->setShapeGesture(KShapeGesture());
00534     return true;
00535 }
00536 
00537 
00538 bool KShortcutsEditorPrivate::stealRockerGesture(KShortcutsEditorItem *item, const KRockerGesture &gst)
00539 {
00540     QString title = i18n("Key Conflict");
00541     QString message = i18n("The '%1' rocker gesture has already been allocated to the \"%2\" action.\n"
00542                            "Do you want to reassign it from that action to the current one?",
00543                            gst.rockerName(), item->m_action->text());
00544 
00545     if (KMessageBox::warningContinueCancel(q, message, title, KGuiItem(i18n("Reassign")))
00546         != KMessageBox::Continue)
00547         return false;
00548 
00549     item->setRockerGesture(KRockerGesture());
00550     return true;
00551 }
00552 
00553 
00554 //TODO have KGlobalAccel emit a signal on changes, connect it to this, do what needs to be done
00555 //slot
00556 void KShortcutsEditorPrivate::globalSettingsChangedSystemwide(int which)
00557 {
00558     Q_UNUSED(which)
00559     //update display or similar
00560 }
00561 
00562 /*TODO for the printShortcuts function
00563 Nice to have features (which I'm not sure I can do before may due to
00564 more important things):
00565 
00566 - adjust the general page borders, IMHO they're too wide
00567 
00568 - add a custom printer options page that allows to filter out all
00569   actions that don't have a shortcut set to reduce this list. IMHO this
00570   should be optional as people might want to simply print all and  when
00571   they find a new action that they assign a shortcut they can simply use
00572   a pen to fill out the empty space
00573 
00574 - find a way to align the Main/Alternate/Global entries in the shortcuts
00575   column without adding borders. I first did this without a nested table
00576   but instead simply added 3 rows and merged the 3 cells in the Action
00577   name and description column, but unfortunately I didn't find a way to
00578   remove the borders between the 6 shortcut cells.
00579 */
00580 void KShortcutsEditorPrivate::printShortcuts() const
00581 {
00582     QTreeWidgetItem* root = ui.list->invisibleRootItem();
00583     QTextDocument doc;
00584     doc.setDefaultFont(KGlobalSettings::generalFont());
00585     QTextCursor cursor(&doc);
00586     cursor.beginEditBlock();
00587     QTextCharFormat headerFormat;
00588     headerFormat.setProperty(QTextFormat::FontSizeAdjustment, 3);
00589     headerFormat.setFontWeight(QFont::Bold);
00590     cursor.insertText(i18nc("header for an applications shortcut list","Shortcuts for %1",
00591                             KGlobal::mainComponent().aboutData()->programName()),
00592                       headerFormat);
00593     QTextCharFormat componentFormat;
00594     componentFormat.setProperty(QTextFormat::FontSizeAdjustment, 2);
00595     componentFormat.setFontWeight(QFont::Bold);
00596     QTextBlockFormat componentBlockFormat = cursor.blockFormat();
00597     componentBlockFormat.setTopMargin(16);
00598     componentBlockFormat.setBottomMargin(16);
00599     
00600     QTextTableFormat tableformat;
00601     tableformat.setHeaderRowCount(1);
00602     tableformat.setCellPadding(4.0);
00603     tableformat.setCellSpacing(0);
00604     tableformat.setBorderStyle(QTextFrameFormat::BorderStyle_Solid);
00605     tableformat.setBorder(0.5);
00606 
00607     QList<QPair<QString,ColumnDesignation> > shortcutTitleToColumn;
00608     shortcutTitleToColumn << qMakePair(i18n("Main:"), LocalPrimary);
00609     shortcutTitleToColumn << qMakePair(i18n("Alternate:"), LocalAlternate);
00610     shortcutTitleToColumn << qMakePair(i18n("Global:"), GlobalPrimary);
00611     
00612     for (int i = 0; i < root->childCount(); i++) {
00613         QTreeWidgetItem* item = root->child(i);
00614         cursor.insertBlock(componentBlockFormat, componentFormat);
00615         cursor.insertText(item->text(0));
00616         
00617         QTextTable* table = cursor.insertTable(1,3);
00618         table->setFormat(tableformat);
00619         int currow = 0;
00620 
00621         QTextTableCell cell = table->cellAt(currow,0);
00622         QTextCharFormat format = cell.format();
00623         format.setFontWeight(QFont::Bold);
00624         cell.setFormat(format);
00625         cell.firstCursorPosition().insertText(i18n("Action Name"));
00626 
00627         cell = table->cellAt(currow,1);
00628         cell.setFormat(format);
00629         cell.firstCursorPosition().insertText(i18n("Shortcuts"));
00630     
00631         cell = table->cellAt(currow,2);
00632         cell.setFormat(format);
00633         cell.firstCursorPosition().insertText(i18n("Description"));
00634         currow++;
00635       
00636         for (int j = 0; j < item->childCount(); j++) {
00637             QTreeWidgetItem* actionitem = item->child(j);
00638             KShortcutsEditorItem* editoritem = 
00639                     dynamic_cast<KShortcutsEditorItem*>(actionitem);
00640             table->insertRows(table->rows(),1);
00641             QVariant data = editoritem->data(Name,Qt::DisplayRole);
00642             table->cellAt(currow, 0).firstCursorPosition().insertText(data.toString());
00643 
00644             QTextTable* shortcutTable = 0 ;
00645             for(int k = 0; k < shortcutTitleToColumn.count(); k++) {
00646               data = editoritem->data(shortcutTitleToColumn.at(k).second,Qt::DisplayRole);
00647               QString key = data.value<QKeySequence>().toString();
00648 
00649               if(!key.isEmpty()) {
00650                 if( !shortcutTable ) {
00651                   shortcutTable = table->cellAt(currow, 1).firstCursorPosition().insertTable(1,2);
00652                   QTextTableFormat shortcutTableFormat = tableformat;
00653                   shortcutTableFormat.setCellSpacing(0.0);
00654                   shortcutTableFormat.setHeaderRowCount(0);
00655                   shortcutTableFormat.setBorder(0.0);
00656                   shortcutTable->setFormat(shortcutTableFormat);
00657                 } else {
00658                   shortcutTable->insertRows(shortcutTable->rows(),1);
00659                 }
00660                 shortcutTable->cellAt(shortcutTable->rows()-1,0).firstCursorPosition().insertText(shortcutTitleToColumn.at(k).first);
00661                 shortcutTable->cellAt(shortcutTable->rows()-1,1).firstCursorPosition().insertText(key);
00662               }
00663             }
00664 
00665             KAction* action = editoritem->m_action;
00666             cell = table->cellAt(currow, 2);
00667             format = cell.format();
00668             format.setProperty(QTextFormat::FontSizeAdjustment, -1);
00669             cell.setFormat(format);
00670             cell.firstCursorPosition().insertHtml(action->whatsThis());
00671 
00672             currow++;
00673         }
00674         cursor.movePosition(QTextCursor::End);
00675     }
00676     cursor.endEditBlock();
00677     
00678     QPrinter printer;
00679     QPrintDialog dlg(&printer);
00680     if (dlg.exec() == QDialog::Accepted) {
00681         doc.print(&printer);
00682     }
00683 }
00684 
00685 #include "kshortcutseditor.moc"

KDEUI

Skip menu "KDEUI"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • KIO
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • Kross
  • KUtils
  • Nepomuk
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal