Qt: More byte view and proto tree fixes.
[metze/wireshark/wip.git] / ui / preference_utils.c
1 /* preference_utils.c
2  * Routines for handling preferences
3  *
4  * Wireshark - Network traffic analyzer
5  * By Gerald Combs <gerald@wireshark.org>
6  * Copyright 1998 Gerald Combs
7  *
8  * SPDX-License-Identifier: GPL-2.0+
9  */
10
11 #include "config.h"
12
13 #include <errno.h>
14
15 #include <epan/column.h>
16 #include <wsutil/filesystem.h>
17 #include <epan/prefs.h>
18 #include <epan/prefs-int.h>
19 #include <epan/packet.h>
20 #include <epan/decode_as.h>
21
22 #ifdef HAVE_LIBPCAP
23 #include "capture_opts.h"
24 #include "ui/capture_globals.h"
25 #endif
26
27 #include "ui/preference_utils.h"
28 #include "ui/simple_dialog.h"
29
30
31 /* Fill in capture options with values from the preferences */
32 void
33 prefs_to_capture_opts(void)
34 {
35 #ifdef HAVE_LIBPCAP
36     /* Set promiscuous mode from the preferences setting. */
37     /* the same applies to other preferences settings as well. */
38     global_capture_opts.default_options.promisc_mode = prefs.capture_prom_mode;
39     global_capture_opts.use_pcapng                   = prefs.capture_pcap_ng;
40     global_capture_opts.show_info                    = prefs.capture_show_info; /* GTK+ only */
41     global_capture_opts.real_time_mode               = prefs.capture_real_time;
42     auto_scroll_live                                 = prefs.capture_auto_scroll;
43 #endif /* HAVE_LIBPCAP */
44 }
45
46 void
47 prefs_main_write(void)
48 {
49     int   err;
50     char *pf_dir_path;
51     char *pf_path;
52
53     /* Create the directory that holds personal configuration files, if
54        necessary.  */
55     if (create_persconffile_dir(&pf_dir_path) == -1) {
56         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
57                 "Can't create directory\n\"%s\"\nfor preferences file: %s.", pf_dir_path,
58                 g_strerror(errno));
59         g_free(pf_dir_path);
60     } else {
61         /* Write the preferencs out. */
62         err = write_prefs(&pf_path);
63         if (err != 0) {
64             simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
65                     "Can't open preferences file\n\"%s\": %s.", pf_path,
66                     g_strerror(err));
67             g_free(pf_path);
68         }
69     }
70 }
71
72 static unsigned int
73 prefs_store_ext_helper(const char * module_name, const char *pref_name, const char *pref_value)
74 {
75     module_t * module = NULL;
76     pref_t * pref = NULL;
77     unsigned int pref_changed = 0;
78
79     if ( ! prefs_is_registered_protocol(module_name))
80         return 0;
81
82     module = prefs_find_module(module_name);
83     if ( ! module )
84         return 0;
85
86     pref = prefs_find_preference(module, pref_name);
87
88     if (!pref)
89         return 0;
90
91     if (prefs_get_type(pref) == PREF_STRING )
92     {
93         pref_changed |= prefs_set_string_value(pref, pref_value, pref_stashed);
94         if ( ! pref_changed || prefs_get_string_value(pref, pref_stashed) != 0 )
95             pref_changed |= prefs_set_string_value(pref, pref_value, pref_current);
96     }
97
98     return pref_changed;
99 }
100
101 unsigned int
102 prefs_store_ext(const char * module_name, const char *pref_name, const char *pref_value)
103 {
104     unsigned int changed_flags = prefs_store_ext_helper(module_name, pref_name, pref_value);
105     if ( changed_flags )
106     {
107         prefs_main_write();
108         prefs_apply_all();
109         prefs_to_capture_opts();
110         return changed_flags;
111     }
112
113     return 0;
114 }
115
116 gboolean
117 prefs_store_ext_multiple(const char * module, GHashTable * pref_values)
118 {
119     gboolean pref_changed = FALSE;
120     GList * keys = NULL;
121
122     if ( ! prefs_is_registered_protocol(module))
123         return pref_changed;
124
125     keys = g_hash_table_get_keys(pref_values);
126     if ( ! keys )
127         return pref_changed;
128
129     while ( keys != NULL )
130     {
131         gchar * pref_name = (gchar *)keys->data;
132         gchar * pref_value = (gchar *) g_hash_table_lookup(pref_values, keys->data);
133
134         if ( pref_name && pref_value )
135         {
136             if ( prefs_store_ext_helper(module, pref_name, pref_value) )
137                 pref_changed = TRUE;
138         }
139         keys = g_list_next(keys);
140     }
141
142     if ( pref_changed )
143     {
144         prefs_main_write();
145         prefs_apply_all();
146         prefs_to_capture_opts();
147     }
148
149     return TRUE;
150 }
151
152 gint
153 column_prefs_add_custom(gint fmt, const gchar *title, const gchar *custom_fields, gint custom_occurrence)
154 {
155     GList *clp;
156     fmt_data *cfmt, *last_cfmt;
157     gint colnr;
158
159     cfmt = (fmt_data *) g_malloc(sizeof(fmt_data));
160     /*
161      * Because a single underscore is interpreted as a signal that the next character
162      * is going to be marked as accelerator for this header (i.e. is going to be
163      * shown underlined), escape it be inserting a second consecutive underscore.
164      */
165     cfmt->title = g_strdup(title);
166     cfmt->fmt = fmt;
167     cfmt->custom_fields = g_strdup(custom_fields);
168     cfmt->custom_occurrence = custom_occurrence;
169     cfmt->resolved = TRUE;
170
171     colnr = g_list_length(prefs.col_list);
172
173     if (custom_fields) {
174         cfmt->visible = TRUE;
175         clp = g_list_last(prefs.col_list);
176         last_cfmt = (fmt_data *) clp->data;
177         if (last_cfmt->fmt == COL_INFO) {
178             /* Last column is COL_INFO, add custom column before this */
179             colnr -= 1;
180             prefs.col_list = g_list_insert(prefs.col_list, cfmt, colnr);
181         } else {
182             prefs.col_list = g_list_append(prefs.col_list, cfmt);
183         }
184     } else {
185         cfmt->visible = FALSE;  /* Will be set to TRUE in visible_toggled() when added to list */
186         prefs.col_list = g_list_append(prefs.col_list, cfmt);
187     }
188
189     return colnr;
190 }
191
192 void
193 column_prefs_remove_link(GList *col_link)
194 {
195     fmt_data *cfmt;
196
197     if (!col_link || !col_link->data) return;
198
199     cfmt = (fmt_data *) col_link->data;
200
201     g_free(cfmt->title);
202     g_free(cfmt->custom_fields);
203     g_free(cfmt);
204     prefs.col_list = g_list_remove_link(prefs.col_list, col_link);
205 }
206
207 void
208 column_prefs_remove_nth(gint col)
209 {
210     column_prefs_remove_link(g_list_nth(prefs.col_list, col));
211 }
212
213 /*
214  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
215  *
216  * Local Variables:
217  * c-basic-offset: 4
218  * tab-width: 8
219  * indent-tabs-mode: nil
220  * End:
221  *
222  * ex: set shiftwidth=4 tabstop=8 expandtab:
223  * :indentSize=4:tabSize=8:noTabs=true:
224  */