Add ability for preferences to determine what they can change.
[metze/wireshark/wip.git] / epan / prefs.c
index a3dfdd8859db00af2ec822a67ce830c2e2258d20..b5b99f502a0a0daa280865f7461d8435090ecf0c 100644 (file)
@@ -204,6 +204,8 @@ struct preference {
     const char *description;         /**< human-readable description of preference */
     int ordinal;                     /**< ordinal number of this preference */
     int type;                        /**< type of that preference */
+    unsigned int effect_flags;       /**< Flags of types effected by preference (PREF_TYPE_DISSECTION, PREF_EFFECT_CAPTURE, etc).
+                                          Flags must be non-zero to ensure saving to disk */
     gui_type_t gui;                  /**< type of the GUI (QT, GTK or both) the preference is registered for */
     union {                          /* The Qt preference code assumes that these will all be pointers (and unique) */
         guint *uint;
@@ -496,9 +498,11 @@ prefs_register_module_or_subtree(module_t *parent, const char *name,
     module->parent = parent;
     module->submodules = NULL;    /* no submodules, to start */
     module->numprefs = 0;
-    module->prefs_changed = FALSE;
+    module->prefs_changed_flags = 0;
     module->obsolete = FALSE;
     module->use_gui = use_gui;
+    /* A module's preferences affects dissection unless otherwise told */
+    module->effect_flags = PREF_EFFECT_DISSECTION;
 
     /*
      * Do we have a module name?
@@ -885,10 +889,10 @@ call_apply_cb(const void *key _U_, void *value, void *data _U_)
 
     if (module->obsolete)
         return FALSE;
-    if (module->prefs_changed) {
+    if (module->prefs_changed_flags) {
         if (module->apply_cb != NULL)
             (*module->apply_cb)();
-        module->prefs_changed = FALSE;
+        module->prefs_changed_flags = 0;
     }
     if (module->submodules)
         wmem_tree_foreach(module->submodules, call_apply_cb, NULL);
@@ -916,7 +920,7 @@ prefs_apply_all(void)
 void
 prefs_apply(module_t *module)
 {
-    if (module && module->prefs_changed)
+    if (module && module->prefs_changed_flags)
         call_apply_cb(NULL, module, NULL);
 }
 
@@ -940,6 +944,9 @@ register_preference(module_t *module, const char *name, const char *title,
     preference->title = title;
     preference->description = description;
     preference->type = type;
+    /* Default to module's preference effects */
+    preference->effect_flags = module->effect_flags;
+
     preference->gui = GUI_ALL;  /* default */
     if (title != NULL)
         preference->ordinal = module->numprefs;
@@ -1179,28 +1186,28 @@ prefs_register_bool_preference(module_t *module, const char *name,
     preference->default_val.boolval = *var;
 }
 
-gboolean prefs_set_bool_value(pref_t *pref, gboolean value, pref_source_t source)
+unsigned int prefs_set_bool_value(pref_t *pref, gboolean value, pref_source_t source)
 {
-    gboolean changed = FALSE;
+    unsigned int changed = 0;
 
     switch (source)
     {
     case pref_default:
         if (pref->default_val.boolval != value) {
             pref->default_val.boolval = value;
-            changed = TRUE;
+            changed = prefs_get_effect_flags(pref);
         }
         break;
     case pref_stashed:
         if (pref->stashed_val.boolval != value) {
             pref->stashed_val.boolval = value;
-            changed = TRUE;
+            changed = prefs_get_effect_flags(pref);
         }
         break;
     case pref_current:
         if (*pref->varp.boolp != value) {
             *pref->varp.boolp = value;
-            changed = TRUE;
+            changed = prefs_get_effect_flags(pref);
         }
         break;
     default:
@@ -1274,28 +1281,28 @@ prefs_register_enum_preference(module_t *module, const char *name,
     preference->info.enum_info.radio_buttons = radio_buttons;
 }
 
-gboolean prefs_set_enum_value(pref_t *pref, gint value, pref_source_t source)
+unsigned int prefs_set_enum_value(pref_t *pref, gint value, pref_source_t source)
 {
-    gboolean changed = FALSE;
+    unsigned int changed = 0;
 
     switch (source)
     {
     case pref_default:
         if (pref->default_val.enumval != value) {
             pref->default_val.enumval = value;
-            changed = TRUE;
+            changed = prefs_get_effect_flags(pref);
         }
         break;
     case pref_stashed:
         if (pref->stashed_val.enumval != value) {
             pref->stashed_val.enumval = value;
-            changed = TRUE;
+            changed = prefs_get_effect_flags(pref);
         }
         break;
     case pref_current:
         if (*pref->varp.enump != value) {
             *pref->varp.enump = value;
-            changed = TRUE;
+            changed = prefs_get_effect_flags(pref);
         }
         break;
     default:
@@ -1379,17 +1386,17 @@ register_string_like_preference(module_t *module, const char *name,
 /*
  * For use by UI code that sets preferences.
  */
-gboolean
+unsigned int
 prefs_set_string_value(pref_t *pref, const char* value, pref_source_t source)
 {
-    gboolean changed = FALSE;
+    unsigned int changed = 0;
 
     switch (source)
     {
     case pref_default:
         if (*pref->default_val.string) {
             if (strcmp(pref->default_val.string, value) != 0) {
-                changed = TRUE;
+                changed = prefs_get_effect_flags(pref);
                 g_free(pref->default_val.string);
                 pref->default_val.string = g_strdup(value);
             }
@@ -1400,7 +1407,7 @@ prefs_set_string_value(pref_t *pref, const char* value, pref_source_t source)
     case pref_stashed:
         if (pref->stashed_val.string) {
             if (strcmp(pref->stashed_val.string, value) != 0) {
-                changed = TRUE;
+                changed = prefs_get_effect_flags(pref);
                 g_free(pref->stashed_val.string);
                 pref->stashed_val.string = g_strdup(value);
             }
@@ -1411,7 +1418,7 @@ prefs_set_string_value(pref_t *pref, const char* value, pref_source_t source)
     case pref_current:
         if (*pref->varp.string) {
             if (strcmp(*pref->varp.string, value) != 0) {
-                changed = TRUE;
+                changed = prefs_get_effect_flags(pref);
                 g_free(*pref->varp.string);
                 *pref->varp.string = g_strdup(value);
             }
@@ -1537,7 +1544,7 @@ prefs_register_range_preference(module_t *module, const char *name,
 
 gboolean
 prefs_set_range_value_work(pref_t *pref, const gchar *value,
-                           gboolean return_range_errors, gboolean *changed)
+                           gboolean return_range_errors, unsigned int *changed_flags)
 {
     range_t *newrange;
 
@@ -1547,7 +1554,7 @@ prefs_set_range_value_work(pref_t *pref, const gchar *value,
     }
 
     if (!ranges_are_equal(*pref->varp.range, newrange)) {
-        *changed = TRUE;
+        *changed_flags |= prefs_get_effect_flags(pref);
         wmem_free(wmem_epan_scope(), *pref->varp.range);
         *pref->varp.range = newrange;
     } else {
@@ -1559,14 +1566,14 @@ prefs_set_range_value_work(pref_t *pref, const gchar *value,
 /*
  * For use by UI code that sets preferences.
  */
-gboolean
+unsigned int
 prefs_set_stashed_range_value(pref_t *pref, const gchar *value)
 {
     range_t *newrange;
 
     if (range_convert_str_work(wmem_epan_scope(), &newrange, value, pref->info.max_value,
                                TRUE) != CVT_NO_ERROR) {
-        return FALSE;        /* number was bad */
+        return 0;        /* number was bad */
     }
 
     if (!ranges_are_equal(pref->stashed_val.range, newrange)) {
@@ -1575,7 +1582,7 @@ prefs_set_stashed_range_value(pref_t *pref, const gchar *value)
     } else {
         wmem_free(wmem_epan_scope(), newrange);
     }
-    return TRUE;
+    return prefs_get_effect_flags(pref);
 
 }
 
@@ -1987,7 +1994,7 @@ pref_unstash(pref_t *pref, gpointer unstash_data_p)
 
     case PREF_DECODE_AS_UINT:
         if (*pref->varp.uint != pref->stashed_val.uint) {
-            unstash_data->module->prefs_changed = TRUE;
+            unstash_data->module->prefs_changed_flags |= prefs_get_effect_flags(pref);
 
             if (unstash_data->handle_decode_as) {
                 if (*pref->varp.uint != pref->default_val.uint) {
@@ -2011,21 +2018,21 @@ pref_unstash(pref_t *pref, gpointer unstash_data_p)
 
     case PREF_UINT:
         if (*pref->varp.uint != pref->stashed_val.uint) {
-            unstash_data->module->prefs_changed = TRUE;
+            unstash_data->module->prefs_changed_flags |= prefs_get_effect_flags(pref);
             *pref->varp.uint = pref->stashed_val.uint;
         }
         break;
 
     case PREF_BOOL:
         if (*pref->varp.boolp != pref->stashed_val.boolval) {
-            unstash_data->module->prefs_changed = TRUE;
+            unstash_data->module->prefs_changed_flags |= prefs_get_effect_flags(pref);
             *pref->varp.boolp = pref->stashed_val.boolval;
         }
         break;
 
     case PREF_ENUM:
         if (*pref->varp.enump != pref->stashed_val.enumval) {
-            unstash_data->module->prefs_changed = TRUE;
+            unstash_data->module->prefs_changed_flags |= prefs_get_effect_flags(pref);
             *pref->varp.enump = pref->stashed_val.enumval;
         }
         break;
@@ -2035,7 +2042,7 @@ pref_unstash(pref_t *pref, gpointer unstash_data_p)
     case PREF_OPEN_FILENAME:
     case PREF_DIRNAME:
         if (strcmp(*pref->varp.string, pref->stashed_val.string) != 0) {
-            unstash_data->module->prefs_changed = TRUE;
+            unstash_data->module->prefs_changed_flags |= prefs_get_effect_flags(pref);
             g_free(*pref->varp.string);
             *pref->varp.string = g_strdup(pref->stashed_val.string);
         }
@@ -2044,7 +2051,7 @@ pref_unstash(pref_t *pref, gpointer unstash_data_p)
     case PREF_DECODE_AS_RANGE:
         if (!ranges_are_equal(*pref->varp.range, pref->stashed_val.range)) {
             guint32 i, j;
-            unstash_data->module->prefs_changed = TRUE;
+            unstash_data->module->prefs_changed_flags |= prefs_get_effect_flags(pref);
 
             if (unstash_data->handle_decode_as) {
                 sub_dissectors = find_dissector_table(pref->name);
@@ -2089,14 +2096,19 @@ pref_unstash(pref_t *pref, gpointer unstash_data_p)
 
     case PREF_RANGE:
         if (!ranges_are_equal(*pref->varp.range, pref->stashed_val.range)) {
-            unstash_data->module->prefs_changed = TRUE;
+            unstash_data->module->prefs_changed_flags |= prefs_get_effect_flags(pref);
             wmem_free(wmem_epan_scope(), *pref->varp.range);
             *pref->varp.range = range_copy(wmem_epan_scope(), pref->stashed_val.range);
         }
     break;
 
     case PREF_COLOR:
-        *pref->varp.colorp = pref->stashed_val.color;
+        if ((pref->varp.colorp->blue != pref->stashed_val.color.blue) ||
+            (pref->varp.colorp->red != pref->stashed_val.color.red) ||
+            (pref->varp.colorp->green != pref->stashed_val.color.green)) {
+            unstash_data->module->prefs_changed_flags |= prefs_get_effect_flags(pref);
+            *pref->varp.colorp = pref->stashed_val.color;
+        }
         break;
 
     case PREF_STATIC_TEXT:
@@ -2348,14 +2360,14 @@ console_log_level_reset_cb(pref_t* pref)
 }
 
 static prefs_set_pref_e
-console_log_level_set_cb(pref_t* pref, const gchar* value, gboolean* changed)
+console_log_level_set_cb(pref_t* pref, const gchar* value, unsigned int* changed_flags)
 {
     guint    uval;
 
     uval = (guint)strtoul(value, NULL, 10);
 
     if (*pref->varp.uint != uval) {
-        *changed = TRUE;
+        *changed_flags = prefs_get_effect_flags(pref);
         *pref->varp.uint = uval;
     }
 
@@ -2403,13 +2415,13 @@ static char * console_log_level_to_str_cb(pref_t* pref, gboolean default_val) {
 static module_t *gui_column_module = NULL;
 
 static prefs_set_pref_e
-column_hidden_set_cb(pref_t* pref, const gchar* value, gboolean* changed)
+column_hidden_set_cb(pref_t* pref, const gchar* value, unsigned int* changed_flags)
 {
     GList       *clp;
     fmt_data    *cfmt;
     pref_t  *format_pref;
 
-    (*changed) |= prefs_set_string_value(pref, value, pref_current);
+    (*changed_flags) |= prefs_set_string_value(pref, value, pref_current);
 
     /*
      * Set the "visible" flag for the existing columns; we need to
@@ -2496,7 +2508,7 @@ column_num_reset_cb(pref_t* pref)
 }
 
 static prefs_set_pref_e
-column_num_set_cb(pref_t* pref _U_, const gchar* value _U_, gboolean* changed _U_)
+column_num_set_cb(pref_t* pref _U_, const gchar* value _U_, unsigned int* changed_flags _U_)
 {
     /* Don't write this to the preferences file */
     return PREFS_SET_OK;
@@ -2596,7 +2608,7 @@ column_format_reset_cb(pref_t* pref)
 }
 
 static prefs_set_pref_e
-column_format_set_cb(pref_t* pref, const gchar* value, gboolean* changed _U_)
+column_format_set_cb(pref_t* pref, const gchar* value, unsigned int* changed_flags _U_)
 {
     GList    *col_l, *col_l_elt;
     fmt_data *cfmt;
@@ -2800,7 +2812,7 @@ capture_column_reset_cb(pref_t* pref)
 }
 
 static prefs_set_pref_e
-capture_column_set_cb(pref_t* pref, const gchar* value, gboolean* changed _U_)
+capture_column_set_cb(pref_t* pref, const gchar* value, unsigned int* changed_flags _U_)
 {
     GList *col_l  = prefs_get_string_list(value);
     GList *col_l_elt;
@@ -2920,9 +2932,9 @@ capture_column_to_str_cb(pref_t* pref, gboolean default_val)
 }
 
 static prefs_set_pref_e
-colorized_frame_set_cb(pref_t* pref, const gchar* value, gboolean* changed)
+colorized_frame_set_cb(pref_t* pref, const gchar* value, unsigned int* changed_flags)
 {
-    (*changed) |= prefs_set_string_value(pref, value, pref_current);
+    (*changed_flags) |= prefs_set_string_value(pref, value, pref_current);
     return PREFS_SET_OK;
 }
 
@@ -4712,27 +4724,27 @@ guint prefs_get_uint_value(const char *module_name, const char* pref_name)
     return prefs_get_uint_value_real(prefs_find_preference(prefs_find_module(module_name), pref_name), pref_current);
 }
 
-gboolean prefs_set_uint_value(pref_t *pref, guint value, pref_source_t source)
+unsigned int prefs_set_uint_value(pref_t *pref, guint value, pref_source_t source)
 {
-    gboolean changed = FALSE;
+    unsigned int changed = 0;
     switch (source)
     {
     case pref_default:
         if (pref->default_val.uint != value) {
             pref->default_val.uint = value;
-            changed = TRUE;
+            changed = prefs_get_effect_flags(pref);
         }
         break;
     case pref_stashed:
         if (pref->stashed_val.uint != value) {
             pref->stashed_val.uint = value;
-            changed = TRUE;
+            changed = prefs_get_effect_flags(pref);
         }
         break;
     case pref_current:
         if (*pref->varp.uint != value) {
             *pref->varp.uint = value;
-            changed = TRUE;
+            changed = prefs_get_effect_flags(pref);
         }
         break;
     default:
@@ -5235,7 +5247,7 @@ deprecated_port_pref(gchar *pref_name, const gchar *value)
             pref = prefs_find_preference(module, port_prefs[i].table_name);
             if (pref != NULL)
             {
-                module->prefs_changed = TRUE;
+                module->prefs_changed_flags |= prefs_get_effect_flags(pref);
                 *pref->varp.uint = uval;
             }
 
@@ -5280,7 +5292,7 @@ deprecated_port_pref(gchar *pref_name, const gchar *value)
                 pref = prefs_find_preference(module, port_range_prefs[i].table_name);
                 if (pref != NULL)
                 {
-                    if (!prefs_set_range_value_work(pref, value, TRUE, &module->prefs_changed))
+                    if (!prefs_set_range_value_work(pref, value, TRUE, &module->prefs_changed_flags))
                     {
                         return FALSE;        /* number was bad */
                     }
@@ -5777,7 +5789,7 @@ set_pref(gchar *pref_name, const gchar *value, void *private_data _U_,
             if (p == value || *p != '\0')
                 return PREFS_SET_SYNTAX_ERR;        /* number was bad */
             if (*pref->varp.uint != uval) {
-                containing_module->prefs_changed = TRUE;
+                containing_module->prefs_changed_flags |= prefs_get_effect_flags(pref);
                 *pref->varp.uint = uval;
             }
             break;
@@ -5796,7 +5808,7 @@ set_pref(gchar *pref_name, const gchar *value, void *private_data _U_,
                 return PREFS_SET_SYNTAX_ERR;        /* number was bad */
 
             if (*pref->varp.uint != uval) {
-                containing_module->prefs_changed = TRUE;
+                containing_module->prefs_changed_flags |= prefs_get_effect_flags(pref);
                 *pref->varp.uint = uval;
 
                 /* Name of preference is the dissector table */
@@ -5825,7 +5837,7 @@ set_pref(gchar *pref_name, const gchar *value, void *private_data _U_,
             else
                 bval = FALSE;
             if (*pref->varp.boolp != bval) {
-                containing_module->prefs_changed = TRUE;
+                containing_module->prefs_changed_flags |= prefs_get_effect_flags(pref);
                 *pref->varp.boolp = bval;
             }
             break;
@@ -5835,7 +5847,7 @@ set_pref(gchar *pref_name, const gchar *value, void *private_data _U_,
             enum_val = find_val_for_string(value, pref->info.enum_info.enumvals,
                                            *pref->varp.enump);
             if (*pref->varp.enump != enum_val) {
-                containing_module->prefs_changed = TRUE;
+                containing_module->prefs_changed_flags |= prefs_get_effect_flags(pref);
                 *pref->varp.enump = enum_val;
             }
             break;
@@ -5844,13 +5856,13 @@ set_pref(gchar *pref_name, const gchar *value, void *private_data _U_,
         case PREF_SAVE_FILENAME:
         case PREF_OPEN_FILENAME:
         case PREF_DIRNAME:
-            containing_module->prefs_changed |= prefs_set_string_value(pref, value, pref_current);
+            containing_module->prefs_changed_flags |= prefs_set_string_value(pref, value, pref_current);
             break;
 
         case PREF_RANGE:
         {
             if (!prefs_set_range_value_work(pref, value, return_range_errors,
-                                            &containing_module->prefs_changed))
+                                            &containing_module->prefs_changed_flags))
                 return PREFS_SET_SYNTAX_ERR;        /* number was bad */
             break;
         }
@@ -5872,7 +5884,7 @@ set_pref(gchar *pref_name, const gchar *value, void *private_data _U_,
             if (!ranges_are_equal(*pref->varp.range, newrange)) {
                 wmem_free(wmem_epan_scope(), *pref->varp.range);
                 *pref->varp.range = newrange;
-                containing_module->prefs_changed = TRUE;
+                containing_module->prefs_changed_flags |= prefs_get_effect_flags(pref);
 
                 /* Name of preference is the dissector table */
                 sub_dissectors = find_dissector_table(pref->name);
@@ -5916,7 +5928,7 @@ set_pref(gchar *pref_name, const gchar *value, void *private_data _U_,
             if ((pref->varp.colorp->red != RED_COMPONENT(cval)) ||
                 (pref->varp.colorp->green != GREEN_COMPONENT(cval)) ||
                 (pref->varp.colorp->blue != BLUE_COMPONENT(cval))) {
-                containing_module->prefs_changed = TRUE;
+                containing_module->prefs_changed_flags |= prefs_get_effect_flags(pref);
                 pref->varp.colorp->red   = RED_COMPONENT(cval);
                 pref->varp.colorp->green = GREEN_COMPONENT(cval);
                 pref->varp.colorp->blue  = BLUE_COMPONENT(cval);
@@ -5925,7 +5937,7 @@ set_pref(gchar *pref_name, const gchar *value, void *private_data _U_,
         }
 
         case PREF_CUSTOM:
-            return pref->custom_cbs.set_cb(pref, value, &containing_module->prefs_changed);
+            return pref->custom_cbs.set_cb(pref, value, &containing_module->prefs_changed_flags);
 
         case PREF_STATIC_TEXT:
         case PREF_UAT:
@@ -6034,6 +6046,46 @@ prefs_pref_type_name(pref_t *pref)
     return type_name;
 }
 
+unsigned int
+prefs_get_effect_flags(pref_t *pref)
+{
+    if (pref == NULL)
+        return 0;
+
+    return pref->effect_flags;
+}
+
+void
+prefs_set_effect_flags(pref_t *pref, unsigned int flags)
+{
+    if (pref != NULL) {
+        pref->effect_flags = flags;
+    }
+}
+
+void
+prefs_set_effect_flags_by_name(module_t * module, const char *pref, unsigned int flags)
+{
+    prefs_set_effect_flags(prefs_find_preference(module, pref), flags);
+}
+
+unsigned int
+prefs_get_module_effect_flags(module_t * module)
+{
+    if (module == NULL)
+        return 0;
+
+    return module->effect_flags;
+}
+
+void
+prefs_set_module_effect_flags(module_t * module, unsigned int flags)
+{
+    if (module != NULL) {
+        module->effect_flags = flags;
+    }
+}
+
 char *
 prefs_pref_type_description(pref_t *pref)
 {