[PATCH] KToggleToolbarAction, KWidgetAction

Tobias Koenig tokoe82 at yahoo.de
Tue Apr 16 22:43:27 BST 2002


On Mon, Apr 15, 2002 at 06:48:39PM +0200, Simon Hausmann wrote:
> On Mon, Apr 15, 2002 at 07:32:41AM +0200, Tobias Koenig wrote:
> > On Mon, Apr 08, 2002 at 11:46:02PM -0700, John Firebaugh wrote:
> > > On Monday 08 April 2002 2:10, Tobias Koenig wrote:
> > > > On Mon, Apr 08, 2002 at 10:24:59PM +0200, Wilco Greven wrote:
> > > > > Maybe we should add a KToggleStatusbarAction too for completeness. It
> > > > > could be used in at least KMail and KGhostView.
> > > >
> > > > What is about KToggleMenuBarAction for konsole and maybe some other
> > > > applications?
> > > 
> > > Unfortunately KMenuBar and KStatusBar do not have a visibilityChanged() signal 
> > > like KToolBar, which is necessary for the action to update itself 
> > > automatically. I don't know why QWidget doesn't have a visibilityChanged() 
> > > signal... seems like an oversight to me.
> > 
> > Since QMenuBar and QStatusBar do not have this signal the attached patch add
> > it to KMenuBar and KStatusBar and provide the two new classes
> > KToggleMenuBarAction and KToggleStatusBarAction. Maybe thet TTs could add
> > the signals to QMenuBar and QStatusBar in the future so we can ommit this
> > workaround. Is it ok to commit?
> 
> Frankly, what I dislike is that this patch duplicates a lot of code
> (don't let David see the patch! :) . How about a KWidgetToggleAction
> or something with a better name that abstracts the pattern of
> listening to a certain signal and show/hide a given widget depending
> on that state?
Ok, this is the new patch. I called the class KToggleBarAction
(better suggestions?) and it takes a QWidget pointer as first argument.
So you have to use
	new KToggleBarAction(toolBar(), "Show Toolbar", actionCollection(), "show_toolbar");
	new KToggleBarAction(menuBar(), "Show Menubar", actionCollection(), "show_menubar");
	new KToggleBarAction(statusBar(), "Show Statusbar", actionCollection(), "show_statusbar");
to create the actions.

Is it an acceptable solution?

Ciao,
Tobias
-- 
In a world without walls and fences who
needs Windows and Gates???
-------------- next part --------------
Index: kaction.cpp
===================================================================
RCS file: /home/kde/kdelibs/kdeui/kaction.cpp,v
retrieving revision 1.256
diff -u -b -p -r1.256 kaction.cpp
--- kaction.cpp	2002/04/13 22:21:27	1.256
+++ kaction.cpp	2002/04/16 21:35:51
@@ -55,6 +55,7 @@
 #include <kmainwindow.h>
 #include <kmenubar.h>
 #include <kpopupmenu.h>
+#include <kstatusbar.h>
 #include <kstdaccel.h>
 #include <ktoolbar.h>
 #include <ktoolbarbutton.h>
@@ -123,6 +124,16 @@ static QValueList<int> get_standard_font
     return fontDataBase->standardSizes();
 }
 
+static KMainWindow* findKMainWindow(QWidget* wdg)
+{
+	QWidget * tl = wdg;
+	QWidget * n;
+	while ( !tl->isDialog() && ( n = tl->parentWidget() ) ) // lookup parent and store
+		tl = n;
+
+	return dynamic_cast<KMainWindow *>(tl);
+}
+
 int KAction::getToolButtonID()
 {
     static int toolbutton_no = -2;
@@ -673,17 +684,11 @@ void KAction::unplugAccel()
 
 void KAction::plugMainWindowAccel( QWidget *w )
 {
-  // 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
+  KMainWindow * mw = findKMainWindow(w); // try to see if it's a kmainwindow
   if (mw)
     plugAccel( mw->accel() );
   else
-    kdDebug(129) << "KAction::plugMainWindowAccel: Toplevel widget isn't a KMainWindow, can't plug accel. " << tl << endl;
+    kdDebug(129) << "KAction::plugMainWindowAccel: Toplevel widget isn't a KMainWindow, can't plug accel. " << w << endl;
 }
 
 void KAction::setEnabled(bool enable)
@@ -2610,6 +2615,73 @@ KPopupMenu *KToolBarPopupAction::popupMe
 
 ////////
 
+KToggleBarAction::KToggleBarAction( QWidget* wdg,
+         const QString& text, KActionCollection* parent, const char* name )
+  : KToggleAction( text, KShortcut(), parent, name )
+  , m_toolBarName( 0 )
+  , m_barWidget( wdg )
+  , isToolBar( false )
+{
+    if (wdg->inherits("KToolBar")) {
+	m_toolBarName = wdg->name();
+	isToolBar = true;
+    }
+}
+
+KToggleBarAction::KToggleBarAction( QWidget* wdg, const QString& text,
+         const KShortcut& cut, KActionCollection* parent, const char* name )
+  : KToggleAction( text, cut, parent, name )
+  , m_toolBarName( 0 )
+  , m_barWidget( wdg )
+  , isToolBar( false )
+{
+    if (wdg->inherits("KToolBar")) {
+	m_toolBarName = wdg->name();
+	isToolBar = true;
+    }
+}
+
+KToggleBarAction::~KToggleBarAction()
+{
+}
+
+int KToggleBarAction::plug( QWidget* w, int index )
+{
+    KMainWindow * mw = findKMainWindow(w);
+
+    if( mw ) {
+	if ( !m_barWidget && isToolBar )
+	    m_barWidget = mw->toolBar( m_toolBarName );
+
+	if ( m_barWidget ) {
+	    setChecked( m_barWidget->isVisible() );
+	    connect( m_barWidget, SIGNAL(visibilityChanged(bool)), this, SLOT(setChecked(bool)) );
+	    // Also emit toggled when the toolbar's visibility changes (see comment in header)
+	    connect( m_barWidget, SIGNAL(visibilityChanged(bool)), this, SIGNAL(toggled(bool)) );
+	} else
+	    setEnabled( false );
+    } else {
+	setEnabled( false );
+    }
+
+    return KToggleAction::plug( w, index );
+}
+
+void KToggleBarAction::setChecked( bool c )
+{
+    if( m_barWidget && c != m_barWidget->isVisible() ) {
+	if( c ) {
+	    m_barWidget->show();
+	} else {
+	    m_barWidget->hide();
+	}
+    }
+
+    KToggleAction::setChecked( c );
+}
+
+////////
+
 KToggleToolBarAction::KToggleToolBarAction( const char* toolBarName,
          const QString& text, KActionCollection* parent, const char* name )
   : KToggleAction( text, KShortcut(), parent, name )
@@ -2624,13 +2696,7 @@ KToggleToolBarAction::~KToggleToolBarAct
 
 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
+  KMainWindow * mw = findKMainWindow(w);
 
   if( mw && (m_toolBar = mw->toolBar( m_toolBarName )) ) {
     setChecked( m_toolBar->isVisible() );
@@ -2879,16 +2945,11 @@ void KActionCollection::setWidget( QWidg
 
 void KActionCollection::findMainWindow( QWidget *w )
 {
-  // Note: topLevelWidget() stops too early, we can't use it.
-  QWidget * tl = w;
-  while ( tl->parentWidget() ) // lookup parent and store
-    tl = tl->parentWidget();
-
-  KMainWindow * mw = dynamic_cast<KMainWindow *>(tl); // try to see if it's a kmainwindow
+  KMainWindow * mw = findKMainWindow(w);
   if (mw)
     d->m_mainwindow = mw;
   else
-    kdDebug(129) << "KAction::plugMainWindowAccel: Toplevel widget isn't a KMainWindow, can't plug accel. " << tl << endl;
+    kdDebug(129) << "KAction::plugMainWindowAccel: Toplevel widget isn't a KMainWindow, can't plug accel. " << w << endl;
 }
 
 void KActionCollection::_insert( KAction* action )
@@ -3423,6 +3484,9 @@ void KActionMenu::virtual_hook( int id, 
 
 void KToolBarPopupAction::virtual_hook( int id, void* data )
 { KAction::virtual_hook( id, data ); }
+
+void KToggleBarAction::virtual_hook( int id, void* data )
+{ KToggleAction::virtual_hook( id, data ); }
 
 void KToggleToolBarAction::virtual_hook( int id, void* data )
 { KToggleAction::virtual_hook( id, data ); }
Index: kaction.h
===================================================================
RCS file: /home/kde/kdelibs/kdeui/kaction.h,v
retrieving revision 1.147
diff -u -b -p -r1.147 kaction.h
--- kaction.h	2002/04/13 22:21:27	1.147
+++ kaction.h	2002/04/16 21:35:55
@@ -49,6 +49,8 @@ class KConfigBase;
 class KURL;
 class KInstance;
 class KToolBar;
+class KMenuBar;
+class KStatusBar;
 class KActionCollection;
 class KPopupMenu;
 
@@ -1631,6 +1633,47 @@ private:
     KToggleToolBarActionPrivate *d;
 };
 
+
+/**
+ * An action that takes care of everything associated with
+ * showing or hiding a toolbar, menubar or statusbar by a menu
+ * action. It will show or hide the bar when activated, and check or
+ * uncheck itself if the bar is manually shown or hidden.
+ */
+class KToggleBarAction : public KToggleAction
+{
+    Q_OBJECT
+public:
+    /**
+     * Create a KToggleBarAction that manages the bar.
+     */
+    KToggleBarAction(QWidget* wdg, const QString& text,
+    		KActionCollection* parent = 0, const char* name = 0);
+
+    KToggleBarAction(QWidget* wdg, const QString& text, const KShortcut& cut,
+    		KActionCollection* parent = 0, const char* name = 0);
+
+    virtual ~KToggleBarAction();
+
+    virtual int plug( QWidget*, int index = -1 );
+
+public slots:
+    virtual void setChecked( bool );
+
+private:
+    QCString			m_toolBarName;
+    QGuardedPtr<QWidget>	m_barWidget;
+    bool			isToolBar;
+
+protected:
+    virtual void virtual_hook( int id, void* data );
+
+private:
+    class KToggleBarActionPrivate;
+    KToggleBarActionPrivate *d;
+};
+
+
 /**
  * An action that automatically embeds a widget into a
  * toolbar.
@@ -1676,6 +1719,7 @@ private:
     class KWidgetActionPrivate;
     KWidgetActionPrivate *d;
 };
+
 
 class KActionSeparator : public KAction
 {
Index: kstatusbar.cpp
===================================================================
RCS file: /home/kde/kdelibs/kdeui/kstatusbar.cpp,v
retrieving revision 1.42
diff -u -b -p -r1.42 kstatusbar.cpp
--- kstatusbar.cpp	2001/10/12 10:13:53	1.42
+++ kstatusbar.cpp	2002/04/16 21:35:55
@@ -136,6 +136,20 @@ void KStatusBar::setItemFixed(int id, in
     kdDebug() << "KStatusBar::setItemFixed: bad item id: " << id << endl;
 }
 
+void KStatusBar::showEvent(QShowEvent* e)
+{
+  emit visibilityChanged(true);
+
+  QStatusBar::showEvent(e);
+}
+
+void KStatusBar::hideEvent(QHideEvent* e)
+{
+  emit visibilityChanged(false);
+
+  QStatusBar::hideEvent(e);
+}
+
 #include "kstatusbar.moc"
 
 //Eh!!!
Index: kstatusbar.h
===================================================================
RCS file: /home/kde/kdelibs/kdeui/kstatusbar.h,v
retrieving revision 1.34
diff -u -b -p -r1.34 kstatusbar.h
--- kstatusbar.h	2002/03/04 00:51:51	1.34
+++ kstatusbar.h	2002/04/16 21:35:56
@@ -178,6 +178,15 @@ signals:
    */
   void released( int );
 
+  /**
+   *  Emitted when member function show() or hide() are called.
+   */
+  void visibilityChanged( bool );
+
+protected:
+  void showEvent( QShowEvent* );
+  void hideEvent( QHideEvent* );
+
 private:
   QIntDict<KStatusBarLabel> items;
   class KStatusBarPrivate* d;
Index: kmenubar.cpp
===================================================================
RCS file: /home/kde/kdelibs/kdeui/kmenubar.cpp,v
retrieving revision 1.157
diff -u -b -p -r1.157 kmenubar.cpp
--- kmenubar.cpp	2002/03/20 07:45:32	1.157
+++ kmenubar.cpp	2002/04/16 21:35:56
@@ -174,6 +174,15 @@ void KMenuBar::showEvent( QShowEvent *e 
 #endif
     }
     QMenuBar::showEvent(e);
+
+    emit visibilityChanged( true );
+}
+
+void KMenuBar::hideEvent( QHideEvent *e )
+{
+    QMenuBar::hideEvent(e);
+
+    emit visibilityChanged( false );
 }
 
 void KMenuBar::setGeometry( int x, int y, int w, int h )
Index: kmenubar.h
===================================================================
RCS file: /home/kde/kdelibs/kdeui/kmenubar.h,v
retrieving revision 1.51
diff -u -b -p -r1.51 kmenubar.h
--- kmenubar.h	2002/03/20 07:45:32	1.51
+++ kmenubar.h	2002/04/16 21:35:56
@@ -75,11 +75,16 @@ public:
     virtual void        setGeometry( int x, int y, int w, int h );
 
     virtual void show();
+
+signals:
+    void visibilityChanged( bool );
+
 protected slots:
     void slotReadConfig();
 
 protected:
     void showEvent( QShowEvent* );
+    void hideEvent( QHideEvent* );
     bool eventFilter(QObject *, QEvent *);
 
 protected:


More information about the kde-core-devel mailing list