[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-devel
Subject:    Re: Fwd: Announcing KShortcutAssistant
From:       "Ulrik Mikaelsson" <ulrik.mikaelsson () gmail ! com>
Date:       2007-08-26 22:40:41
Message-ID: 15c1dfa0708261540s72409d9egddd3378b737df0d2 () mail ! gmail ! com
[Download RAW message or body]

Certainly, without the full understanding of the article, the
screenshot will only raise the question "Yes, but why on EARTH would
you DO that to my program?" ;)

Anyways, here's a new patch that should apply cleanly to HEAD@trunk.
It's getting late here, and I gotta get up to work tomorrow. But if I
get some time, I'll try to attach a small screenshot on the wiki-page
tomorrow to show the current state.

Regards
/ Ulrik

On 8/26/07, Andreas Pakulat <apaku@gmx.de> wrote:
> On 26.08.07 20:47:35, Ulrik Mikaelsson wrote:
> > On 8/26/07, Andreas Pakulat <apaku@gmx.de> wrote:
> > > It would have been nice if you could've provided some more information
> > > how that class/code works specifically. What changes did you do?
> >
> > Certainly, although the important part is not the code itself. The
> > code is trivial and probably not optimal (re-generating the
> > KShortcutAssistant-panel on each display, for instance). What's
> > important here is how it affects usability, and if the direction of
> > development is desired.
> >
> > Anyways, the attached patch should pretty much be self-explanatory,
> > but the current concept is;
> >
> > - Create a new core-widget that displays a centered panel containing
> > all available shortcut-actions.
> >   + Currently, the available actions are inferred by examining the
> > menu of the current KMainWindow. (This happens on each display, room
> > for improvements)
> >   + Actions are currently grouped by where in the menu they occur.
> > Probably not desireable, at least they should be grouped by what the
> > complete key-combo looks like (look how it's done in the article.)
> > - Hook up the widget in the main application event-loop (the only
> > place if found where I are guaranteed to see all keydown-events for
> > the ctrl-key.)
> >
> > Don't hesitate to ask for further questions.
>
> Thanks thats mostly what I was looking for (and not having to read that
> full article). Oh, one last thing: Got a screenshot? You know pictures
> say more than a 1000 words ;) Anyway, I guess to fully understand I have
> to read that article (scheduled for tomorrow).
>
> Andreas
>
> --
> Chicken Little only has to be right once.
>
> >> Visit http://mail.kde.org/mailman/listinfo/kde-devel#unsub to unsubscribe <<
>

["kshortcutassistant-r16227.patch" (text/x-patch)]

=== added file 'kdeui/kernel/kshortcutassistant.cpp'
--- kdeui/kernel/kshortcutassistant.cpp	1970-01-01 00:00:00 +0000
+++ kdeui/kernel/kshortcutassistant.cpp	2007-08-26 21:47:12 +0000
@@ -0,0 +1,156 @@
+/* This file is part of the KDE libraries
+    Copyright (C) 2007, Ulrik Mikaelsson (rawler@users.sf.net)
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+#undef QT_NO_TRANSLATION
+#include "kshortcutassistant.h"
+#define QT_NO_TRANSLATION
+
+#include <math.h>
+
+#include <QtCore/QList>
+#include <QtGui/QDesktopWidget>
+#include <QtGui/QFont>
+#include <QtGui/QGridLayout>
+#include <QtGui/QHBoxLayout>
+#include <QtGui/QKeySequence>
+#include <QtGui/QLabel>
+#include <QtGui/QVBoxLayout>
+
+#include "kapplication.h"
+#include "kdebug.h"
+#include "kmainwindow.h"
+#include "kmenubar.h"
+
+class KShortcutAssistant::Private
+{
+public:
+    QGridLayout * grid;
+
+    Private()
+    {
+        makeGrid();
+    }
+
+    void makeGrid()
+    {
+        grid = new QGridLayout();
+        grid->setSpacing(30);
+    }
+};
+
+KShortcutAssistant::KShortcutAssistant() :
+    QWidget(NULL, Qt::Window | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | \
Qt::X11BypassWindowManagerHint), // Need portable support for avoiding the \
keyboard-stuff +    p(new Private)
+{
+    move(20,20);
+    resize(800,800);
+    setLayout(p->grid);
+}
+
+KShortcutAssistant::~KShortcutAssistant()
+{
+
+}
+
+QLayout * KShortcutAssistant::buildGroup(QMenu * sourceMenu)
+{
+    QVBoxLayout *retVal = new QVBoxLayout();
+    retVal->setSpacing(5);
+
+    QLabel * title = new QLabel(sourceMenu->title().remove('&'), this);
+    title->setFont(QFont("Helvetica", 12, QFont::Bold));
+    retVal->addWidget(title);
+    retVal->addSpacing(5);
+
+    foreach (QAction * action, sourceMenu->actions()) {
+        if (!action->shortcut().isEmpty())
+        {
+            QHBoxLayout * actionLayout = new QHBoxLayout();
+            QLabel * iconLabel = new QLabel(this);
+            iconLabel->setPixmap(action->icon().pixmap(16));
+            QLabel * nameLabel = new QLabel(action->text().remove('&'), this);
+            nameLabel->setAlignment(Qt::AlignLeft);
+            QLabel * shortcutLabel = new QLabel(action->shortcut().toString(), \
this); +            shortcutLabel->setAlignment(Qt::AlignRight);
+            actionLayout->addWidget(iconLabel);
+            actionLayout->addWidget(nameLabel);
+            actionLayout->addWidget(shortcutLabel);
+            retVal->addLayout(actionLayout);
+        }
+    }
+
+    return retVal;
+}
+
+void KShortcutAssistant::buildGrid(QMenuBar * sourceMenu)
+{
+    QList<QLayout*> actionGroupLayouts;
+    int cols;
+    int x=0,y=0;
+
+    foreach (QAction * action, sourceMenu->actions()) {
+        if (action->menu()) {
+            QLayout * l = buildGroup(action->menu());
+
+            if (l)
+                actionGroupLayouts << l;
+        }
+    }
+
+    cols = (int)ceil(sqrt(actionGroupLayouts.count()));
+
+    foreach (QLayout *l, actionGroupLayouts) {
+        p->grid->addLayout(l, y, x);
+        x = (x + 1) % cols;
+        if (x == 0)
+            y += 1;
+    }
+}
+
+void KShortcutAssistant::show()
+{
+    QMainWindow * activeWindow = \
qobject_cast<QMainWindow*>(KApplication::kApplication()->activeWindow()); +    \
QMenuBar * activeMenu = activeWindow ? activeWindow->menuBar() : NULL; +
+    if (activeMenu) { // Focus is in a window that has a menu-structure
+        buildGrid(activeMenu); // Build a helper-pane for the menu
+        resize(p->grid->minimumSize());
+
+        QRect screen = \
KApplication::kApplication()->desktop()->screenGeometry(KApplication::kApplication()->focusWidget());
 +        QRect selfRect = geometry();
+        selfRect.setSize(p->grid->minimumSize());
+        selfRect.moveCenter(screen.center());
+        setGeometry(selfRect);
+
+        QWidget::show();
+    }
+}
+
+void KShortcutAssistant::hide()
+{
+    // Destroy internal widget-stuff
+    QWidget::hide();
+
+    while (QLayoutItem * child = p->grid->takeAt(0)) { // Empty the grid-layout
+        p->grid->removeItem(child);
+        delete(child);
+    }
+    foreach (QWidget* child, findChildren<QWidget*>()) // Remove the child-widgets
+        delete(child);
+}

=== added file 'kdeui/kernel/kshortcutassistant.h'
--- kdeui/kernel/kshortcutassistant.h	1970-01-01 00:00:00 +0000
+++ kdeui/kernel/kshortcutassistant.h	2007-08-26 21:47:12 +0000
@@ -0,0 +1,49 @@
+/* This file is part of the KDE libraries
+    Copyright (C) 2007, Ulrik Mikaelsson (rawler@users.sf.net)
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSHORTCUTASSISTANT_H
+#define KSHORTCUTASSISTANT_H
+
+// Version macros. Never put this further down.
+#include "kdeversion.h"
+#include <kdeui_export.h>
+
+#include <QtGui/QMenu>
+#include <QtGui/QMenuBar>
+#include <QtGui/QLayout>
+
+class KDEUI_EXPORT KShortcutAssistant : public QWidget
+{
+  Q_OBJECT
+public:
+  explicit KShortcutAssistant();
+  virtual ~KShortcutAssistant();
+
+  virtual void show();
+  virtual void hide();
+
+private:
+  QLayout* buildGroup(QMenu* sourceMenu);
+  void buildGrid(QMenuBar* sourceMenu);
+
+  class Private;
+  Private * const p;
+};
+
+#endif

=== modified file 'kdeui/CMakeLists.txt'
--- kdeui/CMakeLists.txt	2007-08-21 18:14:24 +0000
+++ kdeui/CMakeLists.txt	2007-08-26 22:09:21 +0000
@@ -111,6 +111,7 @@
  kernel/kclipboard.cpp
  kernel/kuniqueapplication.cpp
  kernel/ksessionmanager.cpp
+ kernel/kshortcutassistant.cpp
  kernel/kstyle.cpp
  kernel/kstartupinfo.cpp
  kernel/kglobalsettings.cpp
@@ -364,6 +365,7 @@
  kernel/kapplication.h
  kernel/kuniqueapplication.h
  kernel/ksessionmanager.h
+ kernel/kshortcutassistant.h
  kernel/kstyle.h
  kernel/kstartupinfo.h
  kernel/kglobalsettings.h

=== modified file 'kdeui/kernel/kapplication.cpp'
--- kdeui/kernel/kapplication.cpp	2007-08-20 21:33:16 +0000
+++ kdeui/kernel/kapplication.cpp	2007-08-26 22:03:04 +0000
@@ -53,6 +53,7 @@
 #include "ksessionmanager.h"
 #include "kstandarddirs.h"
 #include "kstandardshortcut.h"
+#include "kshortcutassistant.h"
 #include "ktoolinvocation.h"
 #include "kgesturemap.h"
 #include "kurl.h"
@@ -160,6 +161,7 @@
   Private(const QByteArray &cName)
       : componentData(cName),
       checkAccelerators(0),
+      shortcutAssistant(0),
       startup_id("0"),
       app_started_timer(0),
       session_save(false)
@@ -176,6 +178,7 @@
   Private(const KComponentData &cData)
       : componentData(cData),
       checkAccelerators(0),
+      shortcutAssistant(0),
       startup_id("0"),
       app_started_timer(0),
       session_save(false)
@@ -192,6 +195,7 @@
   Private()
       : componentData(KCmdLineArgs::aboutData()),
       checkAccelerators(0),
+      shortcutAssistant(0),
       startup_id( "0" ),
       app_started_timer( 0 ),
       session_save( false )
@@ -211,6 +215,7 @@
 
   KComponentData componentData;
   KCheckAccelerators* checkAccelerators;
+  KShortcutAssistant* shortcutAssistant;
   QByteArray startup_id;
   QTimer* app_started_timer;
   bool session_save;
@@ -277,6 +282,7 @@
 bool KApplication::notify(QObject *receiver, QEvent *event)
 {
     QEvent::Type t = event->type();
+    QKeyEvent *ke;
     if( t == QEvent::Show && receiver->isWidgetType())
     {
         QWidget* w = static_cast< QWidget* >( receiver );
@@ -296,7 +302,13 @@
                 d->app_started_timer->start( 0 );
             }
         }
+    } else if ( (ke = dynamic_cast<QKeyEvent*>(event)) && ke->key() == \
Qt::Key_Control ) { +        if (t == QEvent::KeyPress)
+            d->shortcutAssistant->show();
+        else if (t == QEvent::KeyRelease)
+            d->shortcutAssistant->hide();
     }
+    
     return QApplication::notify(receiver, event);
 }
 
@@ -577,6 +589,7 @@
     KMessage::setMessageHandler( new KMessageBoxMessageHandler(0) );
 
     d->checkAccelerators = new KCheckAccelerators( this );
+    d->shortcutAssistant = new KShortcutAssistant();
     KGestureMap::self()->installEventFilterOnMe( this );
 
     connect(KToolInvocation::self(), SIGNAL(kapplication_hook(QStringList&, \
QByteArray&)),



>> Visit http://mail.kde.org/mailman/listinfo/kde-devel#unsub to unsubscribe <<


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic