aboutsummaryrefslogtreecommitdiffstats
path: root/ui/gtk/stats_tree_stat.c
diff options
context:
space:
mode:
Diffstat (limited to 'ui/gtk/stats_tree_stat.c')
-rw-r--r--ui/gtk/stats_tree_stat.c618
1 files changed, 0 insertions, 618 deletions
diff --git a/ui/gtk/stats_tree_stat.c b/ui/gtk/stats_tree_stat.c
deleted file mode 100644
index 9be6bbd..0000000
--- a/ui/gtk/stats_tree_stat.c
+++ /dev/null
@@ -1,618 +0,0 @@
-/* stats_tree_stat.c
- * GTK Tap implementation of stats_tree
- * 2005, Luis E. G. Ontanon
- *
- * Wireshark - Network traffic analyzer
- * By Gerald Combs <gerald@wireshark.org>
- * Copyright 1998 Gerald Combs
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-/* stats_tree modifications by Deon van der Westhuysen, November 2013
- * support for
- * - sorting by column,
- * - display a generic number of columns(driven by stats_tree.c
- * - copy to clipboard
- * - export to text, CSV or XML file
- */
-
-#include "config.h"
-#include <string.h>
-
-#include <gtk/gtk.h>
-
-#include <wsutil/report_message.h>
-#include <wsutil/file_util.h>
-
-#include <epan/stats_tree_priv.h>
-
-#include "ui/simple_dialog.h"
-
-#include "ui/gtk/gui_utils.h"
-#include "ui/gtk/dlg_utils.h"
-#include "ui/gtk/file_dlg.h"
-#include "ui/gtk/tap_param_dlg.h"
-#include "ui/gtk/main.h"
-
-#include "ui/gtk/old-gtk-compat.h"
-
-#include "ui/gtk/gui_stat_menu.h"
-
-
-#ifdef _WIN32
-#define USE_WIN32_FILE_DIALOGS
-#endif
-
-#ifdef USE_WIN32_FILE_DIALOGS
-#include <gdk/gdkwin32.h>
-#include <windows.h>
-#include "ui/win32/file_dlg_win32.h"
-#endif
-
-#include "globals.h"
-
-void register_tap_listener_stats_tree_stat(void);
-
-struct _st_node_pres {
- GtkTreeIter *iter;
-};
-
-struct _tree_cfg_pres {
- tap_param_dlg *stat_dlg;
-};
-
-struct _tree_pres {
- GString* text;
- GtkWidget *win;
- GtkTreeStore *store;
- GtkWidget* tree;
-};
-
-/* Define fixed column indexes */
-#define NODEPTR_COLUMN 0 /* Always first column */
-#define N_RESERVED_COL 1 /* Number of columns for internal use - added before visible cols */
-
-
-static void
-draw_gtk_node(stat_node* node)
-{
- GtkTreeIter *parent = NULL;
- stat_node *child;
- int num_columns = node->st->num_columns+N_RESERVED_COL;
- gint *columns = (gint*) g_malloc(sizeof(gint)*num_columns);
- GValue *values = (GValue*) g_malloc0(sizeof(GValue)*num_columns);
- gchar **valstrs = stats_tree_get_values_from_node(node);
- int count;
-
- columns[0]= 0;
- g_value_init(values, G_TYPE_POINTER);
- g_value_set_pointer(values, node);
- for (count = N_RESERVED_COL; count<num_columns; count++) {
- columns[count]= count;
- g_value_init(values+count, G_TYPE_STRING);
- g_value_take_string (values+count,valstrs[count-N_RESERVED_COL]);
- }
-
- if (!node->pr) {
- node->pr = (st_node_pres *)g_malloc(sizeof(st_node_pres));
-
- if (node->st->pr->store) {
- node->pr->iter = (GtkTreeIter *)g_malloc0(sizeof(GtkTreeIter));
-
- if ( node->parent && node->parent->pr ) {
- parent = node->parent->pr->iter;
- }
- gtk_tree_store_append (node->st->pr->store, node->pr->iter, parent);
- gtk_tree_store_set_valuesv(node->st->pr->store, node->pr->iter,
- columns, values, num_columns);
- }
- }
- if (node->st->pr->store && node->pr->iter) {
- /* skip reserved columns and first entry in the stats_tree values */
- /* list (the node name). These should already be set and static. */
- gtk_tree_store_set_valuesv(node->st->pr->store, node->pr->iter,
- columns+N_RESERVED_COL+1, values+N_RESERVED_COL+1,
- num_columns-N_RESERVED_COL-1);
- }
-
- for (count = 0; count<num_columns; count++) {
- g_value_unset(values+count);
- }
- g_free(columns);
- g_free(values);
- g_free(valstrs);
-
- if (node->children) {
- for (child = node->children; child; child = child->next )
- draw_gtk_node(child);
- }
-
-}
-
-static void
-draw_gtk_tree(void *psp)
-{
- stats_tree *st = (stats_tree *)psp;
- stat_node *child;
- int count;
- gint sort_column = GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID;
- GtkSortType order = GTK_SORT_DESCENDING;
-
- for (count = 0; count<st->num_columns; count++) {
- gtk_tree_view_column_set_title(gtk_tree_view_get_column(GTK_TREE_VIEW(st->pr->tree),count),
- stats_tree_get_column_name(count));
- }
-
- gtk_tree_sortable_get_sort_column_id (GTK_TREE_SORTABLE (st->pr->store), &sort_column, &order);
- gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (st->pr->store),
- GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID, GTK_SORT_DESCENDING);
-
- for (child = st->root.children; child; child = child->next ) {
- draw_gtk_node(child);
-
- if ( (!(child->st_flags&ST_FLG_DEF_NOEXPAND)) && child->pr->iter && st->pr->store ) {
- gtk_tree_view_expand_row(GTK_TREE_VIEW(st->pr->tree),
- gtk_tree_model_get_path(GTK_TREE_MODEL(st->pr->store),child->pr->iter),
- FALSE);
- }
- }
-
- if ((sort_column==GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID)||
- (sort_column==GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)) {
- sort_column= stats_tree_get_default_sort_col(st)+N_RESERVED_COL;
- order= stats_tree_is_default_sort_DESC(st)?GTK_SORT_DESCENDING:GTK_SORT_ASCENDING;
- }
-
- /* Only call this once the entire list is drawn - else Gtk seems */
- /* to get sorting order wrong (sorting broken when new nodes are */
- /* added after setting sort column.) Also for performance. */
- gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (st->pr->store), sort_column, order);
-}
-
-static gboolean
-copy_tree_to_clipboard
-(GtkWidget *win _U_, stats_tree *st)
-{
- gint sort_column = N_RESERVED_COL; /* default */
- GtkSortType order = GTK_SORT_DESCENDING;
- GString *s;
-
- gtk_tree_sortable_get_sort_column_id (GTK_TREE_SORTABLE (st->pr->store), &sort_column, &order);
- s= stats_tree_format_as_str(st,ST_FORMAT_PLAIN,sort_column-N_RESERVED_COL,order==GTK_SORT_DESCENDING);
- copy_to_clipboard(s);
- g_string_free (s,TRUE);
-
- return TRUE;
-}
-
-
-#ifndef USE_WIN32_FILE_DIALOGS
-static gboolean
-gtk_save_as_statstree(GtkWidget *win, GString *file_name, int *file_type)
-{
- GtkWidget *saveas_w;
- GtkWidget *main_vb;
- GtkWidget *ft_hb, *ft_lb, *ft_combo_box;
- char *st_name;
- gpointer ptr;
-
- saveas_w = file_selection_new("Wireshark: Save stats tree as ...",
- GTK_WINDOW(win), FILE_SELECTION_SAVE);
-
- main_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 5, FALSE);
- gtk_container_set_border_width(GTK_CONTAINER(main_vb), 5);
- file_selection_set_extra_widget(saveas_w, main_vb);
- gtk_widget_show(main_vb);
-
- /* File type row */
- ft_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3, FALSE);
- gtk_box_pack_start(GTK_BOX(main_vb), ft_hb, FALSE, FALSE, 0);
- gtk_widget_show(ft_hb);
-
- ft_lb = gtk_label_new("Save as format:");
- gtk_box_pack_start(GTK_BOX(ft_hb), ft_lb, FALSE, FALSE, 0);
- gtk_widget_show(ft_lb);
-
- ft_combo_box = ws_combo_box_new_text_and_pointer();
- ws_combo_box_append_text_and_pointer(GTK_COMBO_BOX(ft_combo_box), "Plain text file (.txt)", GINT_TO_POINTER(ST_FORMAT_PLAIN));
- ws_combo_box_append_text_and_pointer(GTK_COMBO_BOX(ft_combo_box), "Comma separated values (.csv)", GINT_TO_POINTER(ST_FORMAT_CSV));
- ws_combo_box_append_text_and_pointer(GTK_COMBO_BOX(ft_combo_box), "XML document (.xml)", GINT_TO_POINTER(ST_FORMAT_XML));
- ws_combo_box_append_text_and_pointer(GTK_COMBO_BOX(ft_combo_box), "YAML document (.yaml)", GINT_TO_POINTER(ST_FORMAT_YAML));
-
- gtk_box_pack_start(GTK_BOX(ft_hb), ft_combo_box, FALSE, FALSE, 0);
- gtk_widget_show(ft_combo_box);
- ws_combo_box_set_active(GTK_COMBO_BOX(ft_combo_box), 0);
-
- st_name = file_selection_run(saveas_w);
- if (st_name == NULL) {
- /* User cancelled or closed the dialog. */
- return FALSE;
- }
-
- if (! ws_combo_box_get_active_pointer(GTK_COMBO_BOX(ft_combo_box), &ptr)) {
- g_assert_not_reached(); /* Programming error: somehow nothing is active */
- }
-
- /* Save result from dialog box */
- *file_type = GPOINTER_TO_INT(ptr);
- g_string_printf(file_name, "%s", st_name);
-
- /* We've crossed the Rubicon; get rid of the file save-as box. */
- window_destroy(GTK_WIDGET(saveas_w));
- g_free(st_name);
- return TRUE;
-}
-#endif /* USE_WIN32_FILE_DIALOGS */
-
-static gboolean
-save_as_dialog(GtkWidget *win _U_, stats_tree *st)
-{
- gint sort_column = 1; /* default */
- GtkSortType order = GTK_SORT_DESCENDING;
- GString *str_tree;
- GString *file_name = g_string_new("");
- int file_type;
- gchar *file_name_lower;
- const gchar *file_ext;
- FILE *f;
- gboolean success = FALSE;
- int last_errno;
-
-#ifdef USE_WIN32_FILE_DIALOGS
- if (win32_save_as_statstree(GDK_WINDOW_HWND(gtk_widget_get_window(st->pr->win)),
- file_name, &file_type)) {
-#else /* USE_WIN32_FILE_DIALOGS */
- if (gtk_save_as_statstree(st->pr->win,file_name,&file_type)) {
-#endif /* USE_WIN32_FILE_DIALOGS */
-
- /* add file extension as required */
- file_name_lower = g_utf8_strdown(file_name->str, -1);
- switch (file_type) {
- case ST_FORMAT_YAML: file_ext = ".yaml";
- break;
- case ST_FORMAT_XML: file_ext = ".xml";
- break;
- case ST_FORMAT_CSV: file_ext = ".csv";
- break;
- default: file_ext = ".txt";
- break;
- }
- if (!g_str_has_suffix(file_name_lower, file_ext)) {
- /* Must add extenstion */
- g_string_append(file_name,file_ext);
- }
- g_free(file_name_lower);
-
- gtk_tree_sortable_get_sort_column_id (GTK_TREE_SORTABLE (st->pr->store), &sort_column, &order);
- str_tree=stats_tree_format_as_str(st,(st_format_type)file_type,sort_column-N_RESERVED_COL,order==GTK_SORT_DESCENDING);
-
- /* actually save the file */
- f= ws_fopen (file_name->str,"w");
- last_errno= errno;
- if (f) {
- if (fputs(str_tree->str, f)!=EOF) {
- success= TRUE;
- }
- last_errno= errno;
- fclose(f);
- }
- if (!success) {
- GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW(st->pr->win),
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_ERROR,
- GTK_BUTTONS_CLOSE,
- "Error saving file '%s': %s",
- file_name->str, g_strerror (last_errno));
- gtk_dialog_run (GTK_DIALOG (dialog));
- gtk_widget_destroy (dialog);
- }
-
- g_string_free(str_tree, TRUE);
- }
-
- g_string_free(file_name, TRUE);
-
- return TRUE;
-}
-
-static void
-free_gtk_tree(GtkWindow *win _U_, stats_tree *st)
-{
- remove_tap_listener(st);
-
- if (st->root.pr)
- st->root.pr->iter = NULL;
-
- st->cfg->in_use = FALSE;
- stats_tree_free(st);
-
-}
-
-static void
-clear_node_pr(stat_node* n)
-{
- stat_node* c;
- for (c = n->children; c; c = c->next) {
- clear_node_pr(c);
- }
-
- if (n->pr && n->pr->iter) {
- gtk_tree_store_remove(n->st->pr->store, n->pr->iter);
- n->pr->iter = NULL;
- }
-}
-
-static void
-reset_tap(void* p)
-{
- stats_tree* st = (stats_tree *)p;
- stat_node* c;
-
- for (c = st->root.children; c; c = c->next) {
- clear_node_pr(c);
- }
-
- stats_tree_reinit(st);
-/* st->cfg->init(st); doesn't properly delete nodes */
-}
-
-static gint
-st_sort_func(GtkTreeModel *model,
- GtkTreeIter *a,
- GtkTreeIter *b,
- gpointer user_data)
-{
- gint sort_column= 1; /* default */
- GtkSortType order= GTK_SORT_DESCENDING;
- stat_node *node_a;
- stat_node *node_b;
- gint result;
-
- gtk_tree_sortable_get_sort_column_id (GTK_TREE_SORTABLE (user_data), &sort_column, &order);
-
- gtk_tree_model_get(model, a, NODEPTR_COLUMN, &node_a, -1);
- gtk_tree_model_get(model, b, NODEPTR_COLUMN, &node_b, -1);
-
- result= stats_tree_sort_compare(node_a,node_b,sort_column-N_RESERVED_COL,order==GTK_SORT_DESCENDING);
- if (order==GTK_SORT_DESCENDING) {
- result= -result;
- }
- return result;
-}
-
-/* initializes the stats_tree window */
-static void
-init_gtk_tree(const char* opt_arg, void *userdata _U_)
-{
- gchar *abbr = stats_tree_get_abbr(opt_arg);
- stats_tree* st = NULL;
- stats_tree_cfg* cfg = NULL;
- tree_pres* pr = (tree_pres *)g_malloc(sizeof(tree_pres));
- gchar* title = NULL;
- gchar* window_name = NULL;
- GString* error_string;
- GtkWidget *scr_win;
- size_t init_strlen;
- GtkWidget *main_vb, *bbox, *bt_close, *bt_copy, *bt_saveas;
- GtkTreeViewColumn* column;
- GtkCellRenderer* renderer;
- GtkTreeSortable *sortable;
- GType *col_types;
- int count;
-
- if (abbr) {
- cfg = stats_tree_get_cfg_by_abbr(abbr);
-
- if (cfg && cfg->in_use) {
- /* XXX: ! */
- report_failure("cannot open more than one tree of the same type at once");
- return;
- }
-
- if (cfg != NULL) {
- init_strlen = strlen(cfg->pr->stat_dlg->init_string);
-
- if (strncmp (opt_arg, cfg->pr->stat_dlg->init_string, init_strlen) == 0){
- if (init_strlen == strlen(opt_arg)) {
- st = stats_tree_new(cfg,pr,NULL);
- } else {
- st = stats_tree_new(cfg,pr,opt_arg+init_strlen+1);
- }
-
- } else {
- st = stats_tree_new(cfg,pr,NULL);
- }
- } else {
- report_failure("no such stats_tree (%s) in stats_tree registry",abbr);
- g_free(abbr);
- return;
- }
- g_free(abbr);
-
- } else {
- report_failure("could not obtain stats_tree abbr from opt_arg");
- g_free(pr);
- return;
- }
-
- cfg->in_use = TRUE;
-
- window_name = g_strdup_printf("%s Stats Tree", st->display_name);
-
- st->pr->win = window_new_with_geom(GTK_WINDOW_TOPLEVEL, window_name, NULL, GTK_WIN_POS_CENTER_ON_PARENT);
- gtk_window_set_default_size(GTK_WINDOW(st->pr->win), st->num_columns*80+80, 400);
- g_free(window_name);
-
- if(st->filter){
- title=g_strdup_printf("%s with filter: %s",st->display_name,st->filter);
- } else {
- st->filter=NULL;
- title=g_strdup(st->display_name);
- }
-
- gtk_window_set_title(GTK_WINDOW(st->pr->win), title);
- g_free(title);
-
- main_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 3, FALSE);
- gtk_container_set_border_width(GTK_CONTAINER(main_vb), 12);
- gtk_container_add(GTK_CONTAINER(st->pr->win), main_vb);
-
- scr_win = scrolled_window_new(NULL, NULL);
-
- col_types= (GType*)g_malloc(sizeof(GType)*(st->num_columns+N_RESERVED_COL));
- col_types[0] = G_TYPE_POINTER;
- for (count = 0; count<st->num_columns; count++) {
- col_types[count+N_RESERVED_COL] = G_TYPE_STRING;
- }
- st->pr->store = gtk_tree_store_newv (st->num_columns+N_RESERVED_COL,col_types);
- g_free (col_types);
-
- sortable= GTK_TREE_SORTABLE (st->pr->store);
- st->pr->tree = gtk_tree_view_new_with_model (GTK_TREE_MODEL (st->pr->store));
- gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(st->pr->tree), FALSE);
- g_object_unref(G_OBJECT(st->pr->store));
-
- gtk_container_add( GTK_CONTAINER(scr_win), st->pr->tree);
-
- /* the columns */
- for (count = 0; count<st->num_columns; count++) {
- renderer = gtk_cell_renderer_text_new ();
- column = gtk_tree_view_column_new_with_attributes (stats_tree_get_column_name(count),
- renderer, "text", count+N_RESERVED_COL, NULL);
- gtk_tree_view_column_set_sort_column_id(column, count+N_RESERVED_COL);
- gtk_tree_sortable_set_sort_func(sortable,count+N_RESERVED_COL, st_sort_func, sortable, NULL);
- gtk_tree_view_column_set_resizable (column,TRUE);
- gtk_tree_view_column_set_sizing(column,GTK_TREE_VIEW_COLUMN_AUTOSIZE);
- gtk_tree_view_append_column (GTK_TREE_VIEW (st->pr->tree), column);
- }
-
- gtk_tree_sortable_set_default_sort_func (sortable, NULL, NULL, NULL);
-
- gtk_box_pack_start(GTK_BOX(main_vb), scr_win, TRUE, TRUE, 0);
-
- error_string = register_tap_listener( cfg->tapname,
- st,
- st->filter,
- cfg->flags,
- reset_tap,
- stats_tree_packet,
- draw_gtk_tree);
-
- if (error_string) {
- /* error, we failed to attach to the tap. clean up */
- /* destroy_stat_tree_window(st); */
- report_failure("stats_tree for: %s failed to attach to the tap: %s",cfg->name,error_string->str);
- g_string_free(error_string, TRUE);
- }
-
- /* Button row. */
- bbox = dlg_button_row_new(GTK_STOCK_COPY, GTK_STOCK_SAVE_AS, GTK_STOCK_CLOSE, NULL);
- gtk_box_pack_start(GTK_BOX(main_vb), bbox, FALSE, FALSE, 0);
-
- bt_close = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CLOSE);
- window_set_cancel_button(st->pr->win, bt_close, window_cancel_button_cb);
-
- g_signal_connect(GTK_WINDOW(st->pr->win), "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
- g_signal_connect(GTK_WINDOW(st->pr->win), "destroy", G_CALLBACK(free_gtk_tree), st);
-
- bt_copy = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_COPY);
- g_signal_connect(GTK_WINDOW (bt_copy), "clicked", G_CALLBACK(copy_tree_to_clipboard), st);
-
- bt_saveas = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_SAVE_AS);
- g_signal_connect(GTK_WINDOW (bt_saveas), "clicked", G_CALLBACK(save_as_dialog), st);
-
- gtk_widget_show_all(st->pr->win);
- window_present(st->pr->win);
-
- cf_retap_packets(&cfile);
- gdk_window_raise(gtk_widget_get_window(st->pr->win));
-}
-
-static tap_param tree_stat_params[] = {
- { PARAM_FILTER, "filter", "Filter", NULL, TRUE }
-};
-
-static void
-register_gtk_stats_tree_tap (gpointer k _U_, gpointer v, gpointer p _U_)
-{
- stats_tree_cfg* cfg = (stats_tree_cfg *)v;
- gchar* display_name= stats_tree_get_displayname(cfg->name);
-
- cfg->pr = (tree_cfg_pres *)g_malloc(sizeof(tree_cfg_pres));
-
- cfg->pr->stat_dlg = (tap_param_dlg *)g_malloc(sizeof(tap_param_dlg));
-
- cfg->pr->stat_dlg->win_title = g_strdup_printf("%s Stats Tree",display_name);
- cfg->pr->stat_dlg->init_string = g_strdup_printf("%s,tree",cfg->abbr);
- cfg->pr->stat_dlg->tap_init_cb = init_gtk_tree;
- cfg->pr->stat_dlg->index = -1;
- cfg->pr->stat_dlg->nparams = G_N_ELEMENTS(tree_stat_params);
- cfg->pr->stat_dlg->params = tree_stat_params;
- cfg->pr->stat_dlg->user_data = NULL;
- g_free(display_name);
-}
-
-static void
-free_tree_presentation(stats_tree* st)
-{
- g_free(st->pr);
-}
-
-void
-register_tap_listener_stats_tree_stat(void)
-{
- stats_tree_presentation(register_gtk_stats_tree_tap,
- NULL, free_tree_presentation, NULL);
-}
-
-void gtk_stats_tree_cb(GtkAction *action, gpointer user_data _U_)
-{
- const gchar *action_name;
- gchar *abbr;
- stats_tree_cfg* cfg = NULL;
-
- action_name = gtk_action_get_name (action);
- abbr = strrchr(action_name,'/');
- if(abbr){
- abbr = abbr+1;
- }else{
- abbr = g_strdup(action_name);
- }
- cfg = stats_tree_get_cfg_by_abbr(abbr);
- if(cfg){
- tap_param_dlg_cb(action, cfg->pr->stat_dlg);
- }else{
- simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
- "Failed to find the stat tree named %s",
- abbr);
- return;
- }
-
-}
-
-
-/*
- * Editor modelines - http://www.wireshark.org/tools/modelines.html
- *
- * Local variables:
- * c-basic-offset: 8
- * tab-width: 8
- * indent-tabs-mode: t
- * End:
- *
- * vi: set shiftwidth=8 tabstop=8 noexpandtab:
- * :indentSize=8:tabSize=8:noTabs=false:
- */