2005-11-25 23:42:52 +00:00
/* expert_comp_table.c
* expert_comp_table 2005 Greg Morris
* Portions copied from service_response_time_table . c by Ronnie Sahlberg
* Helper routines common to all composite expert statistics
* tap .
*
* $ Id $
*
2006-05-21 05:12:17 +00:00
* Wireshark - Network traffic analyzer
* By Gerald Combs < gerald @ wireshark . org >
2005-11-25 23:42:52 +00:00
* 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 . , 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA .
*/
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
# include <string.h>
# include <stdlib.h>
# include <stdio.h>
# include <math.h>
2008-04-13 01:54:20 +00:00
2005-11-25 23:42:52 +00:00
# include <gtk/gtk.h>
2008-04-13 01:54:20 +00:00
2005-11-25 23:42:52 +00:00
# include "epan/packet_info.h"
2008-04-13 01:54:20 +00:00
# include <epan/expert.h>
2006-05-04 15:36:41 +00:00
2008-04-13 01:54:20 +00:00
# include "../simple_dialog.h"
# include "../globals.h"
# include "../color.h"
# include "gtk/expert_comp_table.h"
2008-05-17 22:59:52 +00:00
# include "gtk/filter_utils.h"
2005-11-25 23:42:52 +00:00
# include "gtk/find_dlg.h"
# include "gtk/color_dlg.h"
2008-04-13 01:54:20 +00:00
# include "gtk/main.h"
# include "gtk/gui_utils.h"
# include "gtk/gtkglobals.h"
# include "gtk/webbrowser.h"
2005-11-25 23:42:52 +00:00
2006-05-04 15:36:41 +00:00
# define SORT_ALPHABETICAL 0
static gint
sort_iter_compare_func ( GtkTreeModel * model ,
2009-05-19 15:53:26 +00:00
GtkTreeIter * a ,
GtkTreeIter * b ,
gpointer userdata )
2006-05-04 15:36:41 +00:00
{
gint sortcol = GPOINTER_TO_INT ( userdata ) ;
gint ret = 0 ;
switch ( sortcol )
{
case SORT_ALPHABETICAL :
{
2007-12-03 21:55:44 +00:00
gchar * name1 , * name2 ;
gtk_tree_model_get ( model , a , 0 , & name1 , - 1 ) ;
gtk_tree_model_get ( model , b , 0 , & name2 , - 1 ) ;
if ( name1 = = NULL | | name2 = = NULL )
{
if ( name1 = = NULL & & name2 = = NULL )
break ; /* both equal => ret = 0 */
ret = ( name1 = = NULL ) ? - 1 : 1 ;
}
else
{
ret = g_ascii_strcasecmp ( name1 , name2 ) ;
}
g_free ( name1 ) ;
g_free ( name2 ) ;
2009-05-19 15:53:26 +00:00
}
break ;
2006-05-04 15:36:41 +00:00
default :
2007-12-03 21:55:44 +00:00
g_return_val_if_reached ( 0 ) ;
2006-05-04 15:36:41 +00:00
}
return ret ;
}
2005-11-25 23:42:52 +00:00
2006-05-04 15:36:41 +00:00
enum
{
GROUP_COLUMN ,
PROTOCOL_COLUMN ,
SUMMARY_COLUMN ,
COUNT_COLUMN ,
N_COLUMNS
} ;
2005-11-25 23:42:52 +00:00
2006-05-04 15:36:41 +00:00
static gint find_summary_data ( error_equiv_table * err , const expert_info_t * expert_data )
2005-11-25 23:42:52 +00:00
{
2006-05-04 15:36:41 +00:00
gint i ;
/* First time thru values will be 0 */
if ( err - > num_procs = = 0 ) {
return - 1 ;
2005-11-25 23:42:52 +00:00
}
2006-05-04 15:36:41 +00:00
for ( i = 0 ; i < err - > num_procs ; i + + ) {
2007-12-02 10:13:57 +00:00
if ( strcmp ( err - > procedures [ i ] . entries [ 1 ] , expert_data - > protocol ) = = 0 & &
strcmp ( err - > procedures [ i ] . entries [ 2 ] , expert_data - > summary ) = = 0 ) {
2006-05-04 15:36:41 +00:00
return i ;
}
}
return - 1 ;
2005-11-25 23:42:52 +00:00
}
static void
error_select_filter_cb ( GtkWidget * widget _U_ , gpointer callback_data , guint callback_action )
{
2007-12-03 21:55:44 +00:00
int action , type , selection ;
error_equiv_table * err = ( error_equiv_table * ) callback_data ;
char str [ 256 ] ;
const char * current_filter ;
2006-05-04 15:36:41 +00:00
GtkTreeIter iter ;
GtkTreeModel * model ;
2009-05-19 15:53:26 +00:00
expert_info_t expert_data ;
gchar * grp ;
2005-11-25 23:42:52 +00:00
2007-12-04 08:27:48 +00:00
action = FILTER_ACTION ( callback_action ) ;
type = FILTER_ACTYPE ( callback_action ) ;
2006-05-04 15:36:41 +00:00
2005-11-25 23:42:52 +00:00
2006-05-04 15:36:41 +00:00
gtk_tree_selection_get_selected ( err - > select , & model , & iter ) ;
2009-05-19 15:53:26 +00:00
gtk_tree_model_get ( model , & iter ,
GROUP_COLUMN , & grp ,
PROTOCOL_COLUMN , & expert_data . protocol ,
SUMMARY_COLUMN , & expert_data . summary ,
- 1 ) ;
2006-05-04 15:36:41 +00:00
2009-05-19 15:53:26 +00:00
if ( strcmp ( grp , " Packet: " ) = = 0 ) {
2007-12-03 21:55:44 +00:00
simple_dialog ( ESD_TYPE_ERROR , ESD_BTN_OK , " You cannot filter or search for packet number. Click on a valid item header. " ) ;
2009-05-19 15:53:26 +00:00
g_free ( grp ) ;
g_free ( expert_data . protocol ) ;
g_free ( expert_data . summary ) ;
2006-03-19 20:26:45 +00:00
return ;
}
2006-05-04 15:36:41 +00:00
2009-05-19 15:53:26 +00:00
g_free ( grp ) ;
/* XXX: find_summary_data doesn't (currently) reference expert_data.group. */
/* If "group" is required, then the message from GROUP_COLUMN will need */
/* to be translated to the group number (or the actual group number */
/* will also need to be stored in the TreeModel). */
2006-05-04 15:36:41 +00:00
selection = find_summary_data ( err , & expert_data ) ;
2009-05-19 15:53:26 +00:00
g_free ( expert_data . protocol ) ;
g_free ( expert_data . summary ) ;
2007-12-03 21:55:44 +00:00
if ( selection > = ( int ) err - > num_procs ) {
simple_dialog ( ESD_TYPE_ERROR , ESD_BTN_OK , " No items are selected " ) ;
return ;
}
current_filter = gtk_entry_get_text ( GTK_ENTRY ( main_display_filter_widget ) ) ;
2005-11-25 23:42:52 +00:00
/* Some expert data doesn't pass an expert item. Without this we cannot create a filter */
/* But allow for searching of internet for error string */
if ( action ! = 6 & & action ! = 7 ) {
if ( err - > procedures [ selection ] . fvalue_value = = NULL ) {
if ( action ! = 2 & & action ! = 3 & & action ! = 4 ) {
2006-05-22 07:29:40 +00:00
simple_dialog ( ESD_TYPE_ERROR , ESD_BTN_OK , " Wireshark cannot create a filter on this item - %s, try using find instead. " , err - > procedures [ selection ] . entries [ 2 ] ) ;
2005-11-25 23:42:52 +00:00
return ;
}
}
2007-12-03 21:55:44 +00:00
switch ( type ) {
2007-12-04 08:27:48 +00:00
case ACTYPE_SELECTED :
2005-11-25 23:42:52 +00:00
/* if no expert item was passed */
if ( err - > procedures [ selection ] . fvalue_value = = NULL ) {
2009-03-19 17:49:11 +00:00
g_strlcpy ( str , err - > procedures [ selection ] . entries [ 2 ] , sizeof ( str ) ) ;
2005-11-25 23:42:52 +00:00
}
else
{
/* expert item exists. Use it. */
2009-03-19 17:49:11 +00:00
g_strlcpy ( str , err - > procedures [ selection ] . fvalue_value , sizeof ( str ) ) ;
2005-11-25 23:42:52 +00:00
}
2007-12-03 21:55:44 +00:00
break ;
2007-12-04 08:27:48 +00:00
case ACTYPE_NOT_SELECTED :
2005-11-25 23:42:52 +00:00
/* if no expert item was passed */
if ( err - > procedures [ selection ] . fvalue_value = = NULL ) {
2009-03-19 17:49:11 +00:00
g_snprintf ( str , sizeof ( str ) , " !%s " , err - > procedures [ selection ] . entries [ 2 ] ) ;
2005-11-25 23:42:52 +00:00
}
else
{
/* expert item exists. Use it. */
2009-03-19 17:49:11 +00:00
g_snprintf ( str , sizeof ( str ) , " !(%s) " , err - > procedures [ selection ] . fvalue_value ) ;
2005-11-25 23:42:52 +00:00
}
2007-12-03 21:55:44 +00:00
break ;
2005-11-25 23:42:52 +00:00
/* the remaining cases will only exist if the expert item exists so no need to check */
2007-12-04 08:27:48 +00:00
case ACTYPE_AND_SELECTED :
2008-05-17 22:59:52 +00:00
if ( ( ! current_filter ) | | ( 0 = = strlen ( current_filter ) ) )
2009-03-19 17:49:11 +00:00
g_strlcpy ( str , err - > procedures [ selection ] . fvalue_value , sizeof ( str ) ) ;
2008-05-17 22:59:52 +00:00
else
2009-03-19 17:49:11 +00:00
g_snprintf ( str , sizeof ( str ) , " (%s) && (%s) " , current_filter , err - > procedures [ selection ] . fvalue_value ) ;
2007-12-03 21:55:44 +00:00
break ;
2007-12-04 08:27:48 +00:00
case ACTYPE_OR_SELECTED :
2008-05-17 22:59:52 +00:00
if ( ( ! current_filter ) | | ( 0 = = strlen ( current_filter ) ) )
2009-03-19 17:49:11 +00:00
g_strlcpy ( str , err - > procedures [ selection ] . fvalue_value , sizeof ( str ) ) ;
2008-05-17 22:59:52 +00:00
else
2009-03-19 17:49:11 +00:00
g_snprintf ( str , sizeof ( str ) , " (%s) || (%s) " , current_filter , err - > procedures [ selection ] . fvalue_value ) ;
2007-12-03 21:55:44 +00:00
break ;
2007-12-04 08:27:48 +00:00
case ACTYPE_AND_NOT_SELECTED :
2008-05-17 22:59:52 +00:00
if ( ( ! current_filter ) | | ( 0 = = strlen ( current_filter ) ) )
2009-03-19 17:49:11 +00:00
g_snprintf ( str , sizeof ( str ) , " !(%s) " , err - > procedures [ selection ] . fvalue_value ) ;
2008-05-17 22:59:52 +00:00
else
2009-03-19 17:49:11 +00:00
g_snprintf ( str , sizeof ( str ) , " (%s) && !(%s) " , current_filter , err - > procedures [ selection ] . fvalue_value ) ;
2007-12-03 21:55:44 +00:00
break ;
2007-12-04 08:27:48 +00:00
case ACTYPE_OR_NOT_SELECTED :
2008-05-17 22:59:52 +00:00
if ( ( ! current_filter ) | | ( 0 = = strlen ( current_filter ) ) )
2009-03-19 17:49:11 +00:00
g_snprintf ( str , sizeof ( str ) , " !(%s) " , err - > procedures [ selection ] . fvalue_value ) ;
2008-05-17 22:59:52 +00:00
else
2009-03-19 17:49:11 +00:00
g_snprintf ( str , sizeof ( str ) , " (%s) || !(%s) " , current_filter , err - > procedures [ selection ] . fvalue_value ) ;
2007-12-03 21:55:44 +00:00
break ;
2005-11-25 23:42:52 +00:00
default :
simple_dialog ( ESD_TYPE_ERROR , ESD_BTN_OK , " Can't find menu type - %u " , type ) ;
2007-12-03 21:55:44 +00:00
}
2005-11-25 23:42:52 +00:00
}
2007-12-03 21:55:44 +00:00
switch ( action ) {
2007-12-04 08:27:48 +00:00
case ACTION_MATCH :
2007-12-03 21:55:44 +00:00
main_filter_packets ( & cfile , str , FALSE ) ;
2005-11-25 23:42:52 +00:00
break ;
2007-12-04 08:27:48 +00:00
case ACTION_PREPARE :
2005-11-25 23:42:52 +00:00
gtk_entry_set_text ( GTK_ENTRY ( main_display_filter_widget ) , str ) ;
2007-12-03 21:55:44 +00:00
break ;
2007-12-04 08:27:48 +00:00
case ACTION_FIND_FRAME :
2005-11-25 23:42:52 +00:00
/* When trying to perform a find without expert item, we must pass
* the expert string to the find window . The user might need to modify
* the string and click on the text search to locate the packet in question .
* So regardless of the type we will just bring up the find window and allow
* the user to modify the search criteria and options .
*/
2007-12-04 07:50:44 +00:00
find_frame_with_filter ( str ) ;
2007-12-03 21:55:44 +00:00
break ;
2007-12-04 08:27:48 +00:00
case ACTION_FIND_NEXT :
2005-11-25 23:42:52 +00:00
/* In the case of find next, if there was no expert item, then most likely the expert
* string was modified to locate the text inside the message . So we can ' t just perform
* a find with the expert string or we will not really be performing a find next .
* In an effort to allow the user to modify the string and / or continue searching , we
* will just present the user with the find window again with the default expert string .
* A better aproach would be to attempt in capturing the last find string and utilize this
* with a find next / previous . Also a better approach might be to just send a < Ctl - N > keystroke .
*/
if ( err - > procedures [ selection ] . fvalue_value = = NULL ) {
find_frame_with_filter ( str ) ;
}
else
{
/* We have an expert item so just continue search without find dialog. */
2007-12-03 21:55:44 +00:00
find_previous_next_frame_with_filter ( str , FALSE ) ;
2005-11-25 23:42:52 +00:00
}
2007-12-03 21:55:44 +00:00
break ;
2007-12-04 08:27:48 +00:00
case ACTION_FIND_PREVIOUS :
2005-11-25 23:42:52 +00:00
/* In the case of find previous, if there was no expert item, then most likely the expert
* string was modified to locate the text inside the message . So we can ' t just perform
* a find with the expert string or we will not really be performing a find previous .
* In an effort to allow the user to modify the string and / or continue searching , we
* will just present the user with the find window again with the default expert string .
* A better aproach would be to attempt in capturing the last find string and utilize this
* with a find next / previous . Also a better approach might be to just send a < Ctl - B > keystroke .
*/
if ( err - > procedures [ selection ] . fvalue_value = = NULL ) {
find_frame_with_filter ( str ) ;
}
else
{
/* We have an expert item so just continue search without find dialog. */
2007-12-03 21:55:44 +00:00
find_previous_next_frame_with_filter ( str , TRUE ) ;
2005-11-25 23:42:52 +00:00
}
2007-12-03 21:55:44 +00:00
break ;
2007-12-04 08:27:48 +00:00
case ACTION_COLORIZE :
2007-12-03 21:55:44 +00:00
color_display_with_filter ( str ) ;
break ;
2007-12-04 08:27:48 +00:00
case ACTION_WEB_LOOKUP :
2007-12-03 21:55:44 +00:00
/* Lookup expert string on internet. Default search via www.google.com */
2009-03-19 17:49:11 +00:00
g_snprintf ( str , sizeof ( str ) , " http://www.google.com/search?hl=en&q=%s+'%s' " , err - > procedures [ selection ] . entries [ 1 ] , err - > procedures [ selection ] . entries [ 2 ] ) ;
2005-11-25 23:42:52 +00:00
browser_open_url ( str ) ;
2007-12-03 21:55:44 +00:00
break ;
2005-11-25 23:42:52 +00:00
default :
simple_dialog ( ESD_TYPE_ERROR , ESD_BTN_OK , " Can't find menu action - %u " , action ) ;
2007-12-03 21:55:44 +00:00
}
2005-11-25 23:42:52 +00:00
}
static gint
error_show_popup_menu_cb ( void * widg _U_ , GdkEvent * event , error_equiv_table * err )
{
GdkEventButton * bevent = ( GdkEventButton * ) event ;
if ( event - > type = = GDK_BUTTON_PRESS & & bevent - > button = = 3 ) {
gtk_menu_popup ( GTK_MENU ( err - > menu ) , NULL , NULL , NULL , NULL ,
bevent - > button , bevent - > time ) ;
}
return FALSE ;
}
static GtkItemFactoryEntry error_list_menu_items [ ] =
{
/* Match */
2008-04-11 23:12:24 +00:00
{ " /Apply as Filter " , NULL , NULL , 0 , " <Branch> " , NULL , } ,
{ " /Apply as Filter/Selected " , NULL ,
2008-05-17 22:59:52 +00:00
GTK_MENU_FUNC ( error_select_filter_cb ) , CALLBACK_MATCH ( ACTYPE_SELECTED , 0 ) ,
2008-04-11 23:12:24 +00:00
NULL , NULL , } ,
{ " /Apply as Filter/... not Selected " , NULL ,
2008-05-17 22:59:52 +00:00
GTK_MENU_FUNC ( error_select_filter_cb ) , CALLBACK_MATCH ( ACTYPE_NOT_SELECTED , 0 ) ,
2008-04-11 23:12:24 +00:00
NULL , NULL , } ,
{ " /Apply as Filter/.. and Selected " , NULL ,
2008-05-17 22:59:52 +00:00
GTK_MENU_FUNC ( error_select_filter_cb ) , CALLBACK_MATCH ( ACTYPE_AND_SELECTED , 0 ) ,
2008-04-11 23:12:24 +00:00
NULL , NULL , } ,
{ " /Apply as Filter/... or Selected " , NULL ,
2008-05-17 22:59:52 +00:00
GTK_MENU_FUNC ( error_select_filter_cb ) , CALLBACK_MATCH ( ACTYPE_OR_SELECTED , 0 ) ,
2008-04-11 23:12:24 +00:00
NULL , NULL , } ,
{ " /Apply as Filter/... and not Selected " , NULL ,
2008-05-17 22:59:52 +00:00
GTK_MENU_FUNC ( error_select_filter_cb ) , CALLBACK_MATCH ( ACTYPE_AND_NOT_SELECTED , 0 ) ,
2008-04-11 23:12:24 +00:00
NULL , NULL , } ,
{ " /Apply as Filter/... or not Selected " , NULL ,
2008-05-17 22:59:52 +00:00
GTK_MENU_FUNC ( error_select_filter_cb ) , CALLBACK_MATCH ( ACTYPE_OR_NOT_SELECTED , 0 ) ,
2008-04-11 23:12:24 +00:00
NULL , NULL , } ,
2005-11-25 23:42:52 +00:00
/* Prepare */
2008-04-11 23:12:24 +00:00
{ " /Prepare a Filter " , NULL , NULL , 0 , " <Branch> " , NULL , } ,
{ " /Prepare a Filter/Selected " , NULL ,
2008-05-17 22:59:52 +00:00
GTK_MENU_FUNC ( error_select_filter_cb ) , CALLBACK_PREPARE ( ACTYPE_SELECTED , 0 ) ,
2008-04-11 23:12:24 +00:00
NULL , NULL , } ,
{ " /Prepare a Filter/Not Selected " , NULL ,
2008-05-17 22:59:52 +00:00
GTK_MENU_FUNC ( error_select_filter_cb ) , CALLBACK_PREPARE ( ACTYPE_NOT_SELECTED , 0 ) ,
2008-04-11 23:12:24 +00:00
NULL , NULL , } ,
{ " /Prepare a Filter/... and Selected " , NULL ,
2008-05-17 22:59:52 +00:00
GTK_MENU_FUNC ( error_select_filter_cb ) , CALLBACK_PREPARE ( ACTYPE_AND_SELECTED , 0 ) ,
2008-04-11 23:12:24 +00:00
NULL , NULL , } ,
{ " /Prepare a Filter/... or Selected " , NULL ,
2008-05-17 22:59:52 +00:00
GTK_MENU_FUNC ( error_select_filter_cb ) , CALLBACK_PREPARE ( ACTYPE_OR_SELECTED , 0 ) ,
2008-04-11 23:12:24 +00:00
NULL , NULL , } ,
{ " /Prepare a Filter/... and not Selected " , NULL ,
2008-05-17 22:59:52 +00:00
GTK_MENU_FUNC ( error_select_filter_cb ) , CALLBACK_PREPARE ( ACTYPE_AND_NOT_SELECTED , 0 ) ,
2008-04-11 23:12:24 +00:00
NULL , NULL , } ,
{ " /Prepare a Filter/... or not Selected " , NULL ,
2008-05-17 22:59:52 +00:00
GTK_MENU_FUNC ( error_select_filter_cb ) , CALLBACK_PREPARE ( ACTYPE_OR_NOT_SELECTED , 0 ) ,
2008-04-11 23:12:24 +00:00
NULL , NULL , } ,
2005-11-25 23:42:52 +00:00
/* Find Frame */
2008-04-11 23:12:24 +00:00
{ " /Find Frame " , NULL , NULL , 0 , " <Branch> " , NULL , } ,
{ " /Find Frame/Find Frame " , NULL , NULL , 0 , " <Branch> " , NULL , } ,
{ " /Find Frame/Find Frame/Selected " , NULL ,
2008-05-17 22:59:52 +00:00
GTK_MENU_FUNC ( error_select_filter_cb ) , CALLBACK_FIND_FRAME ( ACTYPE_SELECTED , 0 ) ,
2008-04-11 23:12:24 +00:00
NULL , NULL , } ,
{ " /Find Frame/Find Frame/Not Selected " , NULL ,
2008-05-17 22:59:52 +00:00
GTK_MENU_FUNC ( error_select_filter_cb ) , CALLBACK_FIND_FRAME ( ACTYPE_NOT_SELECTED , 0 ) ,
2008-04-11 23:12:24 +00:00
NULL , NULL , } ,
2005-11-25 23:42:52 +00:00
/* Find Next */
2008-04-11 23:12:24 +00:00
{ " /Find Frame/Find Next " , NULL , NULL , 0 , " <Branch> " , NULL , } ,
{ " /Find Frame/Find Next/Selected " , NULL ,
2008-05-17 22:59:52 +00:00
GTK_MENU_FUNC ( error_select_filter_cb ) , CALLBACK_FIND_NEXT ( ACTYPE_SELECTED , 0 ) ,
2008-04-11 23:12:24 +00:00
NULL , NULL , } ,
{ " /Find Frame/Find Next/Not Selected " , NULL ,
2008-05-17 22:59:52 +00:00
GTK_MENU_FUNC ( error_select_filter_cb ) , CALLBACK_FIND_NEXT ( ACTYPE_NOT_SELECTED , 0 ) ,
2008-04-11 23:12:24 +00:00
NULL , NULL , } ,
2005-11-25 23:42:52 +00:00
/* Find Previous */
2008-04-11 23:12:24 +00:00
{ " /Find Frame/Find Previous " , NULL , NULL , 0 , " <Branch> " , NULL , } ,
{ " /Find Frame/Find Previous/Selected " , NULL ,
2008-05-17 22:59:52 +00:00
GTK_MENU_FUNC ( error_select_filter_cb ) , CALLBACK_FIND_PREVIOUS ( ACTYPE_SELECTED , 0 ) ,
2008-04-11 23:12:24 +00:00
NULL , NULL , } ,
{ " /Find Frame/Find Previous/Not Selected " , NULL ,
2008-05-17 22:59:52 +00:00
GTK_MENU_FUNC ( error_select_filter_cb ) , CALLBACK_FIND_PREVIOUS ( ACTYPE_NOT_SELECTED , 0 ) ,
2008-04-11 23:12:24 +00:00
NULL , NULL , } ,
2005-11-25 23:42:52 +00:00
/* Colorize Procedure */
2008-04-11 23:12:24 +00:00
{ " /Colorize Procedure " , NULL , NULL , 0 , " <Branch> " , NULL , } ,
{ " /Colorize Procedure/Selected " , NULL ,
2008-05-17 22:59:52 +00:00
GTK_MENU_FUNC ( error_select_filter_cb ) , CALLBACK_COLORIZE ( ACTYPE_SELECTED , 0 ) ,
2008-04-11 23:12:24 +00:00
NULL , NULL , } ,
{ " /Colorize Procedure/Not Selected " , NULL ,
2008-05-17 22:59:52 +00:00
GTK_MENU_FUNC ( error_select_filter_cb ) , CALLBACK_COLORIZE ( ACTYPE_NOT_SELECTED , 0 ) ,
2008-04-11 23:12:24 +00:00
NULL , NULL , } ,
2005-11-25 23:42:52 +00:00
/* Search Internet */
2008-04-11 23:12:24 +00:00
{ " /Internet Search for Info Text " , NULL ,
GTK_MENU_FUNC ( error_select_filter_cb ) , CALLBACK_WEB_LOOKUP , NULL , NULL , }
2005-11-25 23:42:52 +00:00
} ;
2006-05-04 15:36:41 +00:00
static void
2007-02-19 15:30:06 +00:00
expert_goto_pkt_cb ( GtkTreeSelection * selection , gpointer data _U_ )
2006-05-04 15:36:41 +00:00
{
GtkTreeIter iter ;
GtkTreeModel * model ;
gchar * pkt ;
gchar * grp ;
if ( gtk_tree_selection_get_selected ( selection , & model , & iter ) )
{
2009-05-19 15:53:26 +00:00
gtk_tree_model_get ( model , & iter ,
PROTOCOL_COLUMN , & pkt ,
GROUP_COLUMN , & grp ,
- 1 ) ;
2006-05-04 15:36:41 +00:00
if ( strcmp ( grp , " Packet: " ) = = 0 ) {
cf_goto_frame ( & cfile , atoi ( pkt ) ) ;
}
g_free ( pkt ) ;
g_free ( grp ) ;
}
}
2005-11-25 23:42:52 +00:00
static void
error_create_popup_menu ( error_equiv_table * err )
{
2007-12-04 07:53:23 +00:00
GtkItemFactory * item_factory ;
2005-11-25 23:42:52 +00:00
2006-05-04 15:36:41 +00:00
err - > select = gtk_tree_view_get_selection ( GTK_TREE_VIEW ( err - > tree_view ) ) ;
gtk_tree_selection_set_mode ( err - > select , GTK_SELECTION_SINGLE ) ;
g_signal_connect ( G_OBJECT ( err - > select ) , " changed " ,
G_CALLBACK ( expert_goto_pkt_cb ) ,
err ) ;
2007-12-04 07:53:23 +00:00
item_factory = gtk_item_factory_new ( GTK_TYPE_MENU , " <main> " , NULL ) ;
2005-11-25 23:42:52 +00:00
2007-12-04 07:53:23 +00:00
gtk_item_factory_create_items_ac ( item_factory , sizeof ( error_list_menu_items ) / sizeof ( error_list_menu_items [ 0 ] ) , error_list_menu_items , err , 2 ) ;
2005-11-25 23:42:52 +00:00
2007-12-04 07:53:23 +00:00
err - > menu = gtk_item_factory_get_widget ( item_factory , " <main> " ) ;
2008-04-11 21:39:16 +00:00
g_signal_connect ( err - > tree_view , " button_press_event " , G_CALLBACK ( error_show_popup_menu_cb ) , err ) ;
2005-11-25 23:42:52 +00:00
}
void
init_error_table ( error_equiv_table * err , guint16 num_procs , GtkWidget * vbox )
{
2006-12-11 03:32:01 +00:00
guint16 i , j ;
2006-05-04 15:36:41 +00:00
GtkTreeStore * store ;
GtkWidget * tree ;
GtkTreeViewColumn * column ;
GtkCellRenderer * renderer ;
GtkTreeSortable * sortable ;
/* Create the store */
store = gtk_tree_store_new ( 4 , /* Total number of columns */
G_TYPE_STRING , /* Group */
G_TYPE_STRING , /* Protocol */
G_TYPE_STRING , /* Summary */
2007-04-20 23:10:03 +00:00
G_TYPE_INT ) ; /* Count */
2006-05-04 15:36:41 +00:00
/* Create a view */
tree = gtk_tree_view_new_with_model ( GTK_TREE_MODEL ( store ) ) ;
err - > tree_view = GTK_TREE_VIEW ( tree ) ;
sortable = GTK_TREE_SORTABLE ( store ) ;
/* Setup the sortable columns */
gtk_tree_sortable_set_sort_func ( sortable , SORT_ALPHABETICAL , sort_iter_compare_func , GINT_TO_POINTER ( SORT_ALPHABETICAL ) , NULL ) ;
gtk_tree_sortable_set_sort_column_id ( sortable , SORT_ALPHABETICAL , GTK_SORT_ASCENDING ) ;
gtk_tree_view_set_headers_clickable ( GTK_TREE_VIEW ( tree ) , FALSE ) ;
/* The view now holds a reference. We can get rid of our own reference */
g_object_unref ( G_OBJECT ( store ) ) ;
2009-05-19 15:53:26 +00:00
/* Create a cell renderer */
2006-05-04 15:36:41 +00:00
renderer = gtk_cell_renderer_text_new ( ) ;
/* Create the first column, associating the "text" attribute of the
* cell_renderer to the first column of the model */
column = gtk_tree_view_column_new_with_attributes ( " Group " , renderer , " text " , GROUP_COLUMN , NULL ) ;
gtk_tree_view_column_set_sort_column_id ( column , 0 ) ;
gtk_tree_view_column_set_resizable ( column , TRUE ) ;
/* Add the column to the view. */
gtk_tree_view_append_column ( GTK_TREE_VIEW ( err - > tree_view ) , column ) ;
/* Second column.. Protocol. */
renderer = gtk_cell_renderer_text_new ( ) ;
column = gtk_tree_view_column_new_with_attributes ( " Protocol " , renderer , " text " , PROTOCOL_COLUMN , NULL ) ;
gtk_tree_view_column_set_sort_column_id ( column , 1 ) ;
gtk_tree_view_column_set_resizable ( column , TRUE ) ;
gtk_tree_view_append_column ( GTK_TREE_VIEW ( err - > tree_view ) , column ) ;
/* Third column.. Summary. */
renderer = gtk_cell_renderer_text_new ( ) ;
column = gtk_tree_view_column_new_with_attributes ( " Summary " , renderer , " text " , SUMMARY_COLUMN , NULL ) ;
gtk_tree_view_column_set_sort_column_id ( column , 2 ) ;
gtk_tree_view_column_set_resizable ( column , TRUE ) ;
gtk_tree_view_append_column ( GTK_TREE_VIEW ( err - > tree_view ) , column ) ;
/* Last column.. Count. */
column = gtk_tree_view_column_new_with_attributes ( " Count " , renderer , " text " , COUNT_COLUMN , NULL ) ;
gtk_tree_view_column_set_sort_column_id ( column , 3 ) ;
gtk_tree_view_column_set_resizable ( column , TRUE ) ;
gtk_tree_view_append_column ( GTK_TREE_VIEW ( err - > tree_view ) , column ) ;
2006-12-11 03:32:01 +00:00
err - > scrolled_window = scrolled_window_new ( NULL , NULL ) ;
2006-05-04 15:36:41 +00:00
gtk_container_add ( GTK_CONTAINER ( err - > scrolled_window ) , GTK_WIDGET ( err - > tree_view ) ) ;
2006-12-11 03:32:01 +00:00
gtk_box_pack_start ( GTK_BOX ( vbox ) , err - > scrolled_window , TRUE , TRUE , 0 ) ;
2006-05-04 15:36:41 +00:00
gtk_tree_view_set_search_column ( err - > tree_view , SUMMARY_COLUMN ) ; /* Allow searching the summary */
gtk_tree_view_set_reorderable ( err - > tree_view , TRUE ) ; /* Allow user to reorder data with drag n drop */
/* Now enable the sorting of each column */
gtk_tree_view_set_rules_hint ( GTK_TREE_VIEW ( err - > tree_view ) , TRUE ) ;
gtk_tree_view_set_headers_clickable ( GTK_TREE_VIEW ( err - > tree_view ) , TRUE ) ;
2005-11-25 23:42:52 +00:00
2006-12-11 03:32:01 +00:00
gtk_widget_show ( err - > scrolled_window ) ;
2005-11-25 23:42:52 +00:00
2006-03-19 20:26:45 +00:00
err - > num_procs = num_procs ;
2006-12-11 03:32:01 +00:00
err - > procedures = g_malloc ( sizeof ( error_procedure_t ) * ( num_procs + 1 ) ) ;
for ( i = 0 ; i < num_procs ; i + + ) {
for ( j = 0 ; j < 3 ; j + + ) {
err - > procedures [ i ] . entries [ j ] = NULL ; /* reset all values */
}
}
2005-11-25 23:42:52 +00:00
2006-12-11 03:32:01 +00:00
/* create popup menu for this table */
error_create_popup_menu ( err ) ;
2005-11-25 23:42:52 +00:00
}
void
init_error_table_row ( error_equiv_table * err , const expert_info_t * expert_data )
{
guint16 old_num_procs = err - > num_procs ;
guint16 j ;
gint row = 0 ;
2006-05-04 15:36:41 +00:00
GtkTreeStore * store ;
2006-05-15 02:43:39 +00:00
/* we have discovered a new procedure. Extend the table accordingly */
2005-11-25 23:42:52 +00:00
row = find_summary_data ( err , expert_data ) ;
2006-05-15 02:43:39 +00:00
if ( row = = - 1 ) {
2006-05-04 15:36:41 +00:00
/* First time we have seen this event so initialize memory table */
row = old_num_procs ; /* Number of expert events since this is a new event */
2006-05-15 02:43:39 +00:00
err - > procedures = g_realloc ( err - > procedures , ( sizeof ( error_procedure_t ) * ( old_num_procs + 1 ) ) ) ;
2006-05-04 15:36:41 +00:00
err - > procedures [ row ] . count = 0 ; /* count of events for this item */
err - > procedures [ row ] . fvalue_value = NULL ; /* Filter string value */
2006-03-19 20:26:45 +00:00
for ( j = 0 ; j < 4 ; j + + ) {
2006-05-15 02:43:39 +00:00
err - > procedures [ row ] . entries [ j ] = NULL ;
}
2006-05-04 15:36:41 +00:00
2006-05-15 02:43:39 +00:00
/* Create the item in our memory table */
2006-11-23 21:16:46 +00:00
err - > procedures [ row ] . entries [ 0 ] = ( char * ) g_strdup ( val_to_str ( expert_data - > group , expert_group_vals , " Unknown group (%u) " ) ) ; /* Group */
err - > procedures [ row ] . entries [ 1 ] = ( char * ) g_strdup ( expert_data - > protocol ) ; /* Protocol */
err - > procedures [ row ] . entries [ 2 ] = ( char * ) g_strdup ( expert_data - > summary ) ; /* Summary */
2006-05-04 15:36:41 +00:00
/* Create a new item in our tree view */
store = GTK_TREE_STORE ( gtk_tree_view_get_model ( err - > tree_view ) ) ; /* Get store */
gtk_tree_store_append ( store , & err - > procedures [ row ] . iter , NULL ) ; /* Acquire an iterator */
2009-05-19 15:53:26 +00:00
/* (Note: gtk_tree_store_set *copies* the input strings) */
2006-05-04 15:36:41 +00:00
gtk_tree_store_set ( store , & err - > procedures [ row ] . iter ,
2009-05-19 15:53:26 +00:00
GROUP_COLUMN , val_to_str ( expert_data - > group , expert_group_vals , " Unknown group (%u) " ) ,
PROTOCOL_COLUMN , expert_data - > protocol ,
SUMMARY_COLUMN , expert_data - > summary ,
- 1 ) ;
2006-05-04 15:36:41 +00:00
/* If an expert item was passed then build the filter string */
2006-11-23 21:16:46 +00:00
if ( expert_data - > pitem ) {
char * filter ;
2006-11-24 18:25:23 +00:00
filter = proto_construct_match_selected_string ( expert_data - > pitem - > finfo , NULL ) ;
if ( filter ! = NULL )
2006-11-23 21:16:46 +00:00
err - > procedures [ row ] . fvalue_value = g_strdup ( filter ) ;
2006-03-19 20:26:45 +00:00
}
2006-05-04 15:36:41 +00:00
/* Store the updated count of events */
err - > num_procs = + + old_num_procs ;
2006-05-15 02:43:39 +00:00
}
2006-05-04 15:36:41 +00:00
/* Update our memory table with event data */
err - > procedures [ row ] . count + + ; /* increment the count of events for this item */
/* Store the updated count for this event item */
2006-05-15 02:43:39 +00:00
err - > procedures [ row ] . entries [ 3 ] = ( char * ) g_strdup_printf ( " %d " , err - > procedures [ row ] . count ) ; /* Count */
2006-05-04 15:36:41 +00:00
/* Update the tree with new count for this event */
store = GTK_TREE_STORE ( gtk_tree_view_get_model ( err - > tree_view ) ) ;
2007-04-20 23:10:03 +00:00
gtk_tree_store_set ( store , & err - > procedures [ row ] . iter , COUNT_COLUMN , err - > procedures [ row ] . count , - 1 ) ;
2005-11-25 23:42:52 +00:00
}
void
add_error_table_data ( error_equiv_table * err , const expert_info_t * expert_data )
{
2007-12-03 21:55:44 +00:00
error_procedure_t * errp ;
2005-11-25 23:42:52 +00:00
gint index ;
2006-05-04 15:36:41 +00:00
GtkTreeStore * store ;
GtkTreeIter new_iter ;
2009-05-19 15:53:26 +00:00
gchar str [ 16 ] ;
2005-11-25 23:42:52 +00:00
2009-05-19 15:53:26 +00:00
index = find_summary_data ( err , expert_data ) ;
2005-11-25 23:42:52 +00:00
/* We should never encounter a condition where we cannot find the expert data. If
* we do then we will just abort .
*/
if ( index = = - 1 ) {
simple_dialog ( ESD_TYPE_ERROR , ESD_BTN_OK , " Could not find expert data. Aborting " ) ;
return ;
}
2007-12-03 21:55:44 +00:00
errp = & err - > procedures [ index ] ;
2006-05-04 15:36:41 +00:00
store = GTK_TREE_STORE ( gtk_tree_view_get_model ( err - > tree_view ) ) ;
2009-05-19 15:53:26 +00:00
g_snprintf ( str , sizeof ( str ) , " %d " , expert_data - > packet_num ) ;
2006-05-04 15:36:41 +00:00
gtk_tree_store_append ( store , & new_iter , & errp - > iter ) ;
gtk_tree_store_set ( store , & new_iter ,
2009-05-19 15:53:26 +00:00
GROUP_COLUMN , " Packet: " ,
PROTOCOL_COLUMN , str ,
COUNT_COLUMN , 1 ,
- 1 ) ;
2005-11-25 23:42:52 +00:00
}
void
reset_error_table_data ( error_equiv_table * err )
{
2007-12-03 21:55:44 +00:00
guint16 i ;
2006-05-04 15:36:41 +00:00
GtkTreeStore * store ;
2005-11-25 23:42:52 +00:00
2007-12-03 21:55:44 +00:00
for ( i = 0 ; i < err - > num_procs ; i + + ) {
err - > procedures [ i ] . entries [ 0 ] = NULL ;
err - > procedures [ i ] . entries [ 1 ] = NULL ;
err - > procedures [ i ] . entries [ 2 ] = NULL ;
err - > procedures [ i ] . entries [ 3 ] = NULL ;
2006-05-04 15:36:41 +00:00
err - > procedures [ i ] . count = 0 ;
2007-12-03 21:55:44 +00:00
}
2006-05-04 15:36:41 +00:00
store = GTK_TREE_STORE ( gtk_tree_view_get_model ( err - > tree_view ) ) ;
gtk_tree_store_clear ( store ) ;
2005-11-25 23:42:52 +00:00
err - > num_procs = 0 ;
}
void
free_error_table_data ( error_equiv_table * err )
{
2007-12-03 21:55:44 +00:00
guint16 i , j ;
2005-11-25 23:42:52 +00:00
2007-12-03 21:55:44 +00:00
for ( i = 0 ; i < err - > num_procs ; i + + ) {
for ( j = 0 ; j < 4 ; j + + ) {
if ( err - > procedures [ i ] . entries [ j ] ) {
err - > procedures [ i ] . entries [ j ] = NULL ;
}
2005-11-25 23:42:52 +00:00
err - > procedures [ i ] . fvalue_value = NULL ;
2006-05-04 15:36:41 +00:00
err - > procedures [ i ] . count = 0 ;
2007-12-03 21:55:44 +00:00
}
}
err - > procedures = NULL ;
err - > num_procs = 0 ;
2005-11-25 23:42:52 +00:00
}