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

List:       kde-core-devel
Subject:    PATCH: defining actions enabled/disabled status in XML
From:       Guillaume Laurent <glaurent () telegraph-road ! org>
Date:       2001-11-01 10:44:11
[Download RAW message or body]

I'd like to commit the attached patch to CVS Head. What it does is allowing 
the definition of "state changes" in an XML rc file, to make easier the 
management of actions' enable/disable status. This is done through a new slot 
in KMainWindow : stateChanged(const QString&);

For instance, you can define something like :

<State name="file_changed">
  <enable>
    <Action name="file_save"/>
    <Action name="edit_undo"/>
  </enable>
</State>

in your application's rc file, then in the relevant place of your code just do
stateChanged("file_changed"), which will enable the "file_save" and 
"edit_undo" actions.

Another example :

<State name="file_loaded">
  <enable>
    <Action name="file_close"/>
  </enable>
  <disable>
    <Action name="file_save"/>
  </disable>
</State>

Then after loading a file you simply call stateChanged("file_loaded"), which 
will enable "file_close" and disable "file_save".

The state names are free form strings.

-- 
					Guillaume.
					http://www.telegraph-road.org

["patch" (text/x-diff)]

? patch
? Makefile.bk
? tests/Makefile.bk
Index: kmainwindow.cpp
===================================================================
RCS file: /home/kde/kdelibs/kdeui/kmainwindow.cpp,v
retrieving revision 1.52
diff -u -b -p -u -r1.52 kmainwindow.cpp
--- kmainwindow.cpp	2001/10/12 14:27:56	1.52
+++ kmainwindow.cpp	2001/11/01 10:18:17
@@ -27,6 +27,7 @@
 #include <qobjectlist.h>
 
 #include <kaccel.h>
+#include <kaction.h>
 #include <kapplication.h>
 #include <kconfig.h>
 #include <kdebug.h>
@@ -435,6 +436,31 @@ void KMainWindow::appHelpActivated( void
     mHelpMenu->appHelpActivated();
 }
 
+void KMainWindow::stateChanged(const QString &newstate)
+{
+    QStringList actionsToEnable = getActionsToEnableForState(newstate),
+        actionsToDisable =  getActionsToDisableForState(newstate);
+
+    // Enable actions which need to be enabled...
+    //
+    for ( QStringList::Iterator it = actionsToEnable.begin();
+          it != actionsToEnable.end(); ++it ) {
+
+        KAction *action = actionCollection()->action((*it).latin1());
+        if (action) action->setEnabled(true);
+    }
+
+    // and disable actions which need to be disabled...
+    //
+    for ( QStringList::Iterator it = actionsToDisable.begin();
+          it != actionsToDisable.end(); ++it ) {
+
+        KAction *action = actionCollection()->action((*it).latin1());
+        if (action) action->setEnabled(false);
+    }
+
+    
+}
 
 void KMainWindow::closeEvent ( QCloseEvent *e )
 {
Index: kmainwindow.h
===================================================================
RCS file: /home/kde/kdelibs/kdeui/kmainwindow.h,v
retrieving revision 1.30
diff -u -b -p -u -r1.30 kmainwindow.h
--- kmainwindow.h	2001/10/26 21:52:58	1.30
+++ kmainwindow.h	2001/11/01 10:18:17
@@ -431,6 +431,13 @@ public slots:
     void appHelpActivated( void );
 
     /**
+     * Apply a state change
+     *
+     * Enable and disable actions as defined in the XML rc file
+     */
+    void stateChanged(const QString &newstate);
+
+    /**
      * @internal. Used for the auto-save-settings feature.
      */
     void setSettingsDirty();
Index: kxmlguibuilder.cpp
===================================================================
RCS file: /home/kde/kdelibs/kdeui/kxmlguibuilder.cpp,v
retrieving revision 1.46
diff -u -b -p -u -r1.46 kxmlguibuilder.cpp
--- kxmlguibuilder.cpp	2001/10/12 10:13:53	1.46
+++ kxmlguibuilder.cpp	2001/11/01 10:18:17
@@ -45,6 +45,7 @@ public:
     QString tagMenu;
     QString tagToolBar;
     QString tagStatusBar;
+    QString tagState;
 
     QString tagSeparator;
     QString tagTearOffHandle;
@@ -80,6 +81,7 @@ KXMLGUIBuilder::KXMLGUIBuilder( QWidget 
   d->tagMenu = QString::fromLatin1( "menu" );
   d->tagToolBar = QString::fromLatin1( "toolbar" );
   d->tagStatusBar = QString::fromLatin1( "statusbar" );
+  d->tagState = QString::fromLatin1( "state" );
 
   d->tagSeparator = QString::fromLatin1( "separator" );
   d->tagTearOffHandle = QString::fromLatin1( "tearoffhandle" );
@@ -112,7 +114,9 @@ KXMLGUIBuilder::~KXMLGUIBuilder()
 QStringList KXMLGUIBuilder::containerTags() const
 {
   QStringList res;
-  res << d->tagMenu << d->tagToolBar << d->tagMainWindow << d->tagMenuBar << d->tagStatusBar;
+  res << d->tagMenu << d->tagToolBar << d->tagMainWindow << d->tagMenuBar << d->tagStatusBar
+      << d->tagState;
+
   return res;
 }
 
Index: kxmlguiclient.cpp
===================================================================
RCS file: /home/kde/kdelibs/kdeui/kxmlguiclient.cpp,v
retrieving revision 1.55
diff -u -b -p -u -r1.55 kxmlguiclient.cpp
--- kxmlguiclient.cpp	2001/10/20 22:48:25	1.55
+++ kxmlguiclient.cpp	2001/11/01 10:18:18
@@ -772,3 +772,37 @@ void KXMLGUIClient::storeActionPropertie
       action.setAttribute( attrIt.key(), attrIt.data() );
   }
 }
+
+void KXMLGUIClient::addStateActionEnabled(const QString& state,
+                                          const QString& action)
+{
+  QStringList actions = m_enabledActionsStateMap[state];
+  
+  actions.append( action );
+
+  m_enabledActionsStateMap.replace( state, actions );
+}
+
+
+void KXMLGUIClient::addStateActionDisabled(const QString& state,
+                                           const QString& action)
+{
+  QStringList actions = m_disabledActionsStateMap[state];
+  
+  actions.append( action );
+
+  m_disabledActionsStateMap.replace( state, actions );
+}
+
+
+QStringList KXMLGUIClient::getActionsToEnableForState(const QString& state)
+{
+  return m_enabledActionsStateMap[state];
+}
+
+
+QStringList KXMLGUIClient::getActionsToDisableForState(const QString& state)
+{
+  return m_disabledActionsStateMap[state];
+}
+
Index: kxmlguiclient.h
===================================================================
RCS file: /home/kde/kdelibs/kdeui/kxmlguiclient.h,v
retrieving revision 1.29
diff -u -b -p -u -r1.29 kxmlguiclient.h
--- kxmlguiclient.h	2001/10/15 21:02:40	1.29
+++ kxmlguiclient.h	2001/11/01 10:18:18
@@ -187,6 +187,14 @@ public:
 
   static QString findMostRecentXMLFile( const QStringList &files, QString &doc );
 
+  void addStateActionEnabled(const QString& state, const QString& action);
+
+  void addStateActionDisabled(const QString& state, const QString& action);
+
+  QStringList getActionsToEnableForState(const QString& state);
+
+  QStringList getActionsToDisableForState(const QString& state);
+  
 protected:
   /**
    * Sets the instance (@ref KInstance) for this part.
@@ -255,6 +263,9 @@ private:
   static void storeActionProperties( QDomDocument &doc, const ActionPropertiesMap &properties );
 
   static QString findVersionNumber( const QString &_xml );
+
+  QMap<QString,QStringList> m_enabledActionsStateMap;
+  QMap<QString,QStringList> m_disabledActionsStateMap;
 
   KXMLGUIClientPrivate *d;
 };
Index: kxmlguifactory.cpp
===================================================================
RCS file: /home/kde/kdelibs/kdeui/kxmlguifactory.cpp,v
retrieving revision 1.105
diff -u -b -p -u -r1.105 kxmlguifactory.cpp
--- kxmlguifactory.cpp	2001/10/20 22:48:25	1.105
+++ kxmlguifactory.cpp	2001/11/01 10:18:19
@@ -673,6 +673,7 @@ void KXMLGUIFactory::buildRecursive( con
     // some often used QStrings
     static const QString &tagAction = KGlobal::staticQString( "action" );
     static const QString &tagMerge = KGlobal::staticQString( "merge" );
+    static const QString &tagState = KGlobal::staticQString( "state" );
     static const QString &tagDefineGroup = KGlobal::staticQString( "definegroup" );
     static const QString &attrGroup = KGlobal::staticQString( "group" );
 
@@ -836,6 +837,10 @@ void KXMLGUIFactory::buildRecursive( con
             calcMergingIndex( parentNode, QString::null, d->m_currentClientMergingIt,
                               ignoreDefaultMergingIndex );
         }
+        else if ( tag == tagState )
+        {
+          processStateElement( e );
+        }
         else if ( containerTags.findIndex( tag ) != -1 )
         {
             /*
@@ -1336,5 +1341,43 @@ void KXMLGUIFactory::unplugActionListRec
     for (; childIt.current(); ++childIt )
         unplugActionListRecursive( childIt.current() );
 }
+
+void KXMLGUIFactory::processStateElement( const QDomElement &element )
+{
+  QString stateName = element.attribute( "name" );
+
+  if ( !stateName || !stateName.length() ) return;
+
+  QDomElement e = element.firstChild().toElement();
+
+  for (; !e.isNull(); e = e.nextSibling().toElement() ) {
+    QString tagName = e.tagName().lower();
+    
+    if ( tagName != "enable" && tagName != "disable" )
+      continue;
+    
+    bool processingActionsToEnable = (tagName == "enable");
+
+    // process action names
+    QDomElement actionEl = e.firstChild().toElement();
+
+    for (; !actionEl.isNull(); actionEl = actionEl.nextSibling().toElement() ) {
+      if ( actionEl.tagName().lower() != "action" ) continue;
+
+      QString actionName = actionEl.attribute( "name" );
+      if ( !actionName || !actionName.length() ) return;
+
+      if ( processingActionsToEnable )
+        m_client->addStateActionEnabled( stateName, actionName );
+      else
+        m_client->addStateActionDisabled( stateName, actionName );
+
+    }
+
+  }
+  
+  
+}
+
 
 #include "kxmlguifactory.moc"
Index: kxmlguifactory.h
===================================================================
RCS file: /home/kde/kdelibs/kdeui/kxmlguifactory.h,v
retrieving revision 1.54
diff -u -b -p -u -r1.54 kxmlguifactory.h
--- kxmlguifactory.h	2001/10/20 22:48:25	1.54
+++ kxmlguifactory.h	2001/11/01 10:18:19
@@ -174,6 +174,8 @@ class KXMLGUIFactory : public QObject
   void plugActionListRecursive( KXMLGUIContainerNode *node );
   void unplugActionListRecursive( KXMLGUIContainerNode *node );
 
+  void processStateElement( const QDomElement &element );
+
   KXMLGUIClient *m_client;
   KXMLGUIBuilder *m_builder;
 


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

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