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

List:       kde-core-devel
Subject:    [PATCH] KToggleToolbarAction, KWidgetAction
From:       John Firebaugh <jfirebaugh () kde ! org>
Date:       2002-04-08 2:45:36
[Download RAW message or body]

The attached patch adds two new KAction-subclasses: KToggleToolbarAction and 
KWidgetAction. The first handles everything associated with a "Show ___ 
Toolbar" menu item, including updating itself when the toolbar is shown or 
hidden programmatically. Use of this class will make bugs like "Bug#40413: 
Selections in Settings are displayed incorrectly" easy to fix. The second 
provides an easy way to insert custom widgets into toolbars. It removes the 
necessity of subclassing KAction for every widget you want to insert into a 
toolbar.

To support KToggleToolbarAction I had to make a small change to 
kxmlguibuilder: it now queries the main window for the specified toolbar and 
creates a new one only if the query returns null.

Under the hood, use of KToggleToolbarAction changes one thing that may or may 
not be of significance: a toolbar with an associated KToggleToolbarAction 
will always be created, at the time the action is plugged, regardless of 
whether the toolbar is ever used.

Comments, suggestions, objections? If none of the latter, I will commit in 2 
days.

later,
John
["newkactions.diff" (text/x-diff)]

Index: kaction.cpp
===================================================================
RCS file: /home/kde/kdelibs/kdeui/kaction.cpp,v
retrieving revision 1.249
diff -u -3 -p -r1.249 kaction.cpp
--- kaction.cpp	2002/04/05 18:57:36	1.249
+++ kaction.cpp	2002/04/08 02:34:35
@@ -2609,6 +2609,88 @@ KPopupMenu *KToolBarPopupAction::popupMe
 
 ////////
 
+KToggleToolbarAction::KToggleToolbarAction( const char* toolBarName,
+         const QString& text, QObject* parent, const char* name )
+  : KToggleAction( text, KShortcut(), parent, name )
+  , m_toolBarName( toolBarName )
+  , m_toolBar( 0L )
+{
+}
+
+KToggleToolbarAction::~KToggleToolbarAction()
+{
+}
+
+int KToggleToolbarAction::plug( QWidget* w, int index )
+{
+  // Note: topLevelWidget() stops too early, we can't use it.
+  QWidget * tl = w;
+  QWidget * n;
+  while ( !tl->isDialog() && ( n = tl->parentWidget() ) ) // lookup parent and store
+    tl = n;
+
+  KMainWindow * mw = dynamic_cast<KMainWindow *>(tl); // try to see if it's a kmainwindow
+
+  if( mw && (m_toolBar = mw->toolBar( m_toolBarName )) ) {
+    setChecked( m_toolBar->isVisible() );
+    connect( m_toolBar, SIGNAL(visibilityChanged(bool)), this, SLOT(setChecked(bool)) );
+    connect( this, SIGNAL(toggled(bool)), this, SLOT(slotToggled(bool)) );
+  } else {
+    setEnabled( false );
+  }
+
+  return KToggleAction::plug( w, index );
+}
+
+void KToggleToolbarAction::slotToggled( bool checked )
+{
+  if( !m_toolBar || checked == m_toolBar->isVisible() )
+    return;
+  if( checked ) {
+    m_toolBar->show();
+  } else {
+    m_toolBar->hide();
+  }
+}
+
+////////
+
+KWidgetAction::KWidgetAction( QWidget* widget,
+    const QString& text, const KShortcut& cut,
+    const QObject* receiver, const char* slot,
+    KActionCollection* parent, const char* name )
+  : KAction( text, cut, receiver, slot, parent, name )
+  , m_widget( widget )
+{
+}
+
+KWidgetAction::~KWidgetAction()
+{
+}
+
+int KWidgetAction::plug( QWidget* w, int index )
+{
+  if ( !w->inherits( "KToolBar" ) ) {
+    kdError() << "KToggleToolbarAction must be plugged into KToolBar." << endl;
+    return -1;
+  }
+
+  KToolBar* toolBar = static_cast<KToolBar*>( w );
+
+  int id = KAction::getToolButtonID();
+
+  m_widget->reparent( toolBar, QPoint() );
+  toolBar->insertWidget( id, 0, m_widget, index );
+
+  addContainer( toolBar, id );
+  
+  connect( toolBar, SIGNAL( destroyed() ), this, SLOT( slotDestroyed() ) );
+
+  return containerCount() - 1;
+}
+
+////////
+
 KActionSeparator::KActionSeparator( QObject *parent, const char *name )
   : KAction( parent, name )
 {
@@ -3303,6 +3385,12 @@ void KActionMenu::virtual_hook( int id, 
 { KAction::virtual_hook( id, data ); }
 
 void KToolBarPopupAction::virtual_hook( int id, void* data )
+{ KAction::virtual_hook( id, data ); }
+
+void KToggleToolbarAction::virtual_hook( int id, void* data )
+{ KToggleAction::virtual_hook( id, data ); }
+
+void KWidgetAction::virtual_hook( int id, void* data )
 { KAction::virtual_hook( id, data ); }
 
 void KActionSeparator::virtual_hook( int id, void* data )
Index: kaction.h
===================================================================
RCS file: /home/kde/kdelibs/kdeui/kaction.h,v
retrieving revision 1.141
diff -u -3 -p -r1.141 kaction.h
--- kaction.h	2002/04/04 19:13:19	1.141
+++ kaction.h	2002/04/08 02:34:38
@@ -29,6 +29,7 @@
 #include <qkeysequence.h>
 #include <qobject.h>
 #include <qvaluelist.h>
+#include <qguardedptr.h>
 #include <kguiitem.h>
 #include <kshortcut.h>
 #include <kstdaction.h>
@@ -1587,6 +1588,78 @@ protected:
 private:
     class KToolBarPopupActionPrivate;
     KToolBarPopupActionPrivate *d;
+};
+
+/**
+ * An action that takes care of everything associated with
+ * showing or hiding a toolbar by a menu action. It will
+ * show or hide the toolbar with the given name when
+ * activated, and check or uncheck itself if the toolbar
+ * is manually shown or hidden.
+ */
+class KToggleToolbarAction : public KToggleAction
+{
+    Q_OBJECT
+public:
+    /**
+     * Create a KToggleToolbarAction that manages the toolbar
+     * named toolBarName. This can be either the name of a
+     * toolbar in an xml ui file, or a toolbar programmatically
+     * created with that name.
+     */
+    KToggleToolbarAction( const char* toolBarName, const QString& text,
+                          QObject* parent = 0, const char* name = 0 );
+    virtual ~KToggleToolbarAction();
+
+    virtual int plug( QWidget*, int index = -1 );
+protected slots:
+    virtual void slotToggled(bool);
+private:
+    const char*             m_toolBarName;
+    QGuardedPtr<KToolBar>   m_toolBar;
+protected:
+    virtual void virtual_hook( int id, void* data );
+private:
+    class KToggleToolbarActionPrivate;
+    KToggleToolbarActionPrivate *d;
+};
+
+/**
+ * An action that automatically embeds a widget into a
+ * toolbar.
+ */
+class KWidgetAction : public KAction
+{
+    Q_OBJECT
+public:
+    /**
+     * Create an action that will embed widget into a toolbar
+     * when plugged. This action may only be plugged into
+     * a toolbar.
+     */
+    KWidgetAction( QWidget* widget, const QString& text, 
+                   const KShortcut& cut,
+                   const QObject* receiver, const char* slot,
+                   KActionCollection* parent, const char* name );
+    virtual ~KWidgetAction();
+
+    /**
+     * Returns the widget associated with this action.
+     */
+    QWidget* widget() { return m_widget; }
+
+    /**
+     * Plug the action. The widget passed to the constructor
+     * will be reparented to w, which must inherit KToolBar.
+     */
+    virtual int plug( QWidget* w, int index = -1 );
+private:
+    QGuardedPtr<QWidget> m_widget;
+protected:
+    virtual void virtual_hook( int id, void* data );
+private:
+    class KToggleToolbarActionPrivate;
+    KToggleToolbarActionPrivate *d;
 };
 
 class KActionSeparator : public KAction
Index: kxmlguibuilder.cpp
===================================================================
RCS file: /home/kde/kdelibs/kdeui/kxmlguibuilder.cpp,v
retrieving revision 1.54
diff -u -3 -p -r1.54 kxmlguibuilder.cpp
--- kxmlguibuilder.cpp	2002/04/04 03:49:18	1.54
+++ kxmlguibuilder.cpp	2002/04/08 02:34:39
@@ -215,7 +215,13 @@ QWidget *KXMLGUIBuilder::createContainer
   {
     bool honor = (element.attribute( d->attrName ) == "mainToolBar");
 
-    KToolBar *bar = new KToolBar( d->m_widget, element.attribute( d->attrName ).utf8(), honor, false );
+    QCString name = element.attribute( d->attrName ).utf8();
+
+    KToolBar *bar = static_cast<KToolBar*>(d->m_widget->child( name, "KToolBar" ));
+    if( !bar )
+    {
+       bar = new KToolBar( d->m_widget, name, honor, false );
+    }
 
     if ( d->m_widget->inherits( "KMainWindow" ) )
     {


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

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