From 74d8e4fc4a9ec94a3f61464f689e90fb92ada665 Mon Sep 17 00:00:00 2001
From: basos g <noxelia 4t gmail d0t c0m>
Date: Mon, 6 Apr 2009 15:32:33 +0000
Subject: [PATCH 19/20] ADD QT4 Implement slave config update.

Implement the master slave config relationship for list configs
where a change on the master is commited instantly and triggers
a list update procedur on the slave elements.
---
 modules/gui/qt4/components/open_panels.cpp         |    2 +-
 modules/gui/qt4/components/preferences_widgets.cpp |  183 ++++++++++++++------
 modules/gui/qt4/components/preferences_widgets.hpp |   24 ++-
 3 files changed, 152 insertions(+), 57 deletions(-)

diff --git a/modules/gui/qt4/components/open_panels.cpp b/modules/gui/qt4/components/open_panels.cpp
index 97b1399..074ffde 100644
--- a/modules/gui/qt4/components/open_panels.cpp
+++ b/modules/gui/qt4/components/open_panels.cpp
@@ -1244,7 +1244,7 @@ void CaptureOpenPanel::advancedDialog()
         if ( p_item->i_type & CONFIG_HINT || !p_item->b_advanced )
             continue ;
         ConfigControl *config = ConfigControl::createControl(
-                        VLC_OBJECT( p_intf ), p_item, advFrame, gLayout, n );
+                        VLC_OBJECT( p_intf ), p_item, advFrame, gLayout, n, &controls );
         if ( config )
             controls.append( config );
         else
diff --git a/modules/gui/qt4/components/preferences_widgets.cpp b/modules/gui/qt4/components/preferences_widgets.cpp
index ebd01d0..e3ab5ad 100644
--- a/modules/gui/qt4/components/preferences_widgets.cpp
+++ b/modules/gui/qt4/components/preferences_widgets.cpp
@@ -77,7 +77,8 @@ ConfigControl *ConfigControl::createControl( vlc_object_t *p_this,
 ConfigControl *ConfigControl::createControl( vlc_object_t *p_this,
                                              module_config_t *p_item,
                                              QWidget *parent,
-                                             QGridLayout *l, int &line )
+                                             QGridLayout *l, int &line,
+                                             QList<ConfigControl *> *_p_siblings )
 {
     ConfigControl *p_control = NULL;
 
@@ -159,10 +160,15 @@ ConfigControl *ConfigControl::createControl( vlc_object_t *p_this,
     default:
         break;
     }
+    if ( p_control )
+    {
+         p_control->p_siblings = _p_siblings ;
+    }
+
     return p_control;
 }
 
-void ConfigControl::doApply( intf_thread_t *p_intf )
+void ConfigControl::doApply( vlc_object_t *p_obj )
 {
     switch( getType() )
     {
@@ -171,7 +177,7 @@ void ConfigControl::doApply( intf_thread_t *p_intf )
         {
             VIntConfigControl *vicc = qobject_cast<VIntConfigControl *>(this);
             assert( vicc );
-            config_PutInt( p_intf, vicc->getName(), vicc->getValue() );
+            config_PutInt( p_obj, vicc->getName(), vicc->getValue() );
             break;
         }
         case CONFIG_ITEM_FLOAT:
@@ -179,7 +185,7 @@ void ConfigControl::doApply( intf_thread_t *p_intf )
             VFloatConfigControl *vfcc =
                                     qobject_cast<VFloatConfigControl *>(this);
             assert( vfcc );
-            config_PutFloat( p_intf, vfcc->getName(), vfcc->getValue() );
+            config_PutFloat( p_obj, vfcc->getName(), vfcc->getValue() );
             break;
         }
         case CONFIG_ITEM_STRING:
@@ -187,7 +193,7 @@ void ConfigControl::doApply( intf_thread_t *p_intf )
             VStringConfigControl *vscc =
                             qobject_cast<VStringConfigControl *>(this);
             assert( vscc );
-            config_PutPsz( p_intf, vscc->getName(), qtu( vscc->getValue() ) );
+            config_PutPsz( p_obj, vscc->getName(), qtu( vscc->getValue() ) );
             break;
         }
         case CONFIG_ITEM_KEY:
@@ -383,23 +389,8 @@ StringListConfigControl::StringListConfigControl( vlc_object_t *_p_this,
     combo->setMinimumWidth( MINWIDTH_BOX );
     combo->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Preferred );
 
-    module_config_t *p_module_config = config_FindConfig( p_this, p_item->psz_name );
-    if(p_module_config && p_module_config->pf_update_list)
-    {
-       vlc_value_t val;
-       val.psz_string = strdup(p_module_config->value.psz);
-
-       p_module_config->pf_update_list(p_this, p_item->psz_name, val, val, NULL);
+    update();
 
-       // assume in any case that dirty was set to true
-       // because lazy programmes will use the same callback for
-       // this, like the one behind the refresh push button?
-       p_module_config->b_dirty = false;
-
-       free( val.psz_string );
-    }
-
-    finish( p_module_config, bycat );
     if( !l )
     {
         l = new QGridLayout();
@@ -429,6 +420,45 @@ StringListConfigControl::StringListConfigControl( vlc_object_t *_p_this,
         CONNECT( signalMapper, mapped( int ),
                 this, actionRequested( int ) );
     }
+
+    if ( p_item->ppsz_slaves )
+        CONNECT( combo, currentIndexChanged( int ), this, onComboChanged() ) ;
+}
+
+StringListConfigControl::StringListConfigControl( vlc_object_t *_p_this,
+                module_config_t *_p_item, QLabel *_label, QComboBox *_combo,
+                bool bycat ) : VStringConfigControl( _p_this, _p_item )
+{
+    combo = _combo;
+    label = _label;
+
+    update();
+
+    if ( p_item->ppsz_slaves )
+        CONNECT( combo, currentIndexChanged( int ), this, onComboChanged() ) ;
+}
+
+void StringListConfigControl::update()
+{
+    module_config_t *p_module_config = config_FindConfig( p_this, p_item->psz_name );
+    if(p_module_config && p_module_config->pf_update_list)
+    {
+       msg_Dbg( p_this, "Calling list update callback for %s", getName() ) ;
+       vlc_value_t val;
+       val.psz_string = strdup(p_module_config->value.psz);
+
+       p_module_config->pf_update_list(p_this, p_item->psz_name, val, val, NULL);
+
+       // assume in any case that dirty was set to true
+       // because lazy programmes will use the same callback for
+       // this, like the one behind the refresh push button?
+       p_module_config->b_dirty = false;
+
+       free( val.psz_string );
+    }
+
+    combo->clear();
+    finish( p_module_config );
 }
 
 void StringListConfigControl::actionRequested( int i_action )
@@ -448,23 +478,40 @@ void StringListConfigControl::actionRequested( int i_action )
     if( p_module_config->b_dirty )
     {
         combo->clear();
-        finish( p_module_config, true );
+        finish( p_module_config );
         p_module_config->b_dirty = false;
     }
 }
-StringListConfigControl::StringListConfigControl( vlc_object_t *_p_this,
-                module_config_t *_p_item, QLabel *_label, QComboBox *_combo,
-                bool bycat ) : VStringConfigControl( _p_this, _p_item )
+
+void StringListConfigControl::onComboChanged( )
 {
-    combo = _combo;
-    label = _label;
+    if ( !p_item->i_slaves )
+        return ;
 
-    module_config_t *p_module_config = config_FindConfig( p_this, getName() );
+    doApply( p_this ) ; /* save config for possible interconfig reference */
+
+    /* don't bother to update controls if we don't have a siblings list. Assume they will be loaded later */
+    if ( !p_siblings )
+        return ;
+
+    int j,i ;
+    char* psz_slave ;
 
-    finish( p_module_config, bycat );
+    for ( i = 0; i < p_item->i_slaves; i++)
+    {
+        psz_slave = p_item->ppsz_slaves[i] ;
+        for ( j = 0; j < p_siblings->size(); j++ )
+        {
+            ConfigControl* p_control =
+                p_siblings->at(j) ;
+            assert( p_control );
+            if ( !strcmp( p_control->getName(), psz_slave ) )
+                p_control->update() ;
+        }
+    }
 }
 
-void StringListConfigControl::finish(module_config_t *p_module_config, bool bycat )
+void StringListConfigControl::finish(module_config_t *p_module_config)
 {
     combo->setEditable( false );
 
@@ -883,22 +930,8 @@ IntegerListConfigControl::IntegerListConfigControl( vlc_object_t *_p_this,
     combo = new QComboBox();
     combo->setMinimumWidth( MINWIDTH_BOX );
 
-    module_config_t *p_module_config = config_FindConfig( p_this, p_item->psz_name );
-    if(p_module_config && p_module_config->pf_update_list)
-    {
-       vlc_value_t val;
-       val.i_int = p_module_config->value.i;
-
-       p_module_config->pf_update_list(p_this, p_item->psz_name, val, val, NULL);
+    update() ;
 
-       // assume in any case that dirty was set to true
-       // because lazy programmes will use the same callback for
-       // this, like the one behind the refresh push button?
-       p_module_config->b_dirty = false;
-    }
-
-
-    finish( p_module_config, bycat );
     if( !l )
     {
         QHBoxLayout *layout = new QHBoxLayout();
@@ -929,6 +962,9 @@ IntegerListConfigControl::IntegerListConfigControl( vlc_object_t *_p_this,
                 this, actionRequested( int ) );
     }
 
+    if ( p_item->ppsz_slaves )
+        CONNECT( combo, currentIndexChanged( int ), this, onComboChanged() ) ;
+
 }
 IntegerListConfigControl::IntegerListConfigControl( vlc_object_t *_p_this,
                 module_config_t *_p_item, QLabel *_label, QComboBox *_combo,
@@ -937,12 +973,41 @@ IntegerListConfigControl::IntegerListConfigControl( vlc_object_t *_p_this,
     combo = _combo;
     label = _label;
 
-    module_config_t *p_module_config = config_FindConfig( p_this, getName() );
+    update() ;
+
+    if ( p_item->ppsz_slaves )
+        CONNECT( combo, currentIndexChanged( int ), this, onComboChanged() ) ;
+}
 
-    finish( p_module_config, bycat );
+void IntegerListConfigControl::onComboChanged( )
+{
+    if ( !p_item->i_slaves )
+        return ;
+
+    doApply( p_this ) ; /* save config for possible interconfig reference */
+
+    /* don't bother to update controls if we don't have a siblings list. Assume they will be loaded later */
+    if ( !p_siblings )
+        return ;
+
+    int j,i ;
+    char* psz_slave ;
+
+    for ( i = 0; i < p_item->i_slaves; i++)
+    {
+        psz_slave = p_item->ppsz_slaves[i] ;
+        for ( j = 0; j < p_siblings->size(); j++ )
+        {
+            ConfigControl* p_control =
+                p_siblings->at(j) ;
+            assert( p_control );
+            if ( !strcmp( p_control->getName(), psz_slave ) )
+                p_control->update() ;
+        }
+    }
 }
 
-void IntegerListConfigControl::finish(module_config_t *p_module_config, bool bycat )
+void IntegerListConfigControl::finish(module_config_t *p_module_config)
 {
     combo->setEditable( false );
 
@@ -963,6 +1028,26 @@ void IntegerListConfigControl::finish(module_config_t *p_module_config, bool byc
     }
 }
 
+void IntegerListConfigControl::update()
+{
+    module_config_t *p_module_config = config_FindConfig( p_this, p_item->psz_name );
+    if(p_module_config && p_module_config->pf_update_list)
+    {
+       vlc_value_t val;
+       val.i_int = p_module_config->value.i;
+
+       p_module_config->pf_update_list(p_this, p_item->psz_name, val, val, NULL);
+
+       // assume in any case that dirty was set to true
+       // because lazy programmes will use the same callback for
+       // this, like the one behind the refresh push button?
+       p_module_config->b_dirty = false;
+    }
+
+    combo->clear();
+    finish( p_module_config );
+}
+
 void IntegerListConfigControl::actionRequested( int i_action )
 {
     /* Supplementary check for boundaries */
@@ -980,7 +1065,7 @@ void IntegerListConfigControl::actionRequested( int i_action )
     if( p_module_config->b_dirty )
     {
         combo->clear();
-        finish( p_module_config, true );
+        finish( p_module_config );
         p_module_config->b_dirty = false;
     }
 }
diff --git a/modules/gui/qt4/components/preferences_widgets.hpp b/modules/gui/qt4/components/preferences_widgets.hpp
index 05a27c5..ff55231 100644
--- a/modules/gui/qt4/components/preferences_widgets.hpp
+++ b/modules/gui/qt4/components/preferences_widgets.hpp
@@ -58,16 +58,16 @@ class ConfigControl : public QObject
     Q_OBJECT
 public:
     ConfigControl( vlc_object_t *_p_this, module_config_t *_p_conf,
-                   QWidget *p ) : p_this( _p_this ), p_item( _p_conf )
+                   QWidget *p ) : p_this( _p_this ), p_item( _p_conf ), p_siblings( NULL )
     {
         widget = new QWidget( p );
     }
     ConfigControl( vlc_object_t *_p_this, module_config_t *_p_conf ) :
-                            p_this (_p_this ), p_item( _p_conf )
+                            p_this (_p_this ), p_item( _p_conf ), p_siblings( NULL )
     {
         widget = NULL;
     }
-    virtual ~ConfigControl() {};
+    virtual ~ConfigControl() { msg_Dbg(p_this, "Deleting control %s", getName() ); }
     virtual int getType() = 0;
     const char * getName() { return  p_item->psz_name; }
     QWidget *getWidget() { assert( widget ); return widget; }
@@ -77,16 +77,22 @@ public:
 
     static ConfigControl * createControl( vlc_object_t*,
                                           module_config_t*,QWidget* );
+
+    /* p_siblings is an optional arg to a Qlist that has all other configcontrols on the panel. Used for dependency finding */
     static ConfigControl * createControl( vlc_object_t*,
                                           module_config_t*,QWidget*,
-                                          QGridLayout *, int& );
-    void doApply( intf_thread_t *);
+                                          QGridLayout *, int&,
+                                          QList<ConfigControl *> *p_siblings = NULL );
+    void doApply( vlc_object_t *);
+    void doApply( intf_thread_t * p_i) { doApply( (vlc_object_t *) p_i );  }
+    virtual void update() {                } ; /*update a control that has other control dependencies onthefly */
 protected:
     vlc_object_t *p_this;
     module_config_t *p_item;
     QString _name;
     QWidget *widget;
     bool _advanced;
+    QList<ConfigControl *> *p_siblings;
 #if 0
 /* You shouldn't use that now..*/
 signals:
@@ -169,12 +175,14 @@ public:
     virtual int getValue();
     virtual void hide() { combo->hide(); if( label ) label->hide(); }
     virtual void show() { combo->show(); if( label ) label->show(); }
+    virtual void update() ;
 private:
-    void finish(module_config_t *, bool );
+    void finish(module_config_t *);
     QLabel *label;
     QComboBox *combo;
 private slots:
     void actionRequested( int );
+    void onComboChanged() ;
 
 };
 
@@ -383,12 +391,14 @@ public:
     virtual QString getValue();
     virtual void hide() { combo->hide(); if( label ) label->hide(); }
     virtual void show() { combo->show(); if( label ) label->show(); }
+    virtual void update() ;
     QComboBox *combo;
 private:
-    void finish(module_config_t *, bool );
+    void finish( module_config_t * );
     QLabel *label;
 private slots:
     void actionRequested( int );
+    void onComboChanged() ;
 
 };
 
-- 
1.6.1.3

